1 /* Copyright (c) 2006,2007 Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include "modest-window-mgr.h"
32 #include "modest-runtime.h"
33 #include "modest-tny-folder.h"
34 #include "modest-ui-actions.h"
35 #include "modest-platform.h"
36 #include "widgets/modest-main-window.h"
37 #include "widgets/modest-msg-edit-window.h"
38 #include "widgets/modest-msg-view-window.h"
41 /* 'private'/'protected' functions */
42 static void modest_window_mgr_class_init (ModestWindowMgrClass *klass);
43 static void modest_window_mgr_init (ModestWindowMgr *obj);
44 static void modest_window_mgr_finalize (GObject *obj);
46 static gboolean on_window_destroy (ModestWindow *window,
48 ModestWindowMgr *self);
57 typedef struct _ModestWindowMgrPrivate ModestWindowMgrPrivate;
58 struct _ModestWindowMgrPrivate {
61 ModestWindow *main_window;
62 GtkDialog *easysetup_dialog;
64 gboolean fullscreen_mode;
65 gboolean show_toolbars;
66 gboolean show_toolbars_fullscreen;
68 GSList *windows_that_prevent_hibernation;
69 GSList *preregistered_uids;
70 GHashTable *destroy_handlers;
71 GHashTable *viewer_handlers;
75 #define MODEST_WINDOW_MGR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
76 MODEST_TYPE_WINDOW_MGR, \
77 ModestWindowMgrPrivate))
79 static GObjectClass *parent_class = NULL;
81 /* uncomment the following if you have defined any signals */
82 /* static guint signals[LAST_SIGNAL] = {0}; */
85 modest_window_mgr_get_type (void)
87 static GType my_type = 0;
89 static const GTypeInfo my_info = {
90 sizeof(ModestWindowMgrClass),
92 NULL, /* base finalize */
93 (GClassInitFunc) modest_window_mgr_class_init,
94 NULL, /* class finalize */
95 NULL, /* class data */
96 sizeof(ModestWindowMgr),
98 (GInstanceInitFunc) modest_window_mgr_init,
101 my_type = g_type_register_static (G_TYPE_OBJECT,
109 modest_window_mgr_class_init (ModestWindowMgrClass *klass)
111 GObjectClass *gobject_class;
112 gobject_class = (GObjectClass*) klass;
114 parent_class = g_type_class_peek_parent (klass);
115 gobject_class->finalize = modest_window_mgr_finalize;
117 g_type_class_add_private (gobject_class, sizeof(ModestWindowMgrPrivate));
121 modest_window_mgr_init (ModestWindowMgr *obj)
123 ModestWindowMgrPrivate *priv;
125 priv = MODEST_WINDOW_MGR_GET_PRIVATE(obj);
126 priv->window_list = NULL;
127 priv->main_window = NULL;
128 priv->fullscreen_mode = FALSE;
129 priv->easysetup_dialog = NULL;
131 priv->preregistered_uids = NULL;
133 /* Could not initialize it from gconf, singletons are not
135 priv->show_toolbars = FALSE;
136 priv->show_toolbars_fullscreen = FALSE;
137 priv->destroy_handlers = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
138 priv->viewer_handlers = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
140 priv->closing_time = 0;
144 modest_window_mgr_finalize (GObject *obj)
146 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE(obj);
148 if (priv->window_list) {
149 GList *iter = priv->window_list;
150 /* unregister pending windows */
152 modest_window_mgr_unregister_window (MODEST_WINDOW_MGR (obj),
153 MODEST_WINDOW (iter->data));
154 iter = g_list_next (iter);
156 g_list_free (priv->window_list);
157 priv->window_list = NULL;
160 g_slist_foreach (priv->preregistered_uids, (GFunc)g_free, NULL);
161 g_slist_free (priv->preregistered_uids);
164 /* Free the hash table with the handlers */
165 if (priv->destroy_handlers) {
166 g_hash_table_destroy (priv->destroy_handlers);
167 priv->destroy_handlers = NULL;
170 if (priv->viewer_handlers) {
171 g_hash_table_destroy (priv->viewer_handlers);
172 priv->viewer_handlers = NULL;
175 if (priv->easysetup_dialog) {
176 g_warning ("%s: forgot to destroy an easysetup dialog somewhere",
178 gtk_widget_destroy (GTK_WIDGET(priv->easysetup_dialog));
179 priv->easysetup_dialog = NULL;
182 /* Do not unref priv->main_window because it does not hold a
186 G_OBJECT_CLASS(parent_class)->finalize (obj);
190 modest_window_mgr_new (void)
192 return MODEST_WINDOW_MGR(g_object_new(MODEST_TYPE_WINDOW_MGR, NULL));
198 /* do we have uid? */
200 has_uid (GSList *list, const gchar *uid)
202 GSList *cursor = list;
208 if (cursor->data && strcmp (cursor->data, uid) == 0)
210 cursor = g_slist_next (cursor);
216 /* remove all from the list have have uid = uid */
218 remove_uid (GSList *list, const gchar *uid)
220 GSList *cursor = list, *start = list;
226 GSList *next = g_slist_next (cursor);
227 if (cursor->data && strcmp (cursor->data, uid) == 0) {
228 g_free (cursor->data);
229 start = g_slist_delete_link (start, cursor);
238 append_uid (GSList *list, const gchar *uid)
240 return g_slist_append (list, g_strdup(uid));
246 modest_window_mgr_register_header (ModestWindowMgr *self, TnyHeader *header)
248 ModestWindowMgrPrivate *priv;
251 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
252 g_return_if_fail (TNY_IS_HEADER(header));
254 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
255 uid = modest_tny_folder_get_header_unique_id (header);
258 if (!has_uid (priv->preregistered_uids, uid)) {
259 g_debug ("registering new uid %s", uid);
260 priv->preregistered_uids = append_uid (priv->preregistered_uids, uid);
262 g_debug ("already had uid %s", uid);
268 modest_window_mgr_unregister_header (ModestWindowMgr *self, TnyHeader *header)
270 ModestWindowMgrPrivate *priv;
273 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
274 g_return_if_fail (TNY_IS_HEADER(header));
276 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
277 uid = modest_tny_folder_get_header_unique_id (header);
279 if (!has_uid (priv->preregistered_uids, uid)) {
280 g_debug ("trying to unregister non-existing uid %s", uid);
281 priv->preregistered_uids = append_uid (priv->preregistered_uids, uid);
283 g_debug ("unregistering uid %s", uid);
285 if (has_uid (priv->preregistered_uids, uid)) {
286 priv->preregistered_uids = remove_uid (priv->preregistered_uids, uid);
287 if (has_uid (priv->preregistered_uids, uid))
288 g_debug ("BUG: uid %s NOT removed", uid);
290 g_debug ("uid %s removed", uid);
297 compare_msguids (ModestWindow *win,
300 const gchar *msg_uid;
302 if ((!MODEST_IS_MSG_EDIT_WINDOW (win)) && (!MODEST_IS_MSG_VIEW_WINDOW (win)))
305 /* Get message uid from msg window */
306 if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
307 msg_uid = modest_msg_edit_window_get_message_uid (MODEST_MSG_EDIT_WINDOW (win));
309 msg_uid = modest_msg_view_window_get_message_uid (MODEST_MSG_VIEW_WINDOW (win));
312 if (msg_uid && uid &&!strcmp (msg_uid, uid))
321 modest_window_mgr_find_registered_header (ModestWindowMgr *self, TnyHeader *header,
324 ModestWindowMgrPrivate *priv;
326 gboolean has_header, has_window = FALSE;
329 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
330 g_return_val_if_fail (TNY_IS_HEADER(header), FALSE);
332 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
334 uid = modest_tny_folder_get_header_unique_id (header);
339 /* g_debug ("windows in list: %d", g_list_length (priv->window_list)); */
340 /* g_debug ("headers in list: %d", g_slist_length (priv->preregistered_uids)); */
342 has_header = has_uid (priv->preregistered_uids, uid);
344 item = g_list_find_custom (priv->window_list, uid, (GCompareFunc) compare_msguids);
348 if ((!MODEST_IS_MSG_VIEW_WINDOW(item->data)) &&
349 (!MODEST_IS_MSG_EDIT_WINDOW (item->data)))
350 g_debug ("not a valid window!");
352 g_debug ("found a window");
353 *win = MODEST_WINDOW (item->data);
359 return has_header || has_window;
365 modest_window_mgr_register_window (ModestWindowMgr *self,
366 ModestWindow *window)
368 static gboolean first_time = TRUE;
371 ModestWindowMgrPrivate *priv;
374 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
375 g_return_if_fail (GTK_IS_WINDOW (window));
377 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
379 win = g_list_find (priv->window_list, window);
381 g_warning ("Trying to register an already registered window");
385 /* Check that it's not a second main window */
386 if (MODEST_IS_MAIN_WINDOW (window)) {
387 if (priv->main_window) {
388 g_warning ("Trying to register a second main window");
391 priv->main_window = window;
396 /* remove from the list of pre-registered uids */
397 if (MODEST_IS_MSG_VIEW_WINDOW(window)) {
398 const gchar *uid = modest_msg_view_window_get_message_uid
399 (MODEST_MSG_VIEW_WINDOW (window));
401 g_debug ("registering window for %s", uid);
403 if (!has_uid (priv->preregistered_uids, uid))
404 g_debug ("weird: no uid for window (%s)", uid);
406 priv->preregistered_uids =
407 remove_uid (priv->preregistered_uids,
408 modest_msg_view_window_get_message_uid
409 (MODEST_MSG_VIEW_WINDOW (window)));
410 } else if (MODEST_IS_MSG_EDIT_WINDOW(window)) {
411 const gchar *uid = modest_msg_edit_window_get_message_uid
412 (MODEST_MSG_EDIT_WINDOW (window));
414 g_debug ("registering window for %s", uid);
416 if (!has_uid (priv->preregistered_uids, uid))
417 g_debug ("weird: no uid for window (%s)", uid);
419 priv->preregistered_uids =
420 remove_uid (priv->preregistered_uids,
421 modest_msg_edit_window_get_message_uid
422 (MODEST_MSG_EDIT_WINDOW (window)));
425 /* Add to list. Keep a reference to the window */
426 g_object_ref (window);
427 priv->window_list = g_list_prepend (priv->window_list, window);
429 /* Listen to object destruction */
430 handler_id = g_malloc0 (sizeof (gint));
431 *handler_id = g_signal_connect (window, "delete-event", G_CALLBACK (on_window_destroy), self);
432 g_hash_table_insert (priv->destroy_handlers, window, handler_id);
434 /* If there is a msg view window, let the main window listen the msg-changed signal */
435 if (MODEST_IS_MSG_VIEW_WINDOW(window) && priv->main_window) {
437 handler = g_malloc0 (sizeof (gulong));
438 *handler = g_signal_connect (window, "msg-changed",
439 G_CALLBACK (modest_main_window_on_msg_view_window_msg_changed),
441 g_hash_table_insert (priv->viewer_handlers, window, handler);
444 /* Put into fullscreen if needed */
445 if (priv->fullscreen_mode)
446 gtk_window_fullscreen (GTK_WINDOW (window));
450 ModestConf *conf = modest_runtime_get_conf ();
451 priv->show_toolbars =
452 modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR, NULL);
453 priv->show_toolbars_fullscreen =
454 modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR_FULLSCREEN, NULL);
458 /* Show/hide toolbar */
459 if (priv->fullscreen_mode)
460 show = priv->show_toolbars_fullscreen;
462 show = priv->show_toolbars;
463 modest_window_show_toolbar (window, show);
467 on_window_destroy (ModestWindow *window,
469 ModestWindowMgr *self)
471 /* Specific stuff first */
472 if (MODEST_IS_MAIN_WINDOW (window)) {
473 ModestWindowMgrPrivate *priv;
474 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
476 /* If more than one window already opened */
477 if (g_list_length (priv->window_list) > 1) {
479 /* If the user wants to close all the windows */
480 if (modest_main_window_close_all (MODEST_MAIN_WINDOW (window))) {
481 GList *iter = priv->window_list;
483 if (iter->data != window) {
484 GList *tmp = iter->next;
485 on_window_destroy (MODEST_WINDOW (iter->data),
490 iter = g_list_next (iter);
497 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
498 gboolean sent = FALSE;
499 gint response = GTK_RESPONSE_ACCEPT;
500 sent = modest_msg_edit_window_get_sent (MODEST_MSG_EDIT_WINDOW (window));
501 /* Save currently edited message to Drafts if it was not sent */
502 if (!sent && modest_msg_edit_window_is_modified (MODEST_MSG_EDIT_WINDOW (window))) {
505 modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
506 _("mcen_nc_no_email_message_modified_save_changes"));
508 if (response != GTK_RESPONSE_CANCEL)
509 modest_ui_actions_on_save_to_drafts (NULL, MODEST_MSG_EDIT_WINDOW (window));
515 /* Save configuration state (TODO: why edit window does not require this function ?) */
516 if (!MODEST_IS_MSG_EDIT_WINDOW (window))
517 modest_window_save_state (MODEST_WINDOW(window));
520 /* Unregister window */
521 modest_window_mgr_unregister_window (self, window);
527 disconnect_msg_changed (gpointer key,
533 handler_id = (gulong *) value;
534 g_signal_handler_disconnect (G_OBJECT (key), *handler_id);
539 /* interval before retrying to close the application */
540 #define CLOSING_RETRY_INTERVAL 3000
541 /* interval before cancel whatever is left in the queue, and closing anyway */
542 #define MAX_WAIT_FOR_CLOSING 30 * 1000
545 on_quit_maybe (ModestWindowMgr *self)
547 ModestWindowMgrPrivate *priv;
550 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
552 /* it seems, in the meantime some windows were
553 * created. in that case, stop 'on_quit_maybe' */
554 if (priv->window_list) {
555 priv->closing_time = 0;
559 if (priv->closing_time >= MAX_WAIT_FOR_CLOSING) {
560 /* we waited long enough: cancel all remaining operations */
561 g_debug ("%s: we waited long enough (%ds), cancelling queue and quiting",
562 __FUNCTION__, priv->closing_time/1000);
563 /* FIXME: below gives me a lot of:
564 * GLIB CRITICAL ** default - modest_mail_operation_cancel:
565 * assertion `priv->account' failed
566 * which means there is no account for the given operation
567 * so, we're not trying to be nice, we're just quiting.
569 //modest_mail_operation_queue_cancel_all
570 // (modest_runtime_get_mail_operation_queue());
573 /* if there is anything left in our operation queue,
576 queue_num = modest_mail_operation_queue_num_elements
577 (modest_runtime_get_mail_operation_queue());
579 g_debug ("%s: waiting, there are still %d operation(s) queued",
580 __FUNCTION__, queue_num);
581 priv->closing_time += CLOSING_RETRY_INTERVAL;
586 /* so: no windows left, nothing in the queue: quit */
587 priv->closing_time = 0;
594 modest_window_mgr_unregister_window (ModestWindowMgr *self,
595 ModestWindow *window)
598 ModestWindowMgrPrivate *priv;
599 gulong *tmp, handler_id;
601 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
602 g_return_if_fail (MODEST_IS_WINDOW (window));
604 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
606 win = g_list_find (priv->window_list, window);
608 g_warning ("Trying to unregister a window that has not being registered yet");
612 /* If it's the main window unset it */
613 if (priv->main_window == window) {
614 priv->main_window = NULL;
616 /* Disconnect all emissions of msg-changed */
617 if (priv->viewer_handlers) {
618 g_hash_table_foreach (priv->viewer_handlers,
619 disconnect_msg_changed,
621 g_hash_table_destroy (priv->viewer_handlers);
622 priv->viewer_handlers = NULL;
626 /* Remove the viewer window handler from the hash table. The
627 HashTable could not exist if the main window was closeed
628 when there were other windows remaining */
629 if (MODEST_IS_MSG_VIEW_WINDOW (window) && priv->viewer_handlers) {
630 tmp = (gulong *) g_hash_table_lookup (priv->viewer_handlers, window);
631 g_signal_handler_disconnect (window, *tmp);
632 g_hash_table_remove (priv->viewer_handlers, window);
636 modest_window_save_state (window);
638 /* Remove from list & hash table */
639 priv->window_list = g_list_remove_link (priv->window_list, win);
640 tmp = g_hash_table_lookup (priv->destroy_handlers, window);
642 g_hash_table_remove (priv->destroy_handlers, window);
644 /* Disconnect the "delete-event" handler, we won't need it anymore */
645 g_signal_handler_disconnect (window, handler_id);
647 /* Disconnect all the window signals */
648 modest_window_disconnect_signals (window);
650 /* Destroy the window */
651 gtk_widget_destroy (win->data);
653 /* If there are no more windows registered then exit program */
654 if (priv->window_list == NULL) {
656 ModestConf *conf = modest_runtime_get_conf ();
657 /* Save show toolbar status */
658 modest_conf_set_bool (conf, MODEST_CONF_SHOW_TOOLBAR_FULLSCREEN,
659 priv->show_toolbars_fullscreen, NULL);
660 modest_conf_set_bool (conf, MODEST_CONF_SHOW_TOOLBAR,
661 priv->show_toolbars, NULL);
663 g_timeout_add (CLOSING_RETRY_INTERVAL,
664 (GSourceFunc)on_quit_maybe, self);
671 modest_window_mgr_set_fullscreen_mode (ModestWindowMgr *self,
674 ModestWindowMgrPrivate *priv;
677 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
679 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
681 /* If there is no change do nothing */
682 if (priv->fullscreen_mode == on)
685 priv->fullscreen_mode = on;
688 win = priv->window_list;
691 gtk_window_fullscreen (GTK_WINDOW (win->data));
692 modest_window_show_toolbar (MODEST_WINDOW (win->data),
693 priv->show_toolbars_fullscreen);
695 gtk_window_unfullscreen (GTK_WINDOW (win->data));
696 modest_window_show_toolbar (MODEST_WINDOW (win->data),
697 priv->show_toolbars);
699 win = g_list_next (win);
704 modest_window_mgr_get_fullscreen_mode (ModestWindowMgr *self)
706 ModestWindowMgrPrivate *priv;
708 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
710 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
712 return priv->fullscreen_mode;
716 modest_window_mgr_show_toolbars (ModestWindowMgr *self,
717 gboolean show_toolbars,
720 ModestWindowMgrPrivate *priv;
722 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
724 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
726 /* If nothing changes then return. Otherwise cache it, do not
727 save to GConf for the moment, it will be done when all
728 windows become unregistered in order to avoid unnecessary
731 if (priv->show_toolbars_fullscreen == show_toolbars)
734 priv->show_toolbars_fullscreen = show_toolbars;
736 if (priv->show_toolbars == show_toolbars)
739 priv->show_toolbars = show_toolbars;
742 /* Apply now if the view mode is the right one */
743 if ((fullscreen && priv->fullscreen_mode) ||
744 (!fullscreen && !priv->fullscreen_mode)) {
746 GList *win = priv->window_list;
749 modest_window_show_toolbar (MODEST_WINDOW (win->data),
751 win = g_list_next (win);
757 modest_window_mgr_get_main_window (ModestWindowMgr *self)
759 ModestWindowMgrPrivate *priv;
761 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), NULL);
762 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
764 /* create the main window, if it hasn't been created yet */
765 if (!priv->main_window) {
766 g_debug ("%s: creating main window\n", __FUNCTION__);
767 modest_window_mgr_register_window (self, modest_main_window_new ());
770 return priv->main_window;
775 modest_window_mgr_get_easysetup_dialog (ModestWindowMgr *self)
777 ModestWindowMgrPrivate *priv;
779 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), NULL);
780 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
782 return priv->easysetup_dialog;
787 modest_window_mgr_set_easysetup_dialog (ModestWindowMgr *self, GtkDialog *dialog)
789 ModestWindowMgrPrivate *priv;
791 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), NULL);
792 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
794 return priv->easysetup_dialog = dialog;
799 on_nonhibernating_window_hide(GtkWidget *widget, gpointer user_data)
801 ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
802 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
804 /* Forget this window,
805 * so hibernation will be allowed again if no windows are remembered: */
806 priv->windows_that_prevent_hibernation =
807 g_slist_remove (priv->windows_that_prevent_hibernation, GTK_WINDOW(widget));
811 on_nonhibernating_window_show(GtkWidget *widget, gpointer user_data)
813 ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
814 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
816 GtkWindow *window = GTK_WINDOW (widget);
818 priv->windows_that_prevent_hibernation =
819 g_slist_append (priv->windows_that_prevent_hibernation, window);
821 /* Allow hibernation again when the window has been hidden: */
822 g_signal_connect (window, "hide",
823 G_CALLBACK (on_nonhibernating_window_hide), self);
827 modest_window_mgr_prevent_hibernation_while_window_is_shown (ModestWindowMgr *self,
830 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
832 if (GTK_WIDGET_VISIBLE(window)) {
833 on_nonhibernating_window_show (GTK_WIDGET (window), self);
835 /* Wait for it to be shown: */
836 g_signal_connect (window, "show",
837 G_CALLBACK (on_nonhibernating_window_show), self);
842 modest_window_mgr_get_hibernation_is_prevented (ModestWindowMgr *self)
844 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
846 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
848 /* Prevent hibernation if any open windows are currently
849 * preventing hibernation: */
850 return (g_slist_length (priv->windows_that_prevent_hibernation) > 0);
855 modest_window_mgr_save_state_for_all_windows (ModestWindowMgr *self)
857 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
859 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
861 /* Iterate over all windows */
862 GList *win = priv->window_list;
864 ModestWindow *window = MODEST_WINDOW (win->data);
866 /* This calls the vfunc,
867 * so each window can do its own thing: */
868 modest_window_save_state (window);
871 win = g_list_next (win);