[Xfce4-commits] <xfce4-panel:devel> Wait for grab when running popup menus at pointer.

Nick Schermer noreply at xfce.org
Tue Feb 23 20:44:02 CET 2010


Updating branch refs/heads/devel
         to c4379d5379b56d8c9a1587305ae98aae75fd4592 (commit)
       from 73d66167f6dcf2c1ad1461f9101dd8d79430d1b7 (commit)

commit c4379d5379b56d8c9a1587305ae98aae75fd4592
Author: Nick Schermer <nick at xfce.org>
Date:   Tue Feb 23 20:40:53 2010 +0100

    Wait for grab when running popup menus at pointer.
    
    Popup scripts doesn't really work if we don't wait until
    the pointer and keyboard grab is available.

 common/panel-utils.c                        |   51 +++++++++++++++++++++++++++
 common/panel-utils.h                        |   16 +++++----
 plugins/applicationsmenu/applicationsmenu.c |    3 +-
 plugins/directorymenu/directorymenu.c       |    3 +-
 plugins/windowmenu/windowmenu.c             |    3 +-
 5 files changed, 66 insertions(+), 10 deletions(-)

diff --git a/common/panel-utils.c b/common/panel-utils.c
index b90541c..6c95805 100644
--- a/common/panel-utils.c
+++ b/common/panel-utils.c
@@ -174,3 +174,54 @@ panel_utils_show_help (GtkWindow   *parent,
 
   g_free (uri);
 }
+
+
+
+gboolean
+panel_utils_grab_available (void)
+{
+  GdkScreen     *screen;
+  GdkWindow     *root;
+  GdkGrabStatus  grab_pointer = GDK_GRAB_FROZEN;
+  GdkGrabStatus  grab_keyboard = GDK_GRAB_FROZEN;
+  gboolean       grab_succeed = FALSE;
+  guint          i;
+  GdkEventMask   pointer_mask = GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+                                | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK
+                                | GDK_POINTER_MOTION_MASK;
+
+  screen = xfce_gdk_screen_get_active (NULL);
+  root = gdk_screen_get_root_window (screen);
+
+  /* don't try to get the grab for longer then 1/4 second */
+  for (i = 0; i < (G_USEC_PER_SEC / 100 / 4); i++)
+    {
+      grab_keyboard = gdk_keyboard_grab (root, TRUE, GDK_CURRENT_TIME);
+      if (grab_keyboard == GDK_GRAB_SUCCESS)
+        {
+          grab_pointer = gdk_pointer_grab (root, TRUE, pointer_mask,
+                                           NULL, NULL, GDK_CURRENT_TIME);
+          if (grab_pointer == GDK_GRAB_SUCCESS)
+            {
+              grab_succeed = TRUE;
+              break;
+            }
+        }
+
+      g_usleep (100);
+    }
+
+  /* release the grab so the gtk_menu_popup() can take it */
+  if (grab_pointer == GDK_GRAB_SUCCESS)
+    gdk_pointer_ungrab (GDK_CURRENT_TIME);
+  if (grab_keyboard == GDK_GRAB_SUCCESS)
+    gdk_keyboard_ungrab (GDK_CURRENT_TIME);
+
+  if (!grab_succeed)
+    {
+      g_printerr (PACKAGE_NAME ": Unable to get keyboard and mouse "
+                  "grab. Menu popup failed.\n");
+    }
+
+  return grab_succeed;
+}
diff --git a/common/panel-utils.h b/common/panel-utils.h
index b10565b..79c3ee3 100644
--- a/common/panel-utils.h
+++ b/common/panel-utils.h
@@ -27,13 +27,15 @@
   if (xfce_titled_dialog_get_type () == 0) \
     return;
 
-GtkBuilder *panel_utils_builder_new (XfcePanelPlugin  *panel_plugin,
-                                     const gchar      *buffer,
-                                     gsize             length,
-                                     GObject         **dialog_return) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+GtkBuilder *panel_utils_builder_new    (XfcePanelPlugin  *panel_plugin,
+                                        const gchar      *buffer,
+                                        gsize             length,
+                                        GObject         **dialog_return) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
 
-void        panel_utils_show_help   (GtkWindow        *parent,
-                                     const gchar      *page,
-                                     const gchar      *offset);
+void        panel_utils_show_help      (GtkWindow        *parent,
+                                        const gchar      *page,
+                                        const gchar      *offset);
+
+gboolean    panel_utils_grab_available (void);
 
 #endif /* !__PANEL_BUILDER_H__ */
diff --git a/plugins/applicationsmenu/applicationsmenu.c b/plugins/applicationsmenu/applicationsmenu.c
index 91d5044..6e8a987 100644
--- a/plugins/applicationsmenu/applicationsmenu.c
+++ b/plugins/applicationsmenu/applicationsmenu.c
@@ -547,7 +547,8 @@ applications_menu_plugin_remote_event (XfcePanelPlugin *panel_plugin,
           && g_value_get_boolean (value))
         {
           /* show menu under cursor */
-          applications_menu_plugin_menu (NULL, plugin);
+          if (panel_utils_grab_available ())
+            applications_menu_plugin_menu (NULL, plugin);
         }
       else
         {
diff --git a/plugins/directorymenu/directorymenu.c b/plugins/directorymenu/directorymenu.c
index 514ac15..0502d66 100644
--- a/plugins/directorymenu/directorymenu.c
+++ b/plugins/directorymenu/directorymenu.c
@@ -462,7 +462,8 @@ directory_menu_plugin_remote_event (XfcePanelPlugin *panel_plugin,
           && g_value_get_boolean (value))
         {
           /* popup the menu under the pointer */
-          directory_menu_plugin_menu (NULL, plugin);
+          if (panel_utils_grab_available ())
+            directory_menu_plugin_menu (NULL, plugin);
         }
       else
         {
diff --git a/plugins/windowmenu/windowmenu.c b/plugins/windowmenu/windowmenu.c
index 119a3b5..09a86cd 100644
--- a/plugins/windowmenu/windowmenu.c
+++ b/plugins/windowmenu/windowmenu.c
@@ -589,7 +589,8 @@ window_menu_plugin_remote_event (XfcePanelPlugin *panel_plugin,
           && g_value_get_boolean (value))
         {
           /* popup the menu under the pointer */
-          window_menu_plugin_menu (NULL, plugin);
+          if (panel_utils_grab_available ())
+            window_menu_plugin_menu (NULL, plugin);
         }
       else
         {



More information about the Xfce4-commits mailing list