Skip to content

Commit 4679d68

Browse files
authored
fix(windows): use correct position/size on WM_DPICHANGED for Windows 11 (#1056)
1 parent aef8944 commit 4679d68

File tree

2 files changed

+97
-84
lines changed

2 files changed

+97
-84
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tao": patch
3+
---
4+
5+
On Windows 11, fix incorrect window positioning and sizing on `WM_DPICHANGED`.

src/platform_impl/windows/event_loop.rs

Lines changed: 92 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1998,99 +1998,107 @@ unsafe fn public_window_callback_inner<T: 'static>(
19981998
}
19991999

20002000
let new_outer_rect: RECT;
2001-
{
2002-
let suggested_ul = (
2003-
suggested_rect.left + margin_left,
2004-
suggested_rect.top + margin_top,
2005-
);
2006-
2007-
let mut conservative_rect = RECT {
2008-
left: suggested_ul.0,
2009-
top: suggested_ul.1,
2010-
right: suggested_ul.0 + new_physical_inner_size.width as i32,
2011-
bottom: suggested_ul.1 + new_physical_inner_size.height as i32,
2012-
};
2013-
2014-
conservative_rect =
2015-
util::adjust_window_rect_with_styles(window, style, style_ex, conservative_rect)
2016-
.unwrap_or(conservative_rect);
2017-
2018-
// If we're dragging the window, offset the window so that the cursor's
2019-
// relative horizontal position in the title bar is preserved.
2020-
if dragging_window {
2021-
let bias = {
2022-
let cursor_pos = {
2023-
let mut pos = POINT::default();
2024-
let _ = GetCursorPos(&mut pos);
2025-
pos
2026-
};
2027-
let suggested_cursor_horizontal_ratio = (cursor_pos.x - suggested_rect.left) as f64
2028-
/ (suggested_rect.right - suggested_rect.left) as f64;
2001+
if util::WIN_VERSION.build < 22000 {
2002+
// The window position needs adjustment on Windows 10.
2003+
{
2004+
let suggested_ul = (
2005+
suggested_rect.left + margin_left,
2006+
suggested_rect.top + margin_top,
2007+
);
20292008

2030-
(cursor_pos.x
2031-
- (suggested_cursor_horizontal_ratio
2032-
* (conservative_rect.right - conservative_rect.left) as f64) as i32)
2033-
- conservative_rect.left
2009+
let mut conservative_rect = RECT {
2010+
left: suggested_ul.0,
2011+
top: suggested_ul.1,
2012+
right: suggested_ul.0 + new_physical_inner_size.width as i32,
2013+
bottom: suggested_ul.1 + new_physical_inner_size.height as i32,
20342014
};
2035-
conservative_rect.left += bias;
2036-
conservative_rect.right += bias;
2037-
}
20382015

2039-
// Check to see if the new window rect is on the monitor with the new DPI factor.
2040-
// If it isn't, offset the window so that it is.
2041-
let new_dpi_monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONULL);
2042-
let conservative_rect_monitor = MonitorFromRect(&conservative_rect, MONITOR_DEFAULTTONULL);
2043-
new_outer_rect = {
2044-
if conservative_rect_monitor != new_dpi_monitor {
2045-
let get_monitor_rect = |monitor| {
2046-
let mut monitor_info = MONITORINFO {
2047-
cbSize: mem::size_of::<MONITORINFO>() as _,
2048-
..Default::default()
2016+
conservative_rect =
2017+
util::adjust_window_rect_with_styles(window, style, style_ex, conservative_rect)
2018+
.unwrap_or(conservative_rect);
2019+
2020+
// If we're dragging the window, offset the window so that the cursor's
2021+
// relative horizontal position in the title bar is preserved.
2022+
if dragging_window {
2023+
let bias = {
2024+
let cursor_pos = {
2025+
let mut pos = POINT::default();
2026+
let _ = GetCursorPos(&mut pos);
2027+
pos
20492028
};
2050-
let _ = GetMonitorInfoW(monitor, &mut monitor_info);
2051-
monitor_info.rcMonitor
2029+
let suggested_cursor_horizontal_ratio = (cursor_pos.x - suggested_rect.left) as f64
2030+
/ (suggested_rect.right - suggested_rect.left) as f64;
2031+
2032+
(cursor_pos.x
2033+
- (suggested_cursor_horizontal_ratio
2034+
* (conservative_rect.right - conservative_rect.left) as f64)
2035+
as i32)
2036+
- conservative_rect.left
20522037
};
2053-
let wrong_monitor = conservative_rect_monitor;
2054-
let wrong_monitor_rect = get_monitor_rect(wrong_monitor);
2055-
let new_monitor_rect = get_monitor_rect(new_dpi_monitor);
2056-
2057-
// The direction to nudge the window in to get the window onto the monitor with
2058-
// the new DPI factor. We calculate this by seeing which monitor edges are
2059-
// shared and nudging away from the wrong monitor based on those.
2060-
let delta_nudge_to_dpi_monitor = (
2061-
if wrong_monitor_rect.left == new_monitor_rect.right {
2062-
-1
2063-
} else if wrong_monitor_rect.right == new_monitor_rect.left {
2064-
1
2065-
} else {
2066-
0
2067-
},
2068-
if wrong_monitor_rect.bottom == new_monitor_rect.top {
2069-
1
2070-
} else if wrong_monitor_rect.top == new_monitor_rect.bottom {
2071-
-1
2072-
} else {
2073-
0
2074-
},
2075-
);
2038+
conservative_rect.left += bias;
2039+
conservative_rect.right += bias;
2040+
}
20762041

2077-
let abort_after_iterations = new_monitor_rect.right - new_monitor_rect.left
2078-
+ new_monitor_rect.bottom
2079-
- new_monitor_rect.top;
2080-
for _ in 0..abort_after_iterations {
2081-
conservative_rect.left += delta_nudge_to_dpi_monitor.0;
2082-
conservative_rect.right += delta_nudge_to_dpi_monitor.0;
2083-
conservative_rect.top += delta_nudge_to_dpi_monitor.1;
2084-
conservative_rect.bottom += delta_nudge_to_dpi_monitor.1;
2085-
2086-
if MonitorFromRect(&conservative_rect, MONITOR_DEFAULTTONULL) == new_dpi_monitor {
2087-
break;
2042+
// Check to see if the new window rect is on the monitor with the new DPI factor.
2043+
// If it isn't, offset the window so that it is.
2044+
let new_dpi_monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONULL);
2045+
let conservative_rect_monitor =
2046+
MonitorFromRect(&conservative_rect, MONITOR_DEFAULTTONULL);
2047+
new_outer_rect = {
2048+
if conservative_rect_monitor != new_dpi_monitor {
2049+
let get_monitor_rect = |monitor| {
2050+
let mut monitor_info = MONITORINFO {
2051+
cbSize: mem::size_of::<MONITORINFO>() as _,
2052+
..Default::default()
2053+
};
2054+
let _ = GetMonitorInfoW(monitor, &mut monitor_info);
2055+
monitor_info.rcMonitor
2056+
};
2057+
let wrong_monitor = conservative_rect_monitor;
2058+
let wrong_monitor_rect = get_monitor_rect(wrong_monitor);
2059+
let new_monitor_rect = get_monitor_rect(new_dpi_monitor);
2060+
2061+
// The direction to nudge the window in to get the window onto the monitor with
2062+
// the new DPI factor. We calculate this by seeing which monitor edges are
2063+
// shared and nudging away from the wrong monitor based on those.
2064+
let delta_nudge_to_dpi_monitor = (
2065+
if wrong_monitor_rect.left == new_monitor_rect.right {
2066+
-1
2067+
} else if wrong_monitor_rect.right == new_monitor_rect.left {
2068+
1
2069+
} else {
2070+
0
2071+
},
2072+
if wrong_monitor_rect.bottom == new_monitor_rect.top {
2073+
1
2074+
} else if wrong_monitor_rect.top == new_monitor_rect.bottom {
2075+
-1
2076+
} else {
2077+
0
2078+
},
2079+
);
2080+
2081+
let abort_after_iterations = new_monitor_rect.right - new_monitor_rect.left
2082+
+ new_monitor_rect.bottom
2083+
- new_monitor_rect.top;
2084+
for _ in 0..abort_after_iterations {
2085+
conservative_rect.left += delta_nudge_to_dpi_monitor.0;
2086+
conservative_rect.right += delta_nudge_to_dpi_monitor.0;
2087+
conservative_rect.top += delta_nudge_to_dpi_monitor.1;
2088+
conservative_rect.bottom += delta_nudge_to_dpi_monitor.1;
2089+
2090+
if MonitorFromRect(&conservative_rect, MONITOR_DEFAULTTONULL) == new_dpi_monitor {
2091+
break;
2092+
}
20882093
}
20892094
}
2090-
}
20912095

2092-
conservative_rect
2093-
};
2096+
conservative_rect
2097+
};
2098+
}
2099+
} else {
2100+
// The suggested position is fine w/o adjustment on Windows 11.
2101+
new_outer_rect = suggested_rect
20942102
}
20952103

20962104
let _ = SetWindowPos(

0 commit comments

Comments
 (0)