167 lines · 4.5 KB · Rust
RawDownload
use std::sync::OnceLock; use ::util::ResultExt;use windows::{    Wdk::System::SystemServices::RtlGetVersion,    Win32::{Foundation::*, UI::WindowsAndMessaging::*},    UI::{        Color,        ViewManagement::{UIColorType, UISettings},    },}; 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) -> 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),        _ => (&ARROW, IDC_ARROW),    };    *(*lock.get_or_init(|| {        HCURSOR(            unsafe { LoadImageW(None, name, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED) }                .log_err()                .unwrap_or_default()                .0,        )        .into()    }))} #[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)}