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
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue