[gnome-software] gs-shell: Change mode in an idle callback after loading is complete



commit cd36673f21fbf9a67158c99ce8f762be7f4ca2ee
Author: Philip Withnall <withnall endlessm com>
Date:   Fri Jun 19 15:04:00 2020 +0100

    gs-shell: Change mode in an idle callback after loading is complete
    
    Otherwise the main context iteration where loading is marked as complete
    has too much happening in it, and takes many cycles in GTK’s frame
    clock. This makes the UI freeze for a noticeable fraction of a second.
    
    Partially avoid that by splitting up some of the work here between two
    main context iterations. The UI still freezes a bit; further work is
    required.
    
    Signed-off-by: Philip Withnall <withnall endlessm com>

 src/gs-shell.c | 24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)
---
diff --git a/src/gs-shell.c b/src/gs-shell.c
index 8f0dc6f1..4765f782 100644
--- a/src/gs-shell.c
+++ b/src/gs-shell.c
@@ -756,15 +756,13 @@ gs_shell_reload_cb (GsPluginLoader *plugin_loader, GsShell *shell)
        }
 }
 
-static void
-overview_page_refresh_done (GsOverviewPage *overview_page, gpointer data)
+static gboolean
+change_mode_idle (gpointer user_data)
 {
-       GsShell *shell = data;
+       GsShell *shell = user_data;
        GsShellPrivate *priv = gs_shell_get_instance_private (shell);
        GsPage *page;
 
-       g_signal_handlers_disconnect_by_func (overview_page, overview_page_refresh_done, data);
-
        page = GS_PAGE (gtk_builder_get_object (priv->builder, "updates_page"));
        gs_page_reload (page);
        page = GS_PAGE (gtk_builder_get_object (priv->builder, "installed_page"));
@@ -772,9 +770,25 @@ overview_page_refresh_done (GsOverviewPage *overview_page, gpointer data)
 
        gs_shell_change_mode (shell, GS_SHELL_MODE_OVERVIEW, NULL, TRUE);
 
+       return G_SOURCE_REMOVE;
+}
+
+static void
+overview_page_refresh_done (GsOverviewPage *overview_page, gpointer data)
+{
+       GsShell *shell = data;
+       GsShellPrivate *priv = gs_shell_get_instance_private (shell);
+
+       g_signal_handlers_disconnect_by_func (overview_page, overview_page_refresh_done, data);
+
        /* now that we're finished with the loading page, connect the reload signal handler */
        g_signal_connect (priv->plugin_loader, "reload",
                          G_CALLBACK (gs_shell_reload_cb), shell);
+
+       /* schedule to change the mode in an idle callback, since it can take a
+        * while and this callback handler is typically called at the end of a
+        * long main context iteration already */
+       g_idle_add (change_mode_idle, shell);
 }
 
 static void


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]