]> Pileus Git - ~andy/gtk/commitdiff
Bug 672193 - windows (including menus) shown multiple times don't...
authorMichael Natterer <mitch@gimp.org>
Tue, 20 Nov 2012 09:28:58 +0000 (10:28 +0100)
committerMichael Natterer <mitch@gimp.org>
Tue, 20 Nov 2012 09:28:58 +0000 (10:28 +0100)
Based on a patch from Paul Davis, inject synthetic enter events directly
into the Quartz event stream, instead of trying to synthesize them in GDK.

This seems to magically fix most combo box popup weirdness, I guess
some code is relying on a specfic order of events, or any other state
imposed by the "proper" code path of events coming in the usual way.

The patch also removes _gdk_quartz_events_send_enter_notify_event()
which is now obsolete.

(sortof cherry-pixked from 979e5061a040f8896f505ffbd230f52af2d61ded
but needed manual editing because GdkQuartzWindow.c was renamed
and apparently earlier patches not picked correctly/completely)

gdk/quartz/GdkQuartzNSWindow.c
gdk/quartz/GdkQuartzNSWindow.h
gdk/quartz/GdkQuartzView.c
gdk/quartz/gdkevents-quartz.c
gdk/quartz/gdkprivate-quartz.h

index 76a759ccc00824eefb941ebc4fb750fc20c9918d..b5eaae25e791d726a89618a22c2f807298dc7a8f 100644 (file)
   return inMove;
 }
 
+-(void)checkSendEnterNotify
+{
+  GdkWindow *window = [[self contentView] gdkWindow];
+  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
+
+  /* When a new window has been created, and the mouse
+   * is in the window area, we will not receive an NSMouseEntered
+   * event.  Therefore, we synthesize an enter notify event manually.
+   */
+  if (!initialPositionKnown)
+    {
+      initialPositionKnown = YES;
+
+      if (NSPointInRect ([NSEvent mouseLocation], [self frame]))
+        {
+          NSEvent *event;
+
+          event = [NSEvent enterExitEventWithType: NSMouseEntered
+                                         location: [self mouseLocationOutsideOfEventStream]
+                                    modifierFlags: 0
+                                        timestamp: [[NSApp currentEvent] timestamp]
+                                     windowNumber: [impl->toplevel windowNumber]
+                                          context: NULL
+                                      eventNumber: 0
+                                   trackingNumber: [impl->view trackingRect]
+                                         userData: nil];
+
+          [NSApp postEvent:event atStart:NO];
+        }
+    }
+}
+
 -(void)windowDidMove:(NSNotification *)aNotification
 {
   GdkWindow *window = [[self contentView] gdkWindow];
   event->configure.height = window->height;
 
   _gdk_event_queue_append (gdk_display_get_default (), event);
+
+  [self checkSendEnterNotify];
 }
 
 -(void)windowDidResize:(NSNotification *)aNotification
   event->configure.height = window->height;
 
   _gdk_event_queue_append (gdk_display_get_default (), event);
+
+  [self checkSendEnterNotify];
 }
 
 -(id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag screen:(NSScreen *)screen
     [impl->toplevel orderFront:nil];
 
   inShowOrHide = NO;
+
+  [self checkSendEnterNotify];
 }
 
 - (void)hide
   inShowOrHide = YES;
   [impl->toplevel orderOut:nil];
   inShowOrHide = NO;
+
+  initialPositionKnown = NO;
 }
 
 - (BOOL)trackManualMove
index b456ff7c71bf7aa9ec80531d42cbcf49edc31ae3..da9ac58a79a4535adfd766e74dae34d0a5efa79f 100644 (file)
@@ -23,6 +23,7 @@
 @interface GdkQuartzNSWindow : NSWindow {
   BOOL    inMove;
   BOOL    inShowOrHide;
+  BOOL    initialPositionKnown;
 
   /* Manually triggered move/resize (not by the window manager) */
   BOOL    inManualMove;
index 0b59119f2b6d52220349612fc2e6688e08fe4c84..4058474a3d05ecd78ee1d57465da31bf3263eaad 100644 (file)
                                  owner:self
                               userData:nil
                           assumeInside:NO];
-
-  if (NSPointInRect ([[self window] convertScreenToBase:[NSEvent mouseLocation]], rect))
-    {
-      /* When a new window (and thus view) has been created, and the mouse
-       * is in the window area, we will not receive an NSMouseEntered
-       * event.  Therefore, we synthesize an enter notify event manually.
-       */
-      _gdk_quartz_events_send_enter_notify_event (gdk_window);
-    }
 }
 
 -(void)viewDidMoveToWindow
index 0d3cdc9650e6aebd675381d29c444486051669e9..cd05882a050af4a35a5a7c5d9552d42f5b8daf3f 100644 (file)
@@ -589,39 +589,6 @@ _gdk_quartz_events_update_focus_window (GdkWindow *window,
     }
 }
 
-void
-_gdk_quartz_events_send_enter_notify_event (GdkWindow *window)
-{
-  NSPoint screen_point;
-  GdkEvent *event;
-  gint x, y, x_root, y_root;
-
-  event = gdk_event_new (GDK_ENTER_NOTIFY);
-  event->any.window = NULL;
-  event->any.send_event = FALSE;
-
-  screen_point = [NSEvent mouseLocation];
-
-  _gdk_quartz_window_nspoint_to_gdk_xy (screen_point, &x_root, &y_root);
-  get_window_point_from_screen_point (window, screen_point, &x, &y);
-
-  event->crossing.window = window;
-  event->crossing.subwindow = NULL;
-  event->crossing.time = GDK_CURRENT_TIME;
-  event->crossing.x = x;
-  event->crossing.y = y;
-  event->crossing.x_root = x_root;
-  event->crossing.y_root = y_root;
-  event->crossing.mode = GDK_CROSSING_NORMAL;
-  event->crossing.detail = GDK_NOTIFY_ANCESTOR;
-  event->crossing.state = _gdk_quartz_events_get_current_keyboard_modifiers () |
-                          _gdk_quartz_events_get_current_mouse_modifiers ();
-
-  gdk_event_set_device (event, _gdk_display->core_pointer);
-
-  append_event (event, TRUE);
-}
-
 void
 _gdk_quartz_events_send_map_event (GdkWindow *window)
 {
index 71fdbb9b403faa1581d503cf7c95f1c7034623bd..dcac5028ba73b61dfb0280e00ff1f99f408bf01b 100644 (file)
@@ -64,7 +64,6 @@ void         _gdk_quartz_events_send_map_event         (GdkWindow *window);
 GdkModifierType _gdk_quartz_events_get_current_keyboard_modifiers (void);
 GdkModifierType _gdk_quartz_events_get_current_mouse_modifiers    (void);
 
-void         _gdk_quartz_events_send_enter_notify_event (GdkWindow *window);
 void         _gdk_quartz_events_break_all_grabs         (guint32    time);
 
 /* Event loop */