aboutsummaryrefslogtreecommitdiff
path: root/hildon/hildon-program.c
diff options
context:
space:
mode:
Diffstat (limited to 'hildon/hildon-program.c')
-rw-r--r--hildon/hildon-program.c843
1 files changed, 843 insertions, 0 deletions
diff --git a/hildon/hildon-program.c b/hildon/hildon-program.c
new file mode 100644
index 0000000..47ead29
--- /dev/null
+++ b/hildon/hildon-program.c
@@ -0,0 +1,843 @@
+/*
+ * This file is a part of hildon
+ *
+ * Copyright (C) 2006 Nokia Corporation, all rights reserved.
+ *
+ * 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, 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
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-program
+ * @short_description: An object that represents an application running in the Hildon framework.
+ * @see_also: #HildonWindow, #HildonStackableWindow
+ *
+ * #HildonProgram is an object used to represent an application running
+ * in the Hildon framework.
+ *
+ * Applications can have one or more #HildonWindow<!-- -->s. These
+ * can be registered in the #HildonProgram with hildon_program_add_window(),
+ * and can be unregistered similarly with hildon_program_remove_window().
+ *
+ * #HildonProgram provides the programmer with commodities such
+ * as applying a common toolbar and menu to all registered
+ * #HildonWindow<!-- -->s. This is done with hildon_program_set_common_menu(),
+ * hildon_program_set_common_app_menu() and hildon_program_set_common_toolbar().
+ *
+ * #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;
+ * HildonAppMenu *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_app_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>
+ */
+
+#undef HILDON_DISABLE_DEPRECATED
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <X11/Xatom.h>
+
+#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);
+
+static void
+hildon_program_finalize (GObject *self);
+
+static void
+hildon_program_class_init (HildonProgramClass *self);
+
+static void
+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);
+
+enum
+{
+ PROP_0,
+ PROP_IS_TOPMOST,
+ PROP_KILLABLE
+};
+
+GType G_GNUC_CONST
+hildon_program_get_type (void)
+{
+ static GType program_type = 0;
+
+ if (! program_type)
+ {
+ static const GTypeInfo program_info =
+ {
+ sizeof (HildonProgramClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_program_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (HildonProgram),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_program_init,
+ };
+ program_type = g_type_register_static(G_TYPE_OBJECT,
+ "HildonProgram", &program_info, 0);
+ }
+ return program_type;
+}
+
+static void
+hildon_program_init (HildonProgram *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->common_menu = NULL;
+ priv->common_app_menu = NULL;
+ priv->common_toolbar = NULL;
+ priv->windows = NULL;
+}
+
+static void
+hildon_program_finalize (GObject *self)
+{
+ HildonProgramPrivate *priv = HILDON_PROGRAM_GET_PRIVATE (HILDON_PROGRAM (self));
+ g_assert (priv);
+
+ if (priv->common_toolbar)
+ {
+ g_object_unref (priv->common_toolbar);
+ priv->common_toolbar = NULL;
+ }
+
+ if (priv->common_menu)
+ {
+ g_object_unref (priv->common_menu);
+ priv->common_menu = NULL;
+ }
+}
+
+static void
+hildon_program_class_init (HildonProgramClass *self)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (self);
+
+ 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;
+
+ /* 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",
+ "Whether one of the program's window or dialog currently "
+ "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",
+ "Whether the program should be set to hibernate by the Task "
+ "Navigator in low memory situation",
+ FALSE,
+ G_PARAM_READWRITE));
+ return;
+}
+
+static void
+hildon_program_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+
+ case PROP_KILLABLE:
+ hildon_program_set_can_hibernate (HILDON_PROGRAM (object), g_value_get_boolean (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+
+}
+
+static void
+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
+ *
+ * Since: 2.2
+ */
+HildonStackableWindow *
+hildon_program_pop_window_stack (HildonProgram *self)
+{
+ 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
+ *
+ * Since: 2.2
+ */
+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)
+{
+ g_return_val_if_fail (HILDON_IS_WINDOW(window_a) &&
+ HILDON_IS_WINDOW(window_b), 1);
+
+ return window_a != window_b;
+}
+
+/*
+ * 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_)
+{
+ if (data && HILDON_IS_WINDOW (data))
+ {
+ HildonWindow *window = HILDON_WINDOW (data);
+ Window window_id = * (Window*)window_id_;
+
+ hildon_window_update_topmost (window, window_id);
+ }
+}
+
+/*
+ * Check the _MB_CURRENT_APP_WINDOW on the root window, and update
+ * the top_most status accordingly
+ */
+static void
+hildon_program_update_top_most (HildonProgram *program)
+{
+ gboolean is_topmost;
+ Window active_window;
+ HildonProgramPrivate *priv;
+
+ priv = HILDON_PROGRAM_GET_PRIVATE (program);
+ g_assert (priv);
+
+ active_window = hildon_window_get_active_window();
+ is_topmost = FALSE;
+
+ if (active_window)
+ {
+ gint xerror;
+ XWMHints *wm_hints;
+
+ gdk_error_trap_push ();
+ wm_hints = XGetWMHints (GDK_DISPLAY (), active_window);
+ xerror = gdk_error_trap_pop ();
+ if (xerror)
+ {
+ if (wm_hints)
+ XFree (wm_hints);
+ return;
+ }
+
+ if (wm_hints)
+ {
+ is_topmost = (wm_hints->window_group == priv->window_group);
+ XFree (wm_hints);
+ }
+ }
+
+ /* Send notification if is_topmost has changed */
+ if (!priv->is_topmost != !is_topmost)
+ {
+ priv->is_topmost = is_topmost;
+ g_object_notify (G_OBJECT (program), "is-topmost");
+ }
+
+ /* Check each window if it was is_topmost */
+ g_slist_foreach (priv->windows,
+ (GFunc)hildon_program_window_list_is_is_topmost, &active_window);
+}
+
+/*
+ * 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)
+{
+ XAnyEvent *eventti = xevent;
+ HildonProgram *program = HILDON_PROGRAM (data);
+ Atom active_app_atom =
+ XInternAtom (GDK_DISPLAY (), "_MB_CURRENT_APP_WINDOW", False);
+
+ if (eventti->type == PropertyNotify)
+ {
+ XPropertyEvent *pevent = xevent;
+
+ if (pevent->atom == active_app_atom)
+ {
+ hildon_program_update_top_most (program);
+ }
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
+/*
+ * 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)
+{
+ if (HILDON_IS_WINDOW (window) && hildon_window_get_is_topmost (HILDON_WINDOW (window)))
+ hildon_window_take_common_toolbar (HILDON_WINDOW (window));
+}
+
+/**
+ * hildon_program_get_instance:
+ *
+ * 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 (void)
+{
+ static HildonProgram *program = NULL;
+
+ if (! program)
+ {
+ program = g_object_new (HILDON_TYPE_PROGRAM, NULL);
+ }
+
+ return program;
+}
+
+/**
+ * hildon_program_add_window:
+ * @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
+ * allows to apply program-wide settings as all the registered windows,
+ * such as hildon_program_set_common_menu(), hildon_program_set_common_app_menu()
+ * and hildon_program_set_common_toolbar().
+ **/
+void
+hildon_program_add_window (HildonProgram *self,
+ HildonWindow *window)
+{
+ HildonProgramPrivate *priv;
+
+ g_return_if_fail (HILDON_IS_PROGRAM (self));
+ g_return_if_fail (HILDON_IS_WINDOW (window));
+
+ priv = HILDON_PROGRAM_GET_PRIVATE (self);
+ g_assert (priv);
+
+ if (g_slist_find_custom (priv->windows, window,
+ hildon_program_window_list_compare) )
+ {
+ /* We already have that window */
+ return;
+ }
+
+ if (!priv->window_count)
+ {
+ hildon_program_update_top_most (self);
+
+ /* 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_add_filter (gdk_get_default_root_window (),
+ hildon_program_root_window_event_filter, self );
+ }
+
+ hildon_window_set_can_hibernate_property (window, &priv->killable);
+
+ hildon_window_set_program (window, G_OBJECT (self));
+
+ priv->windows = g_slist_append (priv->windows, window);
+ priv->window_count ++;
+}
+
+/**
+ * hildon_program_remove_window:
+ * @self: The #HildonProgram to which the window should be unregistered
+ * @window: The #HildonWindow to unregister
+ *
+ * Used to unregister a window from the program. Subsequent calls to
+ * hildon_program_set_common_menu(), hildon_program_set_common_app_menu()
+ * and hildon_program_set_common_toolbar() will not affect the window.
+ **/
+void
+hildon_program_remove_window (HildonProgram *self,
+ HildonWindow *window)
+{
+ HildonProgramPrivate *priv;
+
+ g_return_if_fail (HILDON_IS_PROGRAM (self));
+ g_return_if_fail (HILDON_IS_WINDOW (window));
+
+ priv = HILDON_PROGRAM_GET_PRIVATE (self);
+ g_assert (priv);
+
+ g_return_if_fail (g_slist_find (priv->windows, window));
+
+ hildon_window_unset_program (window);
+
+ priv->windows = g_slist_remove (priv->windows, window);
+
+ priv->window_count --;
+
+ if (! priv->window_count)
+ gdk_window_remove_filter (gdk_get_default_root_window(),
+ hildon_program_root_window_event_filter,
+ self);
+}
+
+/**
+ * hildon_program_set_can_hibernate:
+ * @self: The #HildonProgram which can hibernate or not
+ * @can_hibernate: whether or not the #HildonProgram can hibernate
+ *
+ * Used to set whether or not the Hildon task navigator should
+ * be able to set the program to hibernation in case of low memory
+ **/
+void
+hildon_program_set_can_hibernate (HildonProgram *self,
+ gboolean can_hibernate)
+{
+ HildonProgramPrivate *priv;
+
+ g_return_if_fail (HILDON_IS_PROGRAM (self));
+
+ priv = HILDON_PROGRAM_GET_PRIVATE (self);
+ g_assert (priv);
+
+ if (priv->killable != can_hibernate)
+ {
+ g_slist_foreach (priv->windows,
+ (GFunc) hildon_window_set_can_hibernate_property, &can_hibernate);
+ }
+
+ priv->killable = can_hibernate;
+}
+
+/**
+ * hildon_program_get_can_hibernate:
+ * @self: The #HildonProgram which can hibernate or not
+ *
+ * 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)
+{
+ HildonProgramPrivate *priv;
+
+ g_return_val_if_fail (HILDON_IS_PROGRAM (self), FALSE);
+
+ priv = HILDON_PROGRAM_GET_PRIVATE (self);
+ g_assert (priv);
+
+ return priv->killable;
+}
+
+/**
+ * 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
+ *
+ * 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 does not support #HildonAppMenu<!-- -->s. See
+ * hildon_program_set_common_app_menu() for that.
+ *
+ * Since: 2.2
+ **/
+void
+hildon_program_set_common_menu (HildonProgram *self,
+ GtkMenu *menu)
+{
+ HildonProgramPrivate *priv;
+
+ 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 (priv->common_menu);
+ gtk_menu_shell_deactivate (GTK_MENU_SHELL (priv->common_menu));
+ }
+
+ if (gtk_menu_get_attach_widget (priv->common_menu))
+ {
+ gtk_menu_detach (priv->common_menu);
+ }
+ else
+ {
+ g_object_unref (priv->common_menu);
+ }
+ }
+
+ priv->common_menu = menu;
+
+ if (priv->common_menu)
+ {
+ g_object_ref (menu);
+ gtk_object_sink (GTK_OBJECT (menu));
+ gtk_widget_show_all (GTK_WIDGET (menu));
+ }
+}
+
+/**
+ * hildon_program_get_common_menu:
+ * @self: The #HildonProgram from which to retrieve the common menu
+ *
+ * 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)
+{
+ HildonProgramPrivate *priv;
+
+ g_return_val_if_fail (HILDON_IS_PROGRAM (self), NULL);
+
+ priv = HILDON_PROGRAM_GET_PRIVATE (self);
+ g_assert (priv);
+
+ return 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
+ * #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 does not support #GtkMenu<!-- -->s. See
+ * hildon_program_set_common_menu() for that.
+ *
+ * Since: 2.2
+ **/
+void
+hildon_program_set_common_app_menu (HildonProgram *self,
+ HildonAppMenu *menu)
+{
+ HildonProgramPrivate *priv;
+ HildonAppMenu *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 = menu;
+ if (menu)
+ g_object_ref_sink (menu);
+
+ /* Hide and unref old menu */
+ if (old_menu) {
+ hildon_app_menu_set_parent_window (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 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
+ * 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_add_toolbar(). Both
+ * #HildonProgram and #HildonWindow specific toolbars will be shown
+ **/
+void
+hildon_program_set_common_toolbar (HildonProgram *self,
+ GtkToolbar *toolbar)
+{
+ HildonProgramPrivate *priv;
+
+ g_return_if_fail (HILDON_IS_PROGRAM (self));
+
+ priv = HILDON_PROGRAM_GET_PRIVATE (self);
+ g_assert (priv);
+
+ if (priv->common_toolbar)
+ {
+ if (priv->common_toolbar->parent)
+ {
+ gtk_container_remove (GTK_CONTAINER (priv->common_toolbar->parent),
+ priv->common_toolbar);
+ }
+
+ g_object_unref (priv->common_toolbar);
+ }
+
+ priv->common_toolbar = GTK_WIDGET (toolbar);
+
+ if (priv->common_toolbar)
+ {
+ g_object_ref (priv->common_toolbar);
+ gtk_object_sink (GTK_OBJECT (priv->common_toolbar) );
+ }
+
+ /* if the program is the topmost we have to update the common
+ toolbar right now for the topmost window */
+ if (priv->is_topmost)
+ {
+ g_slist_foreach (priv->windows,
+ (GFunc) hildon_program_common_toolbar_topmost_window, NULL);
+ }
+}
+
+/**
+ * hildon_program_get_common_toolbar:
+ * @self: The #HildonProgram from which to retrieve the common toolbar
+ *
+ * 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)
+{
+ HildonProgramPrivate *priv;
+
+ 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;
+}
+
+/**
+ * hildon_program_get_is_topmost:
+ * @self: A #HildonWindow
+ *
+ * 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)
+{
+ HildonProgramPrivate *priv;
+
+ 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
+ *
+ * Since: 2.2
+ */
+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);
+ }
+}