@@ -740,31 +740,58 @@ impl WindowsWindowInner {
lock.border_offset.update(handle).log_err();
drop(lock);
- let rect = unsafe { &*(lparam.0 as *const RECT) };
- let width = rect.right - rect.left;
- let height = rect.bottom - rect.top;
- // this will emit `WM_SIZE` and `WM_MOVE` right here
- // even before this function returns
- // the new size is handled in `WM_SIZE`
- unsafe {
- SetWindowPos(
- handle,
- None,
- rect.left,
- rect.top,
- width,
- height,
- SWP_NOZORDER | SWP_NOACTIVATE,
- )
- .context("unable to set window position after dpi has changed")
- .log_err();
- }
-
- // When maximized, SetWindowPos doesn't send WM_SIZE, so we need to manually
- // update the size and call the resize callback
if is_maximized {
- let device_size = size(DevicePixels(width), DevicePixels(height));
- self.handle_size_change(device_size, new_scale_factor, true);
+ // Get the monitor and its work area at the new DPI
+ let monitor = unsafe { MonitorFromWindow(handle, MONITOR_DEFAULTTONEAREST) };
+ let mut monitor_info: MONITORINFO = unsafe { std::mem::zeroed() };
+ monitor_info.cbSize = std::mem::size_of::<MONITORINFO>() as u32;
+ if unsafe { GetMonitorInfoW(monitor, &mut monitor_info) }.as_bool() {
+ let work_area = monitor_info.rcWork;
+ let width = work_area.right - work_area.left;
+ let height = work_area.bottom - work_area.top;
+
+ // Update the window size to match the new monitor work area
+ // This will trigger WM_SIZE which will handle the size change
+ unsafe {
+ SetWindowPos(
+ handle,
+ None,
+ work_area.left,
+ work_area.top,
+ width,
+ height,
+ SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED,
+ )
+ .context("unable to set maximized window position after dpi has changed")
+ .log_err();
+ }
+
+ // SetWindowPos may not send WM_SIZE for maximized windows in some cases,
+ // so we manually update the size to ensure proper rendering
+ let device_size = size(DevicePixels(width), DevicePixels(height));
+ self.handle_size_change(device_size, new_scale_factor, true);
+ }
+ } else {
+ // For non-maximized windows, use the suggested RECT from the system
+ let rect = unsafe { &*(lparam.0 as *const RECT) };
+ let width = rect.right - rect.left;
+ let height = rect.bottom - rect.top;
+ // this will emit `WM_SIZE` and `WM_MOVE` right here
+ // even before this function returns
+ // the new size is handled in `WM_SIZE`
+ unsafe {
+ SetWindowPos(
+ handle,
+ None,
+ rect.left,
+ rect.top,
+ width,
+ height,
+ SWP_NOZORDER | SWP_NOACTIVATE,
+ )
+ .context("unable to set window position after dpi has changed")
+ .log_err();
+ }
}
Some(0)