2009-03-04 Alberto Garcia <agarcia@igalia.com>
authorAlberto Garcia <agarcia@igalia.com>
Wed, 4 Mar 2009 15:52:04 +0000 (15:52 +0000)
committerAlberto Garcia <agarcia@igalia.com>
Wed, 4 Mar 2009 15:52:04 +0000 (15:52 +0000)
* doc/hildon-sections.txt
* src/hildon-stackable-window-private.h
* src/hildon-stackable-window.h
* src/hildon-stackable-window.c
(-hildon_stackable_window_set_app_menu)
(-hildon_stackable_window_get_app_menu)
(-hildon_stackable_window_toggle_menu)
(-hildon_stackable_window_finalize)
(hildon_stackable_window_class_init)
(hildon_stackable_window_init)
* src/hildon-window-private.h
* src/hildon-window.h
* src/hildon-window.c (hildon_window_init)
(hildon_window_destroy, +hildon_window_toggle_gtk_menu)
(+hildon_window_toggle_app_menu, hildon_window_toggle_menu_real)
(hildon_window_get_main_menu, hildon_window_set_main_menu)
(+hildon_window_set_app_menu, +hildon_window_get_app_menu):
Moved all HildonAppMenu code to HildonWindow. The menu does not
require a HildonStackableWindow anymore.

* src/hildon-app-menu.c
* src/hildon-program.c
* examples/hildon-app-menu-example.c (main):
Update examples and documentation to reflect HildonAppMenu
changes.

ChangeLog
doc/hildon-sections.txt
examples/hildon-app-menu-example.c
src/hildon-app-menu.c
src/hildon-program.c
src/hildon-stackable-window-private.h
src/hildon-stackable-window.c
src/hildon-stackable-window.h
src/hildon-window-private.h
src/hildon-window.c
src/hildon-window.h

index 3af491f..416dd17 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,33 @@
 2009-03-04  Alberto Garcia  <agarcia@igalia.com>
 
+       * doc/hildon-sections.txt
+       * src/hildon-stackable-window-private.h
+       * src/hildon-stackable-window.h
+       * src/hildon-stackable-window.c
+       (-hildon_stackable_window_set_app_menu)
+       (-hildon_stackable_window_get_app_menu)
+       (-hildon_stackable_window_toggle_menu)
+       (-hildon_stackable_window_finalize)
+       (hildon_stackable_window_class_init)
+       (hildon_stackable_window_init)
+       * src/hildon-window-private.h
+       * src/hildon-window.h
+       * src/hildon-window.c (hildon_window_init)
+       (hildon_window_destroy, +hildon_window_toggle_gtk_menu)
+       (+hildon_window_toggle_app_menu, hildon_window_toggle_menu_real)
+       (hildon_window_get_main_menu, hildon_window_set_main_menu)
+       (+hildon_window_set_app_menu, +hildon_window_get_app_menu):
+       Moved all HildonAppMenu code to HildonWindow. The menu does not
+       require a HildonStackableWindow anymore.
+
+       * src/hildon-app-menu.c
+       * src/hildon-program.c
+       * examples/hildon-app-menu-example.c (main):
+       Update examples and documentation to reflect HildonAppMenu
+       changes.
+
+2009-03-04  Alberto Garcia  <agarcia@igalia.com>
+
        * src/hildon-remote-texture.c
        * src/hildon-animation-actor.c:
        Don't include unused private headers.
index 22aa0b6..8798121 100644 (file)
@@ -53,8 +53,6 @@ HildonRangeEditorClass
 <TITLE>HildonStackableWindow</TITLE>
 HildonStackableWindow
 hildon_stackable_window_new
-hildon_stackable_window_set_app_menu
-hildon_stackable_window_get_app_menu
 hildon_stackable_window_get_stack
 hildon_stackable_window_set_main_menu
 <SUBSECTION Standard>
@@ -688,6 +686,8 @@ hildon_window_new
 hildon_window_add_with_scrollbar
 hildon_window_set_main_menu
 hildon_window_get_main_menu
+hildon_window_set_app_menu
+hildon_window_get_app_menu
 hildon_window_set_menu
 hildon_window_get_menu
 hildon_window_add_toolbar
index 6b1b832..7518441 100644 (file)
@@ -117,7 +117,7 @@ main                                            (int argc,
 
     menu = create_menu (label2, accel);
 
-    hildon_stackable_window_set_app_menu (HILDON_STACKABLE_WINDOW (win), menu);
+    hildon_window_set_app_menu (HILDON_WINDOW (win), menu);
 
     gtk_window_add_accel_group (GTK_WINDOW (win), accel);
     g_object_unref (accel);
index 9d0cbd0..5e11553 100644 (file)
  * Besides that, the #HildonAppMenu can contain a group of filter buttons
  * (#GtkToggleButton or #GtkRadioButton).
  *
- * To use a #HildonAppMenu, add it to a #HildonStackableWindow using
- * hildon_stackable_window_set_app_menu(). The menu will appear when
- * the user presses the window title bar. Alternatively, you can show
- * it by hand using hildon_app_menu_popup().
+ * To use a #HildonAppMenu, add it to a #HildonWindow using
+ * hildon_window_set_app_menu(). The menu will appear when the user
+ * presses the window title bar. Alternatively, you can show it by
+ * hand using hildon_app_menu_popup().
  *
  * The menu will be automatically hidden when one of its buttons is
  * clicked. Use g_signal_connect_after() when connecting callbacks to
  * <example>
  * <title>Creating a HildonAppMenu</title>
  * <programlisting>
- * HildonStackableWindow *win;
+ * GtkWidget *win;
  * HildonAppMenu *menu;
  * GtkWidget *button;
  * GtkWidget *filter;
  * <!-- -->
- * win = HILDON_STACKABLE_WINDOW (hildon_stackable_window_new ());
+ * win = hildon_stackable_window_new ();
  * menu = HILDON_APP_MENU (hildon_app_menu_new ());
  * <!-- -->
  * // Create a button and add it to the menu
@@ -85,7 +85,7 @@
  * gtk_widget_show_all (GTK_WIDGET (menu));
  * <!-- -->
  * // Add the menu to the window
- * hildon_stackable_window_set_app_menu (win, menu);
+ * hildon_window_set_app_menu (HILDON_WINDOW (win), menu);
  * </programlisting>
  * </example>
  *
index 8207477..c205b8f 100644 (file)
@@ -35,9 +35,9 @@
  * and can be unregistered similarly with hildon_program_remove_window().
  *
  * The #HildonProgram provides the programmer with commodities such
- * as applying a common toolbar and menu to all the #HildonWindow
- * registered to it. This is done with hildon_program_set_common_menu()
- * and hildon_program_set_common_toolbar().
+ * as applying a common toolbar and menu to all #HildonWindow<!-- -->s
+ * registered to it. This is done with hildon_program_set_common_menu(),
+ * hildon_program_set_common_app_menu() and hildon_program_set_common_toolbar().
  *
  * The #HildonProgram is also used to apply program-wide properties that
  * are specific to the Hildon framework. For instance
@@ -51,7 +51,7 @@
  * HildonWindow *window1;
  * HildonWindow *window2;
  * GtkToolbar *common_toolbar, *window_specific_toolbar;
- * GtkMenu *menu;
+ * HildonAppMenu *menu;
  * <!-- -->
  * program = HILDON_PROGRAM (hildon_program_get_instance ());
  * <!-- -->
@@ -66,7 +66,7 @@
  * hildon_program_add_window (program, window1);
  * hildon_program_add_window (program, window2);
  * <!-- -->
- * hildon_program_set_common_menu (program, menu);
+ * hildon_program_set_common_app_menu (program, menu);
  * <!-- -->
  * hildon_program_set_common_toolbar (program, common_toolbar);
  * hildon_window_add_toolbar (window1, window_specific_toolbar);
@@ -443,8 +443,8 @@ hildon_program_get_instance                     (void)
  *
  * Registers a #HildonWindow as belonging to a given #HildonProgram. This
  * allows to apply program-wide settings as all the registered windows,
- * such as hildon_program_set_common_menu() and
- * hildon_pogram_set_common_toolbar()
+ * such as hildon_program_set_common_menu(), hildon_program_set_common_app_menu()
+ * and hildon_pogram_set_common_toolbar().
  **/
 void
 hildon_program_add_window                       (HildonProgram *self, 
@@ -491,8 +491,8 @@ hildon_program_add_window                       (HildonProgram *self,
  * @window: The @HildonWindow to unregister
  *
  * Used to unregister a window from the program. Subsequent calls to
- * hildon_program_set_common_menu() and hildon_pogram_set_common_toolbar()
- * will not affect the window
+ * hildon_program_set_common_menu(), hildon_program_set_common_app_menu()
+ * and hildon_pogram_set_common_toolbar() will not affect the window.
  **/
 void
 hildon_program_remove_window                    (HildonProgram *self, 
@@ -570,15 +570,15 @@ hildon_program_get_can_hibernate                (HildonProgram *self)
 /**
  * hildon_program_set_common_menu:
  * @self: The #HildonProgram in which the common menu should be used
- * @menu: A GtkMenu to use as common menu for the program
+ * @menu: A #GtkMenu to use as common menu for the program
  *
- * Sets a GtkMenu that will appear in all the #HildonWindow registered
- * with the #HildonProgram. Only one common GtkMenu can be set, further
- * calls will detach the previous common GtkMenu. A #HildonWindow
- * can use its own GtkMenu with hildon_window_set_menu()
+ * Sets a #GtkMenu that will appear in all #HildonWindow<!-- -->s
+ * registered with the #HildonProgram. Only one common #GtkMenu can be
+ * set, further calls will detach the previous common #GtkMenu. A
+ * #HildonWindow can use its own #GtkMenu with
+ * hildon_window_set_menu()
  *
- * This method is not intented for #HildonStackableWindow<!-- -->s and
- * does not support #HildonAppMenu objects. See
+ * This method does not support #HildonAppMenu<!-- -->s. See
  * hildon_program_set_common_app_menu() for that.
  *
  * Since: 2.2
@@ -649,15 +649,13 @@ hildon_program_get_common_menu                  (HildonProgram *self)
  * @self: The #HildonProgram in which the common menu should be used
  * @menu: A #HildonAppMenu to use as common menu for the program
  *
- * Sets a #HildonAppMenu that will appear in all the
- * #HildonStackableWindow<!-- -->s registered with the
- * #HildonProgram. Only one common #HildonAppMenu can be set, further
- * calls will detach the previous common #HildonAppMenu. A
- * #HildonStackableWindow can use its own #HildonAppMenu with
- * hildon_stackable_window_set_app_menu()
+ * Sets a #HildonAppMenu that will appear in all
+ * #HildonWindow<!-- -->s registered with the #HildonProgram. Only
+ * one common #HildonAppMenu can be set, further calls will detach the
+ * previous common #HildonAppMenu. A #HildonWindow can use its own
+ * #HildonAppMenu with hildon_window_set_app_menu()
  *
- * This method is not intented for standard #HildonWindow<!-- -->s and
- * does not support #GtkMenu objects. See
+ * This method does not support #GtkMenu<!-- -->s. See
  * hildon_program_set_common_menu() for that.
  *
  * Since: 2.2
index b162359..e32f8d2 100644 (file)
@@ -31,7 +31,6 @@ typedef struct                                  _HildonStackableWindowPrivate Hi
 
 struct                                          _HildonStackableWindowPrivate
 {
-    HildonAppMenu *app_menu;
     HildonWindowStack *stack;
     gint stack_position;
 };
index 0bc3f7c..80c5806 100644 (file)
 
 #include                                        "hildon-stackable-window.h"
 #include                                        "hildon-stackable-window-private.h"
-#include                                        "hildon-app-menu-private.h"
 #include                                        "hildon-window-stack.h"
 #include                                        "hildon-window-stack-private.h"
-#include                                        "hildon-window-private.h"
-#include                                        "hildon-program.h"
 
 G_DEFINE_TYPE (HildonStackableWindow, hildon_stackable_window, HILDON_TYPE_WINDOW);
 
@@ -144,120 +141,17 @@ hildon_stackable_window_get_stack               (HildonStackableWindow *self)
 }
 
 /**
- * hildon_stackable_window_set_app_menu:
- * @self: a #HildonStackableWindow
- * @menu: a #HildonAppMenu to be used for this window
- *
- * Sets the menu to be used for this window. Pass %NULL to remove the
- * current menu. Any reference to a previous menu will be dropped.
- * #HildonStackableWindow takes ownership of the passed menu and
- * you're not supposed to free it yourself anymore.
- *
- * Note that #HildonStackableWindow widgets use #HildonAppMenu rather
- * than #GtkMenu, so you're not supposed to use
- * hildon_window_set_main_menu() with a #HildonStackableWindow.
- *
- * Since: 2.2
- **/
-void
-hildon_stackable_window_set_app_menu            (HildonStackableWindow *self,
-                                                 HildonAppMenu *menu)
-{
-    HildonStackableWindowPrivate *priv;
-    HildonAppMenu *old_menu;
-
-    g_return_if_fail (HILDON_IS_STACKABLE_WINDOW (self));
-    g_return_if_fail (!menu || HILDON_IS_APP_MENU (menu));
-    priv = HILDON_STACKABLE_WINDOW_GET_PRIVATE (self);
-
-    old_menu = priv->app_menu;
-
-    /* Add new menu */
-    priv->app_menu = menu;
-    if (menu)
-        g_object_ref_sink (menu);
-
-    /* Unref old menu */
-    if (old_menu)
-        g_object_unref (old_menu);
-}
-
-/**
- * hildon_stackable_window_get_app_menu:
- * @self: a #HildonStackableWindow
- *
- * Returns the #HildonAppMenu assigned to @self, or %NULL if it's
- * unset. Note that the window is still the owner of the menu.
- *
- * Returns: a #HildonAppMenu
- *
- * Since: 2.2
- **/
-HildonAppMenu *
-hildon_stackable_window_get_app_menu            (HildonStackableWindow *self)
-{
-    HildonStackableWindowPrivate *priv;
-
-    g_return_val_if_fail (HILDON_IS_STACKABLE_WINDOW (self), NULL);
-
-    priv = HILDON_STACKABLE_WINDOW_GET_PRIVATE (self);
-
-    return priv->app_menu;
-}
-
-/**
  * hildon_stackable_window_set_main_menu:
  * @self: a #HildonStackableWindow
  * @menu: a #HildonAppMenu to be used for this window
  *
- * Deprecated: Hildon 2.2: use hildon_stackable_window_set_app_menu()
+ * Deprecated: Hildon 2.2: use hildon_window_set_app_menu()
  **/
 void
 hildon_stackable_window_set_main_menu           (HildonStackableWindow *self,
                                                  HildonAppMenu *menu)
 {
-    hildon_stackable_window_set_app_menu (self, menu);
-}
-
-static gboolean
-hildon_stackable_window_toggle_menu             (HildonWindow *self,
-                                                guint button,
-                                                guint32 time)
-{
-    HildonStackableWindowPrivate *priv;
-    HildonAppMenu *menu_to_use = NULL;
-
-    g_return_val_if_fail (HILDON_IS_STACKABLE_WINDOW (self), FALSE);
-    priv = HILDON_STACKABLE_WINDOW_GET_PRIVATE (self);
-    g_assert (priv != NULL);
-
-    if (priv->app_menu) {
-        menu_to_use = priv->app_menu;
-    } else {
-        HildonProgram *program = HILDON_WINDOW_GET_PRIVATE (self)->program;
-
-        if (program) {
-            menu_to_use = hildon_program_get_common_app_menu (program);
-            if (menu_to_use) {
-                if (self != hildon_app_menu_get_parent_window (HILDON_APP_MENU (menu_to_use)))
-                    gtk_widget_hide (GTK_WIDGET (menu_to_use));
-            }
-        }
-    }
-
-    if (menu_to_use) {
-        if (GTK_WIDGET_MAPPED (GTK_WIDGET (menu_to_use))) {
-            gtk_widget_hide (GTK_WIDGET (menu_to_use));
-        } else {
-            hildon_app_menu_popup (menu_to_use, GTK_WINDOW (self));
-        }
-
-        return TRUE;
-    } else if (HILDON_WINDOW_CLASS (hildon_stackable_window_parent_class)->toggle_menu) {
-        return HILDON_WINDOW_CLASS (hildon_stackable_window_parent_class)->toggle_menu (self, button, time);
-    } else {
-        return FALSE;
-    }
+    hildon_window_set_app_menu (HILDON_WINDOW (self), menu);
 }
 
 static void
@@ -325,35 +219,15 @@ hildon_stackable_window_delete_event            (GtkWidget   *widget,
 }
 
 static void
-hildon_stackable_window_finalize                (GObject *object)
-{
-    HildonStackableWindowPrivate *priv = HILDON_STACKABLE_WINDOW_GET_PRIVATE (object);
-
-    if (priv->app_menu) {
-        hildon_app_menu_set_parent_window (priv->app_menu, NULL);
-        g_object_unref (GTK_WIDGET (priv->app_menu));
-    }
-
-    if (G_OBJECT_CLASS (hildon_stackable_window_parent_class)->finalize)
-        G_OBJECT_CLASS (hildon_stackable_window_parent_class)->finalize (object);
-}
-
-static void
 hildon_stackable_window_class_init              (HildonStackableWindowClass *klass)
 {
-    GObjectClass      *obj_class    = G_OBJECT_CLASS (klass);
     GtkWidgetClass    *widget_class = GTK_WIDGET_CLASS (klass);
-    HildonWindowClass *window_class = HILDON_WINDOW_CLASS (klass);
-
-    obj_class->finalize             = hildon_stackable_window_finalize;
 
     widget_class->map               = hildon_stackable_window_map;
     widget_class->show              = hildon_stackable_window_show;
     widget_class->hide              = hildon_stackable_window_hide;
     widget_class->delete_event      = hildon_stackable_window_delete_event;
 
-    window_class->toggle_menu       = hildon_stackable_window_toggle_menu;
-
     g_type_class_add_private (klass, sizeof (HildonStackableWindowPrivate));
 }
 
@@ -362,7 +236,6 @@ hildon_stackable_window_init                    (HildonStackableWindow *self)
 {
     HildonStackableWindowPrivate *priv = HILDON_STACKABLE_WINDOW_GET_PRIVATE (self);
 
-    priv->app_menu = NULL;
     priv->stack = NULL;
     priv->stack_position = -1;
 }
index 228e4d4..2e2a712 100644 (file)
@@ -92,13 +92,6 @@ hildon_stackable_window_set_main_menu           (HildonStackableWindow *self,
                                                  HildonAppMenu *menu);
 #endif
 
-void
-hildon_stackable_window_set_app_menu            (HildonStackableWindow *self,
-                                                 HildonAppMenu *menu);
-
-HildonAppMenu *
-hildon_stackable_window_get_app_menu            (HildonStackableWindow *self);
-
 HildonWindowStack *
 hildon_stackable_window_get_stack               (HildonStackableWindow *self);
 
index 3d80c23..fc5493d 100644 (file)
@@ -35,7 +35,8 @@ typedef struct                                  _HildonWindowPrivate HildonWindo
 
 struct                                          _HildonWindowPrivate
 {
-    GtkWidget *menu;
+    GtkMenu *menu;
+    HildonAppMenu *app_menu;
     GtkWidget *vbox;
     GtkWidget *edit_toolbar;
 
index 03d0e57..6a980a5 100644 (file)
  * framework.
  *
  * Among these windows in the Hildon framework can have a single menu
- * attached, which is toggled with a hardware key or by tapping
- * a custom button in the window frame. This menu can be set
- * by providing a GtkMenu to the hildon_window_set_main_menu() method.
+ * attached, which is toggled with a hardware key or by tapping a
+ * custom button in the window frame. This menu can be either a
+ * #GtkMenu or a #HildonAppMenu (set with
+ * hildon_window_set_main_menu() and hildon_window_set_app_menu()
+ * respectively). Only one type of menu can be used at the same time.
+ *
+ * In Hildon 2.2, #HildonAppMenu is the recommended menu to use.
  *
  * Similarly, a window in the Hildon framework can have several toolbars
  * attached. These can be added to the HildonWindow with
@@ -48,7 +52,7 @@
  * <programlisting>
  * HildonWindow *window;
  * GtkToolbar *toolbar;
- * GtkMenu *menu;
+ * HildonAppMenu *menu;
  * GdkPixbuf *icon_pixbuf;
  * <!-- -->
  * window = HILDON_WINDOW (hildon_window_new());
@@ -59,7 +63,7 @@
  * <!-- -->
  * icon_pixbuf = create_icon();
  * <!-- -->
- * hildon_window_set_main_menu (window, menu);
+ * hildon_window_set_app_menu (window, menu);
  * <!-- -->
  * hildon_window_add_toolbar (window, toolbar);
  * <!-- -->
@@ -90,6 +94,7 @@
 
 #include                                        "hildon-window.h"
 #include                                        "hildon-window-private.h"
+#include                                        "hildon-app-menu-private.h"
 #include                                        "hildon-find-toolbar.h"
 #include                                        "hildon-defines.h"
 
@@ -328,6 +333,7 @@ hildon_window_init                              (HildonWindow *self)
     priv->vbox = gtk_vbox_new (TRUE, TOOLBAR_MIDDLE);
     gtk_widget_set_parent (priv->vbox, GTK_WIDGET(self));
     priv->menu = NULL;
+    priv->app_menu = NULL;
     priv->edit_toolbar = NULL;
     priv->visible_toolbars = 0;
     priv->is_topmost = FALSE;
@@ -853,6 +859,13 @@ hildon_window_destroy                           (GtkObject *obj)
         priv->edit_toolbar = NULL;
     }
 
+    if (priv->app_menu)
+    {
+        hildon_app_menu_set_parent_window (priv->app_menu, NULL);
+        g_object_unref (priv->app_menu);
+        priv->app_menu = NULL;
+    }
+
     menu_list = g_list_copy (gtk_menu_get_for_attach_widget (GTK_WIDGET (obj)));
     menu_node = menu_list;
 
@@ -1466,90 +1479,134 @@ hildon_window_toggle_menu                       (HildonWindow *self,
 }
 
 
-/*
- * Toggles the display of the HildonWindow menu.
- * Returns whether or not something was done (whether or not we had a menu
- * to toggle)
- */
 static gboolean
-hildon_window_toggle_menu_real                  (HildonWindow * self,
-                                                guint button,
-                                                guint32 time)
+hildon_window_toggle_gtk_menu                   (HildonWindow *self,
+                                                GtkMenu      *menu,
+                                                guint         button,
+                                                guint32       time)
 {
-    GtkMenu *menu_to_use = NULL;
-    GList *menu_children = NULL;
-    HildonWindowPrivate *priv = HILDON_WINDOW_GET_PRIVATE (self);
+    gboolean retvalue = FALSE;
 
     g_return_val_if_fail (HILDON_IS_WINDOW (self), FALSE);
-    g_assert (priv != NULL);
+    g_return_val_if_fail (GTK_IS_MENU (menu), FALSE);
 
-    /* Select which menu to use, Window specific has highest priority,
-     * then program specific */
-    if (priv->menu)
+    if (gtk_menu_get_attach_widget (menu) != GTK_WIDGET (self))
+    {
+        g_object_ref (menu);
+        if (gtk_menu_get_attach_widget (menu))
+        {
+            gtk_menu_detach (menu);
+        }
+        gtk_menu_attach_to_widget (menu, GTK_WIDGET (self), &detach_menu_func);
+        g_object_unref (menu);
+    }
+
+    if (GTK_WIDGET_MAPPED (menu))
     {
-        menu_to_use = GTK_MENU (priv->menu);
+        gtk_menu_popdown (menu);
+        gtk_menu_shell_deactivate (GTK_MENU_SHELL (menu));
+        retvalue = TRUE;
     }
-    else if (priv->program)
+    else
     {
-        menu_to_use = hildon_program_get_common_menu (priv->program);
-        if (menu_to_use && gtk_menu_get_attach_widget (menu_to_use) != 
-                GTK_WIDGET (self))
+        /* Check if the menu has items */
+        GList *menu_children = gtk_container_get_children (GTK_CONTAINER (menu));
+
+        if (menu_children)
         {
-            g_object_ref (menu_to_use);
-            if (gtk_menu_get_attach_widget (menu_to_use))
+            HildonWindowPrivate *priv = HILDON_WINDOW_GET_PRIVATE (self);
+            g_list_free (menu_children);
+
+            /* Apply right theming */
+            gtk_widget_set_name (GTK_WIDGET (menu), "menu_force_with_corners");
+
+            if (priv->fullscreen)
             {
-                gtk_menu_detach (menu_to_use);
+                gtk_menu_popup (menu, NULL, NULL,
+                                (GtkMenuPositionFunc)
+                                hildon_window_menu_popup_func_full,
+                                self, button, time);
             }
-
-            gtk_menu_attach_to_widget (menu_to_use, GTK_WIDGET (self), 
-                    &detach_menu_func);
-            g_object_unref (menu_to_use);
+            else
+            {
+                gtk_menu_popup (menu, NULL, NULL,
+                                (GtkMenuPositionFunc)
+                                hildon_window_menu_popup_func,
+                                self, button, time);
+            }
+            gtk_menu_shell_select_first (GTK_MENU_SHELL (menu), TRUE);
+            retvalue = TRUE;
         }
     }
 
-    if (! menu_to_use)
+    return retvalue;
+}
+
+static gboolean
+hildon_window_toggle_app_menu                   (HildonWindow  *self,
+                                                HildonAppMenu *menu)
+{
+    g_return_val_if_fail (HILDON_IS_WINDOW (self), FALSE);
+    g_return_val_if_fail (HILDON_IS_APP_MENU (menu), FALSE);
+
+    if (self != hildon_app_menu_get_parent_window (menu))
     {
-        return FALSE;
+        gtk_widget_hide (GTK_WIDGET (menu));
     }
 
-
-    if (GTK_WIDGET_MAPPED (GTK_WIDGET (menu_to_use)))
+    if (GTK_WIDGET_MAPPED (menu))
     {
-        gtk_menu_popdown (menu_to_use);
-        gtk_menu_shell_deactivate (GTK_MENU_SHELL (menu_to_use));
-        return TRUE;
+        gtk_widget_hide (GTK_WIDGET (menu));
+    }
+    else
+    {
+        hildon_app_menu_popup (menu, GTK_WINDOW (self));
     }
 
-    /* Check if the menu has items */
-    menu_children = gtk_container_get_children (GTK_CONTAINER (menu_to_use));
+    return TRUE;
+}
 
-    if (menu_children)
-    {
-        g_list_free (menu_children);
+/*
+ * Toggles the display of the HildonWindow menu.
+ * Returns whether or not something was done (whether or not we had a menu
+ * to toggle)
+ */
+static gboolean
+hildon_window_toggle_menu_real                  (HildonWindow * self,
+                                                guint button,
+                                                guint32 time)
+{
+    gboolean retvalue = FALSE;
+    HildonWindowPrivate *priv = HILDON_WINDOW_GET_PRIVATE (self);
 
-        /* Apply right theming */
-        gtk_widget_set_name (GTK_WIDGET (menu_to_use),
-                "menu_force_with_corners");
+    g_return_val_if_fail (HILDON_IS_WINDOW (self), FALSE);
 
-        if (priv->fullscreen) 
+    /* Select which menu to use, Window specific has highest priority,
+     * then program specific */
+    if (priv->menu)
+    {
+        retvalue = hildon_window_toggle_gtk_menu (self, priv->menu, button, time);
+    }
+    else if (priv->app_menu)
+    {
+        retvalue = hildon_window_toggle_app_menu (self, priv->app_menu);
+    }
+    else if (priv->program)
+    {
+        GtkMenu *gtkmenu = hildon_program_get_common_menu (priv->program);
+        HildonAppMenu *appmenu = hildon_program_get_common_app_menu (priv->program);
+
+        if (gtkmenu)
         {
-            gtk_menu_popup (menu_to_use, NULL, NULL,
-                    (GtkMenuPositionFunc)
-                    hildon_window_menu_popup_func_full,
-                    self, button, time);
+            retvalue = hildon_window_toggle_gtk_menu (self, gtkmenu, button, time);
         }
-        else
+        else if (appmenu)
         {
-            gtk_menu_popup (menu_to_use, NULL, NULL,
-                    (GtkMenuPositionFunc)
-                    hildon_window_menu_popup_func,
-                    self, button, time);
+            retvalue = hildon_window_toggle_app_menu (self, appmenu);
         }
-        gtk_menu_shell_select_first (GTK_MENU_SHELL (menu_to_use), TRUE);
-        return TRUE;
     }
 
-    return FALSE;
+    return retvalue;
 }
 
 /*
@@ -1776,6 +1833,9 @@ hildon_window_set_edit_toolbar                  (HildonWindow      *self,
  * Gets the #GtMenu assigned to the #HildonAppview. Note that the 
  * window is still the owner of the menu.
  * 
+ * Note that if you're using a #HildonAppMenu rather than a #GtkMenu
+ * you should use hildon_window_get_app_menu() instead.
+ *
  * Return value: The #GtkMenu assigned to this application view. 
  **/
 GtkMenu*
@@ -1787,7 +1847,7 @@ hildon_window_get_main_menu                     (HildonWindow * self)
 
     priv = HILDON_WINDOW_GET_PRIVATE (self);
 
-    return GTK_MENU (priv->menu);
+    return priv->menu;
 }
 
 /**
@@ -1796,7 +1856,8 @@ hildon_window_get_main_menu                     (HildonWindow * self)
  *
  * Return value: a #GtkMenu
  *
- * Deprecated: Hildon 2.2: use hildon_window_get_main_menu()
+ * Deprecated: In Hildon 2.2 this function has been renamed to
+ * hildon_window_get_main_menu() for consistency
  **/
 GtkMenu*
 hildon_window_get_menu                          (HildonWindow * self)
@@ -1833,11 +1894,8 @@ hildon_window_add_accel_group (HildonWindow *self,
  * menu. #HildonWindow takes ownership of the passed menu and you're
  * not supposed to free it yourself anymore.
  *
- * Note that if you're using a #HildonStackableWindow (and not just a
- * standard #HildonWindow) you should use
- * hildon_stackable_window_set_app_menu()
- * instead. #HildonStackableWindow uses #HildonAppMenu rather than
- * #GtkMenu.
+ * Note that if you're using a #HildonAppMenu rather than a #GtkMenu
+ * you should use hildon_window_set_app_menu() instead.
  **/ 
 void
 hildon_window_set_main_menu (HildonWindow* self,
@@ -1852,22 +1910,22 @@ hildon_window_set_main_menu (HildonWindow* self,
 
     if (priv->menu != NULL)
     {
-       accel_group = gtk_menu_get_accel_group (GTK_MENU (priv->menu));
+       accel_group = gtk_menu_get_accel_group (priv->menu);
        if (accel_group != NULL)
            gtk_window_remove_accel_group (GTK_WINDOW (self), accel_group);
 
-        gtk_menu_detach (GTK_MENU (priv->menu));
+        gtk_menu_detach (priv->menu);
         g_object_unref (priv->menu);
     }
 
-    priv->menu = (menu != NULL) ? GTK_WIDGET (menu) : NULL;
+    priv->menu = menu;
     if (priv->menu != NULL)
     {
-        gtk_widget_set_name (priv->menu, "menu_force_with_corners");
-        gtk_menu_attach_to_widget (GTK_MENU (priv->menu), GTK_WIDGET (self), &detach_menu_func);
-        g_object_ref (GTK_MENU (priv->menu));
+        gtk_widget_set_name (GTK_WIDGET (priv->menu), "menu_force_with_corners");
+        gtk_menu_attach_to_widget (priv->menu, GTK_WIDGET (self), &detach_menu_func);
+        g_object_ref (priv->menu);
 
-       accel_group = gtk_menu_get_accel_group (GTK_MENU (priv->menu));
+       accel_group = gtk_menu_get_accel_group (priv->menu);
        if (accel_group != NULL)
            hildon_window_add_accel_group (self, accel_group);
     }
@@ -1880,7 +1938,7 @@ hildon_window_set_main_menu (HildonWindow* self,
  * 
  * Sets the menu to be used for this window. This menu overrides
  * a program-wide menu that may have been set with
- * hildon_program_set_common_menu. Pass NULL to remove the current
+ * hildon_program_set_common_menu(). Pass %NULL to remove the current
  * menu. HildonWindow takes ownership of the passed menu and you're
  * not supposed to free it yourself anymore.
  *
@@ -1927,3 +1985,66 @@ hildon_window_get_is_topmost                    (HildonWindow *self)
     return priv->is_topmost;
 }
 
+/**
+ * hildon_window_set_app_menu:
+ * @self: a #HildonWindow
+ * @menu: a #HildonAppMenu to be used for this window
+ *
+ * Sets the menu to be used for this window. Pass %NULL to remove the
+ * current menu. Any reference to a previous menu will be dropped.
+ * #HildonWindow takes ownership of the passed menu and
+ * you're not supposed to free it yourself anymore.
+ *
+ * Note that if you're using a #GtkMenu rather than a #HildonAppMenu
+ * you should use hildon_window_set_main_menu() instead.
+ *
+ * Since: 2.2
+ **/
+void
+hildon_window_set_app_menu                      (HildonWindow  *self,
+                                                 HildonAppMenu *menu)
+{
+    HildonWindowPrivate *priv;
+    HildonAppMenu *old_menu;
+
+    g_return_if_fail (HILDON_IS_WINDOW (self));
+    g_return_if_fail (!menu || HILDON_IS_APP_MENU (menu));
+    priv = HILDON_WINDOW_GET_PRIVATE (self);
+
+    old_menu = priv->app_menu;
+
+    /* Add new menu */
+    priv->app_menu = menu;
+    if (menu)
+        g_object_ref_sink (menu);
+
+    /* Unref old menu */
+    if (old_menu)
+        g_object_unref (old_menu);
+}
+
+/**
+ * hildon_window_get_app_menu:
+ * @self: a #HildonWindow
+ *
+ * Returns the #HildonAppMenu assigned to @self, or %NULL if it's
+ * unset. Note that the window is still the owner of the menu.
+ *
+ * Note that if you're using a #GtkMenu rather than a #HildonAppMenu
+ * you should use hildon_window_get_main_menu() instead.
+ *
+ * Returns: a #HildonAppMenu
+ *
+ * Since: 2.2
+ **/
+HildonAppMenu *
+hildon_window_get_app_menu                      (HildonWindow *self)
+{
+    HildonWindowPrivate *priv;
+
+    g_return_val_if_fail (HILDON_IS_WINDOW (self), NULL);
+
+    priv = HILDON_WINDOW_GET_PRIVATE (self);
+
+    return priv->app_menu;
+}
index cb53180..8dec729 100644 (file)
@@ -26,6 +26,7 @@
 #define                                         __HILDON_WINDOW_H__
 
 #include                                        <gtk/gtk.h>
+#include                                        "hildon-app-menu.h"
 #include                                        "hildon-edit-toolbar.h"
 
 G_BEGIN_DECLS
@@ -96,6 +97,13 @@ hildon_window_set_main_menu                     (HildonWindow *self,
 GtkMenu*
 hildon_window_get_main_menu                     (HildonWindow *self);
 
+void
+hildon_window_set_app_menu                      (HildonWindow  *self,
+                                                 HildonAppMenu *menu);
+
+HildonAppMenu *
+hildon_window_get_app_menu                      (HildonWindow *self);
+
 #ifndef HILDON_DISABLE_DEPRECATED
 void        
 hildon_window_set_menu                          (HildonWindow *self,