Skip to content

Commit f0fa3c9

Browse files
committed
fix(windows): use correct position/size on WM_DPICHANGED for Windows 11
Adjustments to the OS-suggested position are now only applied on Windows 10. They are not needed anymore on Windows 11. Fixes #1053, tauri-apps/tauri#10263, tauri-apps/tauri#12626.
1 parent 5cc9298 commit f0fa3c9

File tree

2 files changed

+95
-84
lines changed

2 files changed

+95
-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: 90 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1997,99 +1997,105 @@ unsafe fn public_window_callback_inner<T: 'static>(
19971997
}
19981998

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

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

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

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

2091-
conservative_rect
2092-
};
2093+
conservative_rect
2094+
};
2095+
}
2096+
} else {
2097+
// The suggested position is fine w/o adjustment on Windows 11.
2098+
new_outer_rect = suggested_rect
20932099
}
20942100

20952101
let _ = SetWindowPos(

0 commit comments

Comments
 (0)