windows: Implement `window_appearance()` and `should_auto_hide_scrollbars()` (#12527)

张小白 created

Release Notes:

- N/A

Change summary

Cargo.toml                                   |  1 
crates/gpui/src/platform/windows/platform.rs | 35 +++++++++++++++++++--
2 files changed, 32 insertions(+), 4 deletions(-)

Detailed changes

Cargo.toml 🔗

@@ -416,6 +416,7 @@ features = [
     "Foundation_Numerics",
     "System",
     "System_Threading",
+    "UI_ViewManagement",
     "Wdk_System_SystemServices",
     "Win32_Globalization",
     "Win32_Graphics_Direct2D",

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

@@ -27,6 +27,10 @@ use windows::{
         System::{Com::*, LibraryLoader::*, Ole::*, SystemInformation::*, Threading::*, Time::*},
         UI::{Input::KeyboardAndMouse::*, Shell::*, WindowsAndMessaging::*},
     },
+    UI::{
+        Color,
+        ViewManagement::{UIColorType, UISettings},
+    },
 };
 
 use crate::*;
@@ -300,9 +304,8 @@ impl Platform for WindowsPlatform {
         Ok(Box::new(window))
     }
 
-    // todo(windows)
     fn window_appearance(&self) -> WindowAppearance {
-        WindowAppearance::Dark
+        system_appearance().log_err().unwrap_or_default()
     }
 
     fn open_url(&self, url: &str) {
@@ -498,9 +501,8 @@ impl Platform for WindowsPlatform {
         }
     }
 
-    // todo(windows)
     fn should_auto_hide_scrollbars(&self) -> bool {
-        false
+        should_auto_hide_scrollbars().log_err().unwrap_or(false)
     }
 
     fn write_to_clipboard(&self, item: ClipboardItem) {
@@ -682,3 +684,28 @@ fn load_icon() -> Result<HICON> {
     };
     Ok(HICON(handle.0))
 }
+
+// https://learn.microsoft.com/en-us/windows/apps/desktop/modernize/apply-windows-themes
+#[inline]
+fn system_appearance() -> Result<WindowAppearance> {
+    let ui_settings = UISettings::new()?;
+    let foreground_color = ui_settings.GetColorValue(UIColorType::Foreground)?;
+    // If the foreground is light, then is_color_light will evaluate to true,
+    // meaning Dark mode is enabled.
+    if is_color_light(&foreground_color) {
+        Ok(WindowAppearance::Dark)
+    } else {
+        Ok(WindowAppearance::Light)
+    }
+}
+
+#[inline(always)]
+fn is_color_light(color: &Color) -> bool {
+    ((5 * color.G as u32) + (2 * color.R as u32) + color.B as u32) > (8 * 128)
+}
+
+#[inline]
+fn should_auto_hide_scrollbars() -> Result<bool> {
+    let ui_settings = UISettings::new()?;
+    Ok(ui_settings.AutoHideScrollBars()?)
+}