Minor stylistic cleanup in Windows platform (#35503)
This PR doesn't change any logic, it just cleans up some naming and style in the windows platform layer. * Rename `WindowsWindowStatePtr` to `WindowsWindowInner`, since it isn't a pointer type. * Move window event handler methods into an impl on this type, so that all of the `state_ptr: &Rc<WindowsWindowInner>` parameters can just be replaced with `&self`. * In window creation, use a `match` instead of a conditional followed by an unwrap There's a lot of whitespace in the diff, so view it with `w=1`. Release Notes: - N/A
This commit is contained in:
parent
0ea4016e66
commit
f3f2dba606
3 changed files with 1233 additions and 1309 deletions
File diff suppressed because it is too large
Load diff
|
@ -144,12 +144,12 @@ impl WindowsPlatform {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn try_get_windows_inner_from_hwnd(&self, hwnd: HWND) -> Option<Rc<WindowsWindowStatePtr>> {
|
||||
pub fn window_from_hwnd(&self, hwnd: HWND) -> Option<Rc<WindowsWindowInner>> {
|
||||
self.raw_window_handles
|
||||
.read()
|
||||
.iter()
|
||||
.find(|entry| *entry == &hwnd)
|
||||
.and_then(|hwnd| try_get_window_inner(*hwnd))
|
||||
.and_then(|hwnd| window_from_hwnd(*hwnd))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -434,7 +434,7 @@ impl Platform for WindowsPlatform {
|
|||
|
||||
fn active_window(&self) -> Option<AnyWindowHandle> {
|
||||
let active_window_hwnd = unsafe { GetActiveWindow() };
|
||||
self.try_get_windows_inner_from_hwnd(active_window_hwnd)
|
||||
self.window_from_hwnd(active_window_hwnd)
|
||||
.map(|inner| inner.handle)
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ use windows::{
|
|||
|
||||
use crate::*;
|
||||
|
||||
pub(crate) struct WindowsWindow(pub Rc<WindowsWindowStatePtr>);
|
||||
pub(crate) struct WindowsWindow(pub Rc<WindowsWindowInner>);
|
||||
|
||||
pub struct WindowsWindowState {
|
||||
pub origin: Point<Pixels>,
|
||||
|
@ -61,9 +61,9 @@ pub struct WindowsWindowState {
|
|||
hwnd: HWND,
|
||||
}
|
||||
|
||||
pub(crate) struct WindowsWindowStatePtr {
|
||||
pub(crate) struct WindowsWindowInner {
|
||||
hwnd: HWND,
|
||||
this: Weak<Self>,
|
||||
pub(super) this: Weak<Self>,
|
||||
drop_target_helper: IDropTargetHelper,
|
||||
pub(crate) state: RefCell<WindowsWindowState>,
|
||||
pub(crate) handle: AnyWindowHandle,
|
||||
|
@ -79,7 +79,7 @@ pub(crate) struct WindowsWindowStatePtr {
|
|||
impl WindowsWindowState {
|
||||
fn new(
|
||||
hwnd: HWND,
|
||||
cs: &CREATESTRUCTW,
|
||||
window_params: &CREATESTRUCTW,
|
||||
current_cursor: Option<HCURSOR>,
|
||||
display: WindowsDisplay,
|
||||
min_size: Option<Size<Pixels>>,
|
||||
|
@ -90,9 +90,12 @@ impl WindowsWindowState {
|
|||
let monitor_dpi = unsafe { GetDpiForWindow(hwnd) } as f32;
|
||||
monitor_dpi / USER_DEFAULT_SCREEN_DPI as f32
|
||||
};
|
||||
let origin = logical_point(cs.x as f32, cs.y as f32, scale_factor);
|
||||
let origin = logical_point(window_params.x as f32, window_params.y as f32, scale_factor);
|
||||
let logical_size = {
|
||||
let physical_size = size(DevicePixels(cs.cx), DevicePixels(cs.cy));
|
||||
let physical_size = size(
|
||||
DevicePixels(window_params.cx),
|
||||
DevicePixels(window_params.cy),
|
||||
);
|
||||
physical_size.to_pixels(scale_factor)
|
||||
};
|
||||
let fullscreen_restore_bounds = Bounds {
|
||||
|
@ -201,7 +204,7 @@ impl WindowsWindowState {
|
|||
}
|
||||
}
|
||||
|
||||
impl WindowsWindowStatePtr {
|
||||
impl WindowsWindowInner {
|
||||
fn new(context: &WindowCreateContext, hwnd: HWND, cs: &CREATESTRUCTW) -> Result<Rc<Self>> {
|
||||
let state = RefCell::new(WindowsWindowState::new(
|
||||
hwnd,
|
||||
|
@ -230,13 +233,13 @@ impl WindowsWindowStatePtr {
|
|||
}
|
||||
|
||||
fn toggle_fullscreen(&self) {
|
||||
let Some(state_ptr) = self.this.upgrade() else {
|
||||
let Some(this) = self.this.upgrade() else {
|
||||
log::error!("Unable to toggle fullscreen: window has been dropped");
|
||||
return;
|
||||
};
|
||||
self.executor
|
||||
.spawn(async move {
|
||||
let mut lock = state_ptr.state.borrow_mut();
|
||||
let mut lock = this.state.borrow_mut();
|
||||
let StyleAndBounds {
|
||||
style,
|
||||
x,
|
||||
|
@ -248,10 +251,9 @@ impl WindowsWindowStatePtr {
|
|||
} else {
|
||||
let (window_bounds, _) = lock.calculate_window_bounds();
|
||||
lock.fullscreen_restore_bounds = window_bounds;
|
||||
let style =
|
||||
WINDOW_STYLE(unsafe { get_window_long(state_ptr.hwnd, GWL_STYLE) } as _);
|
||||
let style = WINDOW_STYLE(unsafe { get_window_long(this.hwnd, GWL_STYLE) } as _);
|
||||
let mut rc = RECT::default();
|
||||
unsafe { GetWindowRect(state_ptr.hwnd, &mut rc) }.log_err();
|
||||
unsafe { GetWindowRect(this.hwnd, &mut rc) }.log_err();
|
||||
let _ = lock.fullscreen.insert(StyleAndBounds {
|
||||
style,
|
||||
x: rc.left,
|
||||
|
@ -275,10 +277,10 @@ impl WindowsWindowStatePtr {
|
|||
}
|
||||
};
|
||||
drop(lock);
|
||||
unsafe { set_window_long(state_ptr.hwnd, GWL_STYLE, style.0 as isize) };
|
||||
unsafe { set_window_long(this.hwnd, GWL_STYLE, style.0 as isize) };
|
||||
unsafe {
|
||||
SetWindowPos(
|
||||
state_ptr.hwnd,
|
||||
this.hwnd,
|
||||
None,
|
||||
x,
|
||||
y,
|
||||
|
@ -328,7 +330,7 @@ pub(crate) struct Callbacks {
|
|||
}
|
||||
|
||||
struct WindowCreateContext {
|
||||
inner: Option<Result<Rc<WindowsWindowStatePtr>>>,
|
||||
inner: Option<Result<Rc<WindowsWindowInner>>>,
|
||||
handle: AnyWindowHandle,
|
||||
hide_title_bar: bool,
|
||||
display: WindowsDisplay,
|
||||
|
@ -362,13 +364,13 @@ impl WindowsWindow {
|
|||
main_thread_id_win32,
|
||||
disable_direct_composition,
|
||||
} = creation_info;
|
||||
let classname = register_wnd_class(icon);
|
||||
register_window_class(icon);
|
||||
let hide_title_bar = params
|
||||
.titlebar
|
||||
.as_ref()
|
||||
.map(|titlebar| titlebar.appears_transparent)
|
||||
.unwrap_or(true);
|
||||
let windowname = HSTRING::from(
|
||||
let window_name = HSTRING::from(
|
||||
params
|
||||
.titlebar
|
||||
.as_ref()
|
||||
|
@ -414,12 +416,11 @@ impl WindowsWindow {
|
|||
appearance,
|
||||
disable_direct_composition,
|
||||
};
|
||||
let lpparam = Some(&context as *const _ as *const _);
|
||||
let creation_result = unsafe {
|
||||
CreateWindowExW(
|
||||
dwexstyle,
|
||||
classname,
|
||||
&windowname,
|
||||
WINDOW_CLASS_NAME,
|
||||
&window_name,
|
||||
dwstyle,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
|
@ -428,33 +429,35 @@ impl WindowsWindow {
|
|||
None,
|
||||
None,
|
||||
Some(hinstance.into()),
|
||||
lpparam,
|
||||
Some(&context as *const _ as *const _),
|
||||
)
|
||||
};
|
||||
// We should call `?` on state_ptr first, then call `?` on hwnd.
|
||||
// Or, we will lose the error info reported by `WindowsWindowState::new`
|
||||
let state_ptr = context.inner.take().unwrap()?;
|
||||
|
||||
// Failure to create a `WindowsWindowState` can cause window creation to fail,
|
||||
// so check the inner result first.
|
||||
let this = context.inner.take().unwrap()?;
|
||||
let hwnd = creation_result?;
|
||||
register_drag_drop(state_ptr.clone())?;
|
||||
|
||||
register_drag_drop(&this)?;
|
||||
configure_dwm_dark_mode(hwnd, appearance);
|
||||
state_ptr.state.borrow_mut().border_offset.update(hwnd)?;
|
||||
this.state.borrow_mut().border_offset.update(hwnd)?;
|
||||
let placement = retrieve_window_placement(
|
||||
hwnd,
|
||||
display,
|
||||
params.bounds,
|
||||
state_ptr.state.borrow().scale_factor,
|
||||
state_ptr.state.borrow().border_offset,
|
||||
this.state.borrow().scale_factor,
|
||||
this.state.borrow().border_offset,
|
||||
)?;
|
||||
if params.show {
|
||||
unsafe { SetWindowPlacement(hwnd, &placement)? };
|
||||
} else {
|
||||
state_ptr.state.borrow_mut().initial_placement = Some(WindowOpenStatus {
|
||||
this.state.borrow_mut().initial_placement = Some(WindowOpenStatus {
|
||||
placement,
|
||||
state: WindowOpenState::Windowed,
|
||||
});
|
||||
}
|
||||
|
||||
Ok(Self(state_ptr))
|
||||
Ok(Self(this))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -803,7 +806,7 @@ impl PlatformWindow for WindowsWindow {
|
|||
}
|
||||
|
||||
#[implement(IDropTarget)]
|
||||
struct WindowsDragDropHandler(pub Rc<WindowsWindowStatePtr>);
|
||||
struct WindowsDragDropHandler(pub Rc<WindowsWindowInner>);
|
||||
|
||||
impl WindowsDragDropHandler {
|
||||
fn handle_drag_drop(&self, input: PlatformInput) {
|
||||
|
@ -1084,15 +1087,15 @@ enum WindowOpenState {
|
|||
Windowed,
|
||||
}
|
||||
|
||||
fn register_wnd_class(icon_handle: HICON) -> PCWSTR {
|
||||
const CLASS_NAME: PCWSTR = w!("Zed::Window");
|
||||
const WINDOW_CLASS_NAME: PCWSTR = w!("Zed::Window");
|
||||
|
||||
fn register_window_class(icon_handle: HICON) {
|
||||
static ONCE: Once = Once::new();
|
||||
ONCE.call_once(|| {
|
||||
let wc = WNDCLASSW {
|
||||
lpfnWndProc: Some(wnd_proc),
|
||||
lpfnWndProc: Some(window_procedure),
|
||||
hIcon: icon_handle,
|
||||
lpszClassName: PCWSTR(CLASS_NAME.as_ptr()),
|
||||
lpszClassName: PCWSTR(WINDOW_CLASS_NAME.as_ptr()),
|
||||
style: CS_HREDRAW | CS_VREDRAW,
|
||||
hInstance: get_module_handle().into(),
|
||||
hbrBackground: unsafe { CreateSolidBrush(COLORREF(0x00000000)) },
|
||||
|
@ -1100,54 +1103,58 @@ fn register_wnd_class(icon_handle: HICON) -> PCWSTR {
|
|||
};
|
||||
unsafe { RegisterClassW(&wc) };
|
||||
});
|
||||
|
||||
CLASS_NAME
|
||||
}
|
||||
|
||||
unsafe extern "system" fn wnd_proc(
|
||||
unsafe extern "system" fn window_procedure(
|
||||
hwnd: HWND,
|
||||
msg: u32,
|
||||
wparam: WPARAM,
|
||||
lparam: LPARAM,
|
||||
) -> LRESULT {
|
||||
if msg == WM_NCCREATE {
|
||||
let cs = lparam.0 as *const CREATESTRUCTW;
|
||||
let cs = unsafe { &*cs };
|
||||
let ctx = cs.lpCreateParams as *mut WindowCreateContext;
|
||||
let ctx = unsafe { &mut *ctx };
|
||||
let creation_result = WindowsWindowStatePtr::new(ctx, hwnd, cs);
|
||||
if creation_result.is_err() {
|
||||
ctx.inner = Some(creation_result);
|
||||
return LRESULT(0);
|
||||
}
|
||||
let weak = Box::new(Rc::downgrade(creation_result.as_ref().unwrap()));
|
||||
unsafe { set_window_long(hwnd, GWLP_USERDATA, Box::into_raw(weak) as isize) };
|
||||
ctx.inner = Some(creation_result);
|
||||
return unsafe { DefWindowProcW(hwnd, msg, wparam, lparam) };
|
||||
let window_params = lparam.0 as *const CREATESTRUCTW;
|
||||
let window_params = unsafe { &*window_params };
|
||||
let window_creation_context = window_params.lpCreateParams as *mut WindowCreateContext;
|
||||
let window_creation_context = unsafe { &mut *window_creation_context };
|
||||
return match WindowsWindowInner::new(window_creation_context, hwnd, window_params) {
|
||||
Ok(window_state) => {
|
||||
let weak = Box::new(Rc::downgrade(&window_state));
|
||||
unsafe { set_window_long(hwnd, GWLP_USERDATA, Box::into_raw(weak) as isize) };
|
||||
window_creation_context.inner = Some(Ok(window_state));
|
||||
unsafe { DefWindowProcW(hwnd, msg, wparam, lparam) }
|
||||
}
|
||||
Err(error) => {
|
||||
window_creation_context.inner = Some(Err(error));
|
||||
LRESULT(0)
|
||||
}
|
||||
};
|
||||
}
|
||||
let ptr = unsafe { get_window_long(hwnd, GWLP_USERDATA) } as *mut Weak<WindowsWindowStatePtr>;
|
||||
|
||||
let ptr = unsafe { get_window_long(hwnd, GWLP_USERDATA) } as *mut Weak<WindowsWindowInner>;
|
||||
if ptr.is_null() {
|
||||
return unsafe { DefWindowProcW(hwnd, msg, wparam, lparam) };
|
||||
}
|
||||
let inner = unsafe { &*ptr };
|
||||
let r = if let Some(state) = inner.upgrade() {
|
||||
handle_msg(hwnd, msg, wparam, lparam, state)
|
||||
let result = if let Some(inner) = inner.upgrade() {
|
||||
inner.handle_msg(hwnd, msg, wparam, lparam)
|
||||
} else {
|
||||
unsafe { DefWindowProcW(hwnd, msg, wparam, lparam) }
|
||||
};
|
||||
|
||||
if msg == WM_NCDESTROY {
|
||||
unsafe { set_window_long(hwnd, GWLP_USERDATA, 0) };
|
||||
unsafe { drop(Box::from_raw(ptr)) };
|
||||
}
|
||||
r
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
pub(crate) fn try_get_window_inner(hwnd: HWND) -> Option<Rc<WindowsWindowStatePtr>> {
|
||||
pub(crate) fn window_from_hwnd(hwnd: HWND) -> Option<Rc<WindowsWindowInner>> {
|
||||
if hwnd.is_invalid() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let ptr = unsafe { get_window_long(hwnd, GWLP_USERDATA) } as *mut Weak<WindowsWindowStatePtr>;
|
||||
let ptr = unsafe { get_window_long(hwnd, GWLP_USERDATA) } as *mut Weak<WindowsWindowInner>;
|
||||
if !ptr.is_null() {
|
||||
let inner = unsafe { &*ptr };
|
||||
inner.upgrade()
|
||||
|
@ -1170,9 +1177,9 @@ fn get_module_handle() -> HMODULE {
|
|||
}
|
||||
}
|
||||
|
||||
fn register_drag_drop(state_ptr: Rc<WindowsWindowStatePtr>) -> Result<()> {
|
||||
let window_handle = state_ptr.hwnd;
|
||||
let handler = WindowsDragDropHandler(state_ptr);
|
||||
fn register_drag_drop(window: &Rc<WindowsWindowInner>) -> Result<()> {
|
||||
let window_handle = window.hwnd;
|
||||
let handler = WindowsDragDropHandler(window.clone());
|
||||
// The lifetime of `IDropTarget` is handled by Windows, it won't release until
|
||||
// we call `RevokeDragDrop`.
|
||||
// So, it's safe to drop it here.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue