gpui: Fix popup kind window support on Windows (#14063)

Jason Lee created

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

Change summary

crates/gpui/src/platform/windows/events.rs |  5 ++++-
crates/gpui/src/platform/windows/window.rs | 15 +++++++++++++--
2 files changed, 17 insertions(+), 3 deletions(-)

Detailed changes

crates/gpui/src/platform/windows/events.rs 🔗

@@ -801,7 +801,10 @@ fn handle_hit_test_msg(
     lparam: LPARAM,
     state_ptr: Rc<WindowsWindowStatePtr>,
 ) -> Option<isize> {
-    if !state_ptr.hide_title_bar {
+    if !state_ptr.is_movable {
+        return None;
+    }
+    if state_ptr.hide_title_bar {
         return None;
     }
 

crates/gpui/src/platform/windows/window.rs 🔗

@@ -57,6 +57,7 @@ pub(crate) struct WindowsWindowStatePtr {
     pub(crate) state: RefCell<WindowsWindowState>,
     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,