[gnome-software: 1/2] Replace hardcoded spinner animations by CSS ones




commit 5722e3b1702ec569381e025a323a37ce6aee1b18
Author: Adrien Plazas <kekun plazas laposte net>
Date:   Thu Mar 10 16:54:30 2022 +0100

    Replace hardcoded spinner animations by CSS ones
    
    This gives the .fade-in style class to spinners which are animated with
    gs_start/stop_spinner(), animate them with CSS instead, and drop the
    gs_start/stop_spinner() functions. This makes the code simpler and
    cleaner and makes the animations match the frameclock.

 src/gs-common.c            | 66 ----------------------------------------------
 src/gs-common.h            |  2 --
 src/gs-details-page.c      |  6 ++---
 src/gs-details-page.ui     |  3 +++
 src/gs-extras-page.c       |  4 +--
 src/gs-extras-page.ui      |  3 +++
 src/gs-installed-page.c    |  4 +--
 src/gs-installed-page.ui   |  3 +++
 src/gs-moderate-page.c     |  4 +--
 src/gs-moderate-page.ui    |  3 +++
 src/gs-repos-dialog.c      |  4 +--
 src/gs-repos-dialog.ui     |  3 +++
 src/gs-screenshot-image.c  |  4 +--
 src/gs-screenshot-image.ui |  3 +++
 src/gs-search-page.c       |  6 ++---
 src/gs-search-page.ui      |  3 +++
 src/gs-update-dialog.c     |  4 +--
 src/gs-update-dialog.ui    |  3 +++
 src/gs-updates-page.c      |  4 +--
 src/gs-updates-page.ui     |  1 +
 src/style.css              | 22 ++++++++++++++++
 21 files changed, 66 insertions(+), 89 deletions(-)
---
diff --git a/src/gs-common.c b/src/gs-common.c
index 5cfc055ee..6a8965676 100644
--- a/src/gs-common.c
+++ b/src/gs-common.c
@@ -20,72 +20,6 @@
 
 #include <langinfo.h>
 
-#define SPINNER_DELAY 500
-
-static gboolean
-fade_in (gpointer data)
-{
-       GtkWidget *spinner = data;
-       gdouble opacity;
-
-       opacity = gtk_widget_get_opacity (spinner);
-       opacity = opacity + 0.1;
-       gtk_widget_set_opacity (spinner, opacity);
-
-       if (opacity >= 1.0) {
-               g_object_steal_data (G_OBJECT (spinner), "fade-timeout");
-               return G_SOURCE_REMOVE;
-       }
-       return G_SOURCE_CONTINUE;
-}
-
-static void
-remove_source (gpointer data)
-{
-       g_source_remove (GPOINTER_TO_UINT (data));
-}
-
-static gboolean
-start_spinning (gpointer data)
-{
-       GtkWidget *spinner = data;
-       guint id;
-
-       gtk_widget_set_opacity (spinner, 0);
-       gtk_spinner_start (GTK_SPINNER (spinner));
-       id = g_timeout_add (100, fade_in, spinner);
-       g_object_set_data_full (G_OBJECT (spinner), "fade-timeout",
-                               GUINT_TO_POINTER (id), remove_source);
-
-       /* don't try to remove this source in the future */
-       g_object_steal_data (G_OBJECT (spinner), "start-timeout");
-       return G_SOURCE_REMOVE;
-}
-
-void
-gs_stop_spinner (GtkSpinner *spinner)
-{
-       g_object_set_data (G_OBJECT (spinner), "start-timeout", NULL);
-       gtk_spinner_stop (spinner);
-}
-
-void
-gs_start_spinner (GtkSpinner *spinner)
-{
-       gboolean spinning;
-       guint id;
-
-       /* Don't do anything if it's already spinning */
-       g_object_get (spinner, "spinning", &spinning, NULL);
-       if (spinning || g_object_get_data (G_OBJECT (spinner), "start-timeout") != NULL)
-               return;
-
-       gtk_widget_set_opacity (GTK_WIDGET (spinner), 0);
-       id = g_timeout_add (SPINNER_DELAY, start_spinning, spinner);
-       g_object_set_data_full (G_OBJECT (spinner), "start-timeout",
-                               GUINT_TO_POINTER (id), remove_source);
-}
-
 void
 gs_widget_remove_all (GtkWidget    *container,
                       GsRemoveFunc  remove_func)
diff --git a/src/gs-common.h b/src/gs-common.h
index 93904624b..0339ca798 100644
--- a/src/gs-common.h
+++ b/src/gs-common.h
@@ -19,8 +19,6 @@ G_BEGIN_DECLS
 typedef void (*GsRemoveFunc) (GtkWidget *container,
                              GtkWidget *child);
 
-void    gs_start_spinner               (GtkSpinner     *spinner);
-void    gs_stop_spinner                (GtkSpinner     *spinner);
 void    gs_widget_remove_all           (GtkWidget      *container,
                                         GsRemoveFunc    remove_func);
 void    gs_grab_focus_when_mapped      (GtkWidget      *widget);
diff --git a/src/gs-details-page.c b/src/gs-details-page.c
index 7c1130e6d..4a9b4361a 100644
--- a/src/gs-details-page.c
+++ b/src/gs-details-page.c
@@ -201,13 +201,11 @@ gs_details_page_set_state (GsDetailsPage *self,
        /* spinner */
        switch (state) {
        case GS_DETAILS_PAGE_STATE_LOADING:
-               gs_start_spinner (GTK_SPINNER (self->spinner_details));
-               gtk_widget_show (self->spinner_details);
+               gtk_spinner_start (GTK_SPINNER (self->spinner_details));
                break;
        case GS_DETAILS_PAGE_STATE_READY:
        case GS_DETAILS_PAGE_STATE_FAILED:
-               gs_stop_spinner (GTK_SPINNER (self->spinner_details));
-               gtk_widget_hide (self->spinner_details);
+               gtk_spinner_stop (GTK_SPINNER (self->spinner_details));
                break;
        default:
                g_assert_not_reached ();
diff --git a/src/gs-details-page.ui b/src/gs-details-page.ui
index cda8392a1..039feb32a 100644
--- a/src/gs-details-page.ui
+++ b/src/gs-details-page.ui
@@ -31,6 +31,9 @@
                     <property name="valign">center</property>
                     <property name="hexpand">True</property>
                     <property name="vexpand">True</property>
+                    <style>
+                      <class name="fade-in"/>
+                    </style>
                   </object>
                 </child>
                 <child>
diff --git a/src/gs-extras-page.c b/src/gs-extras-page.c
index 2e0c4bbdf..329ccdc1a 100644
--- a/src/gs-extras-page.c
+++ b/src/gs-extras-page.c
@@ -194,12 +194,12 @@ gs_extras_page_update_ui_state (GsExtrasPage *self)
        /* main spinner */
        switch (self->state) {
        case GS_EXTRAS_PAGE_STATE_LOADING:
-               gs_start_spinner (GTK_SPINNER (self->spinner));
+               gtk_spinner_start (GTK_SPINNER (self->spinner));
                break;
        case GS_EXTRAS_PAGE_STATE_READY:
        case GS_EXTRAS_PAGE_STATE_NO_RESULTS:
        case GS_EXTRAS_PAGE_STATE_FAILED:
-               gs_stop_spinner (GTK_SPINNER (self->spinner));
+               gtk_spinner_stop (GTK_SPINNER (self->spinner));
                break;
        default:
                g_assert_not_reached ();
diff --git a/src/gs-extras-page.ui b/src/gs-extras-page.ui
index 72474264a..c2943529d 100644
--- a/src/gs-extras-page.ui
+++ b/src/gs-extras-page.ui
@@ -30,6 +30,9 @@
                     <property name="valign">center</property>
                     <property name="hexpand">True</property>
                     <property name="vexpand">True</property>
+                    <style>
+                      <class name="fade-in"/>
+                    </style>
                   </object>
                 </child>
               </object>
diff --git a/src/gs-installed-page.c b/src/gs-installed-page.c
index e8943afec..8fa5087d5 100644
--- a/src/gs-installed-page.c
+++ b/src/gs-installed-page.c
@@ -385,7 +385,7 @@ gs_installed_page_get_installed_cb (GObject *source_object,
        g_autoptr(GError) error = NULL;
        g_autoptr(GsAppList) list = NULL;
 
-       gs_stop_spinner (GTK_SPINNER (self->spinner_install));
+       gtk_spinner_stop (GTK_SPINNER (self->spinner_install));
        gtk_stack_set_visible_child_name (GTK_STACK (self->stack_install), "view");
 
        self->waiting = FALSE;
@@ -465,7 +465,7 @@ gs_installed_page_load (GsInstalledPage *self)
                                            self->cancellable,
                                            gs_installed_page_get_installed_cb,
                                            self);
-       gs_start_spinner (GTK_SPINNER (self->spinner_install));
+       gtk_spinner_start (GTK_SPINNER (self->spinner_install));
        gtk_stack_set_visible_child_name (GTK_STACK (self->stack_install), "spinner");
 }
 
diff --git a/src/gs-installed-page.ui b/src/gs-installed-page.ui
index 24f20cf86..f80c41cb1 100644
--- a/src/gs-installed-page.ui
+++ b/src/gs-installed-page.ui
@@ -19,6 +19,9 @@
                 <property name="valign">center</property>
                 <property name="hexpand">True</property>
                 <property name="vexpand">True</property>
+                <style>
+                  <class name="fade-in"/>
+                </style>
               </object>
             </property>
           </object>
diff --git a/src/gs-moderate-page.c b/src/gs-moderate-page.c
index 75a0657ce..546179135 100644
--- a/src/gs-moderate-page.c
+++ b/src/gs-moderate-page.c
@@ -196,7 +196,7 @@ gs_moderate_page_refine_unvoted_reviews_cb (GObject      *source_object,
        g_autoptr(GError) error = NULL;
        g_autoptr(GsAppList) list = NULL;
 
-       gs_stop_spinner (GTK_SPINNER (self->spinner_install));
+       gtk_spinner_stop (GTK_SPINNER (self->spinner_install));
        gtk_stack_set_visible_child_name (GTK_STACK (self->stack_install), "view");
 
        list = gs_plugin_loader_job_process_finish (plugin_loader,
@@ -254,7 +254,7 @@ gs_moderate_page_load (GsModeratePage *self)
                                            self->cancellable,
                                            gs_moderate_page_refine_unvoted_reviews_cb,
                                            self);
-       gs_start_spinner (GTK_SPINNER (self->spinner_install));
+       gtk_spinner_start (GTK_SPINNER (self->spinner_install));
        gtk_stack_set_visible_child_name (GTK_STACK (self->stack_install), "spinner");
 }
 
diff --git a/src/gs-moderate-page.ui b/src/gs-moderate-page.ui
index b0e523f17..0f8bd2214 100644
--- a/src/gs-moderate-page.ui
+++ b/src/gs-moderate-page.ui
@@ -19,6 +19,9 @@
                 <property name="valign">center</property>
                 <property name="hexpand">True</property>
                 <property name="vexpand">True</property>
+                <style>
+                  <class name="fade-in"/>
+                </style>
               </object>
             </property>
           </object>
diff --git a/src/gs-repos-dialog.c b/src/gs-repos-dialog.c
index 7bd94264d..b411ecc9c 100644
--- a/src/gs-repos-dialog.c
+++ b/src/gs-repos-dialog.c
@@ -459,7 +459,7 @@ get_sources_cb (GsPluginLoader *plugin_loader,
        }
 
        /* stop the spinner */
-       gs_stop_spinner (GTK_SPINNER (dialog->spinner));
+       gtk_spinner_stop (GTK_SPINNER (dialog->spinner));
 
        /* no results */
        if (gs_app_list_length (list) == 0) {
@@ -754,7 +754,7 @@ gs_repos_dialog_new (GtkWindow *parent, GsPluginLoader *plugin_loader)
                               NULL);
        set_plugin_loader (dialog, plugin_loader);
        gtk_stack_set_visible_child_name (GTK_STACK (dialog->stack), "waiting");
-       gs_start_spinner (GTK_SPINNER (dialog->spinner));
+       gtk_spinner_start (GTK_SPINNER (dialog->spinner));
        reload_third_party_repos (dialog);
 
        return GTK_WIDGET (dialog);
diff --git a/src/gs-repos-dialog.ui b/src/gs-repos-dialog.ui
index c28fca0f3..9183f5b7c 100644
--- a/src/gs-repos-dialog.ui
+++ b/src/gs-repos-dialog.ui
@@ -39,6 +39,9 @@
                     <property name="valign">center</property>
                     <property name="hexpand">True</property>
                     <property name="vexpand">True</property>
+                    <style>
+                      <class name="fade-in"/>
+                    </style>
                   </object>
                 </property>
               </object>
diff --git a/src/gs-screenshot-image.c b/src/gs-screenshot-image.c
index ad00634cc..736f86ac5 100644
--- a/src/gs-screenshot-image.c
+++ b/src/gs-screenshot-image.c
@@ -56,13 +56,13 @@ static void
 gs_screenshot_image_start_spinner (GsScreenshotImage *ssimg)
 {
        gtk_widget_show (ssimg->spinner);
-       gs_start_spinner (GTK_SPINNER (ssimg->spinner));
+       gtk_spinner_start (GTK_SPINNER (ssimg->spinner));
 }
 
 static void
 gs_screenshot_image_stop_spinner (GsScreenshotImage *ssimg)
 {
-       gs_stop_spinner (GTK_SPINNER (ssimg->spinner));
+       gtk_spinner_stop (GTK_SPINNER (ssimg->spinner));
        gtk_widget_hide (ssimg->spinner);
 }
 
diff --git a/src/gs-screenshot-image.ui b/src/gs-screenshot-image.ui
index c992678b3..2606be51d 100644
--- a/src/gs-screenshot-image.ui
+++ b/src/gs-screenshot-image.ui
@@ -20,6 +20,9 @@
             <property name="valign">center</property>
             <property name="hexpand">True</property>
             <property name="vexpand">True</property>
+            <style>
+              <class name="fade-in"/>
+            </style>
           </object>
         </child>
         <child>
diff --git a/src/gs-search-page.c b/src/gs-search-page.c
index dc1fffa26..1d0f5211e 100644
--- a/src/gs-search-page.c
+++ b/src/gs-search-page.c
@@ -120,7 +120,7 @@ gs_search_page_get_search_cb (GObject *source_object,
                        return;
                }
                g_warning ("failed to get search apps: %s", error->message);
-               gs_stop_spinner (GTK_SPINNER (self->spinner_search));
+               gtk_spinner_stop (GTK_SPINNER (self->spinner_search));
                if (self->value && self->value[0])
                        gtk_stack_set_visible_child_name (GTK_STACK (self->stack_search), "no-results");
                else
@@ -141,7 +141,7 @@ gs_search_page_get_search_cb (GObject *source_object,
        /* remove old entries */
        gs_widget_remove_all (self->list_box_search, (GsRemoveFunc) gtk_list_box_remove);
 
-       gs_stop_spinner (GTK_SPINNER (self->spinner_search));
+       gtk_spinner_stop (GTK_SPINNER (self->spinner_search));
        gtk_stack_set_visible_child_name (GTK_STACK (self->stack_search), "results");
        for (i = 0; i < gs_app_list_length (list); i++) {
                app = gs_app_list_index (list, i);
@@ -207,7 +207,7 @@ gs_search_page_waiting_show_cb (gpointer user_data)
 
        /* show spinner */
        gtk_stack_set_visible_child_name (GTK_STACK (self->stack_search), "spinner");
-       gs_start_spinner (GTK_SPINNER (self->spinner_search));
+       gtk_spinner_start (GTK_SPINNER (self->spinner_search));
        gs_search_page_waiting_cancel (self);
        return FALSE;
 }
diff --git a/src/gs-search-page.ui b/src/gs-search-page.ui
index efadcf72a..7d2768e10 100644
--- a/src/gs-search-page.ui
+++ b/src/gs-search-page.ui
@@ -29,6 +29,9 @@
                 <property name="height_request">32</property>
                 <property name="halign">center</property>
                 <property name="valign">center</property>
+                <style>
+                  <class name="fade-in"/>
+                </style>
               </object>
             </property>
           </object>
diff --git a/src/gs-update-dialog.c b/src/gs-update-dialog.c
index 64a28da3b..fc14f2b53 100644
--- a/src/gs-update-dialog.c
+++ b/src/gs-update-dialog.c
@@ -98,7 +98,7 @@ get_installed_updates_cb (GsPluginLoader *plugin_loader,
                return;
        }
 
-       gs_stop_spinner (GTK_SPINNER (dialog->spinner));
+       gtk_spinner_stop (GTK_SPINNER (dialog->spinner));
 
        /* error */
        if (list == NULL) {
@@ -151,7 +151,7 @@ gs_update_dialog_show_installed_updates (GsUpdateDialog *dialog)
        /* TRANSLATORS: this is the title of the installed updates dialog window */
        gtk_window_set_title (GTK_WINDOW (dialog), _("Installed Updates"));
 
-       gs_start_spinner (GTK_SPINNER (dialog->spinner));
+       gtk_spinner_start (GTK_SPINNER (dialog->spinner));
        gtk_stack_set_visible_child_name (GTK_STACK (dialog->stack), "spinner");
 
        plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_GET_UPDATES_HISTORICAL,
diff --git a/src/gs-update-dialog.ui b/src/gs-update-dialog.ui
index d4be842fb..e3927c5f2 100644
--- a/src/gs-update-dialog.ui
+++ b/src/gs-update-dialog.ui
@@ -58,6 +58,9 @@
                             <property name="valign">center</property>
                             <property name="hexpand">True</property>
                             <property name="vexpand">True</property>
+                            <style>
+                              <class name="fade-in"/>
+                            </style>
                           </object>
                         </child>
                       </object>
diff --git a/src/gs-updates-page.c b/src/gs-updates-page.c
index 04971dacf..ca5b0a1da 100644
--- a/src/gs-updates-page.c
+++ b/src/gs-updates-page.c
@@ -279,10 +279,10 @@ gs_updates_page_update_ui_state (GsUpdatesPage *self)
        case GS_UPDATES_PAGE_STATE_STARTUP:
        case GS_UPDATES_PAGE_STATE_ACTION_GET_UPDATES:
        case GS_UPDATES_PAGE_STATE_ACTION_REFRESH:
-               gs_start_spinner (GTK_SPINNER (self->spinner_updates));
+               gtk_spinner_start (GTK_SPINNER (self->spinner_updates));
                break;
        default:
-               gs_stop_spinner (GTK_SPINNER (self->spinner_updates));
+               gtk_spinner_stop (GTK_SPINNER (self->spinner_updates));
                gtk_spinner_stop (GTK_SPINNER (self->header_spinner_start));
                gtk_widget_hide (self->header_spinner_start);
                break;
diff --git a/src/gs-updates-page.ui b/src/gs-updates-page.ui
index 654cbdb3b..dafc72465 100644
--- a/src/gs-updates-page.ui
+++ b/src/gs-updates-page.ui
@@ -69,6 +69,7 @@
                                 <property name="vexpand">True</property>
                                 <style>
                                   <class name="icon"/>
+                                  <class name="fade-in"/>
                                 </style>
                               </object>
                             </child>
diff --git a/src/style.css b/src/style.css
index 4caa21883..6272165b0 100644
--- a/src/style.css
+++ b/src/style.css
@@ -537,3 +537,25 @@ row.app > box.header > image {
 row.app label.warning {
   color: #cc0000;
 }
+
+/**************
+ * GtkSpinner *
+ **************/
+
+/* Ensure the spinner is hidden before the animation is triggered. */
+@keyframes pre-delay {
+  from { opacity: 0; }
+  to { opacity: 0; }
+}
+
+/* We don't use the opacity CSS property because it's used by the spinner and we
+ * want to leave it untouched. */
+@keyframes fade-in {
+  from { filter: opacity(0%); }
+}
+
+/* Give a fade-in animation to spinners. */
+spinner.fade-in:checked {
+  animation: pre-delay 0.5s linear 1, fade-in 1s linear 1, spin 1s linear infinite;
+  animation-delay: 0s, 0.5s, 0.5s;
+}


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