From 1887a6db53da6fb31554a76fc980a8cfc1eab600 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Thu, 11 Jul 2024 03:39:54 +0800 Subject: [PATCH] gpui: Fix popup kind window support on Windows (#14063) Release Notes: - N/A ---- Continue #14044 for Windows ## The problem The `cx.open_window` method has provided us a `window_kind` option to allows creating a Popup kind. This behavior can work on macOS, the popup kind window have no-border, no-shadow, no-resize, and followed the `is_movable` if present true it can't move. This PR to fix those supports on Windows. The border and shadow still exist, I have tried to use WS_POPUP window_style, but it will crash: > This is looks like complex, it is out of my known. ``` Blocking waiting for file lock on build directory Compiling gpui v0.1.0 (F:\work\zed\crates\gpui) Finished `dev` profile [unoptimized + debuginfo] target(s) in 13.96s Running `target\debug\examples\window_positioning.exe` thread 'main' panicked at F:\Users\jason\.cargo\git\checkouts\blade-b2bcd1de1cf7ab6a\21a56f7\blade-graphics\src\vulkan\init.rs:864:18: called `Result::unwrap()` on an `Err` value: ERROR_OUT_OF_DEVICE_MEMORY note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace error: process didn't exit successfully: `target\debug\examples\window_positioning.exe` (exit code: 0xc0000409, STATUS_STACK_BUFFER_OVERRUN) ``` So I just make a simple change, to use `WS_EX_TOOLWINDOW` this can disable resize, and connect `is_movable` to `handle_hit_test_msg` to disable move, and also no Status Bar icon. ## Before https://github.com/zed-industries/zed/assets/5518/76740a71-e0ba-401f-958d-f4afdeb417c6 ## After https://github.com/zed-industries/zed/assets/5518/dca49f13-914c-425a-b8b6-b9fc15f8d208 --- crates/gpui/src/platform/windows/events.rs | 5 ++++- crates/gpui/src/platform/windows/window.rs | 15 +++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/crates/gpui/src/platform/windows/events.rs b/crates/gpui/src/platform/windows/events.rs index 28e992a8e4..cdc8949b59 100644 --- a/crates/gpui/src/platform/windows/events.rs +++ b/crates/gpui/src/platform/windows/events.rs @@ -801,7 +801,10 @@ fn handle_hit_test_msg( lparam: LPARAM, state_ptr: Rc, ) -> Option { - if !state_ptr.hide_title_bar { + if !state_ptr.is_movable { + return None; + } + if state_ptr.hide_title_bar { return None; } diff --git a/crates/gpui/src/platform/windows/window.rs b/crates/gpui/src/platform/windows/window.rs index 1cb469bd0e..43de6ced62 100644 --- a/crates/gpui/src/platform/windows/window.rs +++ b/crates/gpui/src/platform/windows/window.rs @@ -57,6 +57,7 @@ pub(crate) struct WindowsWindowStatePtr { pub(crate) state: RefCell, pub(crate) handle: AnyWindowHandle, pub(crate) hide_title_bar: bool, + pub(crate) is_movable: bool, pub(crate) executor: ForegroundExecutor, } @@ -212,6 +213,7 @@ impl WindowsWindowStatePtr { hwnd, handle: context.handle, hide_title_bar: context.hide_title_bar, + is_movable: context.is_movable, executor: context.executor.clone(), }) } @@ -235,6 +237,7 @@ struct WindowCreateContext { hide_title_bar: bool, display: WindowsDisplay, transparent: bool, + is_movable: bool, executor: ForegroundExecutor, current_cursor: HCURSOR, } @@ -261,7 +264,14 @@ impl WindowsWindow { .map(|title| title.as_ref()) .unwrap_or(""), ); - let dwstyle = WS_THICKFRAME | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX; + let (dwexstyle, dwstyle) = if params.kind == WindowKind::PopUp { + (WS_EX_TOOLWINDOW, WINDOW_STYLE(0x0)) + } else { + ( + WS_EX_OVERLAPPEDWINDOW, + WS_THICKFRAME | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX, + ) + }; let hinstance = get_module_handle(); let display = if let Some(display_id) = params.display_id { // if we obtain a display_id, then this ID must be valid. @@ -275,13 +285,14 @@ impl WindowsWindow { hide_title_bar, display, transparent: true, + is_movable: params.is_movable, executor, current_cursor, }; let lpparam = Some(&context as *const _ as *const _); let raw_hwnd = unsafe { CreateWindowExW( - WS_EX_APPWINDOW, + dwexstyle, classname, &windowname, dwstyle,