[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