X-Git-Url: http://git.maemo.org/git/?p=modest;a=blobdiff_plain;f=src%2Fwidgets%2Fmodest-window-mgr.c;h=fb88abf2cb08f3584af8f5e9dbfe7660a67e792b;hp=81b70b892120e742a4ebe050dcf3849720fb72a5;hb=f6d386ff93e929092ba105385a29d760aeba9ff7;hpb=1da44f9313cda2cd96051b9edfd0d6f09602084c diff --git a/src/widgets/modest-window-mgr.c b/src/widgets/modest-window-mgr.c index 81b70b8..fb88abf 100644 --- a/src/widgets/modest-window-mgr.c +++ b/src/widgets/modest-window-mgr.c @@ -52,6 +52,9 @@ static gboolean on_modal_window_close (GtkWidget *widget, GdkEvent *event, gpointer user_data); +static void on_modal_dialog_destroy (GtkObject *object, + gpointer user_data); + static void on_modal_dialog_close (GtkDialog *dialog, gint arg1, gpointer user_data); @@ -246,14 +249,15 @@ modest_window_mgr_finalize (GObject *obj) } modest_signal_mgr_disconnect_all_and_destroy (priv->window_state_uids); + priv->window_state_uids = NULL; if (priv->window_list) { GList *iter = priv->window_list; /* unregister pending windows */ while (iter) { - modest_window_mgr_unregister_window (MODEST_WINDOW_MGR (obj), - MODEST_WINDOW (iter->data)); + ModestWindow *window = (ModestWindow *) iter->data; iter = g_list_next (iter); + modest_window_mgr_unregister_window (MODEST_WINDOW_MGR (obj), window); } g_list_free (priv->window_list); priv->window_list = NULL; @@ -275,6 +279,7 @@ modest_window_mgr_finalize (GObject *obj) } modest_signal_mgr_disconnect_all_and_destroy (priv->modal_handler_uids); + priv->modal_handler_uids = NULL; if (priv->modal_windows) { g_mutex_lock (priv->queue_lock); @@ -325,7 +330,7 @@ remove_uid (GSList *list, const gchar *uid) GSList *cursor = list, *start = list; if (!uid) - return FALSE; + return list; while (cursor) { GSList *next = g_slist_next (cursor); @@ -420,37 +425,11 @@ modest_window_mgr_register_help_id (ModestWindowMgr *self, GtkWindow *win, const const gchar* modest_window_mgr_get_help_id (ModestWindowMgr *self, GtkWindow *win) { - const gchar* help_id = NULL; - /* we don't need 'self', but for API consistency... */ - g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), NULL); - + g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR (self), NULL); g_return_val_if_fail (win, NULL); - g_return_val_if_fail (GTK_IS_WINDOW(win), NULL); - - if (MODEST_IS_MAIN_WINDOW (win)) { - GtkWidget *folder_view; - TnyFolderStore *folder_store; - - /* Get selected folder */ - folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win), - MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW); - folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)); - - /* Switch help_id */ - if (folder_store && TNY_IS_FOLDER (folder_store)) { - help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store)); - if (!help_id) - g_warning ("%s: BUG: did not get a valid help_id", __FUNCTION__); - } - if (folder_store) - g_object_unref (folder_store); - } - if (!help_id) - help_id = g_object_get_data (G_OBJECT(win), MODEST_WINDOW_HELP_ID_PARAM); - - return help_id; + return g_object_get_data (G_OBJECT(win), MODEST_WINDOW_HELP_ID_PARAM); } static gint @@ -567,7 +546,7 @@ get_show_toolbar_key (GType window_type, return key; } -#ifdef MODEST_PLATFORM_MAEMO +#ifndef MODEST_TOOLKIT_GTK static void on_window_is_topmost (GObject *gobject, GParamSpec *arg1, @@ -693,7 +672,7 @@ modest_window_mgr_register_window (ModestWindowMgr *self, /* Listen to window state changes. Unfortunately window-state-event does not properly work for the Maemo version, so we need to use is-topmost and the ifdef */ -#ifdef MODEST_PLATFORM_MAEMO +#ifndef MODEST_TOOLKIT_GTK priv->window_state_uids = modest_signal_mgr_connect (priv->window_state_uids, G_OBJECT (window), @@ -774,8 +753,10 @@ on_window_destroy (ModestWindow *window, if (g_list_length (priv->window_list) > 1) { /* Present the window if it's not visible now */ - if (!gtk_window_has_toplevel_focus (GTK_WINDOW (window))) + if (!gtk_window_has_toplevel_focus (GTK_WINDOW (window))) { gtk_window_present (GTK_WINDOW (window)); + priv->current_top = window; + } /* Create the confirmation dialog MSG-NOT308 */ dialog_response = modest_platform_run_confirmation_dialog ( GTK_WINDOW (window), _("emev_nc_close_windows")); @@ -836,7 +817,7 @@ on_window_destroy (ModestWindow *window, } /* Unregister window */ modest_window_mgr_unregister_window (self, window); - no_propagate = FALSE; + no_propagate = TRUE; } return no_propagate; @@ -908,21 +889,33 @@ modest_window_mgr_unregister_window (ModestWindowMgr *self, priv->window_list = g_list_remove_link (priv->window_list, win); tmp = g_hash_table_lookup (priv->destroy_handlers, window); handler_id = *tmp; + g_hash_table_remove (priv->destroy_handlers, window); /* cancel open and receive operations */ cancel_window_operations (window); + /* Check if it's the topmost window, and remove the window from the stack. + * This is needed for the cases there's no other topmost window that will + * replace it in topmost handler. + */ + if (window == priv->current_top) + priv->current_top = NULL; + /* Disconnect the "window-state-event" handler, we won't need it anymore */ -#ifdef MODEST_PLATFORM_MAEMO - priv->window_state_uids = modest_signal_mgr_disconnect (priv->window_state_uids, - G_OBJECT (window), - "notify::is-topmost"); + if (priv->window_state_uids) { +#ifndef MODEST_TOOLKIT_GTK + priv->window_state_uids = + modest_signal_mgr_disconnect (priv->window_state_uids, + G_OBJECT (window), + "notify::is-topmost"); #else - priv->window_state_uids = modest_signal_mgr_disconnect (priv->window_state_uids, - G_OBJECT (window), - "window-state-event"); + priv->window_state_uids = + modest_signal_mgr_disconnect (priv->window_state_uids, + G_OBJECT (window), + "window-state-event"); #endif + } /* Disconnect the "delete-event" handler, we won't need it anymore */ g_signal_handler_disconnect (window, handler_id); @@ -931,11 +924,12 @@ modest_window_mgr_unregister_window (ModestWindowMgr *self, modest_window_disconnect_signals (window); /* Destroy the window */ + g_object_unref (win->data); gtk_widget_destroy (win->data); + g_list_free (win); /* If there are no more windows registered emit the signal */ if (modest_window_mgr_num_windows (self) == 0) -/* if (priv->window_list == NULL && priv->banner_counter == 0) */ g_signal_emit (self, signals[WINDOW_LIST_EMPTY_SIGNAL], 0); } @@ -1118,7 +1112,7 @@ modest_window_mgr_set_modal (ModestWindowMgr *self, g_queue_push_head (priv->modal_windows, window); g_mutex_unlock (priv->queue_lock); - if (GTK_IS_DIALOG (window)) + if (GTK_IS_DIALOG (window)) { /* Note that response is not always enough because it could be captured and removed easily by dialogs but works for most of situations */ @@ -1128,13 +1122,25 @@ modest_window_mgr_set_modal (ModestWindowMgr *self, "response", G_CALLBACK (on_modal_dialog_close), self); - else + /* We need this as well because dialogs are often + destroyed with gtk_widget_destroy and this one will + prevent response from happening */ + priv->modal_handler_uids = + modest_signal_mgr_connect (priv->modal_handler_uids, + G_OBJECT (window), + "destroy", + G_CALLBACK (on_modal_dialog_destroy), + self); + } else { priv->modal_handler_uids = modest_signal_mgr_connect (priv->modal_handler_uids, G_OBJECT (window), "delete-event", G_CALLBACK (on_modal_window_close), self); + } + /* Destroy width parent */ + gtk_window_set_destroy_with_parent (window, TRUE); } @@ -1231,6 +1237,10 @@ idle_top_modal (gpointer data) if (topmost) { gdk_threads_enter (); gtk_window_present (topmost); + /* It seems that the window looses modality if some + other is shown on top of it after set_transient_for + and set_parent */ + gtk_window_set_modal (topmost, TRUE); gdk_threads_leave (); } @@ -1259,12 +1269,17 @@ remove_modal_from_queue (GtkWidget *widget, g_mutex_unlock (priv->queue_lock); /* Disconnect handler */ - priv->modal_handler_uids = - modest_signal_mgr_disconnect (priv->modal_handler_uids, + priv->modal_handler_uids = + modest_signal_mgr_disconnect (priv->modal_handler_uids, G_OBJECT (widget), - GTK_IS_DIALOG (widget) ? - "response" : - "destroy-event"); + GTK_IS_DIALOG (widget) ? + "response" : + "delete-event"); + if (GTK_IS_DIALOG (widget)) + priv->modal_handler_uids = + modest_signal_mgr_disconnect (priv->modal_handler_uids, + G_OBJECT (widget), + "destroy"); /* Schedule the next one for being shown */ g_idle_add (idle_top_modal, self); @@ -1291,10 +1306,22 @@ on_modal_dialog_close (GtkDialog *dialog, { ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data); - /* Remove modal window from queue */ + /* Remove modal window from queue. Note that if "destroy" + signal was invoked before the response the window could be + already deleted */ remove_modal_from_queue (GTK_WIDGET (dialog), self); } +static void +on_modal_dialog_destroy (GtkObject *object, + gpointer user_data) +{ + ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data); + + /* Remove modal window from queue */ + remove_modal_from_queue (GTK_WIDGET (object), self); +} + gint modest_window_mgr_num_windows (ModestWindowMgr *self) { @@ -1378,7 +1405,6 @@ modest_window_mgr_unregister_banner (ModestWindowMgr *self) priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); priv->banner_counter--; -/* if (priv->window_list == NULL && priv->banner_counter == 0) */ if (modest_window_mgr_num_windows (self) == 0) g_signal_emit (self, signals[WINDOW_LIST_EMPTY_SIGNAL], 0); }