[Xfce4-commits] <xfdesktop:master> Fix menu popups via the command line

Eric Koegel noreply at xfce.org
Tue Oct 29 16:42:01 CET 2013


Updating branch refs/heads/master
         to 82b385d0e243dc26429b8cc647630f18107ebe6a (commit)
       from 24d5681d0bd57bce021cc1b44995de27c67e5fcc (commit)

commit 82b385d0e243dc26429b8cc647630f18107ebe6a
Author: Eric Koegel <eric.koegel at gmail.com>
Date:   Sun Oct 27 13:04:28 2013 +0300

    Fix menu popups via the command line

 common/xfdesktop-common.c |   40 ++++++++++++++++++++++++++++++++++++++++
 common/xfdesktop-common.h |    2 ++
 src/xfce-desktop.c        |   24 +++++++++++-------------
 src/xfdesktop-icon-view.c |    6 ++++--
 4 files changed, 57 insertions(+), 15 deletions(-)

diff --git a/common/xfdesktop-common.c b/common/xfdesktop-common.c
index 2011e6c..ca6b89c 100644
--- a/common/xfdesktop-common.c
+++ b/common/xfdesktop-common.c
@@ -180,3 +180,43 @@ xfce_translate_image_styles(gint input)
 
     return style;
 }
+
+/* Code taken from xfwm4/src/menu.c:grab_available().  This should fix the case
+ * where binding 'xfdesktop -menu' to a keyboard shortcut sometimes works and
+ * sometimes doesn't.  Credit for this one goes to Olivier.
+ * Returns the grab time if successful, 0 on failure.
+ */
+guint32
+xfdesktop_popup_keyboard_grab_available(GdkWindow *win)
+{
+    GdkGrabStatus grab;
+    gboolean grab_failed = FALSE;
+    guint32 timestamp;
+    gint i = 0;
+
+    TRACE("entering");
+
+    timestamp = gtk_get_current_event_time();
+
+    grab = gdk_keyboard_grab(win, TRUE, timestamp);
+
+    while((i++ < 2500) && (grab_failed = ((grab != GDK_GRAB_SUCCESS))))
+    {
+        TRACE ("keyboard grab not available yet, reason: %d, waiting... (%i)", grab, i);
+        if(grab == GDK_GRAB_INVALID_TIME)
+            break;
+
+        g_usleep (100);
+        if(grab != GDK_GRAB_SUCCESS) {
+            grab = gdk_keyboard_grab(win, TRUE, timestamp);
+        }
+    }
+
+    if (grab == GDK_GRAB_SUCCESS) {
+        gdk_keyboard_ungrab(timestamp);
+    } else {
+        timestamp = 0;
+    }
+
+    return timestamp;
+}
diff --git a/common/xfdesktop-common.h b/common/xfdesktop-common.h
index dde3fa40..3377461 100644
--- a/common/xfdesktop-common.h
+++ b/common/xfdesktop-common.h
@@ -94,6 +94,8 @@ void xfdesktop_send_client_message(Window xid, const gchar *msg);
 
 gint xfce_translate_image_styles(gint input);
 
+guint32 xfdesktop_popup_keyboard_grab_available(GdkWindow *win);
+
 G_END_DECLS
 
 #endif
diff --git a/src/xfce-desktop.c b/src/xfce-desktop.c
index d59a92a..4963851 100644
--- a/src/xfce-desktop.c
+++ b/src/xfce-desktop.c
@@ -862,7 +862,10 @@ xfce_desktop_init(XfceDesktop *desktop)
                                                 XfceDesktopPriv);
     
     gtk_window_set_type_hint(GTK_WINDOW(desktop), GDK_WINDOW_TYPE_HINT_DESKTOP);
-    gtk_window_set_accept_focus(GTK_WINDOW(desktop), FALSE);
+    /* Accept focus is needed for the menu pop up either by the menu key on
+     * the keyboard or Shift+F10. */
+    gtk_window_set_accept_focus(GTK_WINDOW(desktop), TRUE);
+    /* Can focus is needed for the gtk_grab_add/remove commands */
     gtk_widget_set_can_focus(GTK_WIDGET(desktop), TRUE);
     gtk_window_set_resizable(GTK_WINDOW(desktop), FALSE);
 }
@@ -1590,9 +1593,7 @@ xfce_desktop_do_menu_popup(XfceDesktop *desktop,
     if(activate_time == 0)
         activate_time = gtk_get_current_event_time();
 
-    /* bug #3652: for some reason passing the correct button here breaks
-     * on some systems but not others.  always pass 0 for now. */
-    gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, activate_time);
+    gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, button, activate_time);
 }
 
 void
@@ -1600,16 +1601,16 @@ xfce_desktop_popup_root_menu(XfceDesktop *desktop,
                              guint button,
                              guint activate_time)
 {
+    TRACE("entering");
+
     /* If it's launched by xfdesktop --menu we won't have an event time.
-     * Just grab the focus so the menu can pop up */
+     * Grab the keyboard focus */
     if(activate_time == 0)
-        gtk_grab_add(GTK_WIDGET(desktop));
+        activate_time = xfdesktop_popup_keyboard_grab_available(gtk_widget_get_window(GTK_WIDGET(desktop)));
 
     xfce_desktop_do_menu_popup(desktop, button, activate_time,
                                signals[SIG_POPULATE_ROOT_MENU]);
 
-    if(activate_time == 0)
-        gtk_grab_remove(GTK_WIDGET(desktop));
 }
 
 void
@@ -1618,15 +1619,12 @@ xfce_desktop_popup_secondary_root_menu(XfceDesktop *desktop,
                                        guint activate_time)
 {
     /* If it's launched by xfdesktop --windowlist we won't have an event time.
-     * Just grab the focus so the menu can pop up */
+     * Grab the keyboard focus */
     if(activate_time == 0)
-        gtk_grab_add(GTK_WIDGET(desktop));
+        activate_time = xfdesktop_popup_keyboard_grab_available(gtk_widget_get_window(GTK_WIDGET(desktop)));
 
     xfce_desktop_do_menu_popup(desktop, button, activate_time,
                                signals[SIG_POPULATE_SECONDARY_ROOT_MENU]);
-
-    if(activate_time == 0)
-        gtk_grab_remove(GTK_WIDGET(desktop));
 }
 void
 xfce_desktop_refresh(XfceDesktop *desktop)
diff --git a/src/xfdesktop-icon-view.c b/src/xfdesktop-icon-view.c
index 987c9a7..345b400 100644
--- a/src/xfdesktop-icon-view.c
+++ b/src/xfdesktop-icon-view.c
@@ -1028,9 +1028,11 @@ xfdesktop_icon_view_button_release(GtkWidget *widget,
 
         /* If we clicked an icon then we didn't pop up the menu during the
          * button press in order to support right click DND, pop up the menu
-         * now */
+         * now.
+         * We pass 0 as the button because the docs say that you must use 0
+         * for pop ups other than button press events. */
         if(icon_l && (icon = icon_l->data))
-            xfce_desktop_popup_root_menu(XFCE_DESKTOP(widget), evt->button, evt->time);
+            xfce_desktop_popup_root_menu(XFCE_DESKTOP(widget), 0, evt->time);
     }
 
     if(evt->button == 1 || evt->button == 3) {


More information about the Xfce4-commits mailing list