From e8e8c5b94f704fedf191f6e81ee30d507e75dad5 Mon Sep 17 00:00:00 2001 From: Eric Koegel Date: Sun, 27 Oct 2013 13:06:31 +0300 Subject: [PATCH] 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 6d5546d..f4a5b0a 100644 --- a/common/xfdesktop-common.c +++ b/common/xfdesktop-common.c @@ -315,3 +315,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 4dcec73..f4106ce 100644 --- a/common/xfdesktop-common.h +++ b/common/xfdesktop-common.h @@ -88,6 +88,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 b5b718d..9dba64f 100644 --- a/src/xfce-desktop.c +++ b/src/xfce-desktop.c @@ -854,7 +854,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); } @@ -1583,9 +1586,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 @@ -1593,16 +1594,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 @@ -1611,15 +1612,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 817db45..9724e7e 100644 --- a/src/xfdesktop-icon-view.c +++ b/src/xfdesktop-icon-view.c @@ -966,9 +966,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) { -- 1.8.3.2