diff options
Diffstat (limited to 'Stop-confusing-GDK-s-grab-tracking.patch')
-rw-r--r-- | Stop-confusing-GDK-s-grab-tracking.patch | 200 |
1 files changed, 0 insertions, 200 deletions
diff --git a/Stop-confusing-GDK-s-grab-tracking.patch b/Stop-confusing-GDK-s-grab-tracking.patch deleted file mode 100644 index c289453..0000000 --- a/Stop-confusing-GDK-s-grab-tracking.patch +++ /dev/null @@ -1,200 +0,0 @@ -From ab0428a82f8233829c36e2a3ac0ed0848571c59d Mon Sep 17 00:00:00 2001 -From: "Owen W. Taylor" <otaylor@fishsoup.net> -Date: Wed, 9 Jun 2010 19:38:35 -0400 -Subject: [PATCH] Stop confusing GDK's grab tracking - -With client side windows, mixing GDK event delivery with explicit calls -to XUngrabPointer() can result in GDK losing button release events -it expects to get. This means that GDK thinks there is an implicit -grab in effect when there is none and send events to the wrong window. - -Avoid this by bypassing GDK's event handling for most mouse events. -We do a simplified conversion of the X event into a GdkEvent and send -it to directly to libgtk for delivery. - -We make an exception when a GDK grab is already in effect - this is -needed for the correct operation of menus. - -http://bugzilla.gnome.org/show_bug.cgi?id=599181 ---- - src/core/display-private.h | 7 ++ - src/core/display.c | 131 ++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 138 insertions(+), 0 deletions(-) - -diff --git a/src/core/display-private.h b/src/core/display-private.h -index fee321c..7f779fd 100644 ---- a/src/core/display-private.h -+++ b/src/core/display-private.h -@@ -232,6 +232,13 @@ struct _MetaDisplay - /* Closing down the display */ - int closing; - -+ /* To detect double clicks */ -+ guint button_click_number; -+ Window button_click_window; -+ int button_click_x; -+ int button_click_y; -+ guint32 button_click_time; -+ - /* Managed by group.c */ - GHashTable *groups_by_leader; - -diff --git a/src/core/display.c b/src/core/display.c -index 5bcf025..0c5f61d 100644 ---- a/src/core/display.c -+++ b/src/core/display.c -@@ -77,6 +77,7 @@ - #include <X11/extensions/Xfixes.h> - #endif - #include <string.h> -+#include <gtk/gtk.h> - - #define GRAB_OP_IS_WINDOW_SWITCH(g) \ - (g == META_GRAB_OP_KEYBOARD_TABBING_NORMAL || \ -@@ -1362,6 +1363,133 @@ meta_display_queue_autoraise_callback (MetaDisplay *display, - display->autoraise_window = window; - } - -+/* We do some of our event handling in core/frames.c, which expects -+ * GDK events delivered by GTK+. However, since the transition to -+ * client side windows, we can't let GDK see button events, since the -+ * client-side tracking of implicit and explicit grabs it does will -+ * get confused by our direct use of X grabs. -+ * -+ * So we do a very minimal GDK => GTK event conversion here and send on the -+ * events we care about, and then filter them out so they don't go -+ * through the normal GDK event handling. -+ * -+ * To reduce the amount of code, the only events fields filled out -+ * below are the ones that frames.c uses. If frames.c is modified to -+ * use more fields, more fields need to be filled out below. -+ */ -+ -+static gboolean -+maybe_send_event_to_gtk (MetaDisplay *display, -+ XEvent *xevent) -+{ -+ /* We're always using the default display */ -+ GdkDisplay *gdk_display = gdk_display_get_default (); -+ GdkEvent gdk_event; -+ GdkWindow *gdk_window; -+ Window window; -+ -+ switch (xevent->type) -+ { -+ case ButtonPress: -+ case ButtonRelease: -+ window = xevent->xbutton.window; -+ break; -+ case MotionNotify: -+ window = xevent->xmotion.window; -+ break; -+ case EnterNotify: -+ case LeaveNotify: -+ window = xevent->xcrossing.window; -+ break; -+ default: -+ return FALSE; -+ } -+ -+ gdk_window = gdk_window_lookup_for_display (gdk_display, window); -+ if (gdk_window == NULL) -+ return FALSE; -+ -+ /* If GDK already things it has a grab, we better let it see events; this -+ * is the menu-navigation case and events need to get sent to the appropriate -+ * (client-side) subwindow for individual menu items. -+ */ -+ if (gdk_display_pointer_is_grabbed (gdk_display)) -+ return FALSE; -+ -+ memset (&gdk_event, 0, sizeof (gdk_event)); -+ -+ switch (xevent->type) -+ { -+ case ButtonPress: -+ case ButtonRelease: -+ if (xevent->type == ButtonPress) -+ { -+ GtkSettings *settings = gtk_settings_get_default (); -+ int double_click_time; -+ int double_click_distance; -+ -+ g_object_get (settings, -+ "gtk-double-click-time", &double_click_time, -+ "gtk-double-click-distance", &double_click_distance, -+ NULL); -+ -+ if (xevent->xbutton.button == display->button_click_number && -+ xevent->xbutton.window == display->button_click_window && -+ xevent->xbutton.time < display->button_click_time + double_click_time && -+ ABS (xevent->xbutton.x - display->button_click_x) <= double_click_distance && -+ ABS (xevent->xbutton.y - display->button_click_y) <= double_click_distance) -+ { -+ gdk_event.button.type = GDK_2BUTTON_PRESS; -+ -+ display->button_click_number = 0; -+ } -+ else -+ { -+ gdk_event.button.type = GDK_BUTTON_PRESS; -+ display->button_click_number = xevent->xbutton.button; -+ display->button_click_window = xevent->xbutton.window; -+ display->button_click_time = xevent->xbutton.time; -+ display->button_click_x = xevent->xbutton.x; -+ display->button_click_y = xevent->xbutton.y; -+ } -+ } -+ else -+ { -+ gdk_event.button.type = GDK_BUTTON_RELEASE; -+ } -+ -+ gdk_event.button.window = gdk_window; -+ gdk_event.button.button = xevent->xbutton.button; -+ gdk_event.button.time = xevent->xbutton.time; -+ gdk_event.button.x = xevent->xbutton.x; -+ gdk_event.button.y = xevent->xbutton.y; -+ gdk_event.button.x_root = xevent->xbutton.x_root; -+ gdk_event.button.y_root = xevent->xbutton.y_root; -+ -+ break; -+ case MotionNotify: -+ gdk_event.motion.type = GDK_MOTION_NOTIFY; -+ gdk_event.motion.window = gdk_window; -+ break; -+ case EnterNotify: -+ case LeaveNotify: -+ gdk_event.crossing.type = xevent->type == EnterNotify ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY; -+ gdk_event.crossing.window = gdk_window; -+ gdk_event.crossing.x = xevent->xcrossing.x; -+ gdk_event.crossing.y = xevent->xcrossing.y; -+ break; -+ default: -+ g_assert_not_reached (); -+ break; -+ } -+ -+ /* If we've gotten here, we've filled in the gdk_event and should send it on */ -+ -+ gtk_main_do_event (&gdk_event); -+ -+ return TRUE; -+} -+ - /** - * This is the most important function in the whole program. It is the heart, - * it is the nexus, it is the Grand Central Station of Metacity's world. -@@ -2387,6 +2515,9 @@ event_callback (XEvent *event, - event, - window); - } -+ -+ if (maybe_send_event_to_gtk (display, event)) -+ filter_out_event = TRUE; - - display->current_time = CurrentTime; - return filter_out_event; --- -1.7.9 - |