fix(windows): ensure APIs exist before using it (#1080)

* fix(windows): ensure APIs exist before using it

* a few other places

* fix compilation
This commit is contained in:
Amr Bashir
2025-02-28 14:45:21 +02:00
committed by GitHub
parent 7f16fc14ce
commit 9d1da74bb7
4 changed files with 24 additions and 7 deletions

View File

@@ -0,0 +1,5 @@
---
"tao": "patch"
---
Fix crash on Windows because of missing functions on older Windows systems, regression in 0.32

2
Cargo.lock generated
View File

@@ -2216,7 +2216,7 @@ dependencies = [
[[package]]
name = "tao"
version = "0.32.4"
version = "0.32.5"
dependencies = [
"bitflags 2.8.0",
"core-foundation",

View File

@@ -31,7 +31,6 @@ use windows::{
},
UI::{
Controls::{self as win32c, HOVER_DEFAULT},
HiDpi::GetSystemMetricsForDpi,
Input::{KeyboardAndMouse::*, Pointer::*, Touch::*, *},
Shell::{
DefSubclassProc, RemoveWindowSubclass, SHAppBarMessage, SetWindowSubclass, ABE_BOTTOM,
@@ -65,7 +64,7 @@ use crate::{
};
use runner::{EventLoopRunner, EventLoopRunnerShared};
use super::dpi::hwnd_dpi;
use super::{dpi::hwnd_dpi, util::get_system_metrics_for_dpi};
type GetPointerFrameInfoHistory = unsafe extern "system" fn(
pointerId: u32,
@@ -2194,7 +2193,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
);
let dpi = hwnd_dpi(window);
let border_y = GetSystemMetricsForDpi(SM_CYFRAME, dpi);
let border_y = get_system_metrics_for_dpi(SM_CYFRAME, dpi);
// if we have undecorated shadows, we only need to handle the top edge
if window_flags.contains(WindowFlags::MARKER_UNDECORATED_SHADOW) {
@@ -2211,7 +2210,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
}
// otherwise do full hit testing
else {
let border_x = GetSystemMetricsForDpi(SM_CXFRAME, dpi);
let border_x = get_system_metrics_for_dpi(SM_CXFRAME, dpi);
let rect = util::window_rect(window);
let hit_result = crate::window::hit_test(
(rect.left, rect.top, rect.right, rect.bottom),

View File

@@ -288,6 +288,8 @@ pub type GetDpiForMonitor = unsafe extern "system" fn(
dpi_x: *mut u32,
dpi_y: *mut u32,
) -> HRESULT;
type GetSystemMetricsForDpi =
unsafe extern "system" fn(nindex: SYSTEM_METRICS_INDEX, dpi: u32) -> i32;
pub type EnableNonClientDpiScaling = unsafe extern "system" fn(hwnd: HWND) -> BOOL;
pub type AdjustWindowRectExForDpi = unsafe extern "system" fn(
rect: *mut RECT,
@@ -304,6 +306,8 @@ lazy_static! {
get_function!("user32.dll", AdjustWindowRectExForDpi);
pub static ref GET_DPI_FOR_MONITOR: Option<GetDpiForMonitor> =
get_function!("shcore.dll", GetDpiForMonitor);
pub static ref GET_SYSTEM_METRICS_FOR_DPI: Option<GetSystemMetricsForDpi> =
get_function!("user32.dll", GetSystemMetricsForDpi);
pub static ref ENABLE_NON_CLIENT_DPI_SCALING: Option<EnableNonClientDpiScaling> =
get_function!("user32.dll", EnableNonClientDpiScaling);
pub static ref SET_PROCESS_DPI_AWARENESS_CONTEXT: Option<SetProcessDpiAwarenessContext> =
@@ -431,8 +435,8 @@ pub static WIN_VERSION: Lazy<windows_version::OsVersion> =
Lazy::new(windows_version::OsVersion::current);
pub fn get_frame_thickness(dpi: u32) -> i32 {
let resize_frame_thickness = unsafe { GetSystemMetricsForDpi(SM_CXSIZEFRAME, dpi) };
let padding_thickness = unsafe { GetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi) };
let resize_frame_thickness = unsafe { get_system_metrics_for_dpi(SM_CXSIZEFRAME, dpi) };
let padding_thickness = unsafe { get_system_metrics_for_dpi(SM_CXPADDEDBORDER, dpi) };
resize_frame_thickness + padding_thickness
}
@@ -495,3 +499,12 @@ pub fn client_rect(hwnd: HWND) -> RECT {
rect
}
}
pub unsafe fn get_system_metrics_for_dpi(nindex: SYSTEM_METRICS_INDEX, dpi: u32) -> i32 {
#[allow(non_snake_case)]
if let Some(GetSystemMetricsForDpi) = *GET_SYSTEM_METRICS_FOR_DPI {
GetSystemMetricsForDpi(nindex, dpi)
} else {
GetSystemMetrics(nindex)
}
}