On macOS, when Stage Manager is enabled, Wine windows are frozen after minimizing and restoring.
When a window is minimized in Stage Manager, `[window miniaturize:]` is sent, we then tell the Windows app that the minimize button was pushed, if the window wants to be minimized eventually the window style gets changed and we call `[super miniaturize:]` in `setMacDrvState:`. But macOS never seems to actually minimize the window: no `windowWillMinimize` or `windowDidMinimize` is received. Instead it's just `WINDOW_LOST_FOCUS` and `APP_DEACTIVATED`, which is the same as when Stage Manager is off and the app is just backgrounded.
It seems like clicking the yellow button sends minimize, but once the system receives that and Stage Manager is on, it's actually executed as just "put app in background".
To work around this, if Stage Manager is enabled, don't request a Windows minimize, just call up to `[super miniaturize:]`.
From: Brendan Shanks bshanks@codeweavers.com
--- dlls/winemac.drv/cocoa_window.m | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m index e2373b4837c..7e0d12b346c 100644 --- a/dlls/winemac.drv/cocoa_window.m +++ b/dlls/winemac.drv/cocoa_window.m @@ -160,6 +160,21 @@ static inline NSUInteger adjusted_modifiers_for_settings(NSUInteger modifiers) return new_modifiers; }
+static inline BOOL stage_manager_enabled(void) +{ + /* There is no documented way to determine if Stage Manager is enabled, + * but this seems like the best option. + */ + if (floor(NSAppKitVersionNumber) >= 2299 /* NSAppKitVersionNumber13_0 */) + { + NSUserDefaults *defs = [[NSUserDefaults alloc] initWithSuiteName:@"com.apple.WindowManager.plist"]; + BOOL enabled = [defs boolForKey:@"GloballyEnabled"]; + [defs release]; + return enabled; + } + return FALSE; +} +
@interface NSWindow (WineAccessPrivateMethods) - (id) _displayChanged; @@ -2575,6 +2590,16 @@ static CVReturn WineDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTi
- (void) miniaturize:(id)sender { + /* When Stage Manager is enabled, miniaturize: just moves the app/window to + * the background rather than minimizing the window. + * Don't start minimizing the window on the Win32 side. + */ + if (stage_manager_enabled()) + { + [super miniaturize:sender]; + return; + } + macdrv_event* event = macdrv_create_event(WINDOW_MINIMIZE_REQUESTED, self); [queue postEvent:event]; macdrv_release_event(event);