windows: Handle scale factor change while window is maximized (#35686)

Fixes https://github.com/zed-industries/zed/issues/33257

Previously, the scale-factor-change-handling logic relied on
`SetWindowPos` enqueuing a `WM_SIZE` window event. But that does not
happen when the window is maximized. So when the scale factor changed,
maximized windows neglected to call their `resize` callback, and would
misinterpret the positions of mouse events.

This PR adds special logic for maximized windows, to ensure that the
size is updated appropriately.

Release Notes:

- N/A
This commit is contained in:
Max Brunsfeld 2025-08-05 16:42:17 -07:00 committed by GitHub
parent 9caa9d042a
commit d0de81b0b4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -174,20 +174,37 @@ impl WindowsWindowInner {
let width = lparam.loword().max(1) as i32;
let height = lparam.hiword().max(1) as i32;
let new_size = size(DevicePixels(width), DevicePixels(height));
let scale_factor = lock.scale_factor;
let mut should_resize_renderer = false;
if lock.restore_from_minimized.is_some() {
lock.callbacks.request_frame = lock.restore_from_minimized.take();
} else {
lock.renderer.resize(new_size).log_err();
should_resize_renderer = true;
}
drop(lock);
self.handle_size_change(new_size, scale_factor, should_resize_renderer);
Some(0)
}
fn handle_size_change(
&self,
device_size: Size<DevicePixels>,
scale_factor: f32,
should_resize_renderer: bool,
) {
let new_logical_size = device_size.to_pixels(scale_factor);
let mut lock = self.state.borrow_mut();
lock.logical_size = new_logical_size;
if should_resize_renderer {
lock.renderer.resize(device_size).log_err();
}
let new_size = new_size.to_pixels(scale_factor);
lock.logical_size = new_size;
if let Some(mut callback) = lock.callbacks.resize.take() {
drop(lock);
callback(new_size, scale_factor);
callback(new_logical_size, scale_factor);
self.state.borrow_mut().callbacks.resize = Some(callback);
}
Some(0)
}
fn handle_size_move_loop(&self, handle: HWND) -> Option<isize> {
@ -747,7 +764,9 @@ impl WindowsWindowInner {
) -> Option<isize> {
let new_dpi = wparam.loword() as f32;
let mut lock = self.state.borrow_mut();
lock.scale_factor = new_dpi / USER_DEFAULT_SCREEN_DPI as f32;
let is_maximized = lock.is_maximized();
let new_scale_factor = new_dpi / USER_DEFAULT_SCREEN_DPI as f32;
lock.scale_factor = new_scale_factor;
lock.border_offset.update(handle).log_err();
drop(lock);
@ -771,6 +790,13 @@ impl WindowsWindowInner {
.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);
}
Some(0)
}