]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkmenushell.c
GtkTextView: don't popdown a bubble if we don't have one
[~andy/gtk] / gtk / gtkmenushell.c
index 71c25d9c7f41c370773a41465735e50a2e78e443..ae36459d43f981feae370333b014a5f46b5df0f8 100644 (file)
@@ -12,9 +12,7 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  */
 
 /*
  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
  */
 
+/**
+ * SECTION:gtkmenushell
+ * @Title: GtkMenuShell
+ * @Short_description: A base class for menu objects
+ *
+ * A #GtkMenuShell is the abstract base class used to derive the
+ * #GtkMenu and #GtkMenuBar subclasses.
+ *
+ * A #GtkMenuShell is a container of #GtkMenuItem objects arranged
+ * in a list which can be navigated, selected, and activated by the
+ * user to perform application functions. A #GtkMenuItem can have a
+ * submenu associated with it, allowing for nested hierarchical menus.
+ */
 #include "config.h"
-#include "gdk/gdkkeysyms.h"
+
 #include "gtkbindings.h"
 #include "gtkkeyhash.h"
 #include "gtklabel.h"
 #include "gtkmain.h"
 #include "gtkmarshalers.h"
 #include "gtkmenubar.h"
-#include "gtkmenuitem.h"
+#include "gtkmenuitemprivate.h"
 #include "gtkmenushellprivate.h"
 #include "gtkmenuprivate.h"
 #include "gtkmnemonichash.h"
-#include "gtktearoffmenuitem.h"
 #include "gtkwindow.h"
 #include "gtkprivate.h"
+#include "gtkmain.h"
 #include "gtkintl.h"
+#include "gtktypebuiltins.h"
+
+#include "deprecated/gtktearoffmenuitem.h"
+
+#include "a11y/gtkmenushellaccessible.h"
+
 
 #define MENU_SHELL_TIMEOUT   500
 
@@ -56,6 +73,7 @@ enum {
   CANCEL,
   CYCLE_FOCUS,
   MOVE_SELECTED,
+  INSERT,
   LAST_SIGNAL
 };
 
@@ -230,6 +248,12 @@ gtk_menu_shell_class_init (GtkMenuShellClass *klass)
   klass->insert = gtk_menu_shell_real_insert;
   klass->move_selected = gtk_menu_shell_real_move_selected;
 
+  /**
+   * GtkMenuShell::deactivate:
+   * @menushell: the object which received the signal
+   *
+   * This signal is emitted when a menu shell is deactivated.
+   */
   menu_shell_signals[DEACTIVATE] =
     g_signal_new (I_("deactivate"),
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -239,6 +263,13 @@ gtk_menu_shell_class_init (GtkMenuShellClass *klass)
                   _gtk_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
 
+  /**
+   * GtkMenuShell::selection-done:
+   * @menushell: the object which received the signal
+   *
+   * This signal is emitted when a selection has been
+   * completed within a menu shell.
+   */
   menu_shell_signals[SELECTION_DONE] =
     g_signal_new (I_("selection-done"),
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -248,6 +279,14 @@ gtk_menu_shell_class_init (GtkMenuShellClass *klass)
                   _gtk_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
 
+  /**
+   * GtkMenuShell::move-current:
+   * @menushell: the object which received the signal
+   * @direction: the direction to move
+   *
+   * An keybinding signal which moves the current menu item
+   * in the direction specified by @direction.
+   */
   menu_shell_signals[MOVE_CURRENT] =
     g_signal_new (I_("move-current"),
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -258,6 +297,14 @@ gtk_menu_shell_class_init (GtkMenuShellClass *klass)
                   G_TYPE_NONE, 1,
                   GTK_TYPE_MENU_DIRECTION_TYPE);
 
+  /**
+   * GtkMenuShell::activate-current:
+   * @menushell: the object which received the signal
+   * @force_hide: if %TRUE, hide the menu after activating the menu item
+   *
+   * An action signal that activates the current menu item within
+   * the menu shell.
+   */
   menu_shell_signals[ACTIVATE_CURRENT] =
     g_signal_new (I_("activate-current"),
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -268,6 +315,13 @@ gtk_menu_shell_class_init (GtkMenuShellClass *klass)
                   G_TYPE_NONE, 1,
                   G_TYPE_BOOLEAN);
 
+  /**
+   * GtkMenuShell::cancel:
+   * @menushell: the object which received the signal
+   *
+   * An action signal which cancels the selection within the menu shell.
+   * Causes the #GtkMenuShell::selection-done signal to be emitted.
+   */
   menu_shell_signals[CANCEL] =
     g_signal_new (I_("cancel"),
                   G_OBJECT_CLASS_TYPE (object_class),
@@ -277,6 +331,14 @@ gtk_menu_shell_class_init (GtkMenuShellClass *klass)
                   _gtk_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
 
+  /**
+   * GtkMenuShell::cycle-focus:
+   * @menushell: the object which received the signal
+   * @direction: the direction to cycle in
+   *
+   * A keybinding signal which moves the focus in the
+   * given @direction.
+   */
   menu_shell_signals[CYCLE_FOCUS] =
     g_signal_new_class_handler (I_("cycle-focus"),
                                 G_OBJECT_CLASS_TYPE (object_class),
@@ -309,6 +371,31 @@ gtk_menu_shell_class_init (GtkMenuShellClass *klass)
                   G_TYPE_BOOLEAN, 1,
                   G_TYPE_INT);
 
+  /**
+   * GtkMenuShell::insert:
+   * @menu_shell: the object on which the signal is emitted
+   * @child: the #GtkMenuItem that is being inserted
+   * @position: the position at which the insert occurs
+   *
+   * The ::insert signal is emitted when a new #GtkMenuItem is added to
+   * a #GtkMenuShell.  A separate signal is used instead of
+   * GtkContainer::add because of the need for an additional position
+   * parameter.
+   *
+   * The inverse of this signal is the GtkContainer::removed signal.
+   *
+   * Since: 3.2
+   **/
+  menu_shell_signals[INSERT] =
+    g_signal_new (I_("insert"),
+                  G_OBJECT_CLASS_TYPE (object_class),
+                  G_SIGNAL_RUN_FIRST,
+                  G_STRUCT_OFFSET (GtkMenuShellClass, insert),
+                  NULL, NULL,
+                  _gtk_marshal_VOID__OBJECT_INT,
+                  G_TYPE_NONE, 2, GTK_TYPE_WIDGET, G_TYPE_INT);
+
+
   binding_set = gtk_binding_set_by_class (klass);
   gtk_binding_entry_add_signal (binding_set,
                                 GDK_KEY_Escape, 0,
@@ -364,6 +451,8 @@ gtk_menu_shell_class_init (GtkMenuShellClass *klass)
                                                          TRUE,
                                                          GTK_PARAM_READWRITE));
 
+  gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_MENU_SHELL_ACCESSIBLE);
+
   g_type_class_add_private (object_class, sizeof (GtkMenuShellPrivate));
 }
 
@@ -446,6 +535,14 @@ gtk_menu_shell_dispose (GObject *object)
   G_OBJECT_CLASS (gtk_menu_shell_parent_class)->dispose (object);
 }
 
+/**
+ * gtk_menu_shell_append:
+ * @menu_shell: a #GtkMenuShell
+ * @child: The #GtkMenuItem to add
+ *
+ * Adds a new #GtkMenuItem to the end of the menu shell's
+ * item list.
+ */
 void
 gtk_menu_shell_append (GtkMenuShell *menu_shell,
                        GtkWidget    *child)
@@ -453,6 +550,14 @@ gtk_menu_shell_append (GtkMenuShell *menu_shell,
   gtk_menu_shell_insert (menu_shell, child, -1);
 }
 
+/**
+ * gtk_menu_shell_prepend:
+ * @menu_shell: a #GtkMenuShell
+ * @child: The #GtkMenuItem to add
+ *
+ * Adds a new #GtkMenuItem to the beginning of the menu shell's
+ * item list.
+ */
 void
 gtk_menu_shell_prepend (GtkMenuShell *menu_shell,
                         GtkWidget    *child)
@@ -460,20 +565,25 @@ gtk_menu_shell_prepend (GtkMenuShell *menu_shell,
   gtk_menu_shell_insert (menu_shell, child, 0);
 }
 
+/**
+ * gtk_menu_shell_insert:
+ * @menu_shell: a #GtkMenuShell
+ * @child: The #GtkMenuItem to add
+ * @position: The position in the item list where @child
+ *     is added. Positions are numbered from 0 to n-1
+ *
+ * Adds a new #GtkMenuItem to the menu shell's item list
+ * at the position indicated by @position.
+ */
 void
 gtk_menu_shell_insert (GtkMenuShell *menu_shell,
                        GtkWidget    *child,
                        gint          position)
 {
-  GtkMenuShellClass *class;
-
   g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell));
   g_return_if_fail (GTK_IS_MENU_ITEM (child));
 
-  class = GTK_MENU_SHELL_GET_CLASS (menu_shell);
-
-  if (class->insert)
-    class->insert (menu_shell, child, position);
+  g_signal_emit (menu_shell, menu_shell_signals[INSERT], 0, child, position);
 }
 
 static void
@@ -488,12 +598,22 @@ gtk_menu_shell_real_insert (GtkMenuShell *menu_shell,
   gtk_widget_set_parent (child, GTK_WIDGET (menu_shell));
 }
 
+/**
+ * gtk_menu_shell_deactivate:
+ * @menu_shell: a #GtkMenuShell
+ *
+ * Deactivates the menu shell.
+ *
+ * Typically this results in the menu shell being erased
+ * from the screen.
+ */
 void
 gtk_menu_shell_deactivate (GtkMenuShell *menu_shell)
 {
   g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell));
 
-  g_signal_emit (menu_shell, menu_shell_signals[DEACTIVATE], 0);
+  if (menu_shell->priv->active)
+    g_signal_emit (menu_shell, menu_shell_signals[DEACTIVATE], 0);
 }
 
 static void
@@ -503,6 +623,7 @@ gtk_menu_shell_realize (GtkWidget *widget)
   GdkWindow *window;
   GdkWindowAttr attributes;
   gint attributes_mask;
+  GtkStyleContext *context;
 
   gtk_widget_set_realized (widget, TRUE);
 
@@ -528,14 +649,14 @@ gtk_menu_shell_realize (GtkWidget *widget)
   window = gdk_window_new (gtk_widget_get_parent_window (widget),
                            &attributes, attributes_mask);
   gtk_widget_set_window (widget, window);
-  gdk_window_set_user_data (window, widget);
+  gtk_widget_register_window (widget, window);
 
-  gtk_widget_style_attach (widget);
-  gtk_style_set_background (gtk_widget_get_style (widget), window, GTK_STATE_NORMAL);
+  context = gtk_widget_get_style_context (widget);
+  gtk_style_context_set_background (context, window);
 }
 
-void
-_gtk_menu_shell_activate (GtkMenuShell *menu_shell)
+static void
+gtk_menu_shell_activate (GtkMenuShell *menu_shell)
 {
   GtkMenuShellPrivate *priv = menu_shell->priv;
 
@@ -603,7 +724,7 @@ gtk_menu_shell_button_press (GtkWidget      *widget,
               gtk_widget_get_parent (menu_item) == widget &&
               menu_item != priv->active_menu_item)
             {
-              _gtk_menu_shell_activate (menu_shell);
+              gtk_menu_shell_activate (menu_shell);
               priv->button = event->button;
 
               if (GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement == GTK_TOP_BOTTOM)
@@ -645,9 +766,10 @@ gtk_menu_shell_button_press (GtkWidget      *widget,
         }
     }
 
-  if (menu_item && _gtk_menu_item_is_selectable (menu_item) &&
-      GTK_MENU_ITEM (menu_item)->submenu != NULL &&
-      !gtk_widget_get_visible (GTK_MENU_ITEM (menu_item)->submenu))
+  if (menu_item &&
+      _gtk_menu_item_is_selectable (menu_item) &&
+      GTK_MENU_ITEM (menu_item)->priv->submenu != NULL &&
+      !gtk_widget_get_visible (GTK_MENU_ITEM (menu_item)->priv->submenu))
     {
       _gtk_menu_item_popup_submenu (menu_item, FALSE);
       priv->activated_submenu = TRUE;
@@ -701,7 +823,7 @@ gtk_menu_shell_button_release (GtkWidget      *widget,
           if (menu_item && (priv->active_menu_item == menu_item) &&
               _gtk_menu_item_is_selectable (menu_item))
             {
-              GtkWidget *submenu = GTK_MENU_ITEM (menu_item)->submenu;
+              GtkWidget *submenu = GTK_MENU_ITEM (menu_item)->priv->submenu;
 
               if (submenu == NULL)
                 {
@@ -943,7 +1065,7 @@ gtk_menu_shell_enter_notify (GtkWidget        *widget,
 
           if (event->detail != GDK_NOTIFY_INFERIOR)
             {
-              if (gtk_widget_get_state (menu_item) != GTK_STATE_PRELIGHT)
+              if ((gtk_widget_get_state_flags (menu_item) & GTK_STATE_FLAG_PRELIGHT) == 0)
                 gtk_menu_shell_select_item (menu_shell, menu_item);
 
               /* If any mouse button is down, and there is a submenu
@@ -955,19 +1077,17 @@ gtk_menu_shell_enter_notify (GtkWidget        *widget,
                * its submenu.
                */
               if ((event->state & (GDK_BUTTON1_MASK|GDK_BUTTON2_MASK|GDK_BUTTON3_MASK)) &&
-                  GTK_MENU_ITEM (menu_item)->submenu != NULL)
+                  GTK_MENU_ITEM (menu_item)->priv->submenu != NULL)
                 {
                   GTK_MENU_SHELL (parent)->priv->activated_submenu = TRUE;
 
-                  if (!gtk_widget_get_visible (GTK_MENU_ITEM (menu_item)->submenu))
+                  if (!gtk_widget_get_visible (GTK_MENU_ITEM (menu_item)->priv->submenu))
                     {
-                      gboolean touchscreen_mode;
+                      GdkDevice *source_device;
 
-                      g_object_get (gtk_widget_get_settings (widget),
-                                    "gtk-touchscreen-mode", &touchscreen_mode,
-                                    NULL);
+                      source_device = gdk_event_get_source_device ((GdkEvent *) event);
 
-                      if (touchscreen_mode)
+                      if (gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN)
                         _gtk_menu_item_popup_submenu (menu_item, TRUE);
                     }
                 }
@@ -987,7 +1107,7 @@ gtk_menu_shell_leave_notify (GtkWidget        *widget,
                              GdkEventCrossing *event)
 {
   if (event->mode == GDK_CROSSING_GTK_GRAB ||
-      event->mode == GDK_CROSSING_GTK_GRAB ||
+      event->mode == GDK_CROSSING_GTK_UNGRAB ||
       event->mode == GDK_CROSSING_STATE_CHANGED)
     return TRUE;
 
@@ -1010,10 +1130,10 @@ gtk_menu_shell_leave_notify (GtkWidget        *widget,
         }
 
       if ((priv->active_menu_item == event_widget) &&
-          (menu_item->submenu == NULL))
+          (menu_item->priv->submenu == NULL))
         {
           if ((event->detail != GDK_NOTIFY_INFERIOR) &&
-              (gtk_widget_get_state (GTK_WIDGET (menu_item)) != GTK_STATE_NORMAL))
+              (gtk_widget_get_state_flags (GTK_WIDGET (menu_item)) & GTK_STATE_FLAG_PRELIGHT) != 0)
             {
               gtk_menu_shell_deselect (menu_shell);
             }
@@ -1095,7 +1215,6 @@ gtk_real_menu_shell_deactivate (GtkMenuShell *menu_shell)
 
   if (priv->active)
     {
-
       priv->button = 0;
       priv->active = FALSE;
       priv->activate_time = 0;
@@ -1170,6 +1289,13 @@ gtk_menu_shell_get_item (GtkMenuShell *menu_shell,
 
 /* Handlers for action signals */
 
+/**
+ * gtk_menu_shell_select_item:
+ * @menu_shell: a #GtkMenuShell
+ * @menu_item: The #GtkMenuItem to select
+ *
+ * Selects the menu item from the menu shell.
+ */
 void
 gtk_menu_shell_select_item (GtkMenuShell *menu_shell,
                             GtkWidget    *menu_item)
@@ -1211,6 +1337,8 @@ gtk_menu_shell_real_select_item (GtkMenuShell *menu_shell,
       return;
     }
 
+  gtk_menu_shell_activate (menu_shell);
+
   priv->active_menu_item = menu_item;
   if (pack_dir == GTK_PACK_DIRECTION_TTB || pack_dir == GTK_PACK_DIRECTION_BTT)
     _gtk_menu_item_set_placement (GTK_MENU_ITEM (priv->active_menu_item),
@@ -1225,10 +1353,17 @@ gtk_menu_shell_real_select_item (GtkMenuShell *menu_shell,
   /* This allows the bizarre radio buttons-with-submenus-display-history
    * behavior
    */
-  if (GTK_MENU_ITEM (priv->active_menu_item)->submenu)
+  if (GTK_MENU_ITEM (priv->active_menu_item)->priv->submenu)
     gtk_widget_activate (priv->active_menu_item);
 }
 
+/**
+ * gtk_menu_shell_deselect:
+ * @menu_shell: a #GtkMenuShell
+ *
+ * Deselects the currently selected item from the menu shell,
+ * if any.
+ */
 void
 gtk_menu_shell_deselect (GtkMenuShell *menu_shell)
 {
@@ -1244,6 +1379,15 @@ gtk_menu_shell_deselect (GtkMenuShell *menu_shell)
     }
 }
 
+/**
+ * gtk_menu_shell_activate_item:
+ * @menu_shell: a #GtkMenuShell
+ * @menu_item: the #GtkMenuItem to activate
+ * @force_deactivate: if %TRUE, force the deactivation of the
+ *     menu shell after the menu item is activated
+ *
+ * Activates the menu item within the menu shell.
+ */
 void
 gtk_menu_shell_activate_item (GtkMenuShell *menu_shell,
                               GtkWidget    *menu_item,
@@ -1447,11 +1591,11 @@ gtk_menu_shell_select_submenu_first (GtkMenuShell *menu_shell)
 
   menu_item = GTK_MENU_ITEM (priv->active_menu_item);
 
-  if (menu_item->submenu)
+  if (menu_item->priv->submenu)
     {
       _gtk_menu_item_popup_submenu (GTK_WIDGET (menu_item), FALSE);
-      gtk_menu_shell_select_first (GTK_MENU_SHELL (menu_item->submenu), TRUE);
-      if (GTK_MENU_SHELL (menu_item->submenu)->priv->active_menu_item)
+      gtk_menu_shell_select_first (GTK_MENU_SHELL (menu_item->priv->submenu), TRUE);
+      if (GTK_MENU_SHELL (menu_item->priv->submenu)->priv->active_menu_item)
         return TRUE;
     }
 
@@ -1465,45 +1609,19 @@ gtk_real_menu_shell_move_current (GtkMenuShell         *menu_shell,
   GtkMenuShellPrivate *priv = menu_shell->priv;
   GtkMenuShell *parent_menu_shell = NULL;
   gboolean had_selection;
-  gboolean touchscreen_mode;
 
   priv->in_unselectable_item = FALSE;
 
   had_selection = priv->active_menu_item != NULL;
 
-  g_object_get (gtk_widget_get_settings (GTK_WIDGET (menu_shell)),
-                "gtk-touchscreen-mode", &touchscreen_mode,
-                NULL);
-
   if (priv->parent_menu_shell)
     parent_menu_shell = GTK_MENU_SHELL (priv->parent_menu_shell);
 
   switch (direction)
     {
     case GTK_MENU_DIR_PARENT:
-      if (touchscreen_mode &&
-          priv->active_menu_item &&
-          GTK_MENU_ITEM (priv->active_menu_item)->submenu &&
-          gtk_widget_get_visible (GTK_MENU_ITEM (priv->active_menu_item)->submenu))
-        {
-          /* if we are on a menu item that has an open submenu but the
-           * focus is not in that submenu (e.g. because it's empty or
-           * has only insensitive items), close that submenu instead of
-           * running into the code below which would close *this* menu.
-           */
-          _gtk_menu_item_popdown_submenu (priv->active_menu_item);
-          _gtk_menu_shell_update_mnemonics (menu_shell);
-        }
-      else if (parent_menu_shell)
+      if (parent_menu_shell)
         {
-          if (touchscreen_mode)
-            {
-              /* close menu when returning from submenu. */
-              _gtk_menu_item_popdown_submenu (GTK_MENU (menu_shell)->priv->parent_menu_item);
-              _gtk_menu_shell_update_mnemonics (parent_menu_shell);
-              break;
-            }
-
           if (GTK_MENU_SHELL_GET_CLASS (parent_menu_shell)->submenu_placement ==
               GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement)
             gtk_menu_shell_deselect (menu_shell);
@@ -1522,9 +1640,9 @@ gtk_real_menu_shell_move_current (GtkMenuShell         *menu_shell,
        */
       else if (priv->active_menu_item &&
                _gtk_menu_item_is_selectable (priv->active_menu_item) &&
-               GTK_MENU_ITEM (priv->active_menu_item)->submenu)
+               GTK_MENU_ITEM (priv->active_menu_item)->priv->submenu)
         {
-          GtkMenuShell *submenu = GTK_MENU_SHELL (GTK_MENU_ITEM (priv->active_menu_item)->submenu);
+          GtkMenuShell *submenu = GTK_MENU_SHELL (GTK_MENU_ITEM (priv->active_menu_item)->priv->submenu);
 
           if (GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement !=
               GTK_MENU_SHELL_GET_CLASS (submenu)->submenu_placement)
@@ -1535,7 +1653,7 @@ gtk_real_menu_shell_move_current (GtkMenuShell         *menu_shell,
     case GTK_MENU_DIR_CHILD:
       if (priv->active_menu_item &&
           _gtk_menu_item_is_selectable (priv->active_menu_item) &&
-          GTK_MENU_ITEM (priv->active_menu_item)->submenu)
+          GTK_MENU_ITEM (priv->active_menu_item)->priv->submenu)
         {
           if (gtk_menu_shell_select_submenu_first (menu_shell))
             break;
@@ -1562,17 +1680,13 @@ gtk_real_menu_shell_move_current (GtkMenuShell         *menu_shell,
 
     case GTK_MENU_DIR_PREV:
       gtk_menu_shell_move_selected (menu_shell, -1);
-      if (!had_selection &&
-          !priv->active_menu_item &&
-          priv->children)
+      if (!had_selection && !priv->active_menu_item && priv->children)
         _gtk_menu_shell_select_last (menu_shell, TRUE);
       break;
 
     case GTK_MENU_DIR_NEXT:
       gtk_menu_shell_move_selected (menu_shell, 1);
-      if (!had_selection &&
-          !priv->active_menu_item &&
-          priv->children)
+      if (!had_selection && !priv->active_menu_item && priv->children)
         gtk_menu_shell_select_first (menu_shell, TRUE);
       break;
     }
@@ -1587,7 +1701,7 @@ gtk_real_menu_shell_activate_current (GtkMenuShell *menu_shell,
   if (priv->active_menu_item &&
       _gtk_menu_item_is_selectable (priv->active_menu_item))
   {
-    if (GTK_MENU_ITEM (priv->active_menu_item)->submenu == NULL)
+    if (GTK_MENU_ITEM (priv->active_menu_item)->priv->submenu == NULL)
       gtk_menu_shell_activate_item (menu_shell,
                                     priv->active_menu_item,
                                     force_hide);
@@ -1609,12 +1723,10 @@ static void
 gtk_real_menu_shell_cycle_focus (GtkMenuShell     *menu_shell,
                                  GtkDirectionType  dir)
 {
-  GtkMenuShellPrivate *priv = menu_shell->priv;
-
   while (menu_shell && !GTK_IS_MENU_BAR (menu_shell))
     {
-      if (priv->parent_menu_shell)
-        menu_shell = GTK_MENU_SHELL (priv->parent_menu_shell);
+      if (menu_shell->priv->parent_menu_shell)
+        menu_shell = GTK_MENU_SHELL (menu_shell->priv->parent_menu_shell);
       else
         menu_shell = NULL;
     }
@@ -1745,8 +1857,11 @@ gtk_menu_shell_activate_mnemonic (GtkMenuShell *menu_shell,
                                   event->group);
 
   if (entries)
-    result = _gtk_mnemonic_hash_activate (mnemonic_hash,
-                                          GPOINTER_TO_UINT (entries->data));
+    {
+      result = _gtk_mnemonic_hash_activate (mnemonic_hash,
+                                            GPOINTER_TO_UINT (entries->data));
+      g_slist_free (entries);
+    }
 
   return result;
 }
@@ -1876,7 +1991,7 @@ gtk_menu_shell_set_take_focus (GtkMenuShell *menu_shell,
  *
  * Gets the currently selected item.
  *
- * Returns: the currently selected item
+ * Returns: (transfer none): the currently selected item
  *
  * Since: 3.0
  */
@@ -1897,7 +2012,7 @@ gtk_menu_shell_get_selected_item (GtkMenuShell *menu_shell)
  * The parent menu shell of a submenu is the #GtkMenu or #GtkMenuBar
  * from which it was opened up.
  *
- * Returns: the parent #GtkMenuShell
+ * Returns: (transfer none): the parent #GtkMenuShell
  *
  * Since: 3.0
  */