diff --git a/examples/open_parented/src/main.rs b/examples/open_parented/src/main.rs index 4c9433fc..812dd6fc 100644 --- a/examples/open_parented/src/main.rs +++ b/examples/open_parented/src/main.rs @@ -124,6 +124,7 @@ impl WindowHandler for ChildWindowHandler { } fn main() -> Result<(), baseview::Error> { + unsafe { baseview::assume_standalone_in_process() }; let window_open_options = WindowSettings::new().with_size(LogicalSize::new(512.0, 512.0)); Window::create(window_open_options, ParentWindowHandler::new)?.run_until_closed()?; diff --git a/examples/open_window/src/main.rs b/examples/open_window/src/main.rs index 83b299b1..f4019b4b 100644 --- a/examples/open_window/src/main.rs +++ b/examples/open_window/src/main.rs @@ -140,6 +140,8 @@ impl WindowHandler for OpenWindowExample { } fn main() -> Result<(), baseview::Error> { + unsafe { baseview::assume_standalone_in_process() }; + let window_open_options = WindowSettings::new().with_size(LogicalSize::new(512.0, 512.0)); let (mut tx, rx) = RingBuffer::new(128); diff --git a/examples/render_femtovg/src/main.rs b/examples/render_femtovg/src/main.rs index f2e3e0d5..2a012c6f 100644 --- a/examples/render_femtovg/src/main.rs +++ b/examples/render_femtovg/src/main.rs @@ -116,6 +116,7 @@ impl WindowHandler for FemtovgExample { } fn main() -> Result<(), baseview::Error> { + unsafe { baseview::assume_standalone_in_process() }; tracing_subscriber::fmt::init(); let window_open_options = WindowSettings::new() diff --git a/examples/render_wgpu/src/main.rs b/examples/render_wgpu/src/main.rs index 7d254377..5b8f971a 100644 --- a/examples/render_wgpu/src/main.rs +++ b/examples/render_wgpu/src/main.rs @@ -211,6 +211,9 @@ impl WindowHandler for WgpuExample { fn main() -> Result<(), baseview::Error> { env_logger::builder().filter_level(LevelFilter::Debug).init(); + + unsafe { baseview::assume_standalone_in_process() }; + let window_open_options = WindowSettings::new() .with_title("WGPU on Baseview") .with_size(LogicalSize::new(512, 512)) diff --git a/src/lib.rs b/src/lib.rs index 4e2cbe8b..0b991030 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,3 +30,8 @@ pub(crate) use tracing::*; mod utils; pub(crate) mod wrappers; + +#[inline] +pub unsafe fn assume_standalone_in_process() { + platform::assume_standalone_in_process() +} diff --git a/src/platform/macos/mod.rs b/src/platform/macos/mod.rs index 89df2630..cd2967f6 100644 --- a/src/platform/macos/mod.rs +++ b/src/platform/macos/mod.rs @@ -103,3 +103,8 @@ impl PartialEq for ParentWindowHandle { } impl Eq for ParentWindowHandle {} + +#[inline] +pub fn assume_standalone_in_process() { + // No-op on macOS +} diff --git a/src/platform/win/mod.rs b/src/platform/win/mod.rs index 8381bb30..0a92c809 100644 --- a/src/platform/win/mod.rs +++ b/src/platform/win/mod.rs @@ -7,6 +7,7 @@ mod window_state; use crate::wrappers::win32::h_instance::HInstance; use crate::wrappers::win32::window::HWnd; +use crate::wrappers::win32::ExtendedUser32; pub use error::{PlatformError, Result}; use raw_window_handle::{ DisplayHandle, HandleError, HasWindowHandle, RawWindowHandle, Win32WindowHandle, @@ -95,3 +96,18 @@ impl Display for ParentWindowHandleError { } } } + +#[inline] +pub fn assume_standalone_in_process() { + let user32 = match ExtendedUser32::load() { + Ok(user32) => user32, + Err(e) => { + crate::warn!("Failed to load user32.dll: {}", e); + return; + } + }; + + if let Err(e) = user32.set_process_dpi_awareness_context() { + crate::warn!("Failed to set process dpi_awareness_context: {}", e); + } +} diff --git a/src/platform/x11/mod.rs b/src/platform/x11/mod.rs index f7a50789..b86140ca 100644 --- a/src/platform/x11/mod.rs +++ b/src/platform/x11/mod.rs @@ -118,3 +118,8 @@ impl Display for ParentWindowHandleError { } } } + +#[inline] +pub fn assume_standalone_in_process() { + // No-op on X11 +} diff --git a/src/wrappers/win32/user32.rs b/src/wrappers/win32/user32.rs index 93add62d..a1a3385f 100644 --- a/src/wrappers/win32/user32.rs +++ b/src/wrappers/win32/user32.rs @@ -4,7 +4,9 @@ use std::mem::transmute; use windows_core::{s, Error}; use windows_sys::core::BOOL; use windows_sys::Win32::Foundation::{HWND, RECT}; -use windows_sys::Win32::UI::HiDpi::DPI_AWARENESS_CONTEXT; +use windows_sys::Win32::UI::HiDpi::{ + DPI_AWARENESS_CONTEXT, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2, +}; use windows_sys::Win32::UI::WindowsAndMessaging::{WINDOW_EX_STYLE, WINDOW_STYLE}; pub struct ExtendedUser32 { @@ -12,10 +14,12 @@ pub struct ExtendedUser32 { pub set_thread_dpi_awareness_context: Option, pub adjust_window_rect_ex_for_dpi: Option, pub get_dpi_for_window: Option, + pub set_process_dpi_awareness_context: Option, } type SetThreadDpiAwarenessContext = unsafe extern "system" fn(DPI_AWARENESS_CONTEXT) -> DPI_AWARENESS_CONTEXT; +type SetProcessDpiAwarenessContext = unsafe extern "system" fn(DPI_AWARENESS_CONTEXT) -> BOOL; type GetDpiForWindow = unsafe extern "system" fn(HWND) -> u32; @@ -42,10 +46,25 @@ impl ExtendedUser32 { get_dpi_for_window: library .get_proc_address(s!("GetDpiForWindow")) .map(|p| transmute::<*const c_void, GetDpiForWindow>(p)), + set_process_dpi_awareness_context: library + .get_proc_address(s!("SetProcessDpiAwarenessContext")) + .map(|p| transmute::<*const c_void, SetProcessDpiAwarenessContext>(p)), _library: library, }) } } + + pub fn set_process_dpi_awareness_context(&self) -> Result<(), Error> { + let Some(func) = self.set_process_dpi_awareness_context else { return Ok(()) }; + + let result = unsafe { func(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) }; + + if result == 0 { + return Err(Error::from_thread()); + } + + Ok(()) + } } impl Clone for ExtendedUser32 { @@ -61,6 +80,7 @@ impl Clone for ExtendedUser32 { set_thread_dpi_awareness_context: self.set_thread_dpi_awareness_context, adjust_window_rect_ex_for_dpi: self.adjust_window_rect_ex_for_dpi, get_dpi_for_window: self.get_dpi_for_window, + set_process_dpi_awareness_context: self.set_process_dpi_awareness_context, } } }