windows: Fix titlebar rendering on Windows 10 (#14656)

张小白 created

As we discussed in #14190, we agreed to open a new PR.

Release Notes:

- N/A

Change summary

crates/gpui/src/platform/windows/events.rs   | 10 ++++++++--
crates/gpui/src/platform/windows/platform.rs |  4 ++++
crates/gpui/src/platform/windows/util.rs     | 21 +++++++++++++++++++++
crates/gpui/src/platform/windows/window.rs   |  5 +++++
4 files changed, 38 insertions(+), 2 deletions(-)

Detailed changes

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

@@ -664,8 +664,14 @@ fn handle_calc_client_size(
     if state_ptr.state.borrow().is_maximized() {
         requested_client_rect[0].top += frame_y + padding;
     } else {
-        // Magic number that calculates the width of the border
-        requested_client_rect[0].top += frame_y - 3;
+        match state_ptr.windows_version {
+            WindowsVersion::Win10 => {}
+            WindowsVersion::Win11 => {
+                // Magic number that calculates the width of the border
+                let border = (dpi as f32 / USER_DEFAULT_SCREEN_DPI as f32).round() as i32;
+                requested_client_rect[0].top += border;
+            }
+        }
     }
 
     Some(0)

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

@@ -52,6 +52,7 @@ pub(crate) struct WindowsPlatform {
     text_system: Arc<DirectWriteTextSystem>,
     clipboard_hash_format: u32,
     clipboard_metadata_format: u32,
+    windows_version: WindowsVersion,
 }
 
 pub(crate) struct WindowsPlatformState {
@@ -98,6 +99,7 @@ impl WindowsPlatform {
         let clipboard_hash_format = register_clipboard_format(CLIPBOARD_HASH_FORMAT).unwrap();
         let clipboard_metadata_format =
             register_clipboard_format(CLIPBOARD_METADATA_FORMAT).unwrap();
+        let windows_version = WindowsVersion::new().expect("Error retrieve windows version");
 
         Self {
             state,
@@ -108,6 +110,7 @@ impl WindowsPlatform {
             text_system,
             clipboard_hash_format,
             clipboard_metadata_format,
+            windows_version,
         }
     }
 
@@ -300,6 +303,7 @@ impl Platform for WindowsPlatform {
             self.icon,
             self.foreground_executor.clone(),
             lock.current_cursor,
+            self.windows_version,
         )?;
         drop(lock);
         let handle = window.get_raw_handle();

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

@@ -2,6 +2,7 @@ use std::sync::OnceLock;
 
 use ::util::ResultExt;
 use windows::{
+    Wdk::System::SystemServices::RtlGetVersion,
     Win32::{Foundation::*, UI::WindowsAndMessaging::*},
     UI::{
         Color,
@@ -11,6 +12,26 @@ use windows::{
 
 use crate::*;
 
+#[derive(Debug, Clone, Copy)]
+pub(crate) enum WindowsVersion {
+    Win10,
+    Win11,
+}
+
+impl WindowsVersion {
+    pub(crate) fn new() -> anyhow::Result<Self> {
+        let mut version = unsafe { std::mem::zeroed() };
+        let status = unsafe { RtlGetVersion(&mut version) };
+
+        status.ok()?;
+        if version.dwBuildNumber >= 22000 {
+            Ok(WindowsVersion::Win11)
+        } else {
+            Ok(WindowsVersion::Win10)
+        }
+    }
+}
+
 pub(crate) trait HiLoWord {
     fn hiword(&self) -> u16;
     fn loword(&self) -> u16;

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

@@ -61,6 +61,7 @@ pub(crate) struct WindowsWindowStatePtr {
     pub(crate) hide_title_bar: bool,
     pub(crate) is_movable: bool,
     pub(crate) executor: ForegroundExecutor,
+    pub(crate) windows_version: WindowsVersion,
 }
 
 impl WindowsWindowState {
@@ -222,6 +223,7 @@ impl WindowsWindowStatePtr {
             hide_title_bar: context.hide_title_bar,
             is_movable: context.is_movable,
             executor: context.executor.clone(),
+            windows_version: context.windows_version,
         }))
     }
 }
@@ -247,6 +249,7 @@ struct WindowCreateContext {
     is_movable: bool,
     executor: ForegroundExecutor,
     current_cursor: HCURSOR,
+    windows_version: WindowsVersion,
 }
 
 impl WindowsWindow {
@@ -256,6 +259,7 @@ impl WindowsWindow {
         icon: HICON,
         executor: ForegroundExecutor,
         current_cursor: HCURSOR,
+        windows_version: WindowsVersion,
     ) -> Result<Self> {
         let classname = register_wnd_class(icon);
         let hide_title_bar = params
@@ -295,6 +299,7 @@ impl WindowsWindow {
             is_movable: params.is_movable,
             executor,
             current_cursor,
+            windows_version,
         };
         let lpparam = Some(&context as *const _ as *const _);
         let creation_result = unsafe {