diff --git a/winit-win32/Cargo.toml b/winit-win32/Cargo.toml index 5a5df3ff9a..c9cfc787c0 100644 --- a/winit-win32/Cargo.toml +++ b/winit-win32/Cargo.toml @@ -39,6 +39,7 @@ windows-sys = { workspace = true, features = [ "Win32_System_SystemServices", "Win32_System_Threading", "Win32_System_WindowsProgramming", + "Win32_System_Registry", "Win32_UI_Accessibility", "Win32_UI_Controls", "Win32_UI_HiDpi", diff --git a/winit-win32/src/dark_mode.rs b/winit-win32/src/dark_mode.rs index be54f1680d..07ac380ab5 100644 --- a/winit-win32/src/dark_mode.rs +++ b/winit-win32/src/dark_mode.rs @@ -3,8 +3,9 @@ use std::sync::LazyLock; /// which is inspired by the solution in https://github.com/ysc3839/win32-darkmode use std::{ffi::c_void, ptr}; -use windows_sys::Win32::Foundation::{BOOL, HWND, LPARAM, S_OK, WPARAM}; +use windows_sys::Win32::Foundation::{BOOL, ERROR_SUCCESS, HWND, LPARAM, S_OK, WPARAM}; use windows_sys::Win32::System::LibraryLoader::{GetProcAddress, LoadLibraryA}; +use windows_sys::Win32::System::Registry::{HKEY_CURRENT_USER, RRF_RT_REG_DWORD, RegGetValueW}; use windows_sys::Win32::UI::Accessibility::{HCF_HIGHCONTRASTON, HIGHCONTRASTA}; use windows_sys::Win32::UI::Controls::SetWindowTheme; use windows_sys::Win32::UI::Input::KeyboardAndMouse::GetActiveWindow; @@ -121,6 +122,13 @@ pub fn should_use_dark_mode() -> bool { } fn should_apps_use_dark_mode() -> bool { + if let Some(apps_use_light_theme) = read_apps_use_light_theme() { + return !apps_use_light_theme; + } + + // This undocumented method `ShouldAppsUseDarkMode` may return + // incorrect values on Windows 11. + // See https://github.com/tauri-apps/tao/pull/1165 type ShouldAppsUseDarkMode = unsafe extern "system" fn() -> bool; static SHOULD_APPS_USE_DARK_MODE: LazyLock> = LazyLock::new(|| unsafe { @@ -148,6 +156,24 @@ fn should_apps_use_dark_mode() -> bool { .unwrap_or(false) } +fn read_apps_use_light_theme() -> Option { + let mut data: u32 = 0; + let mut data_size = std::mem::size_of::() as u32; + let status = unsafe { + RegGetValueW( + HKEY_CURRENT_USER, + w!(r"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"), + w!("AppsUseLightTheme"), + RRF_RT_REG_DWORD, + ptr::null_mut(), + &mut data as *mut _ as _, + &mut data_size, + ) + }; + + if status == ERROR_SUCCESS { Some(data != 0) } else { None } +} + fn is_high_contrast() -> bool { let mut hc = HIGHCONTRASTA { cbSize: 0, dwFlags: 0, lpszDefaultScheme: ptr::null_mut() }; diff --git a/winit/src/changelog/unreleased.md b/winit/src/changelog/unreleased.md index 62121352ce..5a597173f1 100644 --- a/winit/src/changelog/unreleased.md +++ b/winit/src/changelog/unreleased.md @@ -48,3 +48,4 @@ changelog entry. - On X11, fix `set_hittest` not working on some window managers. - On Redox, handle `EINTR` when reading from `event_socket` instead of panicking. +- On Windows, fix Dark/light theme detection sometimes isn't working.