From 6476fbfd89ee795803897e5adcb276a87558e48e Mon Sep 17 00:00:00 2001 From: Alexander Schwinn <alexxcons@xfce.org> Date: Sat, 23 May 2020 14:56:03 +0200 Subject: [PATCH] Fixed menu freeze when using arrow keys for menu navigation and the mouse at the same time. (Issue #293) This as well fixes wrong menu-items when using arrow keys in some conditions --- thunar/thunar-window.c | 99 ++++++++++++++++++++++++++++++++---------- 1 file changed, 77 insertions(+), 22 deletions(-) diff --git a/thunar/thunar-window.c b/thunar/thunar-window.c index d2f95671e..77d13eae6 100644 --- a/thunar/thunar-window.c +++ b/thunar/thunar-window.c @@ -250,6 +250,9 @@ static void thunar_window_menu_add_bookmarks (ThunarWindow static gboolean thunar_window_menu_item_hovered (ThunarWindow *window, GdkEventCrossing *event, GtkWidget *menu); +static gboolean thunar_window_menu_move_selected (ThunarWindow *window, + gint distance, + GtkMenuShell *menu_shell); static gboolean thunar_window_check_uca_key_activation (ThunarWindow *window, GdkEventKey *key_event, gpointer user_data); @@ -663,6 +666,7 @@ thunar_window_init (ThunarWindow *window) /* build the menubar */ window->menubar = gtk_menu_bar_new (); + g_signal_connect_swapped (G_OBJECT (window->menubar), "move-selected", G_CALLBACK (thunar_window_menu_move_selected), window); item = xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_FILE_MENU), G_OBJECT (window), GTK_MENU_SHELL (window->menubar)); g_signal_connect_swapped (G_OBJECT (item), "button-press-event", G_CALLBACK (thunar_window_create_file_menu), window); g_signal_connect_swapped (G_OBJECT (item), "enter-notify-event", G_CALLBACK (thunar_window_menu_item_hovered), window); @@ -861,36 +865,67 @@ thunar_window_select_files (ThunarWindow *window, static gboolean -thunar_window_menu_is_open (ThunarWindow *window) +thunar_window_menu_item_hovered (ThunarWindow *window, + GdkEventCrossing *event, + GtkWidget *menu) { - GList *lp; - GtkWidget *submenu; + gboolean ret; + gboolean menu_is_open = FALSE; g_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); - for(lp = gtk_container_get_children (GTK_CONTAINER (window->menubar)); lp != NULL; lp = lp->next) + for (GList *lp = gtk_container_get_children (GTK_CONTAINER (window->menubar)); lp != NULL; lp = lp->next) { - submenu = gtk_menu_item_get_submenu(lp->data); - if (submenu != NULL && gtk_widget_get_visible (submenu)) - return TRUE; + GtkWidget *submenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(lp->data)); + if(submenu != NULL && gtk_widget_get_visible (submenu)) + { + menu_is_open = TRUE; + + /* The menu we want to open is already is open */ + if (menu == lp->data) + return GDK_EVENT_PROPAGATE; + } } - return FALSE; + + /* hover effect only apllies if some menu is already open */ + if (!menu_is_open) + return GDK_EVENT_PROPAGATE; + + g_signal_emit_by_name (menu, "button-press-event", NULL, &ret); + + return GDK_EVENT_STOP; } -static gboolean -thunar_window_menu_item_hovered (ThunarWindow *window, - GdkEventCrossing *event, - GtkWidget *menu) +gboolean +thunar_window_menu_move_selected (ThunarWindow *window, + gint distance, + GtkMenuShell *menu_shell) { - gboolean ret; + gboolean ret = FALSE; + GtkWidget *selected; - g_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), GDK_EVENT_STOP); - if (thunar_window_menu_is_open(window)) - g_signal_emit_by_name (menu, "button-press-event", NULL, &ret); - return FALSE; + selected = gtk_menu_shell_get_selected_item (menu_shell); + for (GList *lp = gtk_container_get_children (GTK_CONTAINER (window->menubar)); lp != NULL; lp = lp->next) + { + GtkWidget *submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (lp->data)); + if (submenu != NULL && gtk_widget_get_visible (submenu)) + gtk_menu_popdown (GTK_MENU (submenu)); + if (lp->data == selected) + { + /* create next/previous menu, or first/last menu on the borders */ + GList *new_item; + if (distance > 0) + new_item = lp->next != NULL ? lp->next : g_list_first (lp); + else + new_item = lp != g_list_first (lp) ? lp->prev : g_list_last (lp); + g_signal_emit_by_name (new_item->data, "button-press-event", NULL, &ret); + } + } + return GDK_EVENT_PROPAGATE; } @@ -906,6 +941,11 @@ thunar_window_create_file_menu (ThunarWindow *window, _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); _thunar_return_val_if_fail (GTK_IS_MENU_ITEM (menu), FALSE); + /* close, if already open */ + submenu = THUNAR_MENU (gtk_menu_item_get_submenu (GTK_MENU_ITEM (menu))); + if (submenu != NULL) + gtk_menu_popdown (GTK_MENU (submenu)); + submenu = g_object_new (THUNAR_TYPE_MENU, "menu-type", THUNAR_MENU_TYPE_WINDOW, "launcher", window->launcher, NULL); gtk_menu_set_accel_group (GTK_MENU (submenu), window->accel_group); @@ -947,6 +987,11 @@ thunar_window_create_edit_menu (ThunarWindow *window, _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); _thunar_return_val_if_fail (GTK_IS_MENU_ITEM (menu), FALSE); + /* close, if already open */ + submenu = THUNAR_MENU (gtk_menu_item_get_submenu (GTK_MENU_ITEM (menu))); + if (submenu != NULL) + gtk_menu_popdown (GTK_MENU (submenu)); + submenu = g_object_new (THUNAR_TYPE_MENU, "launcher", window->launcher, NULL); gtk_menu_set_accel_group (GTK_MENU (submenu), window->accel_group); thunar_menu_add_sections (submenu, THUNAR_MENU_SECTION_CUT @@ -1011,6 +1056,11 @@ thunar_window_create_view_menu (ThunarWindow *window, _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); _thunar_return_val_if_fail (GTK_IS_MENU_ITEM (menu), FALSE); + /* close, if already open */ + submenu = THUNAR_MENU (gtk_menu_item_get_submenu (GTK_MENU_ITEM (menu))); + if (submenu != NULL) + gtk_menu_popdown (GTK_MENU (submenu)); + submenu = g_object_new (THUNAR_TYPE_MENU, "launcher", window->launcher, NULL); gtk_menu_set_accel_group (GTK_MENU (submenu), window->accel_group); xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_RELOAD), G_OBJECT (window), GTK_MENU_SHELL (submenu)); @@ -1084,6 +1134,11 @@ thunar_window_create_go_menu (ThunarWindow *window, if (window->view != NULL) history = thunar_standard_view_get_history (THUNAR_STANDARD_VIEW (window->view)); + /* close, if already open */ + submenu = THUNAR_MENU (gtk_menu_item_get_submenu (GTK_MENU_ITEM (menu))); + if (submenu != NULL) + gtk_menu_popdown (GTK_MENU (submenu)); + submenu = g_object_new (THUNAR_TYPE_MENU, "launcher", window->launcher, NULL); gtk_menu_set_accel_group (GTK_MENU (submenu), window->accel_group); gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu), GTK_WIDGET (submenu)); @@ -1153,6 +1208,11 @@ thunar_window_create_help_menu (ThunarWindow *window, _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); _thunar_return_val_if_fail (GTK_IS_MENU_ITEM (menu), FALSE); + /* close, if already open */ + submenu = THUNAR_MENU (gtk_menu_item_get_submenu (GTK_MENU_ITEM (menu))); + if (submenu != NULL) + gtk_menu_popdown (GTK_MENU (submenu)); + submenu = g_object_new (THUNAR_TYPE_MENU, "launcher", window->launcher, NULL); gtk_menu_set_accel_group (GTK_MENU (submenu), window->accel_group); xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_CONTENTS), G_OBJECT (window), GTK_MENU_SHELL (submenu)); @@ -3275,7 +3335,6 @@ thunar_window_current_directory_changed (ThunarFile *current_directory, gboolean show_full_path; gchar *parse_name = NULL; const gchar *name; - gboolean ret; _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); _thunar_return_if_fail (THUNAR_IS_FILE (current_directory)); @@ -3294,10 +3353,6 @@ thunar_window_current_directory_changed (ThunarFile *current_directory, /* set window icon */ thunar_window_update_window_icon (window); - - /* update the window menu. E.g. relevant for keyboard navigation in the window menu */ - for (GList *lp = gtk_container_get_children (GTK_CONTAINER (window->menubar)); lp != NULL; lp = lp->next) - g_signal_emit_by_name (lp->data, "button-press-event", NULL, &ret); } -- GitLab