[gtk/wip/chergert/for-main: 5/5] macos: fix window activation during shadow click-through




commit 407b5246a6121406f661daef95ac64c674e440bd
Author: Christian Hergert <christian hergert me>
Date:   Thu Mar 10 17:26:56 2022 -0800

    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.

 gdk/macos/GdkMacosView.c              | 14 ++++++++++++++
 gdk/macos/GdkMacosWindow.c            | 10 ++++++++--
 gdk/macos/GdkMacosWindow.h            |  1 +
 gdk/macos/gdkmacosdisplay-translate.c | 24 ++++++++++++++++++++----
 4 files changed, 43 insertions(+), 6 deletions(-)
---
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)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]