2 * This file is a part of hildon
4 * Copyright (C) 2008, 2009 Nokia Corporation, all rights reserved.
6 * Contact: Rodrigo Novo <rodrigo.novo@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: Stackable top-level window in the Hildon framework.
28 * @see_also: #HildonWindowStack, #HildonProgram, #HildonWindow
30 * #HildonStackableWindow is a top-level window that can be stacked on
31 * top of others. It is derived from #HildonWindow. Applications that
32 * use stackable windows are organized in a hierarchical way so users
33 * can go from any window back to the previous one or directly to the
34 * stack's root window.
36 * The user can only see and interact with the window on top of the
37 * stack. Although all other windows are mapped and visible, they are
38 * obscured by the topmost one so in practice the user will see the
39 * whole stack as if it was a single window.
41 * To add a window to the stack, just use gtk_widget_show(). The
42 * previous one will be obscured by the new one. When the new window
43 * is destroyed, the previous one will appear again.
45 * Alternatively, you can remove a window from the top of the stack
46 * without destroying it by using gtk_widget_hide(). The window will
47 * be hidden and the previous one will appear automatically.
49 * It is important to note that all #HildonStackableWindow<!-- -->s on
50 * a stack are always mapped and visible (from the Gtk point of view)
51 * and all visible #HildonStackableWindow<!-- -->s are always on a
54 * To see how to manage multiple stacks per application and for other
55 * advanced details on stack handling, see #HildonWindowStack
58 * <title>Basic HildonStackableWindow example</title>
61 * show_new_window (void)
65 * win = hildon_stackable_window_new ();
67 * // ... configure new window
69 * gtk_widget_show (win);
73 * main (int argc, char **argv)
78 * gtk_init (&argc, &args);
80 * win = hildon_stackable_window_new ();
81 * gtk_window_set_title (GTK_WINDOW (win), "Main window);
83 * // ... add some widgets to the window
85 * g_signal_connect (button, "clicked", G_CALLBACK (show_new_window), NULL);
86 * g_signal_connect (win, "destroy", G_CALLBACK (gtk_main_quit), NULL);
88 * gtk_widget_show_all (win);
97 #undef HILDON_DISABLE_DEPRECATED
100 #include <X11/Xatom.h>
101 #include <gdk/gdkx.h>
103 #include "hildon-stackable-window.h"
104 #include "hildon-stackable-window-private.h"
105 #include "hildon-window-stack.h"
106 #include "hildon-window-stack-private.h"
108 G_DEFINE_TYPE (HildonStackableWindow, hildon_stackable_window, HILDON_TYPE_WINDOW);
111 hildon_stackable_window_set_stack (HildonStackableWindow *self,
112 HildonWindowStack *stack,
115 HildonStackableWindowPrivate *priv = HILDON_STACKABLE_WINDOW_GET_PRIVATE (self);
118 g_object_ref (stack);
121 g_object_unref (priv->stack);
124 priv->stack_position = position;
128 * hildon_stackable_window_get_stack:
129 * @self: a #HildonStackableWindow
131 * Returns the stack where window @self is on, or %NULL if the window
134 * Return value: a #HildonWindowStack, or %NULL
139 hildon_stackable_window_get_stack (HildonStackableWindow *self)
141 HildonStackableWindowPrivate *priv;
143 g_return_val_if_fail (HILDON_IS_STACKABLE_WINDOW (self), NULL);
145 priv = HILDON_STACKABLE_WINDOW_GET_PRIVATE (self);
151 * hildon_stackable_window_set_main_menu:
152 * @self: a #HildonStackableWindow
153 * @menu: a #HildonAppMenu to be used for this window
155 * Sets the menu to be used for this window.
157 * Deprecated: Hildon 2.2: use hildon_window_set_app_menu()
160 hildon_stackable_window_set_main_menu (HildonStackableWindow *self,
163 hildon_window_set_app_menu (HILDON_WINDOW (self), menu);
167 hildon_stackable_window_map (GtkWidget *widget)
172 HildonStackableWindowPrivate *priv = HILDON_STACKABLE_WINDOW_GET_PRIVATE (widget);
174 val = priv->stack_position;
176 /* Set additional property "_HILDON_STACKABLE_WINDOW", to allow the WM to manage
177 it as a stackable window. */
178 display = gdk_drawable_get_display (widget->window);
179 atom = gdk_x11_get_xatom_by_name_for_display (display, "_HILDON_STACKABLE_WINDOW");
180 XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (widget->window), atom,
181 XA_INTEGER, 32, PropModeReplace,
182 (unsigned char *) &val, 1);
184 GTK_WIDGET_CLASS (hildon_stackable_window_parent_class)->map (widget);
188 hildon_stackable_window_show (GtkWidget *widget)
190 HildonStackableWindowPrivate *priv = HILDON_STACKABLE_WINDOW_GET_PRIVATE (widget);
192 /* Stack the window if not already stacked */
193 if (priv->stack == NULL) {
194 HildonWindowStack *stack = hildon_window_stack_get_default ();
195 _hildon_window_stack_do_push (stack, HILDON_STACKABLE_WINDOW (widget));
198 GTK_WIDGET_CLASS (hildon_stackable_window_parent_class)->show (widget);
202 hildon_stackable_window_hide (GtkWidget *widget)
204 HildonStackableWindowPrivate *priv = HILDON_STACKABLE_WINDOW_GET_PRIVATE (widget);
207 hildon_window_stack_remove (HILDON_STACKABLE_WINDOW (widget));
210 GTK_WIDGET_CLASS (hildon_stackable_window_parent_class)->hide (widget);
214 hildon_stackable_window_delete_event (GtkWidget *widget,
217 HildonStackableWindowPrivate *priv = HILDON_STACKABLE_WINDOW_GET_PRIVATE (widget);
218 gboolean retvalue = FALSE;
220 if (priv->stack && hildon_window_stack_peek (priv->stack) != widget) {
221 /* Ignore the delete event if this window is not the topmost one */
223 } else if (GTK_WIDGET_CLASS (hildon_stackable_window_parent_class)->delete_event) {
224 retvalue = GTK_WIDGET_CLASS (hildon_stackable_window_parent_class)->delete_event (widget, event);
231 hildon_stackable_window_class_init (HildonStackableWindowClass *klass)
233 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
235 widget_class->map = hildon_stackable_window_map;
236 widget_class->show = hildon_stackable_window_show;
237 widget_class->hide = hildon_stackable_window_hide;
238 widget_class->delete_event = hildon_stackable_window_delete_event;
240 g_type_class_add_private (klass, sizeof (HildonStackableWindowPrivate));
244 hildon_stackable_window_init (HildonStackableWindow *self)
246 HildonStackableWindowPrivate *priv = HILDON_STACKABLE_WINDOW_GET_PRIVATE (self);
249 priv->stack_position = -1;
253 * hildon_stackable_window_new:
255 * Creates a new #HildonStackableWindow.
257 * Return value: A #HildonStackableWindow
262 hildon_stackable_window_new (void)
264 HildonStackableWindow *newwindow = g_object_new (HILDON_TYPE_STACKABLE_WINDOW, NULL);
266 return GTK_WIDGET (newwindow);