2 * This file is a part of hildon
4 * Copyright (C) 2008 Nokia Corporation, all rights reserved.
6 * Contact: Karl Lattimer <karl.lattimer@nokia.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; version 2.1 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
26 * SECTION:hildon-stackable-window
27 * @short_description: Widget representing a stackable, top-level window in the Hildon framework.
29 * The #HildonStackableWindow is a GTK+ widget which represents a
30 * top-level window in the Hildon framework. It is derived from
31 * #HildonWindow. Applications that use stackable windows are organized
32 * in a hierarchical way so users can go from any window back to the
33 * application's root window.
35 * To add a window to the stack, just use gtk_widget_show(). The
36 * previous one will be automatically hidden. When the new window is
37 * destroyed, the previous one will appear again.
39 * Alternatively, you can remove a window from the top of the stack
40 * without destroying it by using
41 * hildon_program_pop_window_stack(). The window will be automatically
42 * hidden and the previous one will appear.
45 * <title>Basic HildonStackableWindow example</title>
48 * show_new_window (void)
52 * win = hildon_stackable_window_new ();
54 * // ... configure new window
56 * // This automatically hides the previous window
57 * gtk_widget_show (win);
61 * main (int argc, char **argv)
66 * gtk_init (&argc, &args);
68 * win = hildon_stackable_window_new ();
69 * gtk_window_set_title (GTK_WINDOW (win), "Main window);
71 * // ... add some widgets to the window
73 * g_signal_connect (button, "clicked", G_CALLBACK (show_new_window), NULL);
74 * g_signal_connect (win, "destroy", G_CALLBACK (gtk_main_quit), NULL);
76 * gtk_widget_show_all (win);
86 #include <X11/Xatom.h>
88 #include "hildon-stackable-window.h"
89 #include "hildon-stackable-window-private.h"
90 #include "hildon-program.h"
91 #include "hildon-window-private.h"
92 #include "hildon-program-private.h"
94 G_DEFINE_TYPE (HildonStackableWindow, hildon_stackable_window, HILDON_TYPE_WINDOW);
97 hildon_stackable_window_set_going_home (HildonStackableWindow *self,
100 HildonStackableWindowPrivate *priv = HILDON_STACKABLE_WINDOW_GET_PRIVATE (self);
101 priv->going_home = going_home;
104 gboolean G_GNUC_INTERNAL
105 hildon_stackable_window_get_going_home (HildonStackableWindow *self)
107 HildonStackableWindowPrivate *priv = HILDON_STACKABLE_WINDOW_GET_PRIVATE (self);
108 return priv->going_home;
112 * hildon_stackable_window_set_main_menu:
113 * @self: a #HildonStackableWindow
114 * @menu: a #HildonAppMenu to be used for this window
116 * Sets the menu to be used for this window. Pass %NULL to remove the
117 * current menu. Any reference to a previous menu will be dropped.
118 * #HildonStackableWindow takes ownership of the passed menu and
119 * you're not supposed to free it yourself anymore.
121 * Note that #HildonStackableWindow widgets use #HildonAppMenu rather
122 * than #GtkMenu, so you're not supposed to use
123 * hildon_window_set_main_menu() with a #HildonStackableWindow.
126 hildon_stackable_window_set_main_menu (HildonStackableWindow *self,
129 HildonStackableWindowPrivate *priv;
130 HildonAppMenu *old_menu;
132 g_return_if_fail (HILDON_IS_STACKABLE_WINDOW (self));
133 g_return_if_fail (!menu || HILDON_IS_APP_MENU (menu));
134 priv = HILDON_STACKABLE_WINDOW_GET_PRIVATE (self);
136 old_menu = priv->app_menu;
139 priv->app_menu = menu;
141 g_object_ref_sink (menu);
145 g_object_unref (old_menu);
149 hildon_stackable_window_toggle_menu (HildonWindow *self,
153 HildonStackableWindowPrivate *priv;
155 g_return_val_if_fail (HILDON_IS_STACKABLE_WINDOW (self), FALSE);
156 priv = HILDON_STACKABLE_WINDOW_GET_PRIVATE (self);
157 g_assert (priv != NULL);
161 if (GTK_WIDGET_MAPPED (GTK_WIDGET (priv->app_menu)))
162 gtk_widget_hide (GTK_WIDGET (priv->app_menu));
164 gtk_widget_show (GTK_WIDGET (priv->app_menu));
168 else if (HILDON_WINDOW_CLASS (hildon_stackable_window_parent_class)->toggle_menu)
170 return HILDON_WINDOW_CLASS (hildon_stackable_window_parent_class)->toggle_menu (self, button, time);
179 hildon_stackable_window_realize (GtkWidget *widget)
183 unsigned long val = 1;
185 GTK_WIDGET_CLASS (hildon_stackable_window_parent_class)->realize (widget);
187 /* Set additional property "_HILDON_STACKABLE_WINDOW", to allow the WM to manage
188 it as a stackable window. */
189 display = gdk_drawable_get_display (widget->window);
190 atom = gdk_x11_get_xatom_by_name_for_display (display, "_HILDON_STACKABLE_WINDOW");
191 XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (widget->window), atom,
192 XA_ATOM, 32, PropModeReplace,
193 (unsigned char *) &val, 1);
197 hildon_stackable_window_show (GtkWidget *widget)
199 HildonProgram *program = hildon_program_get_instance ();
200 HildonStackableWindow *current_win = HILDON_STACKABLE_WINDOW (widget);
201 HildonStackableWindow *previous_win = hildon_program_peek_window_stack (program);
203 if (previous_win != current_win)
204 _hildon_program_add_to_stack (program, current_win);
206 GTK_WIDGET_CLASS (hildon_stackable_window_parent_class)->show (widget);
210 hildon_stackable_window_hide (GtkWidget *widget)
212 HildonProgram *program = hildon_program_get_instance ();
213 _hildon_program_remove_from_stack (program, HILDON_STACKABLE_WINDOW (widget));
214 GTK_WIDGET_CLASS (hildon_stackable_window_parent_class)->hide (widget);
218 hildon_stackable_window_finalize (GObject *object)
220 HildonStackableWindowPrivate *priv = HILDON_STACKABLE_WINDOW_GET_PRIVATE (object);
223 gtk_widget_destroy (GTK_WIDGET (priv->app_menu));
225 if (G_OBJECT_CLASS (hildon_stackable_window_parent_class)->finalize)
226 G_OBJECT_CLASS (hildon_stackable_window_parent_class)->finalize (object);
230 hildon_stackable_window_class_init (HildonStackableWindowClass *klass)
232 GObjectClass *obj_class = G_OBJECT_CLASS (klass);
233 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
234 HildonWindowClass *window_class = HILDON_WINDOW_CLASS (klass);
236 obj_class->finalize = hildon_stackable_window_finalize;
238 widget_class->realize = hildon_stackable_window_realize;
239 widget_class->show = hildon_stackable_window_show;
240 widget_class->hide = hildon_stackable_window_hide;
242 window_class->toggle_menu = hildon_stackable_window_toggle_menu;
244 g_type_class_add_private (klass, sizeof (HildonStackableWindowPrivate));
248 hildon_stackable_window_init (HildonStackableWindow *self)
250 HildonStackableWindowPrivate *priv = HILDON_STACKABLE_WINDOW_GET_PRIVATE (self);
252 priv->going_home = FALSE;
253 priv->app_menu = NULL;
257 * hildon_stackable_window_new:
259 * Creates a new #HildonStackableWindow.
261 * Return value: A #HildonStackableWindow
264 hildon_stackable_window_new (void)
266 HildonStackableWindow *newwindow = g_object_new (HILDON_TYPE_STACKABLE_WINDOW, NULL);
268 return GTK_WIDGET (newwindow);