X-Git-Url: https://vcs.maemo.org/git/?a=blobdiff_plain;f=src%2Fhildon-program.c;h=b8a93e30885d72638fc5d2491ba6b93b3b52a9ac;hb=8a95e38835d478bf3d24ee0b6e8dcd6b5175580f;hp=5fdc6898dd64dd487f5eb63faa9362e2ce8fe071;hpb=95fc3e48012198771410b27a898e5529521f4277;p=hildon diff --git a/src/hildon-program.c b/src/hildon-program.c index 5fdc689..b8a93e3 100644 --- a/src/hildon-program.c +++ b/src/hildon-program.c @@ -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 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); +}