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:
Max Brunsfeld 2025-08-04 11:22:49 -07:00 committed by GitHub
parent 0ea4016e66
commit f3f2dba606
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 1233 additions and 1309 deletions

File diff suppressed because it is too large Load diff

View file

@ -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 self.raw_window_handles
.read() .read()
.iter() .iter()
.find(|entry| *entry == &hwnd) .find(|entry| *entry == &hwnd)
.and_then(|hwnd| try_get_window_inner(*hwnd)) .and_then(|hwnd| window_from_hwnd(*hwnd))
} }
#[inline] #[inline]
@ -434,7 +434,7 @@ impl Platform for WindowsPlatform {
fn active_window(&self) -> Option<AnyWindowHandle> { fn active_window(&self) -> Option<AnyWindowHandle> {
let active_window_hwnd = unsafe { GetActiveWindow() }; 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) .map(|inner| inner.handle)
} }

View file

@ -28,7 +28,7 @@ use windows::{
use crate::*; use crate::*;
pub(crate) struct WindowsWindow(pub Rc<WindowsWindowStatePtr>); pub(crate) struct WindowsWindow(pub Rc<WindowsWindowInner>);
pub struct WindowsWindowState { pub struct WindowsWindowState {
pub origin: Point<Pixels>, pub origin: Point<Pixels>,
@ -61,9 +61,9 @@ pub struct WindowsWindowState {
hwnd: HWND, hwnd: HWND,
} }
pub(crate) struct WindowsWindowStatePtr { pub(crate) struct WindowsWindowInner {
hwnd: HWND, hwnd: HWND,
this: Weak<Self>, pub(super) this: Weak<Self>,
drop_target_helper: IDropTargetHelper, drop_target_helper: IDropTargetHelper,
pub(crate) state: RefCell<WindowsWindowState>, pub(crate) state: RefCell<WindowsWindowState>,
pub(crate) handle: AnyWindowHandle, pub(crate) handle: AnyWindowHandle,
@ -79,7 +79,7 @@ pub(crate) struct WindowsWindowStatePtr {
impl WindowsWindowState { impl WindowsWindowState {
fn new( fn new(
hwnd: HWND, hwnd: HWND,
cs: &CREATESTRUCTW, window_params: &CREATESTRUCTW,
current_cursor: Option<HCURSOR>, current_cursor: Option<HCURSOR>,
display: WindowsDisplay, display: WindowsDisplay,
min_size: Option<Size<Pixels>>, min_size: Option<Size<Pixels>>,
@ -90,9 +90,12 @@ impl WindowsWindowState {
let monitor_dpi = unsafe { GetDpiForWindow(hwnd) } as f32; let monitor_dpi = unsafe { GetDpiForWindow(hwnd) } as f32;
monitor_dpi / USER_DEFAULT_SCREEN_DPI 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 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) physical_size.to_pixels(scale_factor)
}; };
let fullscreen_restore_bounds = Bounds { 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>> { fn new(context: &WindowCreateContext, hwnd: HWND, cs: &CREATESTRUCTW) -> Result<Rc<Self>> {
let state = RefCell::new(WindowsWindowState::new( let state = RefCell::new(WindowsWindowState::new(
hwnd, hwnd,
@ -230,13 +233,13 @@ impl WindowsWindowStatePtr {
} }
fn toggle_fullscreen(&self) { 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"); log::error!("Unable to toggle fullscreen: window has been dropped");
return; return;
}; };
self.executor self.executor
.spawn(async move { .spawn(async move {
let mut lock = state_ptr.state.borrow_mut(); let mut lock = this.state.borrow_mut();
let StyleAndBounds { let StyleAndBounds {
style, style,
x, x,
@ -248,10 +251,9 @@ impl WindowsWindowStatePtr {
} else { } else {
let (window_bounds, _) = lock.calculate_window_bounds(); let (window_bounds, _) = lock.calculate_window_bounds();
lock.fullscreen_restore_bounds = window_bounds; lock.fullscreen_restore_bounds = window_bounds;
let style = let style = WINDOW_STYLE(unsafe { get_window_long(this.hwnd, GWL_STYLE) } as _);
WINDOW_STYLE(unsafe { get_window_long(state_ptr.hwnd, GWL_STYLE) } as _);
let mut rc = RECT::default(); 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 { let _ = lock.fullscreen.insert(StyleAndBounds {
style, style,
x: rc.left, x: rc.left,
@ -275,10 +277,10 @@ impl WindowsWindowStatePtr {
} }
}; };
drop(lock); 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 { unsafe {
SetWindowPos( SetWindowPos(
state_ptr.hwnd, this.hwnd,
None, None,
x, x,
y, y,
@ -328,7 +330,7 @@ pub(crate) struct Callbacks {
} }
struct WindowCreateContext { struct WindowCreateContext {
inner: Option<Result<Rc<WindowsWindowStatePtr>>>, inner: Option<Result<Rc<WindowsWindowInner>>>,
handle: AnyWindowHandle, handle: AnyWindowHandle,
hide_title_bar: bool, hide_title_bar: bool,
display: WindowsDisplay, display: WindowsDisplay,
@ -362,13 +364,13 @@ impl WindowsWindow {
main_thread_id_win32, main_thread_id_win32,
disable_direct_composition, disable_direct_composition,
} = creation_info; } = creation_info;
let classname = register_wnd_class(icon); register_window_class(icon);
let hide_title_bar = params let hide_title_bar = params
.titlebar .titlebar
.as_ref() .as_ref()
.map(|titlebar| titlebar.appears_transparent) .map(|titlebar| titlebar.appears_transparent)
.unwrap_or(true); .unwrap_or(true);
let windowname = HSTRING::from( let window_name = HSTRING::from(
params params
.titlebar .titlebar
.as_ref() .as_ref()
@ -414,12 +416,11 @@ impl WindowsWindow {
appearance, appearance,
disable_direct_composition, disable_direct_composition,
}; };
let lpparam = Some(&context as *const _ as *const _);
let creation_result = unsafe { let creation_result = unsafe {
CreateWindowExW( CreateWindowExW(
dwexstyle, dwexstyle,
classname, WINDOW_CLASS_NAME,
&windowname, &window_name,
dwstyle, dwstyle,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
@ -428,33 +429,35 @@ impl WindowsWindow {
None, None,
None, None,
Some(hinstance.into()), 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` // Failure to create a `WindowsWindowState` can cause window creation to fail,
let state_ptr = context.inner.take().unwrap()?; // so check the inner result first.
let this = context.inner.take().unwrap()?;
let hwnd = creation_result?; let hwnd = creation_result?;
register_drag_drop(state_ptr.clone())?;
register_drag_drop(&this)?;
configure_dwm_dark_mode(hwnd, appearance); 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( let placement = retrieve_window_placement(
hwnd, hwnd,
display, display,
params.bounds, params.bounds,
state_ptr.state.borrow().scale_factor, this.state.borrow().scale_factor,
state_ptr.state.borrow().border_offset, this.state.borrow().border_offset,
)?; )?;
if params.show { if params.show {
unsafe { SetWindowPlacement(hwnd, &placement)? }; unsafe { SetWindowPlacement(hwnd, &placement)? };
} else { } else {
state_ptr.state.borrow_mut().initial_placement = Some(WindowOpenStatus { this.state.borrow_mut().initial_placement = Some(WindowOpenStatus {
placement, placement,
state: WindowOpenState::Windowed, state: WindowOpenState::Windowed,
}); });
} }
Ok(Self(state_ptr)) Ok(Self(this))
} }
} }
@ -803,7 +806,7 @@ impl PlatformWindow for WindowsWindow {
} }
#[implement(IDropTarget)] #[implement(IDropTarget)]
struct WindowsDragDropHandler(pub Rc<WindowsWindowStatePtr>); struct WindowsDragDropHandler(pub Rc<WindowsWindowInner>);
impl WindowsDragDropHandler { impl WindowsDragDropHandler {
fn handle_drag_drop(&self, input: PlatformInput) { fn handle_drag_drop(&self, input: PlatformInput) {
@ -1084,15 +1087,15 @@ enum WindowOpenState {
Windowed, Windowed,
} }
fn register_wnd_class(icon_handle: HICON) -> PCWSTR { const WINDOW_CLASS_NAME: PCWSTR = w!("Zed::Window");
const CLASS_NAME: PCWSTR = w!("Zed::Window");
fn register_window_class(icon_handle: HICON) {
static ONCE: Once = Once::new(); static ONCE: Once = Once::new();
ONCE.call_once(|| { ONCE.call_once(|| {
let wc = WNDCLASSW { let wc = WNDCLASSW {
lpfnWndProc: Some(wnd_proc), lpfnWndProc: Some(window_procedure),
hIcon: icon_handle, hIcon: icon_handle,
lpszClassName: PCWSTR(CLASS_NAME.as_ptr()), lpszClassName: PCWSTR(WINDOW_CLASS_NAME.as_ptr()),
style: CS_HREDRAW | CS_VREDRAW, style: CS_HREDRAW | CS_VREDRAW,
hInstance: get_module_handle().into(), hInstance: get_module_handle().into(),
hbrBackground: unsafe { CreateSolidBrush(COLORREF(0x00000000)) }, hbrBackground: unsafe { CreateSolidBrush(COLORREF(0x00000000)) },
@ -1100,54 +1103,58 @@ fn register_wnd_class(icon_handle: HICON) -> PCWSTR {
}; };
unsafe { RegisterClassW(&wc) }; unsafe { RegisterClassW(&wc) };
}); });
CLASS_NAME
} }
unsafe extern "system" fn wnd_proc( unsafe extern "system" fn window_procedure(
hwnd: HWND, hwnd: HWND,
msg: u32, msg: u32,
wparam: WPARAM, wparam: WPARAM,
lparam: LPARAM, lparam: LPARAM,
) -> LRESULT { ) -> LRESULT {
if msg == WM_NCCREATE { if msg == WM_NCCREATE {
let cs = lparam.0 as *const CREATESTRUCTW; let window_params = lparam.0 as *const CREATESTRUCTW;
let cs = unsafe { &*cs }; let window_params = unsafe { &*window_params };
let ctx = cs.lpCreateParams as *mut WindowCreateContext; let window_creation_context = window_params.lpCreateParams as *mut WindowCreateContext;
let ctx = unsafe { &mut *ctx }; let window_creation_context = unsafe { &mut *window_creation_context };
let creation_result = WindowsWindowStatePtr::new(ctx, hwnd, cs); return match WindowsWindowInner::new(window_creation_context, hwnd, window_params) {
if creation_result.is_err() { Ok(window_state) => {
ctx.inner = Some(creation_result); let weak = Box::new(Rc::downgrade(&window_state));
return LRESULT(0); unsafe { set_window_long(hwnd, GWLP_USERDATA, Box::into_raw(weak) as isize) };
} window_creation_context.inner = Some(Ok(window_state));
let weak = Box::new(Rc::downgrade(creation_result.as_ref().unwrap())); unsafe { DefWindowProcW(hwnd, msg, wparam, lparam) }
unsafe { set_window_long(hwnd, GWLP_USERDATA, Box::into_raw(weak) as isize) }; }
ctx.inner = Some(creation_result); Err(error) => {
return unsafe { DefWindowProcW(hwnd, msg, wparam, lparam) }; 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() { if ptr.is_null() {
return unsafe { DefWindowProcW(hwnd, msg, wparam, lparam) }; return unsafe { DefWindowProcW(hwnd, msg, wparam, lparam) };
} }
let inner = unsafe { &*ptr }; let inner = unsafe { &*ptr };
let r = if let Some(state) = inner.upgrade() { let result = if let Some(inner) = inner.upgrade() {
handle_msg(hwnd, msg, wparam, lparam, state) inner.handle_msg(hwnd, msg, wparam, lparam)
} else { } else {
unsafe { DefWindowProcW(hwnd, msg, wparam, lparam) } unsafe { DefWindowProcW(hwnd, msg, wparam, lparam) }
}; };
if msg == WM_NCDESTROY { if msg == WM_NCDESTROY {
unsafe { set_window_long(hwnd, GWLP_USERDATA, 0) }; unsafe { set_window_long(hwnd, GWLP_USERDATA, 0) };
unsafe { drop(Box::from_raw(ptr)) }; 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() { if hwnd.is_invalid() {
return None; 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() { if !ptr.is_null() {
let inner = unsafe { &*ptr }; let inner = unsafe { &*ptr };
inner.upgrade() inner.upgrade()
@ -1170,9 +1177,9 @@ fn get_module_handle() -> HMODULE {
} }
} }
fn register_drag_drop(state_ptr: Rc<WindowsWindowStatePtr>) -> Result<()> { fn register_drag_drop(window: &Rc<WindowsWindowInner>) -> Result<()> {
let window_handle = state_ptr.hwnd; let window_handle = window.hwnd;
let handler = WindowsDragDropHandler(state_ptr); let handler = WindowsDragDropHandler(window.clone());
// The lifetime of `IDropTarget` is handled by Windows, it won't release until // The lifetime of `IDropTarget` is handled by Windows, it won't release until
// we call `RevokeDragDrop`. // we call `RevokeDragDrop`.
// So, it's safe to drop it here. // So, it's safe to drop it here.