* Fixes NB#84117, fixes "hangs" when reopening Modest while there are ongoing operations
authorSergio Villar Senin <svillar@igalia.com>
Wed, 16 Apr 2008 15:36:52 +0000 (15:36 +0000)
committerSergio Villar Senin <svillar@igalia.com>
Wed, 16 Apr 2008 15:36:52 +0000 (15:36 +0000)
* Close banners when the window is not visible

pmo-trunk-r4421

src/maemo/modest-main-window.c
src/maemo/modest-platform.c
src/modest-main.c
src/widgets/modest-window-mgr.c

index 308ff82..3023683 100644 (file)
@@ -181,6 +181,10 @@ static gboolean show_retrieving_banner (gpointer user_data);
 static void on_window_destroy (GtkObject *widget,
                               gpointer userdata);
 
+static void on_window_hide (GObject    *gobject,
+                           GParamSpec *arg1,
+                           gpointer    user_data);
+
 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
 struct _ModestMainWindowPrivate {
        GtkWidget *msg_paned;
@@ -1000,6 +1004,8 @@ connect_signals (ModestMainWindow *self)
         * in destroy stage */
        g_signal_connect (G_OBJECT (self), "destroy", G_CALLBACK (on_window_destroy), NULL);
 
+       g_signal_connect (G_OBJECT (self), "notify::visible", G_CALLBACK (on_window_hide), NULL);
+
        /* Mail Operation Queue */
        priv->sighandlers = 
                modest_signal_mgr_connect (priv->sighandlers,
@@ -2787,11 +2793,11 @@ modest_main_window_screen_is_on (ModestMainWindow *self)
 }
 
 static void
-on_window_destroy (GtkObject *widget, gpointer userdata)
+remove_banners (ModestMainWindow *window)
 {
        ModestMainWindowPrivate *priv;
 
-       priv = MODEST_MAIN_WINDOW_GET_PRIVATE (widget);
+       priv = MODEST_MAIN_WINDOW_GET_PRIVATE (window);
 
        if (priv->retrieving_banner_timeout > 0) {
                g_source_remove (priv->retrieving_banner_timeout);
@@ -2811,8 +2817,28 @@ on_window_destroy (GtkObject *widget, gpointer userdata)
        if (priv->updating_banner != NULL) {
                gtk_widget_destroy (priv->updating_banner);
                priv->updating_banner = NULL;
-       }
-       
+       }       
+}
+
+
+static void
+on_window_hide (GObject    *gobject,
+               GParamSpec *arg1,
+               gpointer    user_data)
+{
+       g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
+
+       if (!GTK_WIDGET_VISIBLE (user_data))
+               remove_banners (MODEST_MAIN_WINDOW (user_data));
+}
+
+static void
+on_window_destroy (GtkObject *widget, 
+                  gpointer user_data)
+{
+       g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
+
+       remove_banners (MODEST_MAIN_WINDOW (user_data));
 }
 
 static gboolean
index 73a6ed5..4d61dbd 100644 (file)
@@ -1689,6 +1689,10 @@ modest_platform_animation_banner (GtkWidget *parent,
 
        g_return_val_if_fail (text != NULL, NULL);
 
+       /* If the parent is not visible then do not show */
+       if (parent && !GTK_WIDGET_VISIBLE (parent))
+               return NULL;
+
        inf_note = hildon_banner_show_animation (parent, animation_name, text);
 
        return inf_note;
index 563fe29..2288c6f 100644 (file)
 #include <widgets/modest-main-window.h>
 #include <string.h>
 
- static gboolean
+typedef struct {
+       gulong queue_handler;
+       gulong window_list_handler;
+} MainSignalHandlers;
+
+static gboolean
 on_idle_exit_modest (gpointer data)
 {
+       ModestWindow *main_win;
+       ModestWindowMgr *mgr;
+       MainSignalHandlers *handlers;
+
        /* Protect the Gtk calls */
        gdk_threads_enter ();
 
+       /* Disconnect signals. Will be freed by the destroy notify */
+       handlers = (MainSignalHandlers *) data;
+       g_signal_handler_disconnect (modest_runtime_get_mail_operation_queue (), 
+                                    handlers->queue_handler);
+       g_signal_handler_disconnect (modest_runtime_get_window_mgr (), 
+                                    handlers->window_list_handler);
+
+       /* If the main window is still there but hidden, then unregister it */
+       mgr = modest_runtime_get_window_mgr();
+       main_win = modest_window_mgr_get_main_window (mgr, FALSE);
+       if (main_win)
+               modest_window_mgr_unregister_window (mgr, main_win);
+
        /* Wait for remaining tasks */
        while (gtk_events_pending ())
                gtk_main_iteration ();
@@ -58,11 +80,17 @@ static void
 on_queue_empty (ModestMailOperationQueue *queue,
                gpointer user_data)
 {
+       guint num_windows = 0;
        ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
-
-       /* Exit if the queue is empty and there are no more windows */
-       if (modest_window_mgr_num_windows (mgr) == 0)
-               g_idle_add_full (G_PRIORITY_LOW, on_idle_exit_modest, NULL, NULL);
+       ModestWindow *main_win = modest_window_mgr_get_main_window (mgr, FALSE);
+
+       /* Exit if the queue is empty and there are no more
+          windows. We can exit as well if the main window is hidden
+          and it's the only one */
+       num_windows = modest_window_mgr_num_windows (mgr); 
+       if ((num_windows == 0) || 
+           (num_windows == 1 && main_win && !GTK_WIDGET_VISIBLE (main_win)))
+               g_idle_add_full (G_PRIORITY_LOW, on_idle_exit_modest, user_data, g_free);
 }
 
 static void
@@ -73,7 +101,7 @@ on_window_list_empty (ModestWindowMgr *window_mgr,
 
        /* Exit if there are no more windows and the queue is empty */
        if (modest_mail_operation_queue_num_elements (queue) == 0)
-               g_idle_add_full (G_PRIORITY_LOW, on_idle_exit_modest, NULL, NULL);
+               g_idle_add_full (G_PRIORITY_LOW, on_idle_exit_modest, user_data, g_free);
 }
 
 int
@@ -85,6 +113,7 @@ main (int argc, char *argv[])
         * command line.: */
        gboolean show_ui_without_top_application_method = FALSE;
        int retval  = 0;
+       MainSignalHandlers *handlers;
 
        if (argc >= 2) {
                if (strcmp (argv[1], "showui") == 0)
@@ -120,15 +149,18 @@ main (int argc, char *argv[])
        }
 
        /* Connect to the queue-emtpy signal */
-       g_signal_connect (modest_runtime_get_mail_operation_queue (),
-                         "queue-empty",
-                         G_CALLBACK (on_queue_empty),
-                         NULL);
-
-       g_signal_connect (modest_runtime_get_window_mgr (),
-                         "window-list-empty",
-                         G_CALLBACK (on_window_list_empty),
-                         NULL);
+       handlers = g_malloc0 (sizeof (MainSignalHandlers));
+       handlers->queue_handler = 
+               g_signal_connect (modest_runtime_get_mail_operation_queue (),
+                                 "queue-empty",
+                                 G_CALLBACK (on_queue_empty),
+                                 handlers);
+
+       handlers->window_list_handler = 
+               g_signal_connect (modest_runtime_get_window_mgr (),
+                                 "window-list-empty",
+                                 G_CALLBACK (on_window_list_empty),
+                                 handlers);
 
        /* Usually, we only show the UI when we get the "top_application" D-Bus method.
         * This allows modest to start via D-Bus activation to provide a service,
index 3cfb17b..bd1b95a 100644 (file)
@@ -732,12 +732,38 @@ modest_window_mgr_register_window (ModestWindowMgr *self,
        modest_window_show_toolbar (window, modest_conf_get_bool (modest_runtime_get_conf (), key, NULL));
 }
 
+static void
+cancel_window_operations (ModestWindow *window)
+{
+       GSList* pending_ops = NULL;
+
+       /* cancel open and receive operations */
+       pending_ops = modest_mail_operation_queue_get_by_source (modest_runtime_get_mail_operation_queue (), 
+                                                                G_OBJECT (window));
+       while (pending_ops != NULL) {
+               ModestMailOperationTypeOperation type;
+               GSList* tmp_list = NULL;
+
+               type = modest_mail_operation_get_type_operation (MODEST_MAIL_OPERATION (pending_ops->data));
+               if (type == MODEST_MAIL_OPERATION_TYPE_RECEIVE || type == MODEST_MAIL_OPERATION_TYPE_OPEN) {
+                       modest_mail_operation_cancel (pending_ops->data);
+               }
+               g_object_unref (G_OBJECT (pending_ops->data));
+               tmp_list = pending_ops;
+               pending_ops = g_slist_next (pending_ops);
+               g_slist_free_1 (tmp_list);
+       }
+}
+
+
+
 static gboolean
 on_window_destroy (ModestWindow *window, 
                   GdkEvent *event,
                   ModestWindowMgr *self)
 {
        gint dialog_response = GTK_RESPONSE_NONE;
+       gboolean no_propagate = FALSE;
 
        /* Specific stuff first */
        if (MODEST_IS_MAIN_WINDOW (window)) {
@@ -774,6 +800,18 @@ on_window_destroy (ModestWindow *window,
                                return TRUE;
                        }
                }
+
+               /* Do not unregister it, just hide */
+               gtk_widget_hide_all (GTK_WIDGET (window));
+
+               /* Cancel pending operations */
+               cancel_window_operations (window);
+
+               /* Fake the window system, make it think that there is no window */
+               if (priv->banner_counter == 0)
+                       g_signal_emit (self, signals[WINDOW_LIST_EMPTY_SIGNAL], 0);
+
+               no_propagate = TRUE;
        }
        else {
                if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
@@ -796,12 +834,12 @@ on_window_destroy (ModestWindow *window,
                                                return TRUE;
                        }
                }
+               /* Unregister window */
+               modest_window_mgr_unregister_window (self, window);
+               no_propagate = FALSE;
        }
 
-       /* Unregister window */
-       modest_window_mgr_unregister_window (self, window);
-       
-       return FALSE;
+       return no_propagate;
 }
 
 static void
@@ -823,7 +861,6 @@ modest_window_mgr_unregister_window (ModestWindowMgr *self,
        GList *win;
        ModestWindowMgrPrivate *priv;
        gulong *tmp, handler_id;
-       GSList* pending_ops = NULL;
 
        g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
        g_return_if_fail (MODEST_IS_WINDOW (window));
@@ -851,7 +888,7 @@ modest_window_mgr_unregister_window (ModestWindowMgr *self,
        }
 
        /* Remove the viewer window handler from the hash table. The
-          HashTable could not exist if the main window was closeed
+          HashTable could not exist if the main window was closed
           when there were other windows remaining */
        if (MODEST_IS_MSG_VIEW_WINDOW (window) && priv->viewer_handlers) {
                tmp = (gulong *) g_hash_table_lookup (priv->viewer_handlers, window);
@@ -874,21 +911,7 @@ modest_window_mgr_unregister_window (ModestWindowMgr *self,
        g_hash_table_remove (priv->destroy_handlers, window);
 
        /* cancel open and receive operations */
-       pending_ops = modest_mail_operation_queue_get_by_source (modest_runtime_get_mail_operation_queue (), 
-                                                                G_OBJECT (window));
-       while (pending_ops != NULL) {
-               ModestMailOperationTypeOperation type;
-               GSList* tmp_list = NULL;
-
-               type = modest_mail_operation_get_type_operation (MODEST_MAIL_OPERATION (pending_ops->data));
-               if (type == MODEST_MAIL_OPERATION_TYPE_RECEIVE || type == MODEST_MAIL_OPERATION_TYPE_OPEN) {
-                       modest_mail_operation_cancel (pending_ops->data);
-               }
-               g_object_unref (G_OBJECT (pending_ops->data));
-               tmp_list = pending_ops;
-               pending_ops = g_slist_next (pending_ops);
-               g_slist_free_1 (tmp_list);
-       }
+       cancel_window_operations (window);
 
        /* Disconnect the "window-state-event" handler, we won't need it anymore */
 #ifdef MODEST_PLATFORM_MAEMO