Commit b532e1ff authored by Allison Karlitskaya's avatar Allison Karlitskaya

menu binding: emit submenu close after activate

We want to make sure that the submenu action is changed back to FALSE
_after_ the menu item has been activated.  This prevents the menu
teardown handler from deleting the menu item before it can be activated.

Unfortunately, GtkMenuShell emits "hide" before the item activation.
This is probably done to prevent the application from doing things like
showing dialogs when the menu is still holding the grab.

In the case where we are doing an activate, set a boolean flag on each
of the open menus (following the parent stack) indicating that we'll be
emitting another signal soon (selection done).  If that flag is set, we
defer the setting of the submenu action until we receive the second
signal.

https://bugzilla.gnome.org/show_bug.cgi?id=729820
parent 38a6a72a
...@@ -1360,6 +1360,8 @@ gtk_menu_shell_activate_item (GtkMenuShell *menu_shell, ...@@ -1360,6 +1360,8 @@ gtk_menu_shell_activate_item (GtkMenuShell *menu_shell,
do do
{ {
parent_menu_shell->priv->selection_done_coming_soon = TRUE;
g_object_ref (parent_menu_shell); g_object_ref (parent_menu_shell);
shells = g_slist_prepend (shells, parent_menu_shell); shells = g_slist_prepend (shells, parent_menu_shell);
parent_menu_shell = (GtkMenuShell*) parent_menu_shell->priv->parent_menu_shell; parent_menu_shell = (GtkMenuShell*) parent_menu_shell->priv->parent_menu_shell;
...@@ -1379,7 +1381,10 @@ gtk_menu_shell_activate_item (GtkMenuShell *menu_shell, ...@@ -1379,7 +1381,10 @@ gtk_menu_shell_activate_item (GtkMenuShell *menu_shell,
for (slist = shells; slist; slist = slist->next) for (slist = shells; slist; slist = slist->next)
{ {
g_signal_emit (slist->data, menu_shell_signals[SELECTION_DONE], 0); GtkMenuShell *parent_menu_shell = slist->data;
g_signal_emit (parent_menu_shell, menu_shell_signals[SELECTION_DONE], 0);
parent_menu_shell->priv->selection_done_coming_soon = FALSE;
g_object_unref (slist->data); g_object_unref (slist->data);
} }
g_slist_free (shells); g_slist_free (shells);
...@@ -2010,7 +2015,18 @@ gtk_menu_shell_submenu_hidden (GtkWidget *submenu, ...@@ -2010,7 +2015,18 @@ gtk_menu_shell_submenu_hidden (GtkWidget *submenu,
{ {
GtkMenuTrackerItem *item = user_data; GtkMenuTrackerItem *item = user_data;
gtk_menu_tracker_item_request_submenu_shown (item, FALSE); if (!GTK_MENU_SHELL (submenu)->priv->selection_done_coming_soon)
gtk_menu_tracker_item_request_submenu_shown (item, FALSE);
}
static void
gtk_menu_shell_submenu_selection_done (GtkWidget *submenu,
gpointer user_data)
{
GtkMenuTrackerItem *item = user_data;
if (GTK_MENU_SHELL (submenu)->priv->selection_done_coming_soon)
gtk_menu_tracker_item_request_submenu_shown (item, FALSE);
} }
static void static void
...@@ -2091,6 +2107,7 @@ gtk_menu_shell_tracker_insert_func (GtkMenuTrackerItem *item, ...@@ -2091,6 +2107,7 @@ gtk_menu_shell_tracker_insert_func (GtkMenuTrackerItem *item,
*/ */
g_signal_connect (submenu, "show", G_CALLBACK (gtk_menu_shell_submenu_shown), item); g_signal_connect (submenu, "show", G_CALLBACK (gtk_menu_shell_submenu_shown), item);
g_signal_connect (submenu, "hide", G_CALLBACK (gtk_menu_shell_submenu_hidden), item); g_signal_connect (submenu, "hide", G_CALLBACK (gtk_menu_shell_submenu_hidden), item);
g_signal_connect (submenu, "selection-done", G_CALLBACK (gtk_menu_shell_submenu_selection_done), item);
} }
gtk_widget_show (widget); gtk_widget_show (widget);
......
...@@ -61,6 +61,11 @@ struct _GtkMenuShellPrivate ...@@ -61,6 +61,11 @@ struct _GtkMenuShellPrivate
* the user moves the mouse over * the user moves the mouse over
* an unselectable menuitem. * an unselectable menuitem.
*/ */
guint selection_done_coming_soon : 1; /* Set TRUE when a selection-done
* signal is coming soon (when checked
* from inside of a "hide" handler).
*/
GtkMnemonicHash *mnemonic_hash; GtkMnemonicHash *mnemonic_hash;
GtkKeyHash *key_hash; GtkKeyHash *key_hash;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment