On Windows, make AdjustRect calls DPI-aware when possible (#1015)
* Use AdjustWidowRectExForDPI when available * Prioritize presevering logical size when handling WM_DPICHANGED * Format * Add changelog entry
This commit is contained in:
parent
f379d069b9
commit
6ffd78767f
7 changed files with 143 additions and 107 deletions
|
|
@ -36,7 +36,7 @@ use winapi::{
|
|||
},
|
||||
um::{
|
||||
commctrl, libloaderapi, ole2, processthreadsapi, winbase,
|
||||
winnt::{HANDLE, LPCSTR, SHORT},
|
||||
winnt::{HANDLE, LPCSTR, SHORT},
|
||||
winuser,
|
||||
},
|
||||
};
|
||||
|
|
@ -48,15 +48,12 @@ use crate::{
|
|||
event_loop::{ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootELW},
|
||||
platform_impl::platform::{
|
||||
dark_mode::try_dark_mode,
|
||||
dpi::{
|
||||
become_dpi_aware, dpi_to_scale_factor, enable_non_client_dpi_scaling,
|
||||
},
|
||||
dpi::{become_dpi_aware, dpi_to_scale_factor, enable_non_client_dpi_scaling},
|
||||
drop_handler::FileDropHandler,
|
||||
event::{
|
||||
self, handle_extended_keys, process_key_params, vkey_to_winit_vkey, ModifiersStateSide,
|
||||
},
|
||||
monitor, raw_input, util,
|
||||
window::adjust_size,
|
||||
window_state::{CursorFlags, WindowFlags, WindowState},
|
||||
wrap_device_id, WindowId, DEVICE_ID,
|
||||
},
|
||||
|
|
@ -1394,11 +1391,9 @@ unsafe extern "system" fn public_window_callback<T: 'static>(
|
|||
let window_state = subclass_input.window_state.lock();
|
||||
|
||||
if window_state.min_size.is_some() || window_state.max_size.is_some() {
|
||||
let style = winuser::GetWindowLongA(window, winuser::GWL_STYLE) as DWORD;
|
||||
let ex_style = winuser::GetWindowLongA(window, winuser::GWL_EXSTYLE) as DWORD;
|
||||
if let Some(min_size) = window_state.min_size {
|
||||
let min_size = min_size.to_physical(window_state.dpi_factor);
|
||||
let (width, height) = adjust_size(min_size, style, ex_style);
|
||||
let (width, height): (u32, u32) = util::adjust_size(window, min_size).into();
|
||||
(*mmi).ptMinTrackSize = POINT {
|
||||
x: width as i32,
|
||||
y: height as i32,
|
||||
|
|
@ -1406,7 +1401,7 @@ unsafe extern "system" fn public_window_callback<T: 'static>(
|
|||
}
|
||||
if let Some(max_size) = window_state.max_size {
|
||||
let max_size = max_size.to_physical(window_state.dpi_factor);
|
||||
let (width, height) = adjust_size(max_size, style, ex_style);
|
||||
let (width, height): (u32, u32) = util::adjust_size(window, max_size).into();
|
||||
(*mmi).ptMaxTrackSize = POINT {
|
||||
x: width as i32,
|
||||
y: height as i32,
|
||||
|
|
@ -1428,10 +1423,11 @@ unsafe extern "system" fn public_window_callback<T: 'static>(
|
|||
// https://msdn.microsoft.com/en-us/library/windows/desktop/dn312083(v=vs.85).aspx
|
||||
let new_dpi_x = u32::from(LOWORD(wparam as DWORD));
|
||||
let new_dpi_factor = dpi_to_scale_factor(new_dpi_x);
|
||||
let old_dpi_factor: f64;
|
||||
|
||||
let allow_resize = {
|
||||
let mut window_state = subclass_input.window_state.lock();
|
||||
let old_dpi_factor = window_state.dpi_factor;
|
||||
old_dpi_factor = window_state.dpi_factor;
|
||||
window_state.dpi_factor = new_dpi_factor;
|
||||
|
||||
new_dpi_factor != old_dpi_factor && window_state.fullscreen.is_none()
|
||||
|
|
@ -1468,10 +1464,26 @@ unsafe extern "system" fn public_window_callback<T: 'static>(
|
|||
margins_vertical = (margin_bottom + margin_top) as u32;
|
||||
}
|
||||
|
||||
let physical_inner_rect = PhysicalSize::new(
|
||||
(rect.right - rect.left) as u32 - margins_horizontal,
|
||||
(rect.bottom - rect.top) as u32 - margins_vertical,
|
||||
);
|
||||
// Use the rect suggested by Windows
|
||||
// let physical_inner_rect = PhysicalSize::new(
|
||||
// (rect.right - rect.left) as u32 - margins_horizontal,
|
||||
// (rect.bottom - rect.top) as u32 - margins_vertical,
|
||||
// );
|
||||
|
||||
// We calculate our own rect because the default suggested rect doesn't do a great job
|
||||
// of preserving the window's logical size.
|
||||
let physical_inner_rect = {
|
||||
let mut current_rect = mem::zeroed();
|
||||
winuser::GetClientRect(window, &mut current_rect);
|
||||
|
||||
let client_rect = PhysicalSize::new(
|
||||
(current_rect.right - current_rect.left) as u32,
|
||||
(current_rect.bottom - current_rect.top) as u32,
|
||||
);
|
||||
client_rect
|
||||
.to_logical(old_dpi_factor)
|
||||
.to_physical(new_dpi_factor)
|
||||
};
|
||||
|
||||
// `allow_resize` prevents us from re-applying DPI adjustment to the restored size after
|
||||
// exiting fullscreen (the restored size is already DPI adjusted).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue