From: Christian Hergert Date: Fri, 11 Mar 2022 01:26:56 +0000 (-0800) Subject: macos: fix window activation during shadow click-through X-Git-Tag: archive/raspbian/4.6.5+ds-1+rpi1~1^2~19^2~3^2~7^2~5 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=2c630a74cd3ce405363c1288a103dac60adcbc2c;p=gtk4.git macos: fix window activation during shadow click-through If we are clicking through the shadow of a window, we need to take special care to not raise the old window on mouseUp. This is normally done by the display server for us, so we need to use the proper API that is public to handle this (rather than CGSSetWindowTags()). Doing so requires us to dispatch the event to the NSView and then cancel the activcation from the mouseDown: event there. --- diff --git a/gdk/macos/GdkMacosView.c b/gdk/macos/GdkMacosView.c index 52a55a7cef..18de78aa19 100644 --- a/gdk/macos/GdkMacosView.c +++ b/gdk/macos/GdkMacosView.c @@ -24,6 +24,7 @@ #import "GdkMacosLayer.h" #import "GdkMacosView.h" +#import "GdkMacosWindow.h" @implementation GdkMacosView @@ -56,6 +57,19 @@ return NO; } +-(void)mouseDown:(NSEvent *)nsevent +{ + if ([(GdkMacosWindow *)[self window] needsMouseDownQuirk]) + /* We should only hit this when we are trying to click through + * the shadow of a window into another window. Just request + * that the application not activate this window on mouseUp. + * See gdkmacosdisplay-translate.c for the other half of this. + */ + [NSApp preventWindowOrdering]; + else + [super mouseDown:nsevent]; +} + -(void)setFrame:(NSRect)rect { [super setFrame:rect]; diff --git a/gdk/macos/GdkMacosWindow.c b/gdk/macos/GdkMacosWindow.c index c93be7f49e..23b3f5a3f3 100644 --- a/gdk/macos/GdkMacosWindow.c +++ b/gdk/macos/GdkMacosWindow.c @@ -262,9 +262,9 @@ typedef NSString *CALayerContentsGravity; inShowOrHide = YES; if (makeKey && [self canBecomeKeyWindow]) - [self makeKeyAndOrderFront:nil]; + [self makeKeyAndOrderFront:self]; else - [self orderFront:nil]; + [self orderFront:self]; if (makeKey && [self canBecomeMainWindow]) [self makeMainWindow]; @@ -830,4 +830,10 @@ typedef NSString *CALayerContentsGravity; [(GdkMacosView *)[self contentView] swapBuffer:buffer withDamage:damage]; } +-(BOOL)needsMouseDownQuirk +{ + return GDK_IS_MACOS_TOPLEVEL_SURFACE (gdk_surface) && + !GDK_MACOS_TOPLEVEL_SURFACE (gdk_surface)->decorated; +} + @end diff --git a/gdk/macos/GdkMacosWindow.h b/gdk/macos/GdkMacosWindow.h index cb8b2efad1..3a514ea857 100644 --- a/gdk/macos/GdkMacosWindow.h +++ b/gdk/macos/GdkMacosWindow.h @@ -69,5 +69,6 @@ -(BOOL)trackManualResize; -(void)setDecorated:(BOOL)decorated; -(void)swapBuffer:(GdkMacosBuffer *)buffer withDamage:(const cairo_region_t *)damage; +-(BOOL)needsMouseDownQuirk; @end diff --git a/gdk/macos/gdkmacosdisplay-translate.c b/gdk/macos/gdkmacosdisplay-translate.c index 4ad12ba778..9caddca811 100644 --- a/gdk/macos/gdkmacosdisplay-translate.c +++ b/gdk/macos/gdkmacosdisplay-translate.c @@ -1159,15 +1159,31 @@ _gdk_macos_display_translate (GdkMacosDisplay *self, if (test_resize (nsevent, surface, x, y)) return NULL; - if ((event_type == NSEventTypeRightMouseDown || - event_type == NSEventTypeOtherMouseDown || - event_type == NSEventTypeLeftMouseDown)) + if (event_type == NSEventTypeRightMouseDown || + event_type == NSEventTypeOtherMouseDown || + event_type == NSEventTypeLeftMouseDown) { if (![NSApp isActive]) [NSApp activateIgnoringOtherApps:YES]; if (![window isKeyWindow]) - [window makeKeyWindow]; + { + NSWindow *orig_window = [nsevent window]; + + /* To get NSApp to supress activating the window we might + * have clicked through the shadow of, we need to dispatch + * the event and handle it in GdkMacosView:mouseDown to call + * [NSApp preventWindowOrdering]. Calling it here will not + * do anything as the event is not registered. + */ + if (orig_window && + GDK_IS_MACOS_WINDOW (orig_window) && + [(GdkMacosWindow *)orig_window needsMouseDownQuirk]) + [NSApp sendEvent:nsevent]; + + [window showAndMakeKey:YES]; + _gdk_macos_display_clear_sorting (self); + } } switch ((int)event_type)