From 7ef914a440ad203da05355e6c3f8c482766987ec Mon Sep 17 00:00:00 2001 From: Chenx Dust Date: Sun, 31 May 2026 01:51:26 +0800 Subject: [PATCH] fix(windows): use registry value to detect dark mode Original pull request: https://github.com/rust-windowing/winit/pull/4453 Co-authored-by: Slinetrac --- Cargo.toml | 1 + src/platform_impl/windows/dark_mode.rs | 31 +++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 5b2d09a29f..844face0a4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -236,6 +236,7 @@ features = [ "Win32_System_LibraryLoader", "Win32_System_Ole", "Win32_Security", + "Win32_System_Registry", "Win32_System_SystemInformation", "Win32_System_SystemServices", "Win32_System_Threading", diff --git a/src/platform_impl/windows/dark_mode.rs b/src/platform_impl/windows/dark_mode.rs index 366e44c685..3bb85bc64c 100644 --- a/src/platform_impl/windows/dark_mode.rs +++ b/src/platform_impl/windows/dark_mode.rs @@ -4,8 +4,9 @@ use std::{ffi::c_void, ptr}; use crate::utils::Lazy; use windows_sys::core::PCSTR; -use windows_sys::Win32::Foundation::{BOOL, HWND, NTSTATUS, S_OK}; +use windows_sys::Win32::Foundation::{BOOL, ERROR_SUCCESS, HWND, NTSTATUS, S_OK}; 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::System::SystemInformation::OSVERSIONINFOW; use windows_sys::Win32::UI::Accessibility::{HCF_HIGHCONTRASTON, HIGHCONTRASTA}; use windows_sys::Win32::UI::Controls::SetWindowTheme; @@ -55,6 +56,9 @@ static DARK_MODE_SUPPORTED: Lazy = Lazy::new(|| { static DARK_THEME_NAME: Lazy> = Lazy::new(|| util::encode_wide("DarkMode_Explorer")); static LIGHT_THEME_NAME: Lazy> = Lazy::new(|| util::encode_wide("")); +static PERSONALIZE_KEY: Lazy> = Lazy::new(|| util::encode_wide(r"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize")); +static APPS_USE_LIGHT_THEME: Lazy> = Lazy::new(|| util::encode_wide("AppsUseLightTheme")); + /// Attempt to set a theme on a window, if necessary. /// Returns the theme that was picked pub fn try_theme(hwnd: HWND, preferred_theme: Option) -> Theme { @@ -128,6 +132,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: Lazy> = Lazy::new(|| unsafe { const UXTHEME_SHOULDAPPSUSEDARKMODE_ORDINAL: PCSTR = 132 as PCSTR; @@ -154,6 +165,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, + PERSONALIZE_KEY.as_ptr(), + APPS_USE_LIGHT_THEME.as_ptr(), + 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() };