188 lines · 5.3 KB · Rust
RawDownload
use std::sync::OnceLock; use ::util::ResultExt;use windows::{    UI::{        Color,        ViewManagement::{UIColorType, UISettings},    },    Wdk::System::SystemServices::RtlGetVersion,    Win32::{Foundation::*, Graphics::Dwm::*, UI::WindowsAndMessaging::*},    core::BOOL,}; use crate::*; #[derive(Debug, Clone, Copy)]pub(crate) enum WindowsVersion {    Win10,    Win11,} impl WindowsVersion {    pub(crate) fn new() -> anyhow::Result<Self> {        let mut version = unsafe { std::mem::zeroed() };        let status = unsafe { RtlGetVersion(&mut version) };         status.ok()?;        if version.dwBuildNumber >= 22000 {            Ok(WindowsVersion::Win11)        } else {            Ok(WindowsVersion::Win10)        }    }} pub(crate) trait HiLoWord {    fn hiword(&self) -> u16;    fn loword(&self) -> u16;    fn signed_hiword(&self) -> i16;    fn signed_loword(&self) -> i16;} impl HiLoWord for WPARAM {    fn hiword(&self) -> u16 {        ((self.0 >> 16) & 0xFFFF) as u16    }     fn loword(&self) -> u16 {        (self.0 & 0xFFFF) as u16    }     fn signed_hiword(&self) -> i16 {        ((self.0 >> 16) & 0xFFFF) as i16    }     fn signed_loword(&self) -> i16 {        (self.0 & 0xFFFF) as i16    }} impl HiLoWord for LPARAM {    fn hiword(&self) -> u16 {        ((self.0 >> 16) & 0xFFFF) as u16    }     fn loword(&self) -> u16 {        (self.0 & 0xFFFF) as u16    }     fn signed_hiword(&self) -> i16 {        ((self.0 >> 16) & 0xFFFF) as i16    }     fn signed_loword(&self) -> i16 {        (self.0 & 0xFFFF) as i16    }} pub(crate) unsafe fn get_window_long(hwnd: HWND, nindex: WINDOW_LONG_PTR_INDEX) -> isize {    #[cfg(target_pointer_width = "64")]    unsafe {        GetWindowLongPtrW(hwnd, nindex)    }    #[cfg(target_pointer_width = "32")]    unsafe {        GetWindowLongW(hwnd, nindex) as isize    }} pub(crate) unsafe fn set_window_long(    hwnd: HWND,    nindex: WINDOW_LONG_PTR_INDEX,    dwnewlong: isize,) -> isize {    #[cfg(target_pointer_width = "64")]    unsafe {        SetWindowLongPtrW(hwnd, nindex, dwnewlong)    }    #[cfg(target_pointer_width = "32")]    unsafe {        SetWindowLongW(hwnd, nindex, dwnewlong as i32) as isize    }} pub(crate) fn windows_credentials_target_name(url: &str) -> String {    format!("zed:url={}", url)} pub(crate) fn load_cursor(style: CursorStyle) -> Option<HCURSOR> {    static ARROW: OnceLock<SafeCursor> = OnceLock::new();    static IBEAM: OnceLock<SafeCursor> = OnceLock::new();    static CROSS: OnceLock<SafeCursor> = OnceLock::new();    static HAND: OnceLock<SafeCursor> = OnceLock::new();    static SIZEWE: OnceLock<SafeCursor> = OnceLock::new();    static SIZENS: OnceLock<SafeCursor> = OnceLock::new();    static NO: OnceLock<SafeCursor> = OnceLock::new();    let (lock, name) = match style {        CursorStyle::IBeam | CursorStyle::IBeamCursorForVerticalLayout => (&IBEAM, IDC_IBEAM),        CursorStyle::Crosshair => (&CROSS, IDC_CROSS),        CursorStyle::PointingHand | CursorStyle::DragLink => (&HAND, IDC_HAND),        CursorStyle::ResizeLeft        | CursorStyle::ResizeRight        | CursorStyle::ResizeLeftRight        | CursorStyle::ResizeColumn => (&SIZEWE, IDC_SIZEWE),        CursorStyle::ResizeUp        | CursorStyle::ResizeDown        | CursorStyle::ResizeUpDown        | CursorStyle::ResizeRow => (&SIZENS, IDC_SIZENS),        CursorStyle::OperationNotAllowed => (&NO, IDC_NO),        CursorStyle::None => return None,        _ => (&ARROW, IDC_ARROW),    };    Some(        *(*lock.get_or_init(|| {            HCURSOR(                unsafe { LoadImageW(None, name, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED) }                    .log_err()                    .unwrap_or_default()                    .0,            )            .into()        })),    )} /// This function is used to configure the dark mode for the window built-in title bar.pub(crate) fn configure_dwm_dark_mode(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 {        x: px(x / scale_factor),        y: px(y / scale_factor),    }} // https://learn.microsoft.com/en-us/windows/apps/desktop/modernize/apply-windows-themes#[inline]pub(crate) fn system_appearance() -> Result<WindowAppearance> {    let ui_settings = UISettings::new()?;    let foreground_color = ui_settings.GetColorValue(UIColorType::Foreground)?;    // If the foreground is light, then is_color_light will evaluate to true,    // meaning Dark mode is enabled.    if is_color_light(&foreground_color) {        Ok(WindowAppearance::Dark)    } else {        Ok(WindowAppearance::Light)    }} #[inline(always)]fn is_color_light(color: &Color) -> bool {    ((5 * color.G as u32) + (2 * color.R as u32) + color.B as u32) > (8 * 128)}