[gtk+/client-side-windows: 150/284] Get rid of all the synthesized crossing events except for ANCESTOR one on the toplevel
- From: Alexander Larsson <alexl src gnome org>
- To: svn-commits-list gnome org
- Subject: [gtk+/client-side-windows: 150/284] Get rid of all the synthesized crossing events except for ANCESTOR one on the toplevel
- Date: Thu, 2 Apr 2009 14:12:20 -0400 (EDT)
commit edb35763a29b11c9c3fb44d929cf694a7d3a06b6
Author: Richard Hult <richard imendio com>
Date: Fri Jan 16 20:57:43 2009 +0100
Get rid of all the synthesized crossing events except for ANCESTOR one on the toplevel
---
gdk/quartz/gdkevents-quartz.c | 444 ++++++++---------------------------------
1 files changed, 79 insertions(+), 365 deletions(-)
diff --git a/gdk/quartz/gdkevents-quartz.c b/gdk/quartz/gdkevents-quartz.c
index 0b991ec..a0dc2e2 100644
--- a/gdk/quartz/gdkevents-quartz.c
+++ b/gdk/quartz/gdkevents-quartz.c
@@ -578,250 +578,24 @@ convert_window_coordinates_to_root (GdkWindow *window,
}
}
-/* FIXME: Refactor and share with scroll event. */
-static GdkEvent *
-create_crossing_event (GdkWindow *window,
- NSEvent *nsevent,
- GdkEventType event_type,
- GdkCrossingMode mode,
- GdkNotifyType detail)
-{
- GdkEvent *event;
- gint x_tmp, y_tmp;
-
- event = gdk_event_new (event_type);
-
- event->crossing.window = window;
- event->crossing.subwindow = NULL; /* FIXME */
- event->crossing.time = get_time_from_ns_event (nsevent);
-
- /* Split out this block: */
- {
- NSWindow *nswindow;
- GdkWindow *toplevel;
- GdkWindowImplQuartz *impl;
- GdkWindowObject *private;
- NSPoint point;
-
- nswindow = [nsevent window];
- point = [nsevent locationInWindow];
-
- toplevel = [(GdkQuartzView *)[nswindow contentView] gdkWindow];
-
- impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (toplevel)->impl);
- private = GDK_WINDOW_OBJECT (toplevel);
-
- x_tmp = point.x;
- y_tmp = private->height - point.y;
-
- get_converted_window_coordinates (toplevel,
- x_tmp, y_tmp,
- window,
- &x_tmp, &y_tmp);
- }
-
- event->crossing.x = x_tmp;
- event->crossing.y = y_tmp;
-
- convert_window_coordinates_to_root (window,
- event->crossing.x,
- event->crossing.y,
- &event->crossing.x_root,
- &event->crossing.y_root);
-
- event->crossing.mode = mode;
- event->crossing.detail = detail;
- event->crossing.state = get_keyboard_modifiers_from_ns_event (nsevent);
-
- /* FIXME: focus and button state */
-
- return event;
-}
-
-static void
-synthesize_enter_event (GdkWindow *window,
- NSEvent *nsevent,
- GdkCrossingMode mode,
- GdkNotifyType detail)
-{
- GdkEvent *event;
-
- if (_gdk_quartz_pointer_grab_window != NULL &&
- !pointer_grab_owner_events &&
- !(pointer_grab_event_mask & GDK_ENTER_NOTIFY_MASK))
- return;
-
- if (!(GDK_WINDOW_OBJECT (window)->event_mask & GDK_ENTER_NOTIFY_MASK))
- return;
-
- event = create_crossing_event (window, nsevent, GDK_ENTER_NOTIFY,
- mode, detail);
-
- append_event (event);
-}
-
-static void
-synthesize_enter_events (GdkWindow *from,
- GdkWindow *to,
- NSEvent *nsevent,
- GdkCrossingMode mode,
- GdkNotifyType detail)
-{
- GdkWindow *prev = gdk_window_get_parent (to);
-
- if (prev != from)
- synthesize_enter_events (from, prev, nsevent, mode, detail);
- synthesize_enter_event (to, nsevent, mode, detail);
-}
-
-static void
-synthesize_leave_event (GdkWindow *window,
- NSEvent *nsevent,
- GdkCrossingMode mode,
- GdkNotifyType detail)
-{
- GdkEvent *event;
-
- if (_gdk_quartz_pointer_grab_window != NULL &&
- !pointer_grab_owner_events &&
- !(pointer_grab_event_mask & GDK_LEAVE_NOTIFY_MASK))
- return;
-
- if (!(GDK_WINDOW_OBJECT (window)->event_mask & GDK_LEAVE_NOTIFY_MASK))
- return;
-
- event = create_crossing_event (window, nsevent, GDK_LEAVE_NOTIFY,
- mode, detail);
-
- append_event (event);
-}
-
-static void
-synthesize_leave_events (GdkWindow *from,
- GdkWindow *to,
- NSEvent *nsevent,
- GdkCrossingMode mode,
- GdkNotifyType detail)
-{
- GdkWindow *next = gdk_window_get_parent (from);
-
- synthesize_leave_event (from, nsevent, mode, detail);
- if (next != to)
- synthesize_leave_events (next, to, nsevent, mode, detail);
-}
-
-static void
-synthesize_crossing_events (GdkWindow *window,
- GdkCrossingMode mode,
- NSEvent *nsevent,
- gint x,
- gint y)
+void
+_gdk_quartz_events_send_map_event (GdkWindow *window)
{
- GdkWindow *intermediate, *tem, *common_ancestor;
+ GdkWindowObject *private = (GdkWindowObject *)window;
+ GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
- if (window == current_mouse_window)
+ if (!impl->toplevel)
return;
- if (_gdk_quartz_window_is_ancestor (current_mouse_window, window))
- {
- /* Pointer has moved to an inferior window. */
- synthesize_leave_event (current_mouse_window, nsevent, mode, GDK_NOTIFY_INFERIOR);
-
- /* If there are intermediate windows, generate ENTER_NOTIFY
- * events for them
- */
- intermediate = gdk_window_get_parent (window);
-
- if (intermediate != current_mouse_window)
- {
- synthesize_enter_events (current_mouse_window, intermediate, nsevent, mode, GDK_NOTIFY_VIRTUAL);
- }
-
- synthesize_enter_event (window, nsevent, mode, GDK_NOTIFY_ANCESTOR);
- }
- else if (_gdk_quartz_window_is_ancestor (window, current_mouse_window))
- {
- /* Pointer has moved to an ancestor window. */
- synthesize_leave_event (current_mouse_window, nsevent, mode, GDK_NOTIFY_ANCESTOR);
-
- /* If there are intermediate windows, generate LEAVE_NOTIFY
- * events for them
- */
- intermediate = gdk_window_get_parent (current_mouse_window);
- if (intermediate != window)
- {
- synthesize_leave_events (intermediate, window, nsevent, mode, GDK_NOTIFY_VIRTUAL);
- }
-
- synthesize_enter_event (window, nsevent, mode, GDK_NOTIFY_INFERIOR);
- }
- else if (current_mouse_window)
- {
- /* Find least common ancestor of current_mouse_window and window */
- tem = current_mouse_window;
- do {
- common_ancestor = gdk_window_get_parent (tem);
- tem = common_ancestor;
- } while (common_ancestor &&
- !_gdk_quartz_window_is_ancestor (common_ancestor, window));
- if (common_ancestor)
- {
- synthesize_leave_event (current_mouse_window, nsevent, mode, GDK_NOTIFY_NONLINEAR);
- intermediate = gdk_window_get_parent (current_mouse_window);
- if (intermediate != common_ancestor)
- {
- synthesize_leave_events (intermediate, common_ancestor,
- nsevent, mode, GDK_NOTIFY_NONLINEAR_VIRTUAL);
- }
- intermediate = gdk_window_get_parent (window);
- if (intermediate != common_ancestor)
- {
- synthesize_enter_events (common_ancestor, intermediate,
- nsevent, mode, GDK_NOTIFY_NONLINEAR_VIRTUAL);
- }
- synthesize_enter_event (window, nsevent, mode, GDK_NOTIFY_NONLINEAR);
- }
- }
- else
+ if (private->event_mask & GDK_STRUCTURE_MASK)
{
- /* This means we have no current_mouse_window, which probably
- * means that there is a bug somewhere, we should always have
- * the root in we don't have another window. Does this ever
- * happen?
- */
- g_warning ("Trying to create crossing event when current_mouse_window is NULL");
- }
-
- _gdk_quartz_events_update_mouse_window (window);
-
- /* FIXME: This does't work when someone calls gdk_window_set_cursor
- * during a grab. The right behavior is that the cursor doesn't
- * change when a grab is in effect, but in that case it does.
- */
- if (window && !_gdk_quartz_pointer_grab_window)
- _gdk_quartz_events_update_cursor (window);
-}
+ GdkEvent event;
-void
-_gdk_quartz_events_send_map_event (GdkWindow *window)
-{
- GList *list;
- GdkWindow *interested_window;
- GdkWindowObject *private = (GdkWindowObject *)window;
-
- interested_window = find_window_interested_in_event_mask (window,
- GDK_STRUCTURE_MASK,
- TRUE);
+ event.any.type = GDK_MAP;
+ event.any.window = window;
- if (interested_window)
- {
- GdkEvent *event = gdk_event_new (GDK_MAP);
- event->any.window = interested_window;
- append_event (event);
+ gdk_event_put (&event);
}
-
- for (list = private->children; list != NULL; list = list->next)
- _gdk_quartz_events_send_map_events ((GdkWindow *)list->data);
}
/* Get current mouse window */
@@ -1134,130 +908,7 @@ _gdk_quartz_events_trigger_crossing_events (gboolean defer_to_mainloop)
/*_gdk_quartz_window_debug_highlight (mouse_window, 0);*/
#endif
- synthesize_crossing_events (mouse_window, GDK_CROSSING_NORMAL, nsevent, x, y);
-}
-
-/* Synthesizes crossing events if necessary, based on the passed in
- * NSEvent. Uses NSMouseEntered and NSMouseExisted for toplevels and
- * the mouse moved/dragged events for child windows, to see if the
- * mouse window has changed.
- */
-static void
-synthesize_crossing_events_for_ns_event (NSEvent *nsevent)
-{
- NSEventType event_type;
- GdkWindow *mouse_window;
- gint x;
- gint y;
-
- event_type = [nsevent type];
-
- switch (event_type)
- {
- case NSMouseMoved:
- case NSLeftMouseDragged:
- case NSRightMouseDragged:
- case NSOtherMouseDragged:
- /* We only handle moving the pointer to another GDK window.
- * Leaving to a non-GDK toplevel window (or window title bar or
- * the desktop) is covered by NSMouseExited events.
- */
- mouse_window = find_mouse_window_for_ns_event (nsevent, &x, &y);
- if (mouse_window != _gdk_root)
- synthesize_crossing_events (mouse_window, GDK_CROSSING_NORMAL, nsevent, x, y);
-
- break;
-
- case NSMouseEntered:
- {
- GdkWindow *event_toplevel;
- GdkWindowImplQuartz *impl;
- GdkWindowObject *private;
- NSPoint point;
-
- /* This is the only case where we actually use the window from
- * the event since we need to know which toplevel we entered
- * so it can be tracked properly.
- */
- event_toplevel = [(GdkQuartzView *)[[nsevent window] contentView] gdkWindow];
- impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (event_toplevel)->impl);
- private = GDK_WINDOW_OBJECT (event_toplevel);
-
- point = [nsevent locationInWindow];
-
- x = point.x;
- y = private->height - point.y;
-
- mouse_window = _gdk_quartz_window_find_child (event_toplevel, x, y);
-
- /* Treat unknown windows (like the title bar buttons or
- * desktop) as the root window.
- */
- if (!mouse_window)
- mouse_window = _gdk_root;
-
- if (mouse_window != event_toplevel)
- get_converted_window_coordinates (event_toplevel,
- x, y,
- mouse_window,
- &x, &y);
-
- synthesize_crossing_events (mouse_window, GDK_CROSSING_NORMAL, nsevent, x, y);
- }
- break;
-
- case NSMouseExited:
- {
- GdkWindow *event_toplevel;
- GdkWindowImplQuartz *impl;
- GdkWindowObject *private;
- NSPoint point;
-
- /* We only use NSMouseExited when leaving to the root
- * window. The other cases are handled above by checking the
- * motion/button events, or getting a NSMouseEntered for
- * another GDK window. The reason we don't use NSMouseExited
- * for other windows is that quartz first delivers the entered
- * event and then the exited which is the opposite from what
- * we need.
- */
- event_toplevel = [(GdkQuartzView *)[[nsevent window] contentView] gdkWindow];
- impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (event_toplevel)->impl);
- private = GDK_WINDOW_OBJECT (event_toplevel);
- point = [nsevent locationInWindow];
-
- x = point.x;
- y = private->height - point.y;
-
- x += GDK_WINDOW_OBJECT (event_toplevel)->x;
- y += GDK_WINDOW_OBJECT (event_toplevel)->y;
-
- /* If there is a window other than the root window at this
- * position, it means we didn't exit to the root window and we
- * ignore the event. (Note that we can get NULL here when swithing
- * spaces for example.)
- *
- * FIXME: This is not enough, it doesn't catch the case where
- * we leave a GDK window to a non-GDK window that has GDK
- * windows below it.
- */
- mouse_window = _gdk_quartz_window_find_child (_gdk_root, x, y);
-
- if (!mouse_window ||
- gdk_window_get_toplevel (mouse_window) ==
- gdk_window_get_toplevel (current_mouse_window))
- {
- mouse_window = _gdk_root;
- }
-
- if (mouse_window == _gdk_root)
- synthesize_crossing_events (_gdk_root, GDK_CROSSING_NORMAL, nsevent, x, y);
- }
- break;
-
- default:
- break;
- }
+ /* FIXME: create an event, fill it, put on the queue... */
}
/* This function finds the correct window to send an event to, taking
@@ -1670,6 +1321,69 @@ fill_key_event (GdkWindow *window,
event->key.keyval));
}
+static gboolean
+synthesize_crossing_event (GdkWindow *window,
+ GdkEvent *event,
+ NSEvent *nsevent,
+ gint x,
+ gint y)
+{
+ GdkWindowObject *private;
+
+ private = GDK_WINDOW_OBJECT (window);
+
+ /* FIXME: Do we need to handle grabs here? */
+
+ switch ([nsevent type])
+ {
+ case NSMouseEntered:
+ {
+ /* Enter events are considered always to be from the root window as
+ * we can't know for sure from what window we enter.
+ */
+ if (!(private->event_mask & GDK_ENTER_NOTIFY_MASK))
+ return FALSE;
+
+ fill_crossing_event (window, event, nsevent,
+ x, y,
+ GDK_ENTER_NOTIFY,
+ GDK_CROSSING_NORMAL,
+ GDK_NOTIFY_ANCESTOR);
+ }
+ return TRUE;
+
+ case NSMouseExited:
+ {
+ /* Exited always is to the root window as far as we are concerned,
+ * since there is no way to reliably get information about what new
+ * window is entered when exiting one.
+ */
+ if (!(private->event_mask & GDK_LEAVE_NOTIFY_MASK))
+ return FALSE;
+
+ /*if (!mouse_window ||
+ gdk_window_get_toplevel (mouse_window) ==
+ gdk_window_get_toplevel (current_mouse_window))
+ {
+ mouse_window = _gdk_root;
+ }
+ */
+
+ fill_crossing_event (window, event, nsevent,
+ x, y,
+ GDK_LEAVE_NOTIFY,
+ GDK_CROSSING_NORMAL,
+ GDK_NOTIFY_ANCESTOR);
+ }
+ return TRUE;
+
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
GdkEventMask
_gdk_quartz_events_get_current_event_mask (void)
{
@@ -1755,11 +1469,6 @@ gdk_event_translate (GdkEvent *event,
return FALSE;
}
- /* Take care of NSMouseEntered/Exited events and mouse movements
- * events and emit the right GDK crossing events.
- */
- synthesize_crossing_events_for_ns_event (nsevent);
-
/* Find the right GDK window to send the event to, taking grabs and
* event masks into consideration.
*/
@@ -1873,6 +1582,11 @@ gdk_event_translate (GdkEvent *event,
}
break;
+ case NSMouseEntered:
+ case NSMouseExited:
+ return_val = synthesize_crossing_event (window, event, nsevent, x, y);
+ break;
+
case NSKeyDown:
case NSKeyUp:
case NSFlagsChanged:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]