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);
}
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;
}
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);
GSList *cursor = list, *start = list;
if (!uid)
- return FALSE;
+ return list;
while (cursor) {
GSList *next = g_slist_next (cursor);
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
return key;
}
-#ifdef MODEST_PLATFORM_MAEMO
+#ifndef MODEST_TOOLKIT_GTK
static void
on_window_is_topmost (GObject *gobject,
GParamSpec *arg1,
/* 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),
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"));
cancel_window_operations (window);
/* Fake the window system, make it think that there is no window */
- g_signal_emit (self, signals[WINDOW_LIST_EMPTY_SIGNAL], 0);
+ if (modest_window_mgr_num_windows (self) == 0)
+ g_signal_emit (self, signals[WINDOW_LIST_EMPTY_SIGNAL], 0);
no_propagate = TRUE;
}
}
/* Unregister window */
modest_window_mgr_unregister_window (self, window);
- no_propagate = FALSE;
+ no_propagate = TRUE;
}
return no_propagate;
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);
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 (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);
}
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 */
"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);
}
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 ();
}
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);
{
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)
{
if (priv->window_list)
num_windows = g_list_length (priv->window_list);
+ /* Do not take into account the main window if it was hidden */
+ if (priv->main_window && !GTK_WIDGET_VISIBLE (priv->main_window))
+ num_windows--;
+
return num_windows + priv->banner_counter;
}
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);
- }
-
}