* examples/hildon-stackable-window-example.c (new_window): * src/Makefile.am (noinst_...
[hildon] / src / hildon-program.c
index 5fdc689..b8a93e3 100644 (file)
@@ -8,7 +8,7 @@
  * 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
@@ -52,7 +52,7 @@
  * GtkToolbar *common_toolbar, *window_specific_toolbar;
  * GtkMenu *menu;
  * <!-- -->
- * program = HILDON_PROGRAM (hildon_program_new ());
+ * program = HILDON_PROGRAM (hildon_program_get_instance ());
  * <!-- -->
  * window1 = HILDON_WINDOW (hildon_window_new ());
  * window2 = HILDON_WINDOW (hildon_window_new ());
@@ -62,8 +62,8 @@
  * <!-- -->
  * menu = create_menu ();
  * <!-- -->
- * hildon_program_add (program, window1);
- * hildon_program_add (program, window2);
+ * hildon_program_add_window (program, window1);
+ * hildon_program_add_window (program, window2);
  * <!-- -->
  * hildon_program_set_common_menu (program, menu);
  * <!-- -->
@@ -82,6 +82,8 @@
 #include                                        "hildon-program.h"
 #include                                        "hildon-program-private.h"
 #include                                        "hildon-window-private.h"
+#include                                        "hildon-stackable-window.h"
+#include                                        "hildon-stackable-window-private.h"
 #include                                        <X11/Xatom.h>
 
 static void
@@ -381,7 +383,8 @@ hildon_program_common_toolbar_topmost_window    (gpointer window,
  * hildon_program_get_instance:
  *
  * Return value: Returns the #HildonProgram for the current process.
- * The object is created on the first call.
+ * 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.
  **/
 HildonProgram*
 hildon_program_get_instance                     (void)
@@ -683,3 +686,80 @@ hildon_program_get_is_topmost                   (HildonProgram *self)
 
     return priv->is_topmost;
 }
+
+/**
+ * hildon_program_go_to_root_window:
+ * @self: A #HildonProgram
+ *
+ * Will close all windows in the #HildonProgram but the first one (the
+ * root window) by sending them a delete event. If any of the windows
+ * refuses to close (by handling it) no further events will be
+ * sent. All windows in the program must be #HildonStackableWindow for
+ * this to work.
+ */
+void
+hildon_program_go_to_root_window                (HildonProgram *self)
+{
+    HildonProgramPrivate *priv;
+    GSList *windows, *iter;
+    gboolean windows_left;
+
+    g_return_if_fail (HILDON_IS_PROGRAM (self));
+    priv = HILDON_PROGRAM_GET_PRIVATE (self);
+    g_assert (priv);
+
+    /* List of windows in reverse order (starting from the topmost one) */
+    windows = g_slist_reverse (g_slist_copy (priv->windows));
+    iter = windows;
+
+    /* Destroy all the windows but the last one (which is the root
+     * window, as the list is reversed) */
+    windows_left = (iter != NULL && iter->next != NULL);
+    while (windows_left)
+    {
+        if (HILDON_IS_STACKABLE_WINDOW (iter->data))
+        {
+            GdkEvent *event;
+            HildonStackableWindow *win;
+
+            /* Mark the window as "going home" */
+            win = HILDON_STACKABLE_WINDOW (iter->data);
+            hildon_stackable_window_set_going_home (win, TRUE);
+
+            /* Set win pointer to NULL if the window is destroyed */
+            g_object_add_weak_pointer (G_OBJECT (win), (gpointer) &win);
+
+            /* Send a delete event */
+            event = gdk_event_new (GDK_DELETE);
+            event->any.window = g_object_ref (GTK_WIDGET (win)->window);
+            gtk_main_do_event (event);
+            gdk_event_free (event);
+
+            /* Continue sending delete events if the window has been destroyed */
+            if (win == NULL)
+            {
+                iter = iter->next;
+                windows_left = (iter != NULL && iter->next != NULL);
+            }
+            else
+            {
+                g_object_remove_weak_pointer (G_OBJECT (win), (gpointer) &win);
+                hildon_stackable_window_set_going_home (win, FALSE);
+                windows_left = FALSE;
+            }
+        }
+        else
+        {
+            g_warning ("Window list contains a non-stackable window");
+            windows_left = FALSE;
+        }
+    }
+
+    /* Show the last window that hasn't been destroyed */
+    if (iter != NULL && GTK_IS_WIDGET (iter->data))
+    {
+        gtk_widget_show (GTK_WIDGET (iter->data));
+    }
+
+    g_slist_free (windows);
+}