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.
37 #include <X11/Xatom.h>
38 #include "hildon-stackable-window.h"
39 #include "hildon-stackable-window-private.h"
40 #include "hildon-program.h"
41 #include "hildon-window-private.h"
42 #include "hildon-program-private.h"
44 G_DEFINE_TYPE (HildonStackableWindow, hildon_stackable_window, HILDON_TYPE_WINDOW);
47 hildon_stackable_window_set_going_home (HildonStackableWindow *self,
50 HildonStackableWindowPrivate *priv = HILDON_STACKABLE_WINDOW_GET_PRIVATE (self);
51 priv->going_home = going_home;
54 gboolean G_GNUC_INTERNAL
55 hildon_stackable_window_get_going_home (HildonStackableWindow *self)
57 HildonStackableWindowPrivate *priv = HILDON_STACKABLE_WINDOW_GET_PRIVATE (self);
58 return priv->going_home;
62 get_window_list (GtkWidget *widget)
64 HildonWindowPrivate *wpriv;
65 HildonProgramPrivate *ppriv;
66 GSList *retval = NULL;
67 g_return_val_if_fail (widget != NULL, NULL);
69 wpriv = HILDON_WINDOW_GET_PRIVATE (widget);
70 g_assert (wpriv != NULL);
74 ppriv = HILDON_PROGRAM_GET_PRIVATE (wpriv->program);
75 g_assert (ppriv != NULL);
76 retval = ppriv->windows;
83 get_previous_window_if_last (GtkWidget *widget)
85 GtkWidget *retval = NULL;
86 GSList *iter = get_window_list (widget);
87 GSList *previous = NULL;
89 /* Return NULL if the window hasn't been added to the HildonProgram */
95 /* Go to the end of the window list */
96 while (iter->next != NULL)
102 if ((iter->data == widget) && (previous != NULL))
104 retval = GTK_WIDGET (previous->data);
111 hildon_stackable_window_map (GtkWidget *widget)
113 GtkWidget *previous = get_previous_window_if_last (widget);
115 if (GTK_WIDGET_CLASS (hildon_stackable_window_parent_class)->map)
116 GTK_WIDGET_CLASS (hildon_stackable_window_parent_class)->map (widget);
118 if (HILDON_IS_STACKABLE_WINDOW (previous) && GTK_WIDGET_VISIBLE (previous))
119 gtk_widget_hide (previous);
123 hildon_stackable_window_unmap (GtkWidget *widget)
125 GtkWidget *previous = get_previous_window_if_last (widget);
127 if (GTK_WIDGET_CLASS (hildon_stackable_window_parent_class)->unmap)
128 GTK_WIDGET_CLASS (hildon_stackable_window_parent_class)->unmap (widget);
130 if (HILDON_IS_STACKABLE_WINDOW (previous) && !GTK_WIDGET_VISIBLE (previous) &&
131 !hildon_stackable_window_get_going_home (HILDON_STACKABLE_WINDOW (widget)))
133 gtk_widget_show (previous);
138 hildon_stackable_window_unset_program (HildonWindow *hwin)
140 GtkWidget *previous = get_previous_window_if_last (GTK_WIDGET (hwin));
142 if (HILDON_WINDOW_CLASS (hildon_stackable_window_parent_class)->unset_program)
143 HILDON_WINDOW_CLASS (hildon_stackable_window_parent_class)->unset_program (hwin);
145 if (HILDON_IS_STACKABLE_WINDOW (previous) && !GTK_WIDGET_VISIBLE (previous) &&
146 !hildon_stackable_window_get_going_home (HILDON_STACKABLE_WINDOW (hwin)))
148 gtk_widget_show (previous);
153 hildon_stackable_window_realize (GtkWidget *widget)
158 GTK_WIDGET_CLASS (hildon_stackable_window_parent_class)->realize (widget);
160 /* Set the window type to "_HILDON_WM_WINDOW_TYPE_STACKABLE", to allow the WM to manage
162 display = gdk_drawable_get_display (widget->window);
163 atom = gdk_x11_get_xatom_by_name_for_display (display, "_HILDON_WM_WINDOW_TYPE_STACKABLE");
164 XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (widget->window),
165 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE"),
166 XA_ATOM, 32, PropModeAppend,
171 hildon_stackable_window_delete_event (GtkWidget *widget,
174 GSList *list = get_window_list (widget);
175 list = g_slist_find (list, widget);
177 /* Ignore the delete event if this is not the topmost window */
178 if (list != NULL && list->next != NULL)
180 else if (GTK_WIDGET_CLASS (hildon_stackable_window_parent_class)->delete_event)
181 return GTK_WIDGET_CLASS (hildon_stackable_window_parent_class)->delete_event (widget, event);
187 hildon_stackable_window_class_init (HildonStackableWindowClass *klass)
189 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
190 HildonWindowClass *window_class = HILDON_WINDOW_CLASS (klass);
192 widget_class->map = hildon_stackable_window_map;
193 widget_class->unmap = hildon_stackable_window_unmap;
194 widget_class->realize = hildon_stackable_window_realize;
195 widget_class->delete_event = hildon_stackable_window_delete_event;
197 window_class->unset_program = hildon_stackable_window_unset_program;
199 g_type_class_add_private (klass, sizeof (HildonStackableWindowPrivate));
203 hildon_stackable_window_init (HildonStackableWindow *self)
205 hildon_stackable_window_set_going_home (self, FALSE);
209 * hildon_stackable_window_new:
211 * Creates a new #HildonStackableWindow.
213 * Return value: A #HildonStackableWindow
216 hildon_stackable_window_new (void)
218 HildonStackableWindow *newwindow = g_object_new (HILDON_TYPE_STACKABLE_WINDOW, NULL);
220 return GTK_WIDGET (newwindow);