Skip to content

Commit a9c189a

Browse files
authored
winit-win32: prevent inner size reported as (0,0) when minimized
1 parent 9d9d21c commit a9c189a

File tree

5 files changed

+37
-10
lines changed

5 files changed

+37
-10
lines changed

winit-win32/src/event_loop.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,7 +1301,6 @@ unsafe fn public_window_callback_inner(
13011301
use winit_core::event::WindowEvent::SurfaceResized;
13021302
let w = util::loword(lparam as u32) as u32;
13031303
let h = util::hiword(lparam as u32) as u32;
1304-
13051304
let physical_size = PhysicalSize::new(w, h);
13061305

13071306
{
@@ -1313,7 +1312,14 @@ unsafe fn public_window_callback_inner(
13131312
w.set_window_flags_in_place(|f| f.set(WindowFlags::MAXIMIZED, maximized));
13141313
}
13151314
}
1316-
userdata.send_window_event(window, SurfaceResized(physical_size));
1315+
1316+
let mut state = userdata.window_state_lock();
1317+
if (w, h) != (0, 0) && physical_size != state.surface_size {
1318+
// WM_SIZE is received with size (0, 0) when a window is minimized; ignore.
1319+
state.surface_size = physical_size;
1320+
drop(state);
1321+
userdata.send_window_event(window, SurfaceResized(physical_size));
1322+
}
13171323
result = ProcResult::Value(0);
13181324
},
13191325

winit-win32/src/window.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -509,14 +509,7 @@ impl CoreWindow for Window {
509509
}
510510

511511
fn surface_size(&self) -> PhysicalSize<u32> {
512-
let mut rect: RECT = unsafe { mem::zeroed() };
513-
if unsafe { GetClientRect(self.hwnd(), &mut rect) } == false.into() {
514-
panic!(
515-
"Unexpected GetClientRect failure: please report this error to \
516-
rust-windowing/winit"
517-
)
518-
}
519-
PhysicalSize::new((rect.right - rect.left) as u32, (rect.bottom - rect.top) as u32)
512+
self.window_state_lock().surface_size
520513
}
521514

522515
fn outer_size(&self) -> PhysicalSize<u32> {

winit-win32/src/window_state.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ pub(crate) struct WindowState {
3333
pub min_size: Option<Size>,
3434
pub max_size: Option<Size>,
3535

36+
/// The last known size of the window surface
37+
pub surface_size: PhysicalSize<u32>,
38+
3639
pub surface_resize_increments: Option<Size>,
3740

3841
pub window_icon: Option<Icon>,
@@ -166,6 +169,8 @@ impl WindowState {
166169
min_size: attributes.min_surface_size,
167170
max_size: attributes.max_surface_size,
168171

172+
surface_size: PhysicalSize::default(),
173+
169174
surface_resize_increments: attributes.surface_resize_increments,
170175

171176
window_icon: attributes.window_icon.clone(),

winit/examples/application.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,15 @@ impl Application {
203203
Action::DumpMonitors => self.dump_monitors(_event_loop),
204204
Action::Message => {
205205
info!("User wake up");
206+
for (id, window) in self.windows.iter() {
207+
if window.emit_surface_size {
208+
let size = window.window.surface_size();
209+
info!(
210+
"Window {id:?} has physical surface size {}x{}",
211+
size.width, size.height
212+
);
213+
}
214+
}
206215
},
207216
_ => unreachable!("Tried to execute invalid action without `WindowId`"),
208217
}
@@ -315,6 +324,9 @@ impl Application {
315324
window.continuous_redraw = !window.continuous_redraw;
316325
window.window.request_redraw();
317326
},
327+
Action::EmitSurfaceSize => {
328+
window.toggle_emit_surface_size();
329+
},
318330
}
319331
}
320332

@@ -615,6 +627,8 @@ struct WindowState {
615627
start_time: Instant,
616628
/// Redraw continuously
617629
continuous_redraw: bool,
630+
/// Periodically emit the surface size
631+
emit_surface_size: bool,
618632
/// Cursor position over the window.
619633
cursor_position: Option<PhysicalPosition<f64>>,
620634
/// Window modifiers state.
@@ -666,6 +680,7 @@ impl WindowState {
666680
theme,
667681
animated_fill_color: false,
668682
continuous_redraw: false,
683+
emit_surface_size: false,
669684
#[cfg(not(android_platform))]
670685
start_time: Instant::now(),
671686
cursor_position: Default::default(),
@@ -738,6 +753,10 @@ impl WindowState {
738753
self.window.set_fullscreen(fullscreen);
739754
}
740755

756+
fn toggle_emit_surface_size(&mut self) {
757+
self.emit_surface_size = !self.emit_surface_size;
758+
}
759+
741760
/// Cycle through the grab modes ignoring errors.
742761
fn cycle_cursor_grab(&mut self) {
743762
self.cursor_grab = match self.cursor_grab {
@@ -1031,6 +1050,7 @@ enum Action {
10311050
Message,
10321051
ToggleAnimatedFillColor,
10331052
ToggleContinuousRedraw,
1053+
EmitSurfaceSize,
10341054
}
10351055

10361056
impl Action {
@@ -1076,6 +1096,7 @@ impl Action {
10761096
Action::Message => "Prints a message through a user wake up",
10771097
Action::ToggleAnimatedFillColor => "Toggle animated fill color",
10781098
Action::ToggleContinuousRedraw => "Toggle continuous redraw",
1099+
Action::EmitSurfaceSize => "Periodically print the surface size",
10791100
}
10801101
}
10811102
}
@@ -1294,6 +1315,7 @@ const KEY_BINDINGS: &[Binding<&'static str>] = &[
12941315
Binding::new("T", ModifiersState::META, Action::CreateNewTab),
12951316
#[cfg(macos_platform)]
12961317
Binding::new("O", ModifiersState::CONTROL, Action::CycleOptionAsAlt),
1318+
Binding::new("S", ModifiersState::ALT, Action::EmitSurfaceSize),
12971319
Binding::new("S", ModifiersState::CONTROL, Action::Message),
12981320
];
12991321

winit/src/changelog/unreleased.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ changelog entry.
268268
- On Windows, `Window::theme` will return the correct theme after setting it through `Window::set_theme`.
269269
- On Windows, `Window::set_theme` will change the title bar color immediately now.
270270
- On Windows 11, prevent incorrect shifting when dragging window onto a monitor with different DPI.
271+
- On Windows, avoid returning `SurfaceResized` with size zero when an application is minimized. Let `Window::surface_size` return the pre-minimization window size even while minimized.
271272
- On Web, device events are emitted regardless of cursor type.
272273
- On Wayland, `axis_value120` scroll events now generate `MouseScrollDelta::LineDelta`
273274
- On X11, mouse scroll button events no longer cause duplicated `WindowEvent::MouseWheel` events.

0 commit comments

Comments
 (0)