rust-windowing / rust-windowing/winit
[macOS] Issues with `window.is_maximized()`
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 6.2k
- Forks
- 1.3k
- Avg merge
- 2d 19h
- Merged PRs (30d)
- 9
Description
Description
I apologize for the poor title, but I'm not quite sure how to phrase this as the bug originates in the relationship between egui and winit, and I believe the root cause lies on the winit side.
While investigating a reported deadlock in https://github.com/emilk/egui/issues/3494 involving fetching window.is_maximized() at runtime I found that its implementation can impact egui's ability to make forward progress on rendering.
The call stack for it can be found here: https://gist.github.com/landaire/bf648a199411a4a813cb7e1419bbc4d9
This isn't actually a deadlock, but it looks like in is_zoomed() we change the window style which causes egui to receive consistent redraw requests. I do not have good knowledge of egui, or really any rendering for that fact, but I think the style change somehow prevents us from making significant rendering progress.
This prevents the issue from happening:
diff --git a/src/platform_impl/macos/window_delegate.rs b/src/platform_impl/macos/window_delegate.rs
index 19dc605e..3691ab88 100644
--- a/src/platform_impl/macos/window_delegate.rs
+++ b/src/platform_impl/macos/window_delegate.rs
@@ -1191,14 +1191,14 @@ impl WindowDelegate {
let required = NSWindowStyleMask::Titled | NSWindowStyleMask::Resizable;
let needs_temp_mask = !curr_mask.contains(required);
if needs_temp_mask {
- self.set_style_mask(required);
+ // self.set_style_mask(required);
}
let is_zoomed = self.window().isZoomed();
// Roll back temp styles
if needs_temp_mask {
- self.set_style_mask(curr_mask);
+ // self.set_style_mask(curr_mask);
}
is_zoomed
A candidate fix for winit could be the following:
diff --git a/src/platform_impl/macos/window_delegate.rs b/src/platform_impl/macos/window_delegate.rs
index 19dc605e..ba6004ae 100644
--- a/src/platform_impl/macos/window_delegate.rs
+++ b/src/platform_impl/macos/window_delegate.rs
@@ -1288,7 +1288,7 @@ impl WindowDelegate {
#[inline]
pub fn is_maximized(&self) -> bool {
- self.is_zoomed()
+ self.ivars().maximized.get()
}
#[inline]
But I don't know if there are scenarios where the ivar does not match what is returned from is_zoomed(). But it looks like it's set on window_will_enter_fullscreen and set_maximized which I think should keep it in sync?
I can't really explain why the window styling change prevents egui from making forward progress either, but the behavior is very obvious in a debugger. If you set a breakpoint in update_viewport_info you'll notice it's called consistently. However, if you take either of the above patches you'll notice that it's only called a handful of times (egui is running in the background, so it normally shouldn't be redrawing when it doesn't have focus I believe).
macOS version
ProductName: macOS
ProductVersion: 15.1
BuildVersion: 24B83
Winit version
0.30.7
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/platform_impl/macos/window_delegate.rs, comparing is_maximized, is_zoomed, set_style_mask, and the maximized state updates. Reproduce the macOS 15.1 behavior with winit 0.30.7 and observe update_viewport_info while querying window.is_maximized(). Done means the query remains accurate without causing repeated redraw activity or blocking egui's rendering progress.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100