Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(windows): fix appcrash on windows where darkmode is not supported #1022

Merged
merged 3 commits into from
Dec 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changes/dark-mode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tao": "patch"
---

On Windows, fix crash on older windows versions that doesn't support dark mode.
90 changes: 46 additions & 44 deletions src/platform_impl/windows/dark_mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,58 +42,60 @@ static DARK_MODE_SUPPORTED: Lazy<bool> = Lazy::new(|| {
});

pub fn allow_dark_mode_for_app(is_dark_mode: bool) {
const UXTHEME_ALLOWDARKMODEFORAPP_ORDINAL: u16 = 135;
type AllowDarkModeForApp = unsafe extern "system" fn(bool) -> bool;
static ALLOW_DARK_MODE_FOR_APP: Lazy<Option<AllowDarkModeForApp>> = Lazy::new(|| unsafe {
if HMODULE(*HUXTHEME as _).is_invalid() {
return None;
}
if *DARK_MODE_SUPPORTED {
const UXTHEME_ALLOWDARKMODEFORAPP_ORDINAL: u16 = 135;
type AllowDarkModeForApp = unsafe extern "system" fn(bool) -> bool;
static ALLOW_DARK_MODE_FOR_APP: Lazy<Option<AllowDarkModeForApp>> = Lazy::new(|| unsafe {
if HMODULE(*HUXTHEME as _).is_invalid() {
return None;
}

GetProcAddress(
HMODULE(*HUXTHEME as _),
PCSTR::from_raw(UXTHEME_ALLOWDARKMODEFORAPP_ORDINAL as usize as *mut _),
)
.map(|handle| std::mem::transmute(handle))
});
GetProcAddress(
HMODULE(*HUXTHEME as _),
PCSTR::from_raw(UXTHEME_ALLOWDARKMODEFORAPP_ORDINAL as usize as *mut _),
)
.map(|handle| std::mem::transmute(handle))
});

#[repr(C)]
enum PreferredAppMode {
Default,
AllowDark,
// ForceDark,
// ForceLight,
// Max,
}
const UXTHEME_SETPREFERREDAPPMODE_ORDINAL: u16 = 135;
type SetPreferredAppMode = unsafe extern "system" fn(PreferredAppMode) -> PreferredAppMode;
static SET_PREFERRED_APP_MODE: Lazy<Option<SetPreferredAppMode>> = Lazy::new(|| unsafe {
if HMODULE(*HUXTHEME as _).is_invalid() {
return None;
#[repr(C)]
enum PreferredAppMode {
Default,
AllowDark,
// ForceDark,
// ForceLight,
// Max,
}
const UXTHEME_SETPREFERREDAPPMODE_ORDINAL: u16 = 135;
type SetPreferredAppMode = unsafe extern "system" fn(PreferredAppMode) -> PreferredAppMode;
static SET_PREFERRED_APP_MODE: Lazy<Option<SetPreferredAppMode>> = Lazy::new(|| unsafe {
if HMODULE(*HUXTHEME as _).is_invalid() {
return None;
}

GetProcAddress(
HMODULE(*HUXTHEME as _),
PCSTR::from_raw(UXTHEME_SETPREFERREDAPPMODE_ORDINAL as usize as *mut _),
)
.map(|handle| std::mem::transmute(handle))
});
GetProcAddress(
HMODULE(*HUXTHEME as _),
PCSTR::from_raw(UXTHEME_SETPREFERREDAPPMODE_ORDINAL as usize as *mut _),
)
.map(|handle| std::mem::transmute(handle))
});

if let Some(ver) = *WIN10_BUILD_VERSION {
if ver < 18362 {
if let Some(_allow_dark_mode_for_app) = *ALLOW_DARK_MODE_FOR_APP {
unsafe { _allow_dark_mode_for_app(is_dark_mode) };
if let Some(ver) = *WIN10_BUILD_VERSION {
if ver < 18362 {
if let Some(_allow_dark_mode_for_app) = *ALLOW_DARK_MODE_FOR_APP {
unsafe { _allow_dark_mode_for_app(is_dark_mode) };
}
} else if let Some(_set_preferred_app_mode) = *SET_PREFERRED_APP_MODE {
let mode = if is_dark_mode {
PreferredAppMode::AllowDark
} else {
PreferredAppMode::Default
};
unsafe { _set_preferred_app_mode(mode) };
}
} else if let Some(_set_preferred_app_mode) = *SET_PREFERRED_APP_MODE {
let mode = if is_dark_mode {
PreferredAppMode::AllowDark
} else {
PreferredAppMode::Default
};
unsafe { _set_preferred_app_mode(mode) };
}
}

refresh_immersive_color_policy_state();
refresh_immersive_color_policy_state();
}
}

fn refresh_immersive_color_policy_state() {
Expand Down