use std::thread;
use windows_sys::Win32::Foundation::ERROR_SUCCESS;
use windows_sys::Win32::System::Registry::{
HKEY, HKEY_CURRENT_USER, KEY_NOTIFY, REG_NOTIFY_CHANGE_LAST_SET, RRF_RT_REG_DWORD, RegCloseKey,
RegGetValueW, RegNotifyChangeKeyValue, RegOpenKeyExW,
};
use super::icon::Ink;
const PERSONALIZE: &str = "Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize";
const SYSTEM_USES_LIGHT_THEME: &str = "SystemUsesLightTheme";
pub fn ink() -> Ink {
if light_taskbar().unwrap_or(false) {
Ink::Black
} else {
Ink::White
}
}
fn light_taskbar() -> Option<bool> {
let subkey = utf16_z(PERSONALIZE);
let value = utf16_z(SYSTEM_USES_LIGHT_THEME);
let mut data = 0u32;
let mut size = std::mem::size_of::<u32>() as u32;
let status = unsafe {
RegGetValueW(
HKEY_CURRENT_USER,
subkey.as_ptr(),
value.as_ptr(),
RRF_RT_REG_DWORD,
std::ptr::null_mut(),
std::ptr::from_mut(&mut data).cast(),
&mut size,
)
};
(status == ERROR_SUCCESS).then_some(data != 0)
}
pub fn watch(on_change: impl Fn() + Send + 'static) {
let _ = thread::Builder::new()
.name("taskbar-theme".into())
.spawn(move || {
let subkey = utf16_z(PERSONALIZE);
let mut key: HKEY = std::ptr::null_mut();
let status = unsafe {
RegOpenKeyExW(HKEY_CURRENT_USER, subkey.as_ptr(), 0, KEY_NOTIFY, &mut key)
};
if status != ERROR_SUCCESS {
return;
}
loop {
let status = unsafe {
RegNotifyChangeKeyValue(
key,
0,
REG_NOTIFY_CHANGE_LAST_SET,
std::ptr::null_mut(),
0,
)
};
if status != ERROR_SUCCESS {
break;
}
on_change();
}
unsafe { RegCloseKey(key) };
});
}
fn utf16_z(text: &str) -> Vec<u16> {
text.encode_utf16().chain(std::iter::once(0)).collect()
}