rust-windowing / rust-windowing/winit

[macOS] Issues with `window.is_maximized()`

Open
#4,071 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

B - bug DS - appkit
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.