r24528 - in /desktop/unstable/metacity/debian: changelog patches/04_gdk_grab_tracking.patch patches/series

joss at users.alioth.debian.org joss at users.alioth.debian.org
Wed Jun 16 21:32:47 UTC 2010


Author: joss
Date: Wed Jun 16 21:32:45 2010
New Revision: 24528

URL: http://svn.debian.org/wsvn/pkg-gnome/?sc=1&rev=24528
Log:
04_gdk_grab_tracking.patch: patch from Owen Taylor to prevent events 
from being transmitted to the wrong window. Closes: #559576.

Added:
    desktop/unstable/metacity/debian/patches/04_gdk_grab_tracking.patch
Modified:
    desktop/unstable/metacity/debian/changelog
    desktop/unstable/metacity/debian/patches/series

Modified: desktop/unstable/metacity/debian/changelog
URL: http://svn.debian.org/wsvn/pkg-gnome/desktop/unstable/metacity/debian/changelog?rev=24528&op=diff
==============================================================================
--- desktop/unstable/metacity/debian/changelog [utf-8] (original)
+++ desktop/unstable/metacity/debian/changelog [utf-8] Wed Jun 16 21:32:45 2010
@@ -1,11 +1,13 @@
-metacity (1:2.30.1-2) UNRELEASED; urgency=low
+metacity (1:2.30.1-2) unstable; urgency=low
 
   * Refresh 02_restart_hint.patch.
   * 03_gtop_error.patch: patch from Tomaž Šolc to handle libgtop errors.
     Closes: #549290.
   * Switch to 3.0 source format.
-
- -- Josselin Mouette <joss at debian.org>  Fri, 07 May 2010 21:28:05 +0200
+  * 04_gdk_grab_tracking.patch: patch from Owen Taylor to prevent events 
+    from being transmitted to the wrong window. Closes: #559576.
+
+ -- Josselin Mouette <joss at debian.org>  Wed, 16 Jun 2010 23:32:32 +0200
 
 metacity (1:2.30.1-1) unstable; urgency=low
 

Added: desktop/unstable/metacity/debian/patches/04_gdk_grab_tracking.patch
URL: http://svn.debian.org/wsvn/pkg-gnome/desktop/unstable/metacity/debian/patches/04_gdk_grab_tracking.patch?rev=24528&op=file
==============================================================================
--- desktop/unstable/metacity/debian/patches/04_gdk_grab_tracking.patch (added)
+++ desktop/unstable/metacity/debian/patches/04_gdk_grab_tracking.patch [utf-8] Wed Jun 16 21:32:45 2010
@@ -1,0 +1,199 @@
+From c81be0bc98ff79fcdba7d60276ae63048e53b7c8 Mon Sep 17 00:00:00 2001
+From: Owen W. Taylor <otaylor at 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 19287f3..8bc00fb 100644
+--- a/src/core/display-private.h
++++ b/src/core/display-private.h
+@@ -223,6 +223,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 4c7b4c0..bdd3016 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  ||  \
+@@ -1396,6 +1397,133 @@ handle_net_restack_window (MetaDisplay* display,
+ }
+ #endif
+ 
++/* 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.
+@@ -2403,6 +2531,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.0.1

Modified: desktop/unstable/metacity/debian/patches/series
URL: http://svn.debian.org/wsvn/pkg-gnome/desktop/unstable/metacity/debian/patches/series?rev=24528&op=diff
==============================================================================
--- desktop/unstable/metacity/debian/patches/series [utf-8] (original)
+++ desktop/unstable/metacity/debian/patches/series [utf-8] Wed Jun 16 21:32:45 2010
@@ -1,5 +1,6 @@
 01_Wcast-align.patch
 02_restart_hint.patch
 03_gtop_error.patch
+04_gdk_grab_tracking.patch
 90_autotools.patch
 99_ltmain_as-needed.patch




More information about the pkg-gnome-commits mailing list