[Xfce4-commits] <xfce4-panel:nick/gtk3> Clock: Fixed keyboard and pointer grabbing

Andrzej noreply at xfce.org
Wed Apr 10 22:26:01 CEST 2013


Updating branch refs/heads/nick/gtk3
         to bc829f7ddb7f4b1cb15db89283c842cbf9c66115 (commit)
       from 0d7e446fa7bb874498d076fb5e85ea1386870f38 (commit)

commit bc829f7ddb7f4b1cb15db89283c842cbf9c66115
Author: Andrzej <ndrwrdck at gmail.com>
Date:   Wed Apr 10 21:21:01 2013 +0100

    Clock: Fixed keyboard and pointer grabbing

 plugins/clock/clock.c |  123 ++++++++++++++++++++++++++++++++----------------
 1 files changed, 82 insertions(+), 41 deletions(-)

diff --git a/plugins/clock/clock.c b/plugins/clock/clock.c
index db6678f..3900a48 100644
--- a/plugins/clock/clock.c
+++ b/plugins/clock/clock.c
@@ -85,7 +85,8 @@ static void     clock_plugin_set_mode                  (ClockPlugin           *p
 static void     clock_plugin_reposition_calendar       (ClockPlugin           *plugin);
 static gboolean clock_plugin_pointer_grab              (ClockPlugin           *plugin,
                                                         GtkWidget             *widget,
-                                                        gboolean               keep);
+                                                        gboolean               keep,
+                                                        guint32                activate_time);
 static void     clock_plugin_pointer_ungrab            (ClockPlugin           *plugin,
                                                         GtkWidget             *widget);
 static gboolean clock_plugin_calendar_pointed          (GtkWidget             *calendar_window,
@@ -97,8 +98,7 @@ static gboolean clock_plugin_calendar_button_press_event (GtkWidget           *c
 static gboolean clock_plugin_calendar_key_press_event  (GtkWidget             *calendar_window,
                                                         GdkEventKey           *event,
                                                         ClockPlugin           *plugin);
-static void     clock_plugin_popup_calendar            (ClockPlugin           *plugin,
-                                                        gboolean               modal);
+static void     clock_plugin_popup_calendar            (ClockPlugin           *plugin);
 static void     clock_plugin_hide_calendar             (ClockPlugin           *plugin);
 static gboolean clock_plugin_tooltip                   (gpointer               user_data);
 
@@ -151,7 +151,11 @@ struct _ClockPlugin
   gchar              *tooltip_format;
   ClockTimeTimeout   *tooltip_timeout;
 
-  GdkGrabStatus       grab_pointer;
+  GdkDevice          *device;
+  GdkDevice          *keyboard;
+  GdkDevice          *pointer;
+  gboolean            keyboard_grabbed;
+  gboolean            pointer_grabbed;
 
   gchar              *time_config_tool;
   ClockTime          *time;
@@ -270,6 +274,11 @@ clock_plugin_init (ClockPlugin *plugin)
   plugin->command = NULL;
   plugin->time_config_tool = g_strdup (DEFAULT_TIME_CONFIG_TOOL);
   plugin->rotate_vertically = TRUE;
+  plugin->device = NULL;
+  plugin->keyboard = NULL;
+  plugin->pointer = NULL;
+  plugin->keyboard_grabbed = FALSE;
+  plugin->pointer_grabbed = FALSE;
   plugin->time = clock_time_new ();
 
   plugin->button = xfce_panel_create_toggle_button ();
@@ -436,10 +445,15 @@ clock_plugin_button_press_event (GtkWidget      *widget,
           /* toggle calendar window visibility */
           if (plugin->calendar_window == NULL
               || !gtk_widget_get_visible (GTK_WIDGET (plugin->calendar_window)))
-            clock_plugin_popup_calendar
-              (plugin, event->button == 1 && !(event->state & GDK_CONTROL_MASK));
+            {
+              clock_plugin_popup_calendar (plugin);
+              if (event->button == 1 && !(event->state & GDK_CONTROL_MASK))
+                clock_plugin_pointer_grab (plugin, GTK_WIDGET (plugin->calendar_window), TRUE, event->time);
+            }
           else
-            clock_plugin_hide_calendar (plugin);
+            {
+              clock_plugin_hide_calendar (plugin);
+            }
 
           return TRUE;
         }
@@ -1129,18 +1143,19 @@ static void
 clock_plugin_pointer_ungrab (ClockPlugin *plugin,
                              GtkWidget   *widget)
 {
-  GdkDisplay       *display;
-  GdkDevice        *pointer;
-  GdkDeviceManager *device_manager;
-
-  panel_return_if_fail (GTK_IS_WIDGET (widget));
+  panel_return_if_fail (XFCE_IS_CLOCK_PLUGIN (plugin));
 
-  display = gtk_widget_get_display (widget);
-  device_manager = gdk_display_get_device_manager (display);
-  pointer = gdk_device_manager_get_client_pointer (device_manager);
+  if (plugin->keyboard != NULL && plugin->keyboard_grabbed)
+    {
+      gdk_device_ungrab (plugin->keyboard, GDK_CURRENT_TIME);
+      plugin->keyboard_grabbed = FALSE;
+    }
 
-  if (plugin->grab_pointer == GDK_GRAB_SUCCESS)
-    gdk_device_ungrab (pointer, GDK_CURRENT_TIME);
+  if (plugin->pointer != NULL && plugin->pointer_grabbed)
+    {
+      gdk_device_ungrab (plugin->pointer, GDK_CURRENT_TIME);
+      plugin->pointer_grabbed = FALSE;
+    }
 }
 
 
@@ -1148,35 +1163,64 @@ clock_plugin_pointer_ungrab (ClockPlugin *plugin,
 static gboolean
 clock_plugin_pointer_grab (ClockPlugin *plugin,
                            GtkWidget   *widget,
-                           gboolean     keep)
+                           gboolean     keep,
+                           guint32      activate_time)
 {
   GdkWindow        *window;
-  gboolean          grab_succeed = FALSE;
+  gboolean          grabbed = FALSE;
   guint             i;
   GdkDisplay       *display;
-  GdkDevice        *pointer;
   GdkDeviceManager *device_manager;
-  GdkEventMask      pointer_mask = GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
-                                 | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK
-                                 | GDK_POINTER_MOTION_MASK
-                                 | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK;
+  GList            *devices;
 
-  window = gtk_widget_get_parent_window (widget);
-  display = gtk_widget_get_display (widget);
-  device_manager = gdk_display_get_device_manager (display);
-  pointer = gdk_device_manager_get_client_pointer (device_manager);
+  window = gtk_widget_get_window (widget);
+
+  if (plugin->device == NULL)
+    plugin->device = gtk_get_current_event_device ();
+
+  if (plugin->device == NULL)
+    {
+      display = gtk_widget_get_display (widget);
+      device_manager = gdk_display_get_device_manager (display);
+      devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
+      plugin->device = devices->data;
+      g_list_free (devices);
+    }
+
+  if (gdk_device_get_source (plugin->device) == GDK_SOURCE_KEYBOARD)
+    {
+      plugin->keyboard = plugin->device;
+      plugin->pointer = gdk_device_get_associated_device (plugin->device);
+    }
+  else
+    {
+      plugin->pointer = plugin->device;
+      plugin->keyboard = gdk_device_get_associated_device (plugin->device);
+    }
 
   /* don't try to get the grab for longer then 1/4 second */
   for (i = 0; i < (G_USEC_PER_SEC / 100 / 4); i++)
     {
-      plugin->grab_pointer = gdk_device_grab (pointer, window, GDK_OWNERSHIP_NONE, TRUE, pointer_mask,
-                                              NULL, GDK_CURRENT_TIME);
-      if (plugin->grab_pointer == GDK_GRAB_SUCCESS)
+      plugin->keyboard_grabbed =
+        plugin->keyboard != NULL &&
+        gdk_device_grab (plugin->keyboard, window,
+                         GDK_OWNERSHIP_WINDOW, TRUE,
+                         GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
+                         NULL, activate_time) == GDK_GRAB_SUCCESS;
+      if (plugin->keyboard_grabbed)
         {
-          grab_succeed = TRUE;
-          break;
+          grabbed = plugin->pointer_grabbed =
+            plugin->pointer != NULL &&
+            gdk_device_grab (plugin->pointer, window,
+                             GDK_OWNERSHIP_WINDOW, TRUE,
+                             GDK_SMOOTH_SCROLL_MASK |
+                             GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
+                             GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
+                             GDK_POINTER_MOTION_MASK,
+                             NULL, activate_time) == GDK_GRAB_SUCCESS;
+          if (grabbed)
+            break;
         }
-
       g_usleep (100);
     }
 
@@ -1184,14 +1228,14 @@ clock_plugin_pointer_grab (ClockPlugin *plugin,
   if (!keep)
     clock_plugin_pointer_ungrab (plugin, widget);
 
-  if (!grab_succeed)
+  if (!grabbed)
     {
       clock_plugin_pointer_ungrab (plugin, widget);
       g_printerr (PACKAGE_NAME ": Unable to get keyboard and mouse "
                   "grab. Popup failed.\n");
     }
 
-  return grab_succeed;
+  return grabbed;
 }
 
 
@@ -1206,7 +1250,7 @@ clock_plugin_calendar_pointed (GtkWidget *calendar_window,
 
   if (gtk_widget_get_mapped (calendar_window))
     {
-      gdk_window_get_position (gtk_widget_get_parent_window (calendar_window), &window_x, &window_y);
+      gdk_window_get_position (gtk_widget_get_window (calendar_window), &window_x, &window_y);
 
       gtk_widget_get_allocation (calendar_window, &allocation);
 
@@ -1254,8 +1298,7 @@ clock_plugin_calendar_key_press_event (GtkWidget      *calendar_window,
 
 
 static void
-clock_plugin_popup_calendar (ClockPlugin *plugin,
-                             gboolean     modal)
+clock_plugin_popup_calendar (ClockPlugin *plugin)
 {
   if (plugin->calendar_window == NULL)
     {
@@ -1287,8 +1330,6 @@ clock_plugin_popup_calendar (ClockPlugin *plugin,
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (plugin->button), TRUE);
   gtk_widget_show (GTK_WIDGET (plugin->calendar_window));
   xfce_panel_plugin_block_autohide (XFCE_PANEL_PLUGIN (plugin), TRUE);
-  if (modal)
-    clock_plugin_pointer_grab (plugin, GTK_WIDGET (plugin->calendar_window), TRUE);
 }
 
 


More information about the Xfce4-commits mailing list