2008-12-12 Alberto Garcia <agarcia@igalia.com>
[hildon] / src / hildon-program.c
index 6e45fe7..ad15381 100644 (file)
@@ -1,14 +1,14 @@
 /*
- * This file is part of hildon-libs
+ * This file is a part of hildon
  *
  * Copyright (C) 2006 Nokia Corporation, all rights reserved.
  *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ * Contact: Rodrigo Novo <rodrigo.novo@nokia.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
  * as published by the Free Software Foundation; version 2.1 of
- * the License.
+ * the License, or (at your option) any later version.
  *
  * This library is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  *
  */
 
-/*
- * @file hildon-program.c
+/**
+ * SECTION:hildon-program
+ * @short_description: An object that represents an application running in the Hildon framework.
+ * @see_also: #HildonWindow, #HildonStackableWindow
+ *
+ * The #HildonProgram is an object used to represent an application running
+ * in the Hildon framework.
+ *
+ * Such an application is thought to have one or more #HildonWindow. These
+ * shall be registered to the #HildonProgram with hildon_program_add_window(),
+ * and can be unregistered similarly with hildon_program_remove_window().
  *
- * This file implements the HildonProgram object
+ * 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().
  *
+ * The #HildonProgram is also used to apply program-wide properties that
+ * are specific to the Hildon framework. For instance
+ * hildon_program_set_can_hibernate() sets whether or not an application
+ * can be set to hibernate by the Hildon task navigator, in situations of
+ * low memory.
+ *
+ * <example>
+ * <programlisting>
+ * HildonProgram *program;
+ * HildonWindow *window1;
+ * HildonWindow *window2;
+ * GtkToolbar *common_toolbar, *window_specific_toolbar;
+ * GtkMenu *menu;
+ * <!-- -->
+ * program = HILDON_PROGRAM (hildon_program_get_instance ());
+ * <!-- -->
+ * window1 = HILDON_WINDOW (hildon_window_new ());
+ * window2 = HILDON_WINDOW (hildon_window_new ());
+ * <!-- -->
+ * common_toolbar = create_common_toolbar ();
+ * window_specific_toolbar = create_window_specific_toolbar ();
+ * <!-- -->
+ * menu = create_menu ();
+ * <!-- -->
+ * hildon_program_add_window (program, window1);
+ * hildon_program_add_window (program, window2);
+ * <!-- -->
+ * hildon_program_set_common_menu (program, menu);
+ * <!-- -->
+ * hildon_program_set_common_toolbar (program, common_toolbar);
+ * hildon_window_add_toolbar (window1, window_specific_toolbar);
+ * <!-- -->
+ * hildon_program_set_can_hibernate (program, TRUE);
+ * </programlisting>
+ * </example>
  */
 
-#include <config.h>
-#include "hildon-program.h"
-#include "hildon-window-private.h"
-#include <X11/Xatom.h>
-
-#define HILDON_PROGRAM_GET_PRIVATE(obj) \
-  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), HILDON_TYPE_PROGRAM, HildonProgramPriv));
+#undef                                          HILDON_DISABLE_DEPRECATED
 
+#ifdef                                          HAVE_CONFIG_H
+#include                                        <config.h>
+#endif
 
-typedef struct _HildonProgramPriv HildonProgramPriv;
+#include                                        <X11/Xatom.h>
 
-struct _HildonProgramPriv
-{
-    gboolean killable;
-    gboolean is_topmost;
-    GdkWindow *group_leader;
-    guint window_count;
-    GtkWidget *common_menu;
-    GtkWidget *common_toolbar;
-    GSList *windows;
-    Window window_group;
-    gchar *name;
-};
+#include                                        "hildon-program.h"
+#include                                        "hildon-program-private.h"
+#include                                        "hildon-window-private.h"
+#include                                        "hildon-window-stack.h"
+#include                                        "hildon-app-menu-private.h"
 
 static void
-hildon_program_init (HildonProgram *self);
+hildon_program_init                             (HildonProgram *self);
 
 static void
-hildon_program_finalize (GObject *self);
+hildon_program_finalize                         (GObject *self);
 
 static void
-hildon_program_class_init (HildonProgramClass *self);
+hildon_program_class_init                       (HildonProgramClass *self);
 
 static void
-hildon_program_get_property(GObject * object, guint property_id,
-                        GValue * value, GParamSpec * pspec);
+hildon_program_get_property                     (GObject *object, 
+                                                 guint property_id,
+                                                 GValue *value, 
+                                                 GParamSpec *pspec);
 static void
-hildon_program_set_property (GObject * object, guint property_id,
-                             const GValue * value, GParamSpec * pspec);
+hildon_program_set_property                     (GObject *object, 
+                                                 guint property_id,
+                                                 const GValue *value, 
+                                                 GParamSpec *pspec);
 
 enum
 {
@@ -76,23 +117,22 @@ enum
     PROP_KILLABLE
 };
 
-
-GType
-hildon_program_get_type (void)
+GType G_GNUC_CONST
+hildon_program_get_type                         (void)
 {
     static GType program_type = 0;
 
-    if (!program_type)
+    if (! program_type)
     {
         static const GTypeInfo program_info =
         {
-            sizeof(HildonProgramClass),
+            sizeof (HildonProgramClass),
             NULL,       /* base_init */
             NULL,       /* base_finalize */
             (GClassInitFunc) hildon_program_class_init,
             NULL,       /* class_finalize */
             NULL,       /* class_data */
-            sizeof(HildonProgram),
+            sizeof (HildonProgram),
             0,  /* n_preallocs */
             (GInstanceInitFunc) hildon_program_init,
         };
@@ -103,23 +143,26 @@ hildon_program_get_type (void)
 }
 
 static void
-hildon_program_init (HildonProgram *self)
+hildon_program_init                             (HildonProgram *self)
 {
-    HildonProgramPriv *priv = HILDON_PROGRAM_GET_PRIVATE (self);
-
+    HildonProgramPrivate *priv = HILDON_PROGRAM_GET_PRIVATE (self);
+    g_assert (priv);
+    
     priv->killable = FALSE;
     priv->window_count = 0;
     priv->is_topmost = FALSE;
-    priv->window_group = GDK_WINDOW_XID (gdk_display_get_default_group
-                                  (gdk_display_get_default()));
+    priv->window_group = GDK_WINDOW_XID (gdk_display_get_default_group (gdk_display_get_default()));
+    priv->common_menu = NULL;
+    priv->common_app_menu = NULL;
     priv->common_toolbar = NULL;
-    priv->name = NULL;
+    priv->windows = NULL;
 }
 
 static void
-hildon_program_finalize (GObject *self)
+hildon_program_finalize                         (GObject *self)
 {
-    HildonProgramPriv *priv = HILDON_PROGRAM_GET_PRIVATE (HILDON_PROGRAM (self));
+    HildonProgramPrivate *priv = HILDON_PROGRAM_GET_PRIVATE (HILDON_PROGRAM (self));
+    g_assert (priv);
     
     if (priv->common_toolbar)
     {
@@ -132,24 +175,28 @@ hildon_program_finalize (GObject *self)
         g_object_unref (priv->common_menu);
         priv->common_menu = NULL;
     }
-
-    g_free (priv->name);
-
 }
 
 static void
-hildon_program_class_init (HildonProgramClass *self)
+hildon_program_class_init                       (HildonProgramClass *self)
 {
-    GObjectClass *object_class = G_OBJECT_CLASS(self);
+    GObjectClass *object_class = G_OBJECT_CLASS (self);
 
-    g_type_class_add_private (self, sizeof(HildonProgramPriv));
+    g_type_class_add_private (self, sizeof (HildonProgramPrivate));
 
     /* Set up object virtual functions */
-    object_class->finalize = hildon_program_finalize;
-    object_class->set_property = hildon_program_set_property;
-    object_class->get_property = hildon_program_get_property;
+    object_class->finalize      = hildon_program_finalize;
+    object_class->set_property  = hildon_program_set_property;
+    object_class->get_property  = hildon_program_get_property;
 
     /* Install properties */
+
+    /**
+     * HildonProgram:is-topmost:
+     *
+     * Whether one of the program's window or dialog currently
+     * is activated by window manager. 
+     */
     g_object_class_install_property (object_class, PROP_IS_TOPMOST,
                 g_param_spec_boolean ("is-topmost",
                 "Is top-most",
@@ -157,7 +204,13 @@ hildon_program_class_init (HildonProgramClass *self)
                 "is activated by window manager",
                 FALSE,
                 G_PARAM_READABLE)); 
-    
+
+    /**
+     * HildonProgram:can-hibernate:
+     *
+     * Whether the program should be set to hibernate by the Task
+     * Navigator in low memory situation.
+     */
     g_object_class_install_property (object_class, PROP_KILLABLE,
                 g_param_spec_boolean ("can-hibernate",
                 "Can hibernate",
@@ -168,15 +221,16 @@ hildon_program_class_init (HildonProgramClass *self)
     return;
 }
 
-
 static void
-hildon_program_set_property (GObject * object, guint property_id,
-                             const GValue * value, GParamSpec * pspec)
+hildon_program_set_property                     (GObject *object, 
+                                                 guint property_id,
+                                                 const GValue *value, 
+                                                 GParamSpec *pspec)
 {
-    switch (property_id){
+    switch (property_id) {
+
         case PROP_KILLABLE:
-            hildon_program_set_can_hibernate (HILDON_PROGRAM (object),
-                                         g_value_get_boolean (value));
+            hildon_program_set_can_hibernate (HILDON_PROGRAM (object), g_value_get_boolean (value));
             break;
             
         default:
@@ -187,33 +241,73 @@ hildon_program_set_property (GObject * object, guint property_id,
 }
 
 static void
-hildon_program_get_property (GObject * object, guint property_id,
-                             GValue * value, GParamSpec * pspec)
+hildon_program_get_property                     (GObject *object, 
+                                                 guint property_id,
+                                                 GValue *value, 
+                                                 GParamSpec *pspec)
+{
+    HildonProgramPrivate *priv = HILDON_PROGRAM_GET_PRIVATE (object);
+    g_assert (priv);
+
+    switch (property_id)
+    {
+        case PROP_KILLABLE:
+            g_value_set_boolean (value, priv->killable);
+            break;
+
+        case PROP_IS_TOPMOST:
+            g_value_set_boolean (value, priv->is_topmost);
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+            break;
+    }
+}
+
+/**
+ * hildon_program_pop_window_stack:
+ * @self: A #HildonProgram
+ *
+ * Pops a window from the stack.
+ *
+ * Deprecated: Use hildon_window_stack_pop() instead
+ *
+ * Returns: A #HildonStackableWindow, or %NULL
+ */
+HildonStackableWindow *
+hildon_program_pop_window_stack                 (HildonProgram *self)
 {
-    HildonProgramPriv *priv = HILDON_PROGRAM_GET_PRIVATE (object);
-
-     switch (property_id)
-     {
-         case PROP_KILLABLE:
-               g_value_set_boolean (value, priv->killable);
-               break;
-         case PROP_IS_TOPMOST:
-               g_value_set_boolean (value, priv->is_topmost);
-               break;
-         default:
-               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-               break;
-     }
-               
+    HildonWindowStack *stack = hildon_window_stack_get_default ();
+    GtkWidget *win = hildon_window_stack_pop_1 (stack);
+    g_warning ("%s: this function is deprecated. Use hildon_window_stack_pop() instead", __FUNCTION__);
+    return win ? HILDON_STACKABLE_WINDOW (win) : NULL;
+}
+
+/**
+ * hildon_program_peek_window_stack:
+ * @self: A #HildonProgram
+ *
+ * Deprecated: Use hildon_window_stack_peek() instead
+ *
+ * Returns: A #HildonStackableWindow, or %NULL
+ */
+HildonStackableWindow *
+hildon_program_peek_window_stack                (HildonProgram *self)
+{
+    HildonWindowStack *stack = hildon_window_stack_get_default ();
+    GtkWidget *win = hildon_window_stack_peek (stack);
+    g_warning ("%s: this function is deprecated. Use hildon_window_stack_peek() instead", __FUNCTION__);
+    return win ? HILDON_STACKABLE_WINDOW (win) : NULL;
 }
 
 /* Utilities */
 static gint 
-hildon_program_window_list_compare (gconstpointer window_a, 
-                                    gconstpointer window_b)
+hildon_program_window_list_compare              (gconstpointer window_a, 
+                                                 gconstpointer window_b)
 {
-    g_return_val_if_fail (1, HILDON_IS_WINDOW(window_a) && 
-                             HILDON_IS_WINDOW(window_b));
+    g_return_val_if_fail (HILDON_IS_WINDOW(window_a) && 
+                          HILDON_IS_WINDOW(window_b), 1);
 
     return window_a != window_b;
 }
@@ -222,7 +316,8 @@ hildon_program_window_list_compare (gconstpointer window_a,
  * foreach function, checks if a window is topmost and acts consequently
  */
 static void
-hildon_program_window_list_is_is_topmost (gpointer data, gpointer window_id_)
+hildon_program_window_list_is_is_topmost        (gpointer data, 
+                                                 gpointer window_id_)
 {
     if (data && HILDON_IS_WINDOW (data))
     {
@@ -238,19 +333,26 @@ hildon_program_window_list_is_is_topmost (gpointer data, gpointer window_id_)
  * the top_most status accordingly
  */
 static void
-hildon_program_update_top_most (HildonProgram *program)
+hildon_program_update_top_most                  (HildonProgram *program)
 {
     XWMHints *wm_hints;
     Window active_window;
-    HildonProgramPriv *priv;
+    HildonProgramPrivate *priv;
 
     priv = HILDON_PROGRAM_GET_PRIVATE (program);
+    g_assert (priv);
     
     active_window = hildon_window_get_active_window();
 
     if (active_window)
     {
+      gint xerror;
+      
+      gdk_error_trap_push ();
       wm_hints = XGetWMHints (GDK_DISPLAY (), active_window);
+      xerror = gdk_error_trap_pop ();
+      if (xerror)
+        return;
 
       if (wm_hints)
       {
@@ -277,18 +379,15 @@ hildon_program_update_top_most (HildonProgram *program)
             (GFunc)hildon_program_window_list_is_is_topmost, &active_window);
 }
 
-
-/* Event filter */
-
 /*
  * We keep track of the _MB_CURRENT_APP_WINDOW property on the root window,
  * to detect when a window belonging to this program was is_topmost. This
  * is based on the window group WM hint.
  */
 static GdkFilterReturn
-hildon_program_root_window_event_filter (GdkXEvent *xevent,
-                                         GdkEvent *event,
-                                         gpointer data)
+hildon_program_root_window_event_filter         (GdkXEvent *xevent,
+                                                 GdkEvent *event,
+                                                 gpointer data)
 {
     XAnyEvent *eventti = xevent;
     HildonProgram *program = HILDON_PROGRAM (data);
@@ -307,40 +406,34 @@ hildon_program_root_window_event_filter (GdkXEvent *xevent,
 
     return GDK_FILTER_CONTINUE;
 }
-    
 
-/**
- * hildon_program_common_toolbar_topmost_window:
- * @window: A @HildonWindow to be informed about its new common toolbar
- * @data: Not used, it is here just to respect the API
- *
+/* 
  * Checks if the window is the topmost window of the program and in
  * that case forces the window to take the common toolbar.
- **/
+ */
 static void
-hildon_program_common_toolbar_topmost_window (gpointer window, gpointer data)
+hildon_program_common_toolbar_topmost_window    (gpointer window, 
+                                                 gpointer data)
 {
-    if (HILDON_IS_WINDOW (window) && 
-            hildon_window_get_is_topmost (HILDON_WINDOW (window)))
-    {
+    if (HILDON_IS_WINDOW (window) && hildon_window_get_is_topmost (HILDON_WINDOW (window)))
         hildon_window_take_common_toolbar (HILDON_WINDOW (window));
-    }
 }
 
-/* Public methods */
-
 /**
  * hildon_program_get_instance:
  *
- * Return value: Returns the #HildonProgram for the current process.
- * The object is created on the first call.
+ * Returns the #HildonProgram for the current process. The object is
+ * created on the first call. Note that you're not supposed to unref
+ * the returned object since it's not reffed in the first place.
+ *
+ * Return value: the #HildonProgram.
  **/
-HildonProgram *
-hildon_program_get_instance ()
+HildonProgram*
+hildon_program_get_instance                     (void)
 {
     static HildonProgram *program = NULL;
 
-    if (!program)
+    if (! program)
     {
         program = g_object_new (HILDON_TYPE_PROGRAM, NULL);
     }
@@ -350,22 +443,24 @@ hildon_program_get_instance ()
 
 /**
  * hildon_program_add_window:
- * @program: The @HildonProgram to which the window should be registered
- * @window: A @HildonWindow to be added
+ * @self: The #HildonProgram to which the window should be registered
+ * @window: A #HildonWindow to be added
  *
- * Registers a @HildonWindow as belonging to a given @HildonProgram. This
+ * 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()
  **/
 void
-hildon_program_add_window (HildonProgram *self, HildonWindow *window)
+hildon_program_add_window                       (HildonProgram *self, 
+                                                 HildonWindow *window)
 {
-    HildonProgramPriv *priv;
+    HildonProgramPrivate *priv;
     
-    g_return_if_fail (self && HILDON_IS_PROGRAM (self));
+    g_return_if_fail (HILDON_IS_PROGRAM (self));
     
     priv = HILDON_PROGRAM_GET_PRIVATE (self);
+    g_assert (priv);
 
     if (g_slist_find_custom (priv->windows, window,
            hildon_program_window_list_compare) )
@@ -381,7 +476,8 @@ hildon_program_add_window (HildonProgram *self, HildonWindow *window)
         /* Now that we have a window we should start keeping track of
          * the root window */
         gdk_window_set_events (gdk_get_default_root_window (),
-                          gdk_window_get_events (gdk_get_default_root_window ())                          | GDK_PROPERTY_CHANGE_MASK);
+                gdk_window_get_events (gdk_get_default_root_window ()) | GDK_PROPERTY_CHANGE_MASK);
+
         gdk_window_add_filter (gdk_get_default_root_window (),
                 hildon_program_root_window_event_filter, self );
     }
@@ -404,13 +500,15 @@ hildon_program_add_window (HildonProgram *self, HildonWindow *window)
  * will not affect the window
  **/
 void
-hildon_program_remove_window (HildonProgram *self, HildonWindow *window)
+hildon_program_remove_window                    (HildonProgram *self, 
+                                                 HildonWindow *window)
 {
-    HildonProgramPriv *priv;
+    HildonProgramPrivate *priv;
     
-    g_return_if_fail (self && HILDON_IS_PROGRAM (self));
+    g_return_if_fail (HILDON_IS_PROGRAM (self));
     
     priv = HILDON_PROGRAM_GET_PRIVATE (self);
+    g_assert (priv);
     
     hildon_window_unset_program (window);
 
@@ -418,12 +516,10 @@ hildon_program_remove_window (HildonProgram *self, HildonWindow *window)
 
     priv->window_count --;
 
-    if (!priv->window_count)
-    {
+    if (! priv->window_count)
         gdk_window_remove_filter (gdk_get_default_root_window(),
                 hildon_program_root_window_event_filter,
                 self);
-    }
 }
 
 /**
@@ -435,42 +531,45 @@ hildon_program_remove_window (HildonProgram *self, HildonWindow *window)
  * be able to set the program to hibernation in case of low memory
  **/
 void
-hildon_program_set_can_hibernate (HildonProgram *self, gboolean killable)
+hildon_program_set_can_hibernate                (HildonProgram *self, 
+                                                 gboolean can_hibernate)
 {
-    HildonProgramPriv *priv;
+    HildonProgramPrivate *priv;
     
-    g_return_if_fail (self && HILDON_IS_PROGRAM (self));
+    g_return_if_fail (HILDON_IS_PROGRAM (self));
     
     priv = HILDON_PROGRAM_GET_PRIVATE (self);
+    g_assert (priv);
 
-    if (priv->killable != killable)
+    if (priv->killable != can_hibernate)
     {
         g_slist_foreach (priv->windows, 
-                (GFunc)hildon_window_set_can_hibernate_property, &killable);
+                (GFunc) hildon_window_set_can_hibernate_property, &can_hibernate);
     }
 
-    priv->killable = killable;
-
+    priv->killable = can_hibernate;
 }
 
 /**
  * hildon_program_get_can_hibernate:
  * @self: The #HildonProgram which can hibernate or not
- * 
- * Return value: Whether or not this #HildonProgram is set to be
- * support hibernation from the Hildon task navigator
+ *
+ * Returns whether the #HildonProgram is set to be support hibernation
+ * from the Hildon task navigator
+ *
+ * Return value: %TRUE if the program can hibernate, %FALSE otherwise.
  **/
 gboolean
-hildon_program_get_can_hibernate (HildonProgram *self)
+hildon_program_get_can_hibernate                (HildonProgram *self)
 {
-    HildonProgramPriv *priv;
+    HildonProgramPrivate *priv;
     
-    g_return_val_if_fail (self && HILDON_IS_PROGRAM (self), FALSE);
+    g_return_val_if_fail (HILDON_IS_PROGRAM (self), FALSE);
    
     priv = HILDON_PROGRAM_GET_PRIVATE (self);
+    g_assert (priv);
 
     return priv->killable;
-
 }
 
 /**
@@ -478,25 +577,33 @@ hildon_program_get_can_hibernate (HildonProgram *self)
  * @self: The #HildonProgram in which the common menu should be used
  * @menu: A GtkMenu to use as common menu for the program
  *
- * Sets a GtkMenu that will appear in all the @HildonWindow registered
- * to the #HildonProgram. Only one common GtkMenu can be set, further
- * call will detach the previous common GtkMenu. A @HildonWindow
- * can use it's own GtkMenu with @hildon_window_set_menu
+ * 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()
+ *
+ * This method is not intented for #HildonStackableWindow<!-- -->s and
+ * does not support #HildonAppMenu objects. See
+ * hildon_program_set_common_app_menu() for that.
+ *
+ * Since: 2.2
  **/
 void
-hildon_program_set_common_menu (HildonProgram *self, GtkMenu *menu)
+hildon_program_set_common_menu                  (HildonProgram *self, 
+                                                 GtkMenu *menu)
 {
-    HildonProgramPriv *priv;
+    HildonProgramPrivate *priv;
 
-    g_return_if_fail (self && HILDON_IS_PROGRAM (self));
+    g_return_if_fail (HILDON_IS_PROGRAM (self));
 
     priv = HILDON_PROGRAM_GET_PRIVATE (self);
+    g_assert (priv);
 
     if (priv->common_menu)
     {
         if (GTK_WIDGET_VISIBLE (priv->common_menu))
         {
-            gtk_menu_popdown (GTK_MENU(priv->common_menu));
+            gtk_menu_popdown (GTK_MENU (priv->common_menu));
             gtk_menu_shell_deactivate (GTK_MENU_SHELL (priv->common_menu));
         }
 
@@ -524,40 +631,115 @@ hildon_program_set_common_menu (HildonProgram *self, GtkMenu *menu)
  * hildon_program_get_common_menu:
  * @self: The #HildonProgram from which to retrieve the common menu
  *
- * Return value: the GtkMenu that was set as common menu for this
- * #HildonProgram, or NULL of no common menu was set.
+ * Returns the #GtkMenu that was set as common menu for this
+ * #HildonProgram.
+ *
+ * Return value: the #GtkMenu or %NULL of no common menu was set.
  **/
-GtkMenu *
-hildon_program_get_common_menu (HildonProgram *self)
+GtkMenu*
+hildon_program_get_common_menu                  (HildonProgram *self)
 {
-    HildonProgramPriv *priv;
+    HildonProgramPrivate *priv;
 
-    g_return_val_if_fail (self && HILDON_IS_PROGRAM (self), NULL);
+    g_return_val_if_fail (HILDON_IS_PROGRAM (self), NULL);
 
     priv = HILDON_PROGRAM_GET_PRIVATE (self);
+    g_assert (priv);
 
     return GTK_MENU (priv->common_menu);
 }
 
 /**
+ * hildon_program_set_common_app_menu:
+ * @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_main_menu()
+ *
+ * This method is not intented for standard #HildonWindow<!-- -->s and
+ * does not support #GtkMenu objects. See
+ * hildon_program_set_common_menu() for that.
+ *
+ * Since: 2.2
+ **/
+void
+hildon_program_set_common_app_menu              (HildonProgram *self,
+                                                 HildonAppMenu *menu)
+{
+    HildonProgramPrivate *priv;
+    GtkWidget *old_menu;
+
+    g_return_if_fail (HILDON_IS_PROGRAM (self));
+    g_return_if_fail (menu == NULL || HILDON_IS_APP_MENU (menu));
+
+    priv = HILDON_PROGRAM_GET_PRIVATE (self);
+    g_assert (priv);
+
+    old_menu = priv->common_app_menu;
+
+    /* Set new menu */
+    priv->common_app_menu = GTK_WIDGET (menu);
+    if (menu)
+        g_object_ref_sink (menu);
+
+    /* Hide and unref old menu */
+    if (old_menu) {
+        hildon_app_menu_set_parent_window (HILDON_APP_MENU (old_menu), NULL);
+        g_object_unref (old_menu);
+    }
+}
+
+/**
+ * hildon_program_get_common_app_menu:
+ * @self: The #HildonProgram from which to retrieve the common app menu
+ *
+ * Returns the #HildonAppMenu that was set as common menu for this
+ * #HildonProgram.
+ *
+ * Return value: the #HildonAppMenu or %NULL of no common app menu was
+ * set.
+ *
+ * Since: 2.2
+ **/
+HildonAppMenu*
+hildon_program_get_common_app_menu              (HildonProgram *self)
+{
+    HildonProgramPrivate *priv;
+
+    g_return_val_if_fail (HILDON_IS_PROGRAM (self), NULL);
+
+    priv = HILDON_PROGRAM_GET_PRIVATE (self);
+    g_assert (priv);
+
+    return HILDON_APP_MENU (priv->common_app_menu);
+}
+
+/**
  * hildon_program_set_common_toolbar:
  * @self: The #HildonProgram in which the common toolbar should be used
  * @toolbar: A GtkToolbar to use as common toolbar for the program
  *
- * Sets a GtkToolbar that will appear in all the @HildonWindow registered
+ * Sets a GtkToolbar that will appear in all the #HildonWindow registered
  * to the #HildonProgram. Only one common GtkToolbar can be set, further
- * call will detach the previous common GtkToolbar. A @HildonWindow
- * can use its own GtkToolbar with @hildon_window_set_toolbar. Both
- * #HildonProgram and @HildonWindow specific toolbars will be shown
+ * call will detach the previous common GtkToolbar. A #HildonWindow
+ * can use its own GtkToolbar with hildon_window_add_toolbar(). Both
+ * #HildonProgram and #HildonWindow specific toolbars will be shown
  **/
 void
-hildon_program_set_common_toolbar (HildonProgram *self, GtkToolbar *toolbar)
+hildon_program_set_common_toolbar               (HildonProgram *self, 
+                                                 GtkToolbar *toolbar)
 {
-    HildonProgramPriv *priv;
+    HildonProgramPrivate *priv;
 
-    g_return_if_fail (self && HILDON_IS_PROGRAM (self));
+    g_return_if_fail (HILDON_IS_PROGRAM (self));
 
     priv = HILDON_PROGRAM_GET_PRIVATE (self);
+    g_assert (priv);
 
     if (priv->common_toolbar)
     {
@@ -591,17 +773,21 @@ hildon_program_set_common_toolbar (HildonProgram *self, GtkToolbar *toolbar)
  * hildon_program_get_common_toolbar:
  * @self: The #HildonProgram from which to retrieve the common toolbar
  *
- * Return value: the GtkToolbar that was set as common toolbar for this
- * #HildonProgram, or NULL of no common menu was set.
+ * Returns the #GtkToolbar that was set as common toolbar for this
+ * #HildonProgram.
+ *
+ * Return value: the #GtkToolbar or %NULL of no common toolbar was
+ * set.
  **/
-GtkToolbar *
-hildon_program_get_common_toolbar (HildonProgram *self)
+GtkToolbar*
+hildon_program_get_common_toolbar               (HildonProgram *self)
 {
-    HildonProgramPriv *priv;
+    HildonProgramPrivate *priv;
 
-    g_return_val_if_fail (self && HILDON_IS_PROGRAM (self), NULL);
+    g_return_val_if_fail (HILDON_IS_PROGRAM (self), NULL);
 
     priv = HILDON_PROGRAM_GET_PRIVATE (self);
+    g_assert (priv);
 
     return priv->common_toolbar ? GTK_TOOLBAR (priv->common_toolbar) : NULL;
 }
@@ -610,19 +796,40 @@ hildon_program_get_common_toolbar (HildonProgram *self)
  * hildon_program_get_is_topmost:
  * @self: A #HildonWindow
  *
- * Return value: Whether or not one of the program's window or dialog is 
- * currenltly activated by the window manager.
+ * Returns whether one of the program's windows or dialogs is
+ * currently activated by the window manager.
+ *
+ * Return value: %TRUE if a window or dialog is topmost, %FALSE
+ * otherwise.
  **/
 gboolean
-hildon_program_get_is_topmost (HildonProgram *self)
+hildon_program_get_is_topmost                   (HildonProgram *self)
 {
-    HildonProgramPriv *priv;
+    HildonProgramPrivate *priv;
 
-    g_return_val_if_fail (self && HILDON_IS_PROGRAM (self), FALSE);
+    g_return_val_if_fail (HILDON_IS_PROGRAM (self), FALSE);
     
     priv = HILDON_PROGRAM_GET_PRIVATE (self);
+    g_assert (priv);
 
     return priv->is_topmost;
 }
 
-
+/**
+ * hildon_program_go_to_root_window:
+ * @self: A #HildonProgram
+ *
+ * Goes to the root window of the stack.
+ *
+ * Deprecated: See #HildonWindowStack
+ */
+void
+hildon_program_go_to_root_window                (HildonProgram *self)
+{
+    HildonWindowStack *stack = hildon_window_stack_get_default ();
+    gint n = hildon_window_stack_size (stack);
+    g_warning ("%s: this function is deprecated. Use hildon_window_stack_pop() instead.", __FUNCTION__);
+    if (n > 1) {
+        hildon_window_stack_pop (stack, n-1, NULL);
+    }
+}