gpui: Support windows dark mode title bar (#23700)

This will allow Windows GPUI applications that utilise the native title
bar to support the dark mode variant when the system user has dark mode
enabled in their system settings. [Related Win32
information](https://learn.microsoft.com/en-us/windows/apps/desktop/modernize/ui/apply-windows-themes)

| Before  | After |
| ------------- | ------------- |
|
![image](https://github.com/user-attachments/assets/50f3d131-8f41-4b91-8012-f8120b150033)
|
![image](https://github.com/user-attachments/assets/a36a6c6b-a469-49ba-85a8-9b55db9ea20f)
|

Release Notes:

- N/A

---------

Co-authored-by: 张小白 <364772080@qq.com>
This commit is contained in:
Matin Aniss 2025-01-27 23:07:28 +11:00 committed by GitHub
parent 6293b20fd0
commit 06d00b940d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 24 additions and 4 deletions

View file

@ -89,7 +89,7 @@ pub(crate) fn handle_msg(
WM_IME_COMPOSITION => handle_ime_composition(handle, lparam, state_ptr),
WM_SETCURSOR => handle_set_cursor(lparam, state_ptr),
WM_SETTINGCHANGE => handle_system_settings_changed(handle, state_ptr),
WM_DWMCOLORIZATIONCOLORCHANGED => handle_system_theme_changed(state_ptr),
WM_DWMCOLORIZATIONCOLORCHANGED => handle_system_theme_changed(handle, state_ptr),
WM_GPUI_CURSOR_STYLE_CHANGED => handle_cursor_changed(lparam, state_ptr),
_ => None,
};
@ -1215,7 +1215,10 @@ fn handle_system_command(wparam: WPARAM, state_ptr: Rc<WindowsWindowStatePtr>) -
None
}
fn handle_system_theme_changed(state_ptr: Rc<WindowsWindowStatePtr>) -> Option<isize> {
fn handle_system_theme_changed(
handle: HWND,
state_ptr: Rc<WindowsWindowStatePtr>,
) -> Option<isize> {
let mut callback = state_ptr
.state
.borrow_mut()
@ -1224,6 +1227,7 @@ fn handle_system_theme_changed(state_ptr: Rc<WindowsWindowStatePtr>) -> Option<i
.take()?;
callback();
state_ptr.state.borrow_mut().callbacks.appearance_changed = Some(callback);
set_dwm_window_appearance(handle);
Some(0)
}

View file

@ -3,7 +3,7 @@ use std::sync::OnceLock;
use ::util::ResultExt;
use windows::{
Wdk::System::SystemServices::RtlGetVersion,
Win32::{Foundation::*, UI::WindowsAndMessaging::*},
Win32::{Foundation::*, Graphics::Dwm::*, UI::WindowsAndMessaging::*},
UI::{
Color,
ViewManagement::{UIColorType, UISettings},
@ -139,6 +139,22 @@ pub(crate) fn load_cursor(style: CursorStyle) -> HCURSOR {
}))
}
pub(crate) fn set_dwm_window_appearance(hwnd: HWND) {
let dark_mode_enabled: BOOL = match system_appearance().log_err().unwrap_or_default() {
WindowAppearance::Dark | WindowAppearance::VibrantDark => true.into(),
WindowAppearance::Light | WindowAppearance::VibrantLight => false.into(),
};
unsafe {
DwmSetWindowAttribute(
hwnd,
DWMWA_USE_IMMERSIVE_DARK_MODE,
&dark_mode_enabled as *const _ as _,
std::mem::size_of::<BOOL>() as u32,
)
.log_err();
}
}
#[inline]
pub(crate) fn logical_point(x: f32, y: f32, scale_factor: f32) -> Point<Pixels> {
Point {

View file

@ -443,7 +443,7 @@ impl WindowsWindow {
let state_ptr = context.inner.take().unwrap()?;
let hwnd = creation_result?;
register_drag_drop(state_ptr.clone())?;
set_dwm_window_appearance(hwnd);
state_ptr.state.borrow_mut().border_offset.update(hwnd)?;
let placement = retrieve_window_placement(
hwnd,