[gnome-software: 19/29] gs-page: Expose update/installed counter as GsPage:counter
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software: 19/29] gs-page: Expose update/installed counter as GsPage:counter
- Date: Wed, 31 Mar 2021 16:03:46 +0000 (UTC)
commit b49f9d31d249ba20ea24451c132e47151063a14d
Author: Philip Withnall <pwithnall endlessos org>
Date: Thu Jan 21 13:27:18 2021 +0000
gs-page: Expose update/installed counter as GsPage:counter
Then bind that to the counter labels in the buttonbox at the top of the
shell. This fixes a layering violation where the installed and updates
page would update shell widgets directly themselves.
Signed-off-by: Philip Withnall <pwithnall endlessos org>
src/gs-installed-page.c | 16 +++++-----------
src/gs-page.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
src/gs-page.h | 1 +
src/gs-shell.c | 42 ++++++++++++++++++++++++++++++++++++++++++
src/gs-updates-page.c | 45 +++++++++++++++++++--------------------------
5 files changed, 111 insertions(+), 38 deletions(-)
---
diff --git a/src/gs-installed-page.c b/src/gs-installed-page.c
index eb623b6c8..6aee85c10 100644
--- a/src/gs-installed-page.c
+++ b/src/gs-installed-page.c
@@ -34,6 +34,7 @@ struct _GsInstalledPage
gboolean waiting;
GsShell *shell;
GSettings *settings;
+ guint pending_apps_counter;
GtkWidget *list_box_install;
GtkWidget *scrolledwindow_install;
@@ -535,7 +536,6 @@ gs_installed_page_pending_apps_changed_cb (GsPluginLoader *plugin_loader,
GsInstalledPage *self)
{
GsApp *app;
- GtkWidget *widget;
guint i;
guint cnt = 0;
g_autoptr(GsAppList) pending = NULL;
@@ -558,16 +558,10 @@ gs_installed_page_pending_apps_changed_cb (GsPluginLoader *plugin_loader,
cnt++;
}
- /* show a label with the number of on-going operations */
- widget = GTK_WIDGET (gtk_builder_get_object (self->builder,
- "button_installed_counter"));
- if (cnt == 0) {
- gtk_widget_hide (widget);
- } else {
- g_autofree gchar *label = NULL;
- label = g_strdup_printf ("%u", cnt);
- gtk_label_set_label (GTK_LABEL (widget), label);
- gtk_widget_show (widget);
+ /* update the number of on-going operations */
+ if (cnt != self->pending_apps_counter) {
+ self->pending_apps_counter = cnt;
+ g_object_notify (G_OBJECT (self), "counter");
}
}
diff --git a/src/gs-page.c b/src/gs-page.c
index 8adba6f96..b375d60bd 100644
--- a/src/gs-page.c
+++ b/src/gs-page.c
@@ -30,9 +30,10 @@ G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GsPage, gs_page, GTK_TYPE_BIN)
typedef enum {
PROP_TITLE = 1,
+ PROP_COUNTER,
} GsPageProperty;
-static GParamSpec *obj_props[PROP_TITLE + 1] = { NULL, };
+static GParamSpec *obj_props[PROP_COUNTER + 1] = { NULL, };
GsShell *
gs_page_get_shell (GsPage *page)
@@ -624,6 +625,31 @@ gs_page_get_title (GsPage *page)
return g_value_get_string (&value);
}
+/**
+ * gs_page_get_counter:
+ * @page: a #GsPage
+ *
+ * Get the value of #GsPage:counter.
+ *
+ * Returns: a counter of the number of available updates, installed packages,
+ * etc. on this page
+ *
+ * Since: 40
+ */
+guint
+gs_page_get_counter (GsPage *page)
+{
+ g_auto(GValue) value = G_VALUE_INIT;
+
+ g_return_val_if_fail (GS_IS_PAGE (page), 0);
+
+ /* The property is typically overridden by subclasses; the
+ * implementation in #GsPage itself is just a placeholder. */
+ g_object_get_property (G_OBJECT (page), "counter", &value);
+
+ return g_value_get_uint (&value);
+}
+
/**
* gs_page_switch_to:
*
@@ -721,6 +747,10 @@ gs_page_get_property (GObject *object,
/* Should be overridden by subclasses. */
g_value_set_string (value, NULL);
break;
+ case PROP_COUNTER:
+ /* Should be overridden by subclasses. */
+ g_value_set_uint (value, 0);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -766,6 +796,19 @@ gs_page_class_init (GsPageClass *klass)
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ /**
+ * GsPage:counter:
+ *
+ * A counter indicating the number of installed packages, available
+ * updates, etc. on this page.
+ *
+ * Since: 40
+ */
+ obj_props[PROP_COUNTER] =
+ g_param_spec_uint ("counter", NULL, NULL,
+ 0, G_MAXUINT, 0,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
g_object_class_install_properties (object_class, G_N_ELEMENTS (obj_props), obj_props);
}
diff --git a/src/gs-page.h b/src/gs-page.h
index aba930a52..108c87e25 100644
--- a/src/gs-page.h
+++ b/src/gs-page.h
@@ -76,5 +76,6 @@ gboolean gs_page_setup (GsPage *page,
gboolean gs_page_is_active (GsPage *page);
const gchar *gs_page_get_title (GsPage *page);
+guint gs_page_get_counter (GsPage *page);
G_END_DECLS
diff --git a/src/gs-shell.c b/src/gs-shell.c
index aac0ce36f..5ea1c9bea 100644
--- a/src/gs-shell.c
+++ b/src/gs-shell.c
@@ -76,6 +76,8 @@ struct _GsShell
GsPage *page;
GBinding *application_details_header_binding;
+ GBinding *button_installed_counter_binding;
+ GBinding *button_updates_counter_binding;
#ifdef HAVE_MOGWAI
MwscScheduler *scheduler;
@@ -2093,6 +2095,29 @@ gs_shell_close_window_accel_cb (GtkAccelGroup *accel_group,
return TRUE;
}
+static void
+counter_notify_label_cb (GObject *obj,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ GtkLabel *label = GTK_LABEL (obj);
+ GsShell *shell = GS_SHELL (user_data);
+ gboolean is_interesting;
+
+ /* hide the label if its value is not useful to the user */
+ is_interesting = (g_strcmp0 (gtk_label_get_label (label), "") != 0 &&
+ g_strcmp0 (gtk_label_get_label (label), "0") != 0);
+
+ gtk_widget_set_visible (GTK_WIDGET (label), is_interesting);
+
+ /* update the tab style */
+ if (is_interesting &&
+ gs_shell_get_mode (shell) != GS_SHELL_MODE_UPDATES)
+ gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (label)),
"needs-attention");
+ else
+ gtk_style_context_remove_class (gtk_widget_get_style_context (GTK_WIDGET (label)),
"needs-attention");
+}
+
void
gs_shell_setup (GsShell *shell, GsPluginLoader *plugin_loader, GCancellable *cancellable)
{
@@ -2253,6 +2278,21 @@ gs_shell_setup (GsShell *shell, GsPluginLoader *plugin_loader, GCancellable *can
g_signal_connect (widget, "search-changed",
G_CALLBACK (search_changed_handler), shell);
+ /* bind the counters */
+ widget = GTK_WIDGET (gtk_builder_get_object (shell->builder, "button_installed_counter"));
+ page = g_hash_table_lookup (shell->pages, "installed");
+ shell->button_installed_counter_binding = g_object_bind_property (page, "counter",
+ widget, "label",
+ G_BINDING_SYNC_CREATE);
+ g_signal_connect (widget, "notify::label", G_CALLBACK (counter_notify_label_cb), shell);
+
+ widget = GTK_WIDGET (gtk_builder_get_object (shell->builder, "button_updates_counter"));
+ page = g_hash_table_lookup (shell->pages, "updates");
+ shell->button_updates_counter_binding = g_object_bind_property (page, "counter",
+ widget, "label",
+ G_BINDING_SYNC_CREATE);
+ g_signal_connect (widget, "notify::label", G_CALLBACK (counter_notify_label_cb), shell);
+
/* load content */
page = GS_PAGE (gtk_builder_get_object (shell->builder, "loading_page"));
g_signal_connect (page, "refreshed",
@@ -2438,6 +2478,8 @@ gs_shell_dispose (GObject *object)
GsShell *shell = GS_SHELL (object);
g_clear_object (&shell->application_details_header_binding);
+ g_clear_object (&shell->button_installed_counter_binding);
+ g_clear_object (&shell->button_updates_counter_binding);
if (shell->back_entry_stack != NULL) {
g_queue_free_full (shell->back_entry_stack, (GDestroyNotify) free_back_entry);
diff --git a/src/gs-updates-page.c b/src/gs-updates-page.c
index 8ac643c1e..5f849733e 100644
--- a/src/gs-updates-page.c
+++ b/src/gs-updates-page.c
@@ -64,6 +64,7 @@ struct _GsUpdatesPage
GtkWidget *header_end_box;
gboolean has_agreed_to_mobile_data;
gboolean ampm_available;
+ guint updates_counter;
GtkWidget *updates_box;
GtkWidget *button_updates_mobile;
@@ -104,6 +105,7 @@ typedef enum {
PROP_HSCROLL_POLICY,
PROP_VSCROLL_POLICY,
PROP_TITLE,
+ PROP_COUNTER,
} GsUpdatesPageProperty;
static void
@@ -201,29 +203,18 @@ gs_updates_page_get_state_string (GsPluginStatus status)
static void
refresh_headerbar_updates_counter (GsUpdatesPage *self)
{
- GtkWidget *widget;
- guint num_updates;
-
- num_updates = _get_num_updates (self);
-
- /* update the counter */
- widget = GTK_WIDGET (gtk_builder_get_object (self->builder, "button_updates_counter"));
- if (num_updates > 0 &&
- gs_plugin_loader_get_allow_updates (self->plugin_loader)) {
- g_autofree gchar *text = NULL;
- text = g_strdup_printf ("%u", num_updates);
- gtk_label_set_label (GTK_LABEL (widget), text);
- gtk_widget_show (widget);
- } else {
- gtk_widget_hide (widget);
- }
+ guint new_updates_counter;
+
+ new_updates_counter = _get_num_updates (self);
+ if (!gs_plugin_loader_get_allow_updates (self->plugin_loader) ||
+ self->state == GS_UPDATES_PAGE_STATE_FAILED)
+ new_updates_counter = 0;
- /* update the tab style */
- if (num_updates > 0 &&
- gs_shell_get_mode (self->shell) != GS_SHELL_MODE_UPDATES)
- gtk_style_context_add_class (gtk_widget_get_style_context (widget), "needs-attention");
- else
- gtk_style_context_remove_class (gtk_widget_get_style_context (widget), "needs-attention");
+ if (new_updates_counter == self->updates_counter)
+ return;
+
+ self->updates_counter = new_updates_counter;
+ g_object_notify (G_OBJECT (self), "counter");
}
static void
@@ -430,7 +421,6 @@ gs_updates_page_get_updates_cb (GsPluginLoader *plugin_loader,
GAsyncResult *res,
GsUpdatesPage *self)
{
- GtkWidget *widget;
g_autoptr(GError) error = NULL;
g_autoptr(GsAppList) list = NULL;
@@ -445,9 +435,7 @@ gs_updates_page_get_updates_cb (GsPluginLoader *plugin_loader,
gtk_label_set_label (GTK_LABEL (self->label_updates_failed),
error->message);
gs_updates_page_set_state (self, GS_UPDATES_PAGE_STATE_FAILED);
- widget = GTK_WIDGET (gtk_builder_get_object (self->builder,
- "button_updates_counter"));
- gtk_widget_hide (widget);
+ refresh_headerbar_updates_counter (self);
return;
}
@@ -1318,6 +1306,9 @@ gs_updates_page_get_property (GObject *object,
case PROP_TITLE:
g_value_set_string (value, _("Updates"));
break;
+ case PROP_COUNTER:
+ g_value_set_uint (value, self->updates_counter);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -1347,6 +1338,7 @@ gs_updates_page_set_property (GObject *object,
g_assert_not_reached ();
break;
case PROP_TITLE:
+ case PROP_COUNTER:
/* Read only */
g_assert_not_reached ();
break;
@@ -1408,6 +1400,7 @@ gs_updates_page_class_init (GsUpdatesPageClass *klass)
g_object_class_override_property (object_class, PROP_HSCROLL_POLICY, "hscroll-policy");
g_object_class_override_property (object_class, PROP_VSCROLL_POLICY, "vscroll-policy");
g_object_class_override_property (object_class, PROP_TITLE, "title");
+ g_object_class_override_property (object_class, PROP_COUNTER, "counter");
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/Software/gs-updates-page.ui");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]