diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m index 2e15ec8ce72..6301b47143e 100644 --- a/dlls/winemac.drv/cocoa_window.m +++ b/dlls/winemac.drv/cocoa_window.m @@ -44,6 +44,16 @@ #endif +@interface NSWindow (PrivatePreventsActivation) + +/* Needed to ensure proper behavior after adding or removing + * NSWindowStyleMaskNonactivatingPanel. + * Available since at least macOS 10.6. */ +- (void)_setPreventsActivation:(BOOL)flag; + +@end + + static NSUInteger style_mask_for_features(const struct macdrv_window_features* wf) { NSUInteger style_mask; @@ -58,6 +68,8 @@ static NSUInteger style_mask_for_features(const struct macdrv_window_features* w } else style_mask = NSWindowStyleMaskBorderless; + if (wf->prevents_app_activation) style_mask |= NSWindowStyleMaskNonactivatingPanel; + return style_mask; } @@ -1126,7 +1138,8 @@ - (void) adjustFullScreenBehavior:(NSWindowCollectionBehavior)behavior - (void) setWindowFeatures:(const struct macdrv_window_features*)wf { static const NSUInteger usedStyles = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | - NSWindowStyleMaskResizable | NSWindowStyleMaskUtilityWindow | NSWindowStyleMaskBorderless; + NSWindowStyleMaskResizable | NSWindowStyleMaskUtilityWindow | NSWindowStyleMaskBorderless | + NSWindowStyleMaskNonactivatingPanel; NSUInteger currentStyle = [self styleMask]; NSUInteger newStyle = style_mask_for_features(wf) | (currentStyle & ~usedStyles); @@ -1146,6 +1159,17 @@ - (void) setWindowFeatures:(const struct macdrv_window_features*)wf } [self setStyleMask:newStyle]; + BOOL isNonActivating = (currentStyle & NSWindowStyleMaskNonactivatingPanel) != 0; + BOOL shouldBeNonActivating = (newStyle & NSWindowStyleMaskNonactivatingPanel) != 0; + if (isNonActivating != shouldBeNonActivating) { + // Changing NSWindowStyleMaskNonactivatingPanel with -setStyleMask is also + // buggy. If it's added, clicking the title bar will still activate the + // app. If it's removed, nothing changes at all. + // This private method ensures the correct behavior. + if ([self respondsToSelector:@selector(_setPreventsActivation:)]) + [self _setPreventsActivation:shouldBeNonActivating]; + } + // -setStyleMask: resets the firstResponder to the window. Set it // back to the content view. if ([[self contentView] acceptsFirstResponder]) diff --git a/dlls/winemac.drv/macdrv_cocoa.h b/dlls/winemac.drv/macdrv_cocoa.h index 2304f771bfa..5c19b4f4e81 100644 --- a/dlls/winemac.drv/macdrv_cocoa.h +++ b/dlls/winemac.drv/macdrv_cocoa.h @@ -538,6 +538,7 @@ extern int macdrv_register_hot_key(macdrv_event_queue q, unsigned int vkey, unsi unsigned int maximize_button:1; unsigned int utility:1; unsigned int shadow:1; + unsigned int prevents_app_activation:1; }; struct macdrv_window_state { diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index 6d735bb4ed2..4f3dbc08311 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -63,6 +63,8 @@ static void get_cocoa_window_features(struct macdrv_win_data *data, { memset(wf, 0, sizeof(*wf)); + if (ex_style & WS_EX_NOACTIVATE) wf->prevents_app_activation = TRUE; + if (disable_window_decorations) return; if (IsRectEmpty(window_rect)) return; if (EqualRect(window_rect, client_rect)) return;