diff --git a/SOURCES/0001-info-Add-subscription-manager-integration.patch b/SOURCES/0001-info-Add-subscription-manager-integration.patch index 609a769..9474112 100644 --- a/SOURCES/0001-info-Add-subscription-manager-integration.patch +++ b/SOURCES/0001-info-Add-subscription-manager-integration.patch @@ -1,7 +1,7 @@ -From 0ce01af0e0e58d81f998093f5a8a068539f56c12 Mon Sep 17 00:00:00 2001 +From 3283b063af3f97cfc414766a42de80fc5ee43ba4 Mon Sep 17 00:00:00 2001 From: Kalev Lember Date: Fri, 28 Jun 2019 17:14:36 +0200 -Subject: [PATCH] info: Add subscription manager integration +Subject: [PATCH 1/4] info: Add subscription manager integration --- panels/info/cc-info-overview-panel.c | 157 ++++- @@ -27,7 +27,30 @@ diff --git a/panels/info/cc-info-overview-panel.c b/panels/info/cc-info-overview index 2256b730c..1467060f9 100644 --- a/panels/info/cc-info-overview-panel.c +++ b/panels/info/cc-info-overview-panel.c -@@ -24,6 +24,8 @@ +@@ -1,118 +1,126 @@ + /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2017 Mohammed Sadiq + * Copyright (C) 2010 Red Hat, Inc + * Copyright (C) 2008 William Jon McCann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + + #include + #include "shell/cc-hostname-entry.h" #include "cc-info-resources.h" @@ -36,7 +59,44 @@ index 2256b730c..1467060f9 100644 #include "info-cleanup.h" #include -@@ -68,6 +70,10 @@ typedef struct + #include + #include + #include + #include + + #include + #include + #include + #include + + #include + + #ifdef GDK_WINDOWING_WAYLAND + #include + #endif + #ifdef GDK_WINDOWING_X11 + #include + #endif + + #include "gsd-disk-space-helper.h" + + #include "cc-info-overview-panel.h" + + + typedef struct { + /* Will be one or 2 GPU name strings, or "Unknown" */ + char *hardware_string; + } GraphicsData; + + typedef struct + { + GtkWidget *system_image; + GtkWidget *version_label; + GtkWidget *name_entry; + GtkWidget *memory_label; + GtkWidget *processor_label; + GtkWidget *os_name_label; + GtkWidget *os_type_label; GtkWidget *disk_label; GtkWidget *graphics_label; GtkWidget *virt_type_label; @@ -47,7 +107,18 @@ index 2256b730c..1467060f9 100644 GtkWidget *updates_button; /* Virtualisation labels */ -@@ -86,6 +92,8 @@ typedef struct + GtkWidget *label8; + GtkWidget *grid1; + GtkWidget *label18; + + char *gnome_version; + char *gnome_distributor; + char *gnome_date; + + GCancellable *cancellable; + + /* Free space */ + GList *primary_mounts; guint64 total_bytes; GraphicsData *graphics_data; @@ -56,7 +127,61 @@ index 2256b730c..1467060f9 100644 } CcInfoOverviewPanelPrivate; struct _CcInfoOverviewPanel -@@ -586,7 +594,6 @@ get_primary_disc_info (CcInfoOverviewPanel *self) + { + CcPanel parent_instance; + + /*< private >*/ + CcInfoOverviewPanelPrivate *priv; + }; + + static void get_primary_disc_info_start (CcInfoOverviewPanel *self); + + typedef struct + { + char *major; + char *minor; + char *micro; + char *distributor; + char *date; + char **current; + } VersionData; + + static void + version_data_free (VersionData *data) + { + g_free (data->major); + g_free (data->minor); + g_free (data->micro); + g_free (data->distributor); + g_free (data->date); +@@ -559,61 +567,60 @@ get_primary_disc_info (CcInfoOverviewPanel *self) + points = g_unix_mounts_get (NULL); + + for (p = points; p != NULL; p = p->next) + { + GUnixMountEntry *mount = p->data; + const char *mount_path; + const char *device_path; + + mount_path = g_unix_mount_get_mount_path (mount); + device_path = g_unix_mount_get_device_path (mount); + + /* Do not count multiple mounts with same device_path, because it is + * probably something like btrfs subvolume. Use only the first one in + * order to count the real size. */ + if (gsd_should_ignore_unix_mount (mount) || + gsd_is_removable_mount (mount) || + g_str_has_prefix (mount_path, "/media/") || + g_str_has_prefix (mount_path, g_get_home_dir ()) || + g_hash_table_lookup (hash, device_path) != NULL) + { + g_unix_mount_free (mount); + continue; + } + + priv->primary_mounts = g_list_prepend (priv->primary_mounts, mount); + g_hash_table_insert (hash, (gpointer) device_path, (gpointer) device_path); + } g_list_free (points); g_hash_table_destroy (hash); @@ -64,7 +189,61 @@ index 2256b730c..1467060f9 100644 get_primary_disc_info_start (self); } -@@ -793,6 +800,137 @@ info_overview_panel_setup_overview (CcInfoOverviewPanel *self) + static char * + get_cpu_info (const glibtop_sysinfo *info) + { + g_autoptr(GHashTable) counts = NULL; + g_autoptr(GString) cpu = NULL; + GHashTableIter iter; + gpointer key, value; + int i; + int j; + + counts = g_hash_table_new (g_str_hash, g_str_equal); + + /* count duplicates */ + for (i = 0; i != info->ncpu; ++i) + { + const char * const keys[] = { "model name", "cpu", "Processor" }; + char *model; + int *count; + + model = NULL; + + for (j = 0; model == NULL && j != G_N_ELEMENTS (keys); ++j) + { + model = g_hash_table_lookup (info->cpuinfo[i].values, + keys[j]); + } + +@@ -766,60 +773,191 @@ info_overview_panel_setup_overview (CcInfoOverviewPanel *self) + res = load_gnome_version (&priv->gnome_version, + &priv->gnome_distributor, + &priv->gnome_date); + if (res) + { + g_autofree gchar *text = NULL; + text = g_strdup_printf (_("Version %s"), priv->gnome_version); + gtk_label_set_text (GTK_LABEL (priv->version_label), text); + } + + glibtop_get_mem (&mem); + memory_text = g_format_size_full (mem.total, G_FORMAT_SIZE_IEC_UNITS); + gtk_label_set_text (GTK_LABEL (priv->memory_label), memory_text ? memory_text : ""); + + info = glibtop_get_sysinfo (); + + cpu_text = get_cpu_info (info); + gtk_label_set_markup (GTK_LABEL (priv->processor_label), cpu_text ? cpu_text : ""); + + os_type_text = get_os_type (); + gtk_label_set_text (GTK_LABEL (priv->os_type_label), os_type_text ? os_type_text : ""); + + os_name_text = get_os_name (); + gtk_label_set_text (GTK_LABEL (priv->os_name_label), os_name_text ? os_name_text : ""); + + get_primary_disc_info (self); + gtk_label_set_markup (GTK_LABEL (priv->graphics_label), priv->graphics_data->hardware_string); } @@ -202,7 +381,61 @@ index 2256b730c..1467060f9 100644 static gboolean does_gnome_software_exist (void) { -@@ -856,6 +994,8 @@ cc_info_overview_panel_finalize (GObject *object) + return g_file_test (BINDIR "/gnome-software", G_FILE_TEST_EXISTS); + } + + static gboolean + does_gpk_update_viewer_exist (void) + { + return g_file_test (BINDIR "/gpk-update-viewer", G_FILE_TEST_EXISTS); + } + + static void + on_updates_button_clicked (GtkWidget *widget, + CcInfoOverviewPanel *self) + { + g_autoptr(GError) error = NULL; + gboolean ret; + g_auto(GStrv) argv = NULL; + + argv = g_new0 (gchar *, 3); + if (does_gnome_software_exist ()) + { + argv[0] = g_build_filename (BINDIR, "gnome-software", NULL); + argv[1] = g_strdup_printf ("--mode=updates"); + } + else + { + argv[0] = g_build_filename (BINDIR, "gpk-update-viewer", NULL); + } +@@ -829,88 +967,103 @@ on_updates_button_clicked (GtkWidget *widget, + } + + static void + cc_info_overview_panel_dispose (GObject *object) + { + CcInfoOverviewPanelPrivate *priv = cc_info_overview_panel_get_instance_private (CC_INFO_OVERVIEW_PANEL (object)); + + g_clear_pointer (&priv->graphics_data, graphics_data_free); + + G_OBJECT_CLASS (cc_info_overview_panel_parent_class)->dispose (object); + } + + static void + cc_info_overview_panel_finalize (GObject *object) + { + CcInfoOverviewPanelPrivate *priv = cc_info_overview_panel_get_instance_private (CC_INFO_OVERVIEW_PANEL (object)); + + if (priv->cancellable) + { + g_cancellable_cancel (priv->cancellable); + g_clear_object (&priv->cancellable); + } + + if (priv->primary_mounts) + g_list_free_full (priv->primary_mounts, (GDestroyNotify) g_unix_mount_free); + + g_free (priv->gnome_version); g_free (priv->gnome_date); g_free (priv->gnome_distributor); @@ -211,7 +444,24 @@ index 2256b730c..1467060f9 100644 G_OBJECT_CLASS (cc_info_overview_panel_parent_class)->finalize (object); } -@@ -880,6 +1020,10 @@ cc_info_overview_panel_class_init (CcInfoOverviewPanelClass *klass) + static void + cc_info_overview_panel_class_init (CcInfoOverviewPanelClass *klass) + { + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->finalize = cc_info_overview_panel_finalize; + object_class->dispose = cc_info_overview_panel_dispose; + + gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/info/info-overview.ui"); + + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, system_image); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, version_label); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, name_entry); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, memory_label); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, processor_label); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, os_name_label); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, os_type_label); gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, disk_label); gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, graphics_label); gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, virt_type_label); @@ -222,7 +472,17 @@ index 2256b730c..1467060f9 100644 gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, updates_button); gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, label8); gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, grid1); -@@ -897,15 +1041,24 @@ cc_info_overview_panel_init (CcInfoOverviewPanel *self) + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, label18); + + g_type_ensure (CC_TYPE_HOSTNAME_ENTRY); + } + + static void + cc_info_overview_panel_init (CcInfoOverviewPanel *self) + { + CcInfoOverviewPanelPrivate *priv = cc_info_overview_panel_get_instance_private (self); + + gtk_widget_init_template (GTK_WIDGET (self)); g_resources_register (cc_info_get_resource ()); @@ -248,6 +508,11 @@ index 2256b730c..1467060f9 100644 } GtkWidget * + cc_info_overview_panel_new (void) + { + return g_object_new (CC_TYPE_INFO_OVERVIEW_PANEL, + NULL); + } diff --git a/panels/info/cc-subscription-details-dialog.c b/panels/info/cc-subscription-details-dialog.c new file mode 100644 index 000000000..1931ced81 @@ -2033,7 +2298,10 @@ diff --git a/panels/info/info-overview.ui b/panels/info/info-overview.ui index aa87fbec2..e33ba399a 100644 --- a/panels/info/info-overview.ui +++ b/panels/info/info-overview.ui -@@ -4,16 +4,17 @@ +@@ -1,46 +1,47 @@ + + + + diff --git a/panels/info/info.gresource.xml b/panels/info/info.gresource.xml index c96722350..15d18daac 100644 --- a/panels/info/info.gresource.xml +++ b/panels/info/info.gresource.xml -@@ -4,6 +4,8 @@ +@@ -1,9 +1,11 @@ + + + info-overview.ui info-default-apps.ui info-removable-media.ui @@ -2222,7 +2558,34 @@ diff --git a/panels/info/meson.build b/panels/info/meson.build index 13015b96c..a4ff83a42 100644 --- a/panels/info/meson.build +++ b/panels/info/meson.build -@@ -41,11 +41,15 @@ sources = files(gsd_sources) + files( +@@ -14,65 +14,69 @@ foreach name: panel_names + output: desktop + '.in', + configuration: desktop_conf + ) + + i18n.merge_file( + desktop, + type: 'desktop', + input: desktop_in, + output: desktop, + po_dir: po_dir, + install: true, + install_dir: control_center_desktopdir + ) + endforeach + + cflags += [ + '-DBINDIR="@0@"'.format(control_center_bindir), + '-DDATADIR="@0@"'.format(control_center_datadir), + '-DGNOME_SESSION_DIR="@0@"'.format(gnome_session_libexecdir), + '-DGNOMELOCALEDIR="@0@"'.format(control_center_localedir) + ] + + gsd_headers = ['gsd-disk-space-helper.h'] + + gsd_sources = ['gsd-disk-space-helper.c'] + + sources = files(gsd_sources) + files( 'cc-info-default-apps-panel.c', 'cc-info-overview-panel.c', 'cc-info-removable-media-panel.c', @@ -2238,11 +2601,65 @@ index 13015b96c..a4ff83a42 100644 'info-default-apps.ui', 'info-overview.ui', 'info-removable-media.ui' + ) + + sources += gnome.compile_resources( + 'cc-' + cappletname + '-resources', + cappletname + '.gresource.xml', + c_name: 'cc_' + cappletname, + dependencies: resource_data, + export: true + ) + + deps = common_deps + [ + polkit_gobject_dep, + dependency('libgtop-2.0') + ] + + panels_libs += static_library( + cappletname, + sources: sources, + include_directories: top_inc, + dependencies: deps, + c_args: cflags + ) + + test_name = 'test-info-cleanup' + + sources = files( + 'info-cleanup.c', diff --git a/po/POTFILES.in b/po/POTFILES.in index dfd8ccff0..6cb8938e9 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in -@@ -34,6 +34,10 @@ panels/display/display.ui +@@ -7,60 +7,64 @@ panels/background/cc-background-item.c + panels/background/cc-background-panel.c + panels/background/gnome-background-panel.desktop.in.in + panels/bluetooth/bluetooth.ui + panels/bluetooth/cc-bluetooth-panel.c + panels/bluetooth/gnome-bluetooth-panel.desktop.in.in + panels/color/cc-color-calibrate.c + panels/color/cc-color-common.c + panels/color/cc-color-device.c + panels/color/cc-color-panel.c + panels/color/cc-color-profile.c + panels/color/color-calibrate.ui + panels/color/color.ui + panels/color/gnome-color-panel.desktop.in.in + panels/common/cc-common-language.c + panels/common/cc-language-chooser.c + panels/common/cc-util.c + panels/common/language-chooser.ui + panels/datetime/big.ui + panels/datetime/cc-datetime-panel.c + panels/datetime/datetime.ui + panels/datetime/gnome-datetime-panel.desktop.in.in + panels/datetime/little.ui + panels/datetime/middle.ui + panels/datetime/org.gnome.controlcenter.datetime.policy.in + panels/datetime/ydm.ui + panels/display/cc-display-panel.c + panels/display/display.ui panels/display/gnome-display-panel.desktop.in.in panels/info/cc-info-overview-panel.c panels/info/cc-info-removable-media-panel.c @@ -2253,6 +2670,33 @@ index dfd8ccff0..6cb8938e9 100644 panels/info/gnome-default-apps-panel.desktop.in.in panels/info/gnome-info-overview-panel.desktop.in.in panels/info/gnome-removable-media-panel.desktop.in.in + panels/info/info-default-apps.ui + panels/info/info-overview.ui + panels/info/info-removable-media.ui + panels/keyboard/00-multimedia.xml.in + panels/keyboard/01-input-sources.xml.in + panels/keyboard/01-launchers.xml.in + panels/keyboard/01-screenshot.xml.in + panels/keyboard/01-system.xml.in + panels/keyboard/50-accessibility.xml.in + panels/keyboard/cc-keyboard-manager.c + panels/keyboard/cc-keyboard-option.c + panels/keyboard/cc-keyboard-panel.c + panels/keyboard/cc-keyboard-shortcut-editor.c + panels/keyboard/gnome-keyboard-panel.desktop.in.in + panels/keyboard/gnome-keyboard-panel.ui + panels/keyboard/keyboard-shortcuts.c + panels/keyboard/shortcut-editor.ui + panels/mouse/cc-mouse-panel.c + panels/mouse/gnome-mouse-panel.desktop.in.in + panels/mouse/gnome-mouse-properties.c + panels/mouse/gnome-mouse-properties.ui + panels/mouse/gnome-mouse-test.c + panels/mouse/gnome-mouse-test.ui + panels/network/cc-network-panel.c + panels/network/cc-wifi-panel.c + panels/network/connection-editor/8021x-security-page.ui + panels/network/connection-editor/ce-page-8021x-security.c -- -2.21.0 +2.28.0 diff --git a/SOURCES/0002-info-Move-helper-for-getting-subscription-status-to-.patch b/SOURCES/0002-info-Move-helper-for-getting-subscription-status-to-.patch new file mode 100644 index 0000000..94acfd9 --- /dev/null +++ b/SOURCES/0002-info-Move-helper-for-getting-subscription-status-to-.patch @@ -0,0 +1,228 @@ +From 2025db03559f4ca8872045618cac75cfb2fe10f1 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Sun, 24 Jan 2021 10:29:56 -0500 +Subject: [PATCH 2/4] info: Move helper for getting subscription status to + header + +In the future we're going to need to be able to get the subscription +status in two files, so move the function for getting that status +to a common header. + +Ideally we'd be using code generation for the subscription proxy +instead, but that's a bigger refactor that will have to wait for +another day. +--- + panels/info/cc-info-overview-panel.c | 32 ++------------------------ + panels/info/cc-subscription-common.h | 34 ++++++++++++++++++++++++++++ + 2 files changed, 36 insertions(+), 30 deletions(-) + create mode 100644 panels/info/cc-subscription-common.h + +diff --git a/panels/info/cc-info-overview-panel.c b/panels/info/cc-info-overview-panel.c +index 1467060f9..b2cbefb25 100644 +--- a/panels/info/cc-info-overview-panel.c ++++ b/panels/info/cc-info-overview-panel.c +@@ -1,56 +1,57 @@ + /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2017 Mohammed Sadiq + * Copyright (C) 2010 Red Hat, Inc + * Copyright (C) 2008 William Jon McCann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + + #include + + #include "shell/cc-hostname-entry.h" + + #include "cc-info-resources.h" ++#include "cc-subscription-common.h" + #include "cc-subscription-details-dialog.h" + #include "cc-subscription-register-dialog.h" + #include "info-cleanup.h" + + #include + #include + #include + #include + #include + + #include + #include + #include + #include + + #include + + #ifdef GDK_WINDOWING_WAYLAND + #include + #endif + #ifdef GDK_WINDOWING_X11 + #include + #endif + + #include "gsd-disk-space-helper.h" + + #include "cc-info-overview-panel.h" + + + typedef struct { +@@ -773,102 +774,73 @@ info_overview_panel_setup_overview (CcInfoOverviewPanel *self) + res = load_gnome_version (&priv->gnome_version, + &priv->gnome_distributor, + &priv->gnome_date); + if (res) + { + g_autofree gchar *text = NULL; + text = g_strdup_printf (_("Version %s"), priv->gnome_version); + gtk_label_set_text (GTK_LABEL (priv->version_label), text); + } + + glibtop_get_mem (&mem); + memory_text = g_format_size_full (mem.total, G_FORMAT_SIZE_IEC_UNITS); + gtk_label_set_text (GTK_LABEL (priv->memory_label), memory_text ? memory_text : ""); + + info = glibtop_get_sysinfo (); + + cpu_text = get_cpu_info (info); + gtk_label_set_markup (GTK_LABEL (priv->processor_label), cpu_text ? cpu_text : ""); + + os_type_text = get_os_type (); + gtk_label_set_text (GTK_LABEL (priv->os_type_label), os_type_text ? os_type_text : ""); + + os_name_text = get_os_name (); + gtk_label_set_text (GTK_LABEL (priv->os_name_label), os_name_text ? os_name_text : ""); + + get_primary_disc_info (self); + + gtk_label_set_markup (GTK_LABEL (priv->graphics_label), priv->graphics_data->hardware_string); + } + +-typedef enum { +- GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN, +- GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID, +- GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID, +- GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED, +- GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID, +- GSD_SUBMAN_SUBSCRIPTION_STATUS_LAST +-} GsdSubmanSubscriptionStatus; +- +-static gboolean +-get_subscription_status (CcInfoOverviewPanel *self, GsdSubmanSubscriptionStatus *status) +-{ +- CcInfoOverviewPanelPrivate *priv = cc_info_overview_panel_get_instance_private (self); +- g_autoptr(GVariant) status_variant = NULL; +- guint32 u; +- +- status_variant = g_dbus_proxy_get_cached_property (priv->subscription_proxy, "SubscriptionStatus"); +- if (!status_variant) +- { +- g_debug ("Unable to get SubscriptionStatus property"); +- return FALSE; +- } +- +- g_variant_get (status_variant, "u", &u); +- *status = u; +- +- return TRUE; +-} +- + static void + reload_subscription_status (CcInfoOverviewPanel *self) + { + CcInfoOverviewPanelPrivate *priv = cc_info_overview_panel_get_instance_private (self); + GsdSubmanSubscriptionStatus status; + + if (priv->subscription_proxy == NULL) + { + gtk_widget_hide (priv->subscription_stack); + return; + } + +- if (!get_subscription_status (self, &status)) ++ if (!get_subscription_status (priv->subscription_proxy, &status)) + { + gtk_widget_hide (priv->subscription_stack); + return; + } + + switch (status) + { + case GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN: + case GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID: + case GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED: + case GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID: + gtk_stack_set_visible_child_name (GTK_STACK (priv->subscription_stack), "not-registered"); + gtk_widget_set_sensitive (priv->updates_button, FALSE); + break; + + case GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID: + gtk_stack_set_visible_child_name (GTK_STACK (priv->subscription_stack), "registered"); + gtk_widget_set_sensitive (priv->updates_button, TRUE); + break; + + default: + g_assert_not_reached (); + break; + } + } + + static void + on_details_button_clicked (GtkWidget *widget, + CcInfoOverviewPanel *self) + { +diff --git a/panels/info/cc-subscription-common.h b/panels/info/cc-subscription-common.h +new file mode 100644 +index 000000000..034d64181 +--- /dev/null ++++ b/panels/info/cc-subscription-common.h +@@ -0,0 +1,34 @@ ++#ifndef CC_SUBSCRIPTION_COMMON_H ++#define CC_SUBSCRIPTION_COMMON_H ++ ++typedef enum { ++ GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN, ++ GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID, ++ GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID, ++ GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED, ++ GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID, ++ GSD_SUBMAN_SUBSCRIPTION_STATUS_NO_INSTALLED_PRODUCTS, ++ GSD_SUBMAN_SUBSCRIPTION_STATUS_LAST ++} GsdSubmanSubscriptionStatus; ++ ++static inline gboolean ++get_subscription_status (GDBusProxy *subscription_proxy, ++ GsdSubmanSubscriptionStatus *status) ++{ ++ g_autoptr(GVariant) status_variant = NULL; ++ guint32 u; ++ ++ status_variant = g_dbus_proxy_get_cached_property (subscription_proxy, "SubscriptionStatus"); ++ if (!status_variant) ++ { ++ g_debug ("Unable to get SubscriptionStatus property"); ++ return FALSE; ++ } ++ ++ g_variant_get (status_variant, "u", &u); ++ *status = u; ++ ++ return TRUE; ++} ++ ++#endif +-- +2.28.0 + diff --git a/SOURCES/0003-info-Update-registration-state-in-panel-when-it-happ.patch b/SOURCES/0003-info-Update-registration-state-in-panel-when-it-happ.patch new file mode 100644 index 0000000..bedb0f7 --- /dev/null +++ b/SOURCES/0003-info-Update-registration-state-in-panel-when-it-happ.patch @@ -0,0 +1,654 @@ +From 8bd1e37f59f3b4ec617d6d0bccf7fd77a9d03ca5 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Sun, 24 Jan 2021 13:03:03 -0500 +Subject: [PATCH 3/4] info: Update registration state in panel when it happens + on disk + +The code was failing to listen for change notifications, so if the +panel was open while the system got registered, it wouldn't update. + +This commit fixes that. +--- + panels/info/cc-info-overview-panel.c | 33 ++++++++++++++++--- + panels/info/cc-subscription-details-dialog.c | 17 ++++++++-- + panels/info/cc-subscription-details-dialog.h | 3 +- + panels/info/cc-subscription-register-dialog.c | 17 ++++++++-- + panels/info/cc-subscription-register-dialog.h | 3 +- + 5 files changed, 63 insertions(+), 10 deletions(-) + +diff --git a/panels/info/cc-info-overview-panel.c b/panels/info/cc-info-overview-panel.c +index b2cbefb25..65246758e 100644 +--- a/panels/info/cc-info-overview-panel.c ++++ b/panels/info/cc-info-overview-panel.c +@@ -60,60 +60,61 @@ typedef struct { + } GraphicsData; + + typedef struct + { + GtkWidget *system_image; + GtkWidget *version_label; + GtkWidget *name_entry; + GtkWidget *memory_label; + GtkWidget *processor_label; + GtkWidget *os_name_label; + GtkWidget *os_type_label; + GtkWidget *disk_label; + GtkWidget *graphics_label; + GtkWidget *virt_type_label; + GtkWidget *subscription_stack; + GtkWidget *details_button; + GtkWidget *register_button; + GtkWidget *updates_separator; + GtkWidget *updates_button; + + /* Virtualisation labels */ + GtkWidget *label8; + GtkWidget *grid1; + GtkWidget *label18; + + char *gnome_version; + char *gnome_distributor; + char *gnome_date; + + GCancellable *cancellable; ++ GCancellable *subscription_cancellable; + + /* Free space */ + GList *primary_mounts; + guint64 total_bytes; + + GraphicsData *graphics_data; + + GDBusProxy *subscription_proxy; + } CcInfoOverviewPanelPrivate; + + struct _CcInfoOverviewPanel + { + CcPanel parent_instance; + + /*< private >*/ + CcInfoOverviewPanelPrivate *priv; + }; + + static void get_primary_disc_info_start (CcInfoOverviewPanel *self); + + typedef struct + { + char *major; + char *minor; + char *micro; + char *distributor; + char *date; + char **current; + } VersionData; + +@@ -821,165 +822,188 @@ reload_subscription_status (CcInfoOverviewPanel *self) + + switch (status) + { + case GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN: + case GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID: + case GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED: + case GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID: + gtk_stack_set_visible_child_name (GTK_STACK (priv->subscription_stack), "not-registered"); + gtk_widget_set_sensitive (priv->updates_button, FALSE); + break; + + case GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID: + gtk_stack_set_visible_child_name (GTK_STACK (priv->subscription_stack), "registered"); + gtk_widget_set_sensitive (priv->updates_button, TRUE); + break; + + default: + g_assert_not_reached (); + break; + } + } + + static void + on_details_button_clicked (GtkWidget *widget, + CcInfoOverviewPanel *self) + { + CcInfoOverviewPanelPrivate *priv = cc_info_overview_panel_get_instance_private (self); + CcSubscriptionDetailsDialog *dialog; + GtkWindow *toplevel; + +- dialog = cc_subscription_details_dialog_new (priv->subscription_proxy); ++ dialog = cc_subscription_details_dialog_new (priv->subscription_proxy, ++ priv->subscription_cancellable); + toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self))); + gtk_window_set_transient_for (GTK_WINDOW (dialog), toplevel); + + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (GTK_WIDGET (dialog)); +- +- reload_subscription_status (self); + } + + static void + on_register_button_clicked (GtkWidget *widget, + CcInfoOverviewPanel *self) + { + CcInfoOverviewPanelPrivate *priv = cc_info_overview_panel_get_instance_private (self); + CcSubscriptionRegisterDialog *dialog; + GtkWindow *toplevel; + +- dialog = cc_subscription_register_dialog_new (priv->subscription_proxy); ++ dialog = cc_subscription_register_dialog_new (priv->subscription_proxy, ++ priv->subscription_cancellable); + toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self))); + gtk_window_set_transient_for (GTK_WINDOW (dialog), toplevel); + + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (GTK_WIDGET (dialog)); ++} ++ ++static void ++on_subscription_status_changed (GDBusProxy *proxy, ++ GVariant *changed_properties, ++ GStrv invalidated_properties, ++ CcInfoOverviewPanel *self) ++{ ++ CcInfoOverviewPanelPrivate *priv = cc_info_overview_panel_get_instance_private (self); ++ ++ g_cancellable_cancel (priv->subscription_cancellable); ++ g_object_unref (priv->subscription_cancellable); ++ ++ priv->subscription_cancellable = g_cancellable_new (); + + reload_subscription_status (self); + } + + static void + info_overview_panel_setup_subscriptions (CcInfoOverviewPanel *self) + { + CcInfoOverviewPanelPrivate *priv = cc_info_overview_panel_get_instance_private (self); + g_autoptr(GError) error = NULL; + + priv->subscription_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.gnome.SettingsDaemon.Subscription", + "/org/gnome/SettingsDaemon/Subscription", + "org.gnome.SettingsDaemon.Subscription", + NULL, &error); + if (error != NULL) + { + g_debug ("Unable to create a proxy for org.gnome.SettingsDaemon.Subscription: %s", + error->message); + reload_subscription_status (self); + return; + } + ++ g_signal_connect (priv->subscription_proxy, "g-properties-changed", ++ G_CALLBACK (on_subscription_status_changed), self); ++ + g_signal_connect (priv->details_button, "clicked", G_CALLBACK (on_details_button_clicked), self); + g_signal_connect (priv->register_button, "clicked", G_CALLBACK (on_register_button_clicked), self); + + reload_subscription_status (self); + } + + static gboolean + does_gnome_software_exist (void) + { + return g_file_test (BINDIR "/gnome-software", G_FILE_TEST_EXISTS); + } + + static gboolean + does_gpk_update_viewer_exist (void) + { + return g_file_test (BINDIR "/gpk-update-viewer", G_FILE_TEST_EXISTS); + } + + static void + on_updates_button_clicked (GtkWidget *widget, + CcInfoOverviewPanel *self) + { + g_autoptr(GError) error = NULL; + gboolean ret; + g_auto(GStrv) argv = NULL; + + argv = g_new0 (gchar *, 3); + if (does_gnome_software_exist ()) + { + argv[0] = g_build_filename (BINDIR, "gnome-software", NULL); + argv[1] = g_strdup_printf ("--mode=updates"); + } + else + { + argv[0] = g_build_filename (BINDIR, "gpk-update-viewer", NULL); + } + ret = g_spawn_async (NULL, argv, NULL, 0, NULL, NULL, NULL, &error); + if (!ret) + g_warning ("Failed to spawn %s: %s", argv[0], error->message); + } + + static void + cc_info_overview_panel_dispose (GObject *object) + { + CcInfoOverviewPanelPrivate *priv = cc_info_overview_panel_get_instance_private (CC_INFO_OVERVIEW_PANEL (object)); + + g_clear_pointer (&priv->graphics_data, graphics_data_free); + + G_OBJECT_CLASS (cc_info_overview_panel_parent_class)->dispose (object); + } + + static void + cc_info_overview_panel_finalize (GObject *object) + { + CcInfoOverviewPanelPrivate *priv = cc_info_overview_panel_get_instance_private (CC_INFO_OVERVIEW_PANEL (object)); + ++ if (priv->subscription_cancellable) ++ { ++ g_cancellable_cancel (priv->subscription_cancellable); ++ g_clear_object (&priv->subscription_cancellable); ++ } ++ + if (priv->cancellable) + { + g_cancellable_cancel (priv->cancellable); + g_clear_object (&priv->cancellable); + } + + if (priv->primary_mounts) + g_list_free_full (priv->primary_mounts, (GDestroyNotify) g_unix_mount_free); + + g_free (priv->gnome_version); + g_free (priv->gnome_date); + g_free (priv->gnome_distributor); + + g_clear_object (&priv->subscription_proxy); + + G_OBJECT_CLASS (cc_info_overview_panel_parent_class)->finalize (object); + } + + static void + cc_info_overview_panel_class_init (CcInfoOverviewPanelClass *klass) + { + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->finalize = cc_info_overview_panel_finalize; + object_class->dispose = cc_info_overview_panel_dispose; + + gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/info/info-overview.ui"); + + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, system_image); +@@ -987,55 +1011,56 @@ cc_info_overview_panel_class_init (CcInfoOverviewPanelClass *klass) + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, name_entry); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, memory_label); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, processor_label); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, os_name_label); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, os_type_label); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, disk_label); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, graphics_label); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, virt_type_label); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, subscription_stack); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, details_button); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, register_button); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, updates_separator); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, updates_button); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, label8); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, grid1); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, label18); + + g_type_ensure (CC_TYPE_HOSTNAME_ENTRY); + } + + static void + cc_info_overview_panel_init (CcInfoOverviewPanel *self) + { + CcInfoOverviewPanelPrivate *priv = cc_info_overview_panel_get_instance_private (self); + + gtk_widget_init_template (GTK_WIDGET (self)); + + g_resources_register (cc_info_get_resource ()); + + priv->cancellable = g_cancellable_new (); ++ priv->subscription_cancellable = g_cancellable_new (); + + priv->graphics_data = get_graphics_data (); + + if (does_gnome_software_exist () || does_gpk_update_viewer_exist ()) + g_signal_connect (priv->updates_button, "clicked", G_CALLBACK (on_updates_button_clicked), self); + else + gtk_widget_hide (priv->updates_button); + + info_overview_panel_setup_overview (self); + info_overview_panel_setup_virt (self); + info_overview_panel_setup_subscriptions (self); + + /* show separator when both items are visible */ + if (gtk_widget_get_visible (priv->subscription_stack) && gtk_widget_get_visible (priv->updates_button)) + gtk_widget_show (priv->updates_separator); + else + gtk_widget_hide (priv->updates_separator); + } + + GtkWidget * + cc_info_overview_panel_new (void) + { + return g_object_new (CC_TYPE_INFO_OVERVIEW_PANEL, + NULL); + } +diff --git a/panels/info/cc-subscription-details-dialog.c b/panels/info/cc-subscription-details-dialog.c +index 1931ced81..3d77e6c48 100644 +--- a/panels/info/cc-subscription-details-dialog.c ++++ b/panels/info/cc-subscription-details-dialog.c +@@ -311,97 +311,110 @@ header_unregister_button_clicked_cb (CcSubscriptionDetailsDialog *self) + self); + } + + static void + back_button_clicked_cb (CcSubscriptionDetailsDialog *self) + { + gtk_spinner_stop (self->spinner); + + self->state = DIALOG_STATE_SHOW_DETAILS; + dialog_reload (self); + } + + static void + unregister_button_clicked_cb (CcSubscriptionDetailsDialog *self) + { + self->state = DIALOG_STATE_UNREGISTER; + dialog_reload (self); + } + + static void + dismiss_notification (CcSubscriptionDetailsDialog *self) + { + gtk_revealer_set_reveal_child (self->notification_revealer, FALSE); + } + + static void + cc_subscription_details_dialog_init (CcSubscriptionDetailsDialog *self) + { + gtk_widget_init_template (GTK_WIDGET (self)); + +- self->cancellable = g_cancellable_new (); + self->products = g_ptr_array_new_with_free_func ((GDestroyNotify) product_data_free); + self->state = DIALOG_STATE_SHOW_DETAILS; + } + + static void + cc_subscription_details_dialog_dispose (GObject *obj) + { + CcSubscriptionDetailsDialog *self = (CcSubscriptionDetailsDialog *) obj; + + g_cancellable_cancel (self->cancellable); + g_clear_object (&self->cancellable); + g_clear_object (&self->subscription_proxy); + + G_OBJECT_CLASS (cc_subscription_details_dialog_parent_class)->dispose (obj); + } + + static void + cc_subscription_details_dialog_finalize (GObject *obj) + { + CcSubscriptionDetailsDialog *self = (CcSubscriptionDetailsDialog *) obj; + + g_clear_pointer (&self->products, g_ptr_array_unref); + + G_OBJECT_CLASS (cc_subscription_details_dialog_parent_class)->finalize (obj); + } + + static void + cc_subscription_details_dialog_class_init (CcSubscriptionDetailsDialogClass *klass) + { + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->dispose = cc_subscription_details_dialog_dispose; + object_class->finalize = cc_subscription_details_dialog_finalize; + + gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/info/cc-subscription-details-dialog.ui"); + + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, back_button); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, spinner); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, header_unregister_button); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, notification_revealer); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, error_label); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, stack); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, products_box1); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, products_box2); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, unregister_button); + + gtk_widget_class_bind_template_callback (widget_class, back_button_clicked_cb); + gtk_widget_class_bind_template_callback (widget_class, header_unregister_button_clicked_cb); + gtk_widget_class_bind_template_callback (widget_class, unregister_button_clicked_cb); + gtk_widget_class_bind_template_callback (widget_class, dismiss_notification); + } + ++static void ++on_dialog_cancelled (CcSubscriptionDetailsDialog *self) ++{ ++ gtk_dialog_response (GTK_DIALOG (self), GTK_RESPONSE_CLOSE); ++} ++ + CcSubscriptionDetailsDialog * +-cc_subscription_details_dialog_new (GDBusProxy *subscription_proxy) ++cc_subscription_details_dialog_new (GDBusProxy *subscription_proxy, ++ GCancellable *cancellable) + { + CcSubscriptionDetailsDialog *self; + + self = g_object_new (CC_TYPE_SUBSCRIPTION_DETAILS_DIALOG, "use-header-bar", TRUE, NULL); + self->subscription_proxy = g_object_ref (subscription_proxy); ++ self->cancellable = g_object_ref (cancellable); ++ ++ g_signal_connect_object (G_OBJECT (self->cancellable), ++ "cancelled", ++ G_CALLBACK (on_dialog_cancelled), ++ self, ++ G_CONNECT_SWAPPED); + + load_installed_products (self); + dialog_reload (self); + + return self; + } +diff --git a/panels/info/cc-subscription-details-dialog.h b/panels/info/cc-subscription-details-dialog.h +index a61a22838..f14dd157b 100644 +--- a/panels/info/cc-subscription-details-dialog.h ++++ b/panels/info/cc-subscription-details-dialog.h +@@ -1,32 +1,33 @@ + /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright 2019 Red Hat, Inc, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Written by: Kalev Lember + */ + + #pragma once + + #include + + G_BEGIN_DECLS + + #define CC_TYPE_SUBSCRIPTION_DETAILS_DIALOG (cc_subscription_details_dialog_get_type ()) + G_DECLARE_FINAL_TYPE (CcSubscriptionDetailsDialog, cc_subscription_details_dialog, CC, SUBSCRIPTION_DETAILS_DIALOG, GtkDialog) + +-CcSubscriptionDetailsDialog *cc_subscription_details_dialog_new (GDBusProxy *subscription_proxy); ++CcSubscriptionDetailsDialog *cc_subscription_details_dialog_new (GDBusProxy *subscription_proxy, ++ GCancellable *cancellable); + + G_END_DECLS +diff --git a/panels/info/cc-subscription-register-dialog.c b/panels/info/cc-subscription-register-dialog.c +index d7a17cc99..e8c2f581c 100644 +--- a/panels/info/cc-subscription-register-dialog.c ++++ b/panels/info/cc-subscription-register-dialog.c +@@ -299,61 +299,60 @@ subscription_register_with_username (CcSubscriptionRegisterDialog *self) + self->cancellable, + registration_done_cb, + self); + } + + static void + register_button_clicked_cb (CcSubscriptionRegisterDialog *self) + { + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->register_with_activation_keys_radio))) + subscription_register_with_activation_keys (self); + else + subscription_register_with_username (self); + + gtk_spinner_start (self->spinner); + + self->state = DIALOG_STATE_REGISTERING; + dialog_reload (self); + } + + static void + dismiss_notification (CcSubscriptionRegisterDialog *self) + { + gtk_revealer_set_reveal_child (self->notification_revealer, FALSE); + } + + static void + cc_subscription_register_dialog_init (CcSubscriptionRegisterDialog *self) + { + gtk_widget_init_template (GTK_WIDGET (self)); + +- self->cancellable = g_cancellable_new (); + self->state = DIALOG_STATE_REGISTER; + + gtk_entry_set_text (self->url_entry, SERVER_URL); + gtk_widget_grab_focus (GTK_WIDGET (self->login_entry)); + dialog_validate (self); + dialog_reload (self); + } + + static void + cc_subscription_register_dialog_dispose (GObject *obj) + { + CcSubscriptionRegisterDialog *self = (CcSubscriptionRegisterDialog *) obj; + + g_cancellable_cancel (self->cancellable); + g_clear_object (&self->cancellable); + g_clear_object (&self->subscription_proxy); + + G_OBJECT_CLASS (cc_subscription_register_dialog_parent_class)->dispose (obj); + } + + static void + cc_subscription_register_dialog_finalize (GObject *obj) + { + G_OBJECT_CLASS (cc_subscription_register_dialog_parent_class)->finalize (obj); + } + + static void + cc_subscription_register_dialog_class_init (CcSubscriptionRegisterDialogClass *klass) + { + GObjectClass *object_class = G_OBJECT_CLASS (klass); +@@ -364,40 +363,54 @@ cc_subscription_register_dialog_class_init (CcSubscriptionRegisterDialogClass *k + + gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/info/cc-subscription-register-dialog.ui"); + + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, spinner); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, register_button); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, notification_revealer); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, error_label); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, default_url_radio); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, custom_url_radio); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, register_radio); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, register_with_activation_keys_radio); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, stack); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, register_grid); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, register_with_activation_keys_grid); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, url_label); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, url_entry); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, login_entry); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, password_entry); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, activation_keys_entry); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, organization_label); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, organization_entry); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, organization_entry_with_activation_keys); + + gtk_widget_class_bind_template_callback (widget_class, dialog_validate); + gtk_widget_class_bind_template_callback (widget_class, register_button_clicked_cb); + gtk_widget_class_bind_template_callback (widget_class, dismiss_notification); + gtk_widget_class_bind_template_callback (widget_class, custom_url_radio_toggled_cb); + gtk_widget_class_bind_template_callback (widget_class, register_with_activation_keys_radio_toggled_cb); + } + ++static void ++on_dialog_cancelled (CcSubscriptionRegisterDialog *self) ++{ ++ gtk_dialog_response (GTK_DIALOG (self), GTK_RESPONSE_CLOSE); ++} ++ + CcSubscriptionRegisterDialog * +-cc_subscription_register_dialog_new (GDBusProxy *subscription_proxy) ++cc_subscription_register_dialog_new (GDBusProxy *subscription_proxy, ++ GCancellable *cancellable) + { + CcSubscriptionRegisterDialog *self; + + self = g_object_new (CC_TYPE_SUBSCRIPTION_REGISTER_DIALOG, "use-header-bar", TRUE, NULL); + self->subscription_proxy = g_object_ref (subscription_proxy); ++ self->cancellable = g_object_ref (cancellable); ++ ++ g_signal_connect_object (G_OBJECT (self->cancellable), ++ "cancelled", ++ G_CALLBACK (on_dialog_cancelled), ++ self, ++ G_CONNECT_SWAPPED); + + return self; + } +diff --git a/panels/info/cc-subscription-register-dialog.h b/panels/info/cc-subscription-register-dialog.h +index c5918df9f..31c254084 100644 +--- a/panels/info/cc-subscription-register-dialog.h ++++ b/panels/info/cc-subscription-register-dialog.h +@@ -1,32 +1,33 @@ + /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright 2019 Red Hat, Inc, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Written by: Kalev Lember + */ + + #pragma once + + #include + + G_BEGIN_DECLS + + #define CC_TYPE_SUBSCRIPTION_REGISTER_DIALOG (cc_subscription_register_dialog_get_type ()) + G_DECLARE_FINAL_TYPE (CcSubscriptionRegisterDialog, cc_subscription_register_dialog, CC, SUBSCRIPTION_REGISTER_DIALOG, GtkDialog) + +-CcSubscriptionRegisterDialog *cc_subscription_register_dialog_new (GDBusProxy *subscription_proxy); ++CcSubscriptionRegisterDialog *cc_subscription_register_dialog_new (GDBusProxy *subscription_proxy, ++ GCancellable *cancellable); + + G_END_DECLS +-- +2.28.0 + diff --git a/SOURCES/0004-info-Better-support-registered-but-no-subscriptions-.patch b/SOURCES/0004-info-Better-support-registered-but-no-subscriptions-.patch new file mode 100644 index 0000000..04ed1b2 --- /dev/null +++ b/SOURCES/0004-info-Better-support-registered-but-no-subscriptions-.patch @@ -0,0 +1,1367 @@ +From 26bae6e6d9a7968bbc2e189bf72c8d1588135dfa Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Sun, 24 Jan 2021 13:59:17 -0500 +Subject: [PATCH 4/4] info: Better support registered-but-no-subscriptions + cases + +There are cases when the machine can be registered for updates, +but not have any active subscriptions. For instance, if the +admin runs "subscription-manager register" but fails to pass +--auto-attach. As another case, the org may be configured to +be in "Simple Content Access" mode where updates don't require +specific production subscriptions. + +This commit tries to accomodate those cases better. If the user +is registered, but needs a subscription, the dialog provides a +way to attach one. + +If the user is registered and doesn't need a subscription, the +dialog now shows an updated message to reflect that fact. +--- + panels/info/cc-info-overview-panel.c | 25 +- + panels/info/cc-subscription-details-dialog.c | 180 ++++++++++++- + panels/info/cc-subscription-details-dialog.ui | 249 +++++++++++++++--- + panels/info/info-overview.ui | 35 ++- + 4 files changed, 431 insertions(+), 58 deletions(-) + +diff --git a/panels/info/cc-info-overview-panel.c b/panels/info/cc-info-overview-panel.c +index 65246758e..571654fa0 100644 +--- a/panels/info/cc-info-overview-panel.c ++++ b/panels/info/cc-info-overview-panel.c +@@ -49,60 +49,61 @@ + #include + #endif + + #include "gsd-disk-space-helper.h" + + #include "cc-info-overview-panel.h" + + + typedef struct { + /* Will be one or 2 GPU name strings, or "Unknown" */ + char *hardware_string; + } GraphicsData; + + typedef struct + { + GtkWidget *system_image; + GtkWidget *version_label; + GtkWidget *name_entry; + GtkWidget *memory_label; + GtkWidget *processor_label; + GtkWidget *os_name_label; + GtkWidget *os_type_label; + GtkWidget *disk_label; + GtkWidget *graphics_label; + GtkWidget *virt_type_label; + GtkWidget *subscription_stack; + GtkWidget *details_button; + GtkWidget *register_button; + GtkWidget *updates_separator; + GtkWidget *updates_button; ++ GtkWidget *updates_stack; + + /* Virtualisation labels */ + GtkWidget *label8; + GtkWidget *grid1; + GtkWidget *label18; + + char *gnome_version; + char *gnome_distributor; + char *gnome_date; + + GCancellable *cancellable; + GCancellable *subscription_cancellable; + + /* Free space */ + GList *primary_mounts; + guint64 total_bytes; + + GraphicsData *graphics_data; + + GDBusProxy *subscription_proxy; + } CcInfoOverviewPanelPrivate; + + struct _CcInfoOverviewPanel + { + CcPanel parent_instance; + + /*< private >*/ + CcInfoOverviewPanelPrivate *priv; + }; + +@@ -796,72 +797,85 @@ info_overview_panel_setup_overview (CcInfoOverviewPanel *self) + + os_name_text = get_os_name (); + gtk_label_set_text (GTK_LABEL (priv->os_name_label), os_name_text ? os_name_text : ""); + + get_primary_disc_info (self); + + gtk_label_set_markup (GTK_LABEL (priv->graphics_label), priv->graphics_data->hardware_string); + } + + static void + reload_subscription_status (CcInfoOverviewPanel *self) + { + CcInfoOverviewPanelPrivate *priv = cc_info_overview_panel_get_instance_private (self); + GsdSubmanSubscriptionStatus status; + + if (priv->subscription_proxy == NULL) + { + gtk_widget_hide (priv->subscription_stack); + return; + } + + if (!get_subscription_status (priv->subscription_proxy, &status)) + { + gtk_widget_hide (priv->subscription_stack); + return; + } + + switch (status) + { + case GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN: +- case GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID: +- case GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED: +- case GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID: + gtk_stack_set_visible_child_name (GTK_STACK (priv->subscription_stack), "not-registered"); ++ gtk_stack_set_visible_child_name (GTK_STACK (priv->updates_stack), "no-updates"); + gtk_widget_set_sensitive (priv->updates_button, FALSE); + break; +- ++ case GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED: ++ gtk_stack_set_visible_child_name (GTK_STACK (priv->subscription_stack), "registered"); ++ gtk_stack_set_visible_child_name (GTK_STACK (priv->updates_stack), "updates"); ++ gtk_widget_set_sensitive (priv->updates_button, TRUE); ++ break; + case GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID: ++ case GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID: + gtk_stack_set_visible_child_name (GTK_STACK (priv->subscription_stack), "registered"); ++ gtk_stack_set_visible_child_name (GTK_STACK (priv->updates_stack), "updates"); + gtk_widget_set_sensitive (priv->updates_button, TRUE); + break; +- ++ case GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID: ++ gtk_stack_set_visible_child_name (GTK_STACK (priv->subscription_stack), "registered"); ++ gtk_stack_set_visible_child_name (GTK_STACK (priv->updates_stack), "no-updates"); ++ gtk_widget_set_sensitive (priv->updates_button, FALSE); ++ break; ++ case GSD_SUBMAN_SUBSCRIPTION_STATUS_NO_INSTALLED_PRODUCTS: ++ gtk_stack_set_visible_child_name (GTK_STACK (priv->subscription_stack), "not-registered"); ++ gtk_stack_set_visible_child_name (GTK_STACK (priv->updates_stack), "no-updates"); ++ gtk_widget_set_sensitive (priv->updates_button, FALSE); ++ break; + default: + g_assert_not_reached (); + break; + } + } + + static void + on_details_button_clicked (GtkWidget *widget, + CcInfoOverviewPanel *self) + { + CcInfoOverviewPanelPrivate *priv = cc_info_overview_panel_get_instance_private (self); + CcSubscriptionDetailsDialog *dialog; + GtkWindow *toplevel; + + dialog = cc_subscription_details_dialog_new (priv->subscription_proxy, + priv->subscription_cancellable); + toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self))); + gtk_window_set_transient_for (GTK_WINDOW (dialog), toplevel); + + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (GTK_WIDGET (dialog)); + } + + static void + on_register_button_clicked (GtkWidget *widget, + CcInfoOverviewPanel *self) + { + CcInfoOverviewPanelPrivate *priv = cc_info_overview_panel_get_instance_private (self); + CcSubscriptionRegisterDialog *dialog; + GtkWindow *toplevel; +@@ -994,60 +1008,61 @@ cc_info_overview_panel_finalize (GObject *object) + + G_OBJECT_CLASS (cc_info_overview_panel_parent_class)->finalize (object); + } + + static void + cc_info_overview_panel_class_init (CcInfoOverviewPanelClass *klass) + { + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->finalize = cc_info_overview_panel_finalize; + object_class->dispose = cc_info_overview_panel_dispose; + + gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/info/info-overview.ui"); + + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, system_image); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, version_label); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, name_entry); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, memory_label); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, processor_label); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, os_name_label); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, os_type_label); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, disk_label); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, graphics_label); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, virt_type_label); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, subscription_stack); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, details_button); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, register_button); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, updates_separator); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, updates_button); ++ gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, updates_stack); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, label8); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, grid1); + gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, label18); + + g_type_ensure (CC_TYPE_HOSTNAME_ENTRY); + } + + static void + cc_info_overview_panel_init (CcInfoOverviewPanel *self) + { + CcInfoOverviewPanelPrivate *priv = cc_info_overview_panel_get_instance_private (self); + + gtk_widget_init_template (GTK_WIDGET (self)); + + g_resources_register (cc_info_get_resource ()); + + priv->cancellable = g_cancellable_new (); + priv->subscription_cancellable = g_cancellable_new (); + + priv->graphics_data = get_graphics_data (); + + if (does_gnome_software_exist () || does_gpk_update_viewer_exist ()) + g_signal_connect (priv->updates_button, "clicked", G_CALLBACK (on_updates_button_clicked), self); + else + gtk_widget_hide (priv->updates_button); + + info_overview_panel_setup_overview (self); + info_overview_panel_setup_virt (self); + info_overview_panel_setup_subscriptions (self); + +diff --git a/panels/info/cc-subscription-details-dialog.c b/panels/info/cc-subscription-details-dialog.c +index 3d77e6c48..f8e70d751 100644 +--- a/panels/info/cc-subscription-details-dialog.c ++++ b/panels/info/cc-subscription-details-dialog.c +@@ -1,420 +1,578 @@ + /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright 2019 Red Hat, Inc, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Written by: Kalev Lember + */ + + #include "config.h" + + #include + #include + #include + + #include "cc-subscription-details-dialog.h" ++#include "cc-subscription-common.h" + + #define DBUS_TIMEOUT 300000 /* 5 minutes */ + + typedef enum { + DIALOG_STATE_SHOW_DETAILS, ++ DIALOG_STATE_SUBSCRIBE, ++ DIALOG_STATE_SUBSCRIBING, + DIALOG_STATE_UNREGISTER, + DIALOG_STATE_UNREGISTERING + } DialogState; + + struct _CcSubscriptionDetailsDialog + { + GtkDialog parent_instance; + + DialogState state; + GCancellable *cancellable; + GDBusProxy *subscription_proxy; + GPtrArray *products; + + /* template widgets */ + GtkButton *back_button; + GtkSpinner *spinner; ++ GtkStack *header_stack; ++ GtkButton *header_subscribe_button; + GtkButton *header_unregister_button; + GtkRevealer *notification_revealer; + GtkLabel *error_label; + GtkStack *stack; ++ GtkStack *status_stack; + GtkBox *products_box1; + GtkBox *products_box2; ++ GtkBox *products_box3; ++ GtkButton *subscribe_button; ++ GtkSeparator *separator; + GtkButton *unregister_button; + }; + + G_DEFINE_TYPE (CcSubscriptionDetailsDialog, cc_subscription_details_dialog, GTK_TYPE_DIALOG); + ++static void reload_installed_products (CcSubscriptionDetailsDialog *self); ++ + typedef struct + { + gchar *product_name; + gchar *product_id; + gchar *version; + gchar *arch; + gchar *status; + gchar *starts; + gchar *ends; + } ProductData; + + static void + product_data_free (ProductData *product) + { + g_free (product->product_name); + g_free (product->product_id); + g_free (product->version); + g_free (product->arch); + g_free (product->status); + g_free (product->starts); + g_free (product->ends); + g_free (product); + } + + G_DEFINE_AUTOPTR_CLEANUP_FUNC (ProductData, product_data_free); + + static void + add_product_row (GtkGrid *product_grid, const gchar *name, const gchar *value, gint top_attach) + { + GtkWidget *w; + + w = gtk_label_new (name); + gtk_style_context_add_class (gtk_widget_get_style_context (w), "dim-label"); + gtk_grid_attach (product_grid, w, 0, top_attach, 1, 1); + gtk_widget_set_halign (w, GTK_ALIGN_END); + gtk_widget_show (w); + + if (value == NULL) + value = _("Unknown"); + + w = gtk_label_new (value); + gtk_grid_attach (product_grid, w, 1, top_attach, 1, 1); + gtk_widget_set_halign (w, GTK_ALIGN_START); + gtk_widget_set_hexpand (w, TRUE); + gtk_widget_show (w); + } + + static GtkWidget * +-add_product (CcSubscriptionDetailsDialog *self, ProductData *product) ++add_product (CcSubscriptionDetailsDialog *self, ProductData *product, GsdSubmanSubscriptionStatus status) + { + GtkGrid *product_grid; + const gchar *status_text; + + if (g_strcmp0 (product->status, "subscribed") == 0) + status_text = _("Subscribed"); ++ else if (status == GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED) ++ status_text = _("No Specific Subscription"); + else +- status_text = _("Not Subscribed (Not supported by a valid subscription.)"); ++ status_text = _("Not Subscribed"); + + product_grid = GTK_GRID (gtk_grid_new ()); + gtk_grid_set_column_spacing (product_grid, 12); + gtk_grid_set_row_spacing (product_grid, 6); + gtk_widget_set_margin_top (GTK_WIDGET (product_grid), 18); + gtk_widget_set_margin_bottom (GTK_WIDGET (product_grid), 12); + gtk_widget_show (GTK_WIDGET (product_grid)); + + add_product_row (product_grid, _("Product Name"), product->product_name, 0); + add_product_row (product_grid, _("Product ID"), product->product_id, 1); + add_product_row (product_grid, _("Version"), product->version, 2); + add_product_row (product_grid, _("Arch"), product->arch, 3); + add_product_row (product_grid, _("Status"), status_text, 4); +- add_product_row (product_grid, _("Starts"), product->starts, 5); +- add_product_row (product_grid, _("Ends"), product->ends, 6); ++ ++ if (product->starts[0] != '\0' && product->ends[0] != '\0') ++ { ++ add_product_row (product_grid, _("Starts"), product->starts, 5); ++ add_product_row (product_grid, _("Ends"), product->ends, 6); ++ } + + return GTK_WIDGET (product_grid); + } + + static void + remove_all_children (GtkContainer *container) + { + g_autoptr(GList) list = gtk_container_get_children (container); + + for (GList *l = list; l != NULL; l = l->next) + gtk_container_remove (container, (GtkWidget *) l->data); + } + + static void + dialog_reload (CcSubscriptionDetailsDialog *self) + { + GtkHeaderBar *header = GTK_HEADER_BAR (gtk_dialog_get_header_bar (GTK_DIALOG (self))); ++ GsdSubmanSubscriptionStatus status = GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN; ++ ++ reload_installed_products (self); + + switch (self->state) + { + case DIALOG_STATE_SHOW_DETAILS: + gtk_header_bar_set_show_close_button (header, TRUE); + + gtk_window_set_title (GTK_WINDOW (self), _("Registration Details")); + gtk_widget_set_sensitive (GTK_WIDGET (self->header_unregister_button), TRUE); ++ gtk_widget_set_sensitive (GTK_WIDGET (self->header_subscribe_button), TRUE); + + gtk_widget_hide (GTK_WIDGET (self->back_button)); +- gtk_widget_hide (GTK_WIDGET (self->header_unregister_button)); ++ gtk_widget_hide (GTK_WIDGET (self->header_stack)); + + gtk_stack_set_visible_child_name (self->stack, "show-details"); + break; + ++ case DIALOG_STATE_SUBSCRIBE: ++ gtk_header_bar_set_show_close_button (header, FALSE); ++ gtk_stack_set_visible_child_name (self->header_stack, "subscribe"); ++ gtk_window_set_title (GTK_WINDOW (self), _("Subscribe System")); ++ gtk_widget_set_sensitive (GTK_WIDGET (self->header_subscribe_button), TRUE); ++ ++ gtk_widget_show (GTK_WIDGET (self->back_button)); ++ ++ gtk_stack_set_visible_child_name (self->header_stack, "subscribe"); ++ gtk_widget_show (GTK_WIDGET (self->header_stack)); ++ ++ gtk_stack_set_visible_child_name (self->stack, "subscribe"); ++ break; ++ ++ case DIALOG_STATE_SUBSCRIBING: ++ gtk_header_bar_set_show_close_button (header, FALSE); ++ gtk_window_set_title (GTK_WINDOW (self), _("Looking For Available Subscriptions…")); ++ gtk_widget_set_sensitive (GTK_WIDGET (self->header_subscribe_button), FALSE); ++ ++ gtk_widget_show (GTK_WIDGET (self->back_button)); ++ ++ gtk_stack_set_visible_child_name (self->header_stack, "subscribe"); ++ gtk_widget_show (GTK_WIDGET (self->header_stack)); ++ ++ gtk_stack_set_visible_child_name (self->stack, "subscribe"); ++ break; ++ + case DIALOG_STATE_UNREGISTER: + gtk_header_bar_set_show_close_button (header, FALSE); + + gtk_window_set_title (GTK_WINDOW (self), _("Unregister System")); + gtk_widget_set_sensitive (GTK_WIDGET (self->header_unregister_button), TRUE); + + gtk_widget_show (GTK_WIDGET (self->back_button)); +- gtk_widget_show (GTK_WIDGET (self->header_unregister_button)); ++ ++ gtk_stack_set_visible_child_name (self->header_stack, "unregister"); ++ gtk_widget_show (GTK_WIDGET (self->header_stack)); + + gtk_stack_set_visible_child_name (self->stack, "unregister"); + break; + + case DIALOG_STATE_UNREGISTERING: + gtk_header_bar_set_show_close_button (header, FALSE); + + gtk_window_set_title (GTK_WINDOW (self), _("Unregistering System…")); + gtk_widget_set_sensitive (GTK_WIDGET (self->header_unregister_button), FALSE); + + gtk_widget_show (GTK_WIDGET (self->back_button)); +- gtk_widget_show (GTK_WIDGET (self->header_unregister_button)); ++ ++ gtk_stack_set_visible_child_name (self->header_stack, "unregister"); ++ gtk_widget_show (GTK_WIDGET (self->header_stack)); + + gtk_stack_set_visible_child_name (self->stack, "unregister"); + break; + + default: + g_assert_not_reached (); + break; + } + + remove_all_children (GTK_CONTAINER (self->products_box1)); + remove_all_children (GTK_CONTAINER (self->products_box2)); ++ remove_all_children (GTK_CONTAINER (self->products_box3)); + + if (self->products == NULL || self->products->len == 0) + { + /* the widgets are duplicate to allow sliding between two stack pages */ + GtkWidget *w1 = gtk_label_new (_("No installed products detected.")); + GtkWidget *w2 = gtk_label_new (_("No installed products detected.")); ++ GtkWidget *w3 = gtk_label_new (_("No installed products detected.")); + gtk_widget_show (w1); + gtk_widget_show (w2); ++ gtk_widget_show (w3); + gtk_container_add (GTK_CONTAINER (self->products_box1), w1); + gtk_container_add (GTK_CONTAINER (self->products_box2), w2); ++ gtk_container_add (GTK_CONTAINER (self->products_box3), w3); ++ gtk_stack_set_visible_child_name (self->status_stack, "no-installed-products"); ++ ++ gtk_widget_hide (GTK_WIDGET (self->subscribe_button)); ++ gtk_widget_hide (GTK_WIDGET (self->separator)); + return; + } + ++ get_subscription_status (self->subscription_proxy, &status); ++ + for (guint i = 0; i < self->products->len; i++) + { + ProductData *product = g_ptr_array_index (self->products, i); + /* the widgets are duplicate to allow sliding between two stack pages */ +- GtkWidget *w1 = add_product (self, product); +- GtkWidget *w2 = add_product (self, product); ++ GtkWidget *w1 = add_product (self, product, status); ++ GtkWidget *w2 = add_product (self, product, status); ++ GtkWidget *w3 = add_product (self, product, status); + gtk_container_add (GTK_CONTAINER (self->products_box1), w1); + gtk_container_add (GTK_CONTAINER (self->products_box2), w2); ++ gtk_container_add (GTK_CONTAINER (self->products_box3), w3); + } ++ ++ switch (status) ++ { ++ case GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID: ++ gtk_stack_set_visible_child_name (self->status_stack, "fully-subscribed"); ++ gtk_widget_hide (GTK_WIDGET (self->subscribe_button)); ++ break; ++ ++ case GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID: ++ gtk_stack_set_visible_child_name (self->status_stack, "partly-subscribed"); ++ gtk_widget_show (GTK_WIDGET (self->subscribe_button)); ++ break; ++ ++ case GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED: ++ gtk_stack_set_visible_child_name (self->status_stack, "subscription-not-needed"); ++ gtk_widget_hide (GTK_WIDGET (self->subscribe_button)); ++ break; ++ ++ case GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN: ++ default: ++ gtk_stack_set_visible_child_name (self->status_stack, "not-subscribed"); ++ gtk_widget_show (GTK_WIDGET (self->subscribe_button)); ++ break; ++ } ++ ++ gtk_widget_set_visible (GTK_WIDGET (self->separator), ++ gtk_widget_get_visible (GTK_WIDGET (self->subscribe_button))); ++ + } + + static ProductData * + parse_product_variant (GVariant *product_variant) + { + g_autoptr(ProductData) product = g_new0 (ProductData, 1); + g_auto(GVariantDict) dict; + + g_variant_dict_init (&dict, product_variant); + + g_variant_dict_lookup (&dict, "product-name", "s", &product->product_name); + g_variant_dict_lookup (&dict, "product-id", "s", &product->product_id); + g_variant_dict_lookup (&dict, "version", "s", &product->version); + g_variant_dict_lookup (&dict, "arch", "s", &product->arch); + g_variant_dict_lookup (&dict, "status", "s", &product->status); + g_variant_dict_lookup (&dict, "starts", "s", &product->starts); + g_variant_dict_lookup (&dict, "ends", "s", &product->ends); + + return g_steal_pointer (&product); + } + + static void +-load_installed_products (CcSubscriptionDetailsDialog *self) ++reload_installed_products (CcSubscriptionDetailsDialog *self) + { + GVariantIter iter_array; + GVariant *child; + g_autoptr(GError) error = NULL; + g_autoptr(GVariant) installed_products_variant = NULL; + + installed_products_variant = g_dbus_proxy_get_cached_property (self->subscription_proxy, "InstalledProducts"); + if (installed_products_variant == NULL) + { + g_debug ("Unable to get InstalledProducts dbus property"); + return; + } + + g_ptr_array_set_size (self->products, 0); + + g_variant_iter_init (&iter_array, installed_products_variant); + while ((child = g_variant_iter_next_value (&iter_array)) != NULL) + { + g_autoptr(GVariant) product_variant = g_steal_pointer (&child); + g_ptr_array_add (self->products, parse_product_variant (product_variant)); + } + } + ++static void ++subscription_done_cb (GObject *source_object, ++ GAsyncResult *res, ++ gpointer user_data) ++{ ++ CcSubscriptionDetailsDialog *self = (CcSubscriptionDetailsDialog *) user_data; ++ g_autoptr(GVariant) results = NULL; ++ g_autoptr(GError) error = NULL; ++ ++ results = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), ++ res, ++ &error); ++ if (results == NULL) ++ { ++ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) ++ return; ++ ++ g_dbus_error_strip_remote_error (error); ++ gtk_label_set_text (self->error_label, error->message); ++ gtk_revealer_set_reveal_child (self->notification_revealer, TRUE); ++ ++ gtk_spinner_stop (self->spinner); ++ ++ self->state = DIALOG_STATE_SUBSCRIBE; ++ dialog_reload (self); ++ return; ++ } ++ ++ gtk_spinner_stop (self->spinner); ++ ++ self->state = DIALOG_STATE_SHOW_DETAILS; ++ dialog_reload (self); ++} ++ ++static void ++header_subscribe_button_clicked_cb (CcSubscriptionDetailsDialog *self) ++{ ++ gtk_spinner_start (self->spinner); ++ ++ self->state = DIALOG_STATE_SUBSCRIBING; ++ dialog_reload (self); ++ ++ g_dbus_proxy_call (self->subscription_proxy, ++ "Attach", ++ NULL, ++ G_DBUS_CALL_FLAGS_NONE, ++ DBUS_TIMEOUT, ++ self->cancellable, ++ subscription_done_cb, ++ self); ++} ++ + static void + unregistration_done_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) + { + CcSubscriptionDetailsDialog *self = (CcSubscriptionDetailsDialog *) user_data; + g_autoptr(GVariant) results = NULL; + g_autoptr(GError) error = NULL; + + results = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), + res, + &error); + if (results == NULL) + { + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + g_dbus_error_strip_remote_error (error); + gtk_label_set_text (self->error_label, error->message); + gtk_revealer_set_reveal_child (self->notification_revealer, TRUE); + + gtk_spinner_stop (self->spinner); + + self->state = DIALOG_STATE_UNREGISTER; + dialog_reload (self); + return; + } + + gtk_spinner_stop (self->spinner); + + gtk_dialog_response (GTK_DIALOG (self), GTK_RESPONSE_ACCEPT); + } + + static void + header_unregister_button_clicked_cb (CcSubscriptionDetailsDialog *self) + { + gtk_spinner_start (self->spinner); + + self->state = DIALOG_STATE_UNREGISTERING; + dialog_reload (self); + + g_dbus_proxy_call (self->subscription_proxy, + "Unregister", + NULL, + G_DBUS_CALL_FLAGS_NONE, + DBUS_TIMEOUT, + self->cancellable, + unregistration_done_cb, + self); + } + + static void + back_button_clicked_cb (CcSubscriptionDetailsDialog *self) + { + gtk_spinner_stop (self->spinner); + + self->state = DIALOG_STATE_SHOW_DETAILS; + dialog_reload (self); + } + ++static void ++subscribe_button_clicked_cb (CcSubscriptionDetailsDialog *self) ++{ ++ self->state = DIALOG_STATE_SUBSCRIBE; ++ dialog_reload (self); ++} ++ + static void + unregister_button_clicked_cb (CcSubscriptionDetailsDialog *self) + { + self->state = DIALOG_STATE_UNREGISTER; + dialog_reload (self); + } + + static void + dismiss_notification (CcSubscriptionDetailsDialog *self) + { + gtk_revealer_set_reveal_child (self->notification_revealer, FALSE); + } + + static void + cc_subscription_details_dialog_init (CcSubscriptionDetailsDialog *self) + { + gtk_widget_init_template (GTK_WIDGET (self)); + + self->products = g_ptr_array_new_with_free_func ((GDestroyNotify) product_data_free); + self->state = DIALOG_STATE_SHOW_DETAILS; + } + + static void + cc_subscription_details_dialog_dispose (GObject *obj) + { + CcSubscriptionDetailsDialog *self = (CcSubscriptionDetailsDialog *) obj; + + g_cancellable_cancel (self->cancellable); + g_clear_object (&self->cancellable); + g_clear_object (&self->subscription_proxy); + + G_OBJECT_CLASS (cc_subscription_details_dialog_parent_class)->dispose (obj); + } + + static void + cc_subscription_details_dialog_finalize (GObject *obj) + { + CcSubscriptionDetailsDialog *self = (CcSubscriptionDetailsDialog *) obj; + + g_clear_pointer (&self->products, g_ptr_array_unref); + + G_OBJECT_CLASS (cc_subscription_details_dialog_parent_class)->finalize (obj); + } + + static void + cc_subscription_details_dialog_class_init (CcSubscriptionDetailsDialogClass *klass) + { + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->dispose = cc_subscription_details_dialog_dispose; + object_class->finalize = cc_subscription_details_dialog_finalize; + + gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/info/cc-subscription-details-dialog.ui"); + + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, back_button); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, spinner); ++ gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, header_stack); ++ gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, header_subscribe_button); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, header_unregister_button); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, notification_revealer); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, error_label); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, stack); ++ gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, status_stack); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, products_box1); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, products_box2); ++ gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, products_box3); ++ gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, subscribe_button); ++ gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, separator); + gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, unregister_button); + + gtk_widget_class_bind_template_callback (widget_class, back_button_clicked_cb); ++ gtk_widget_class_bind_template_callback (widget_class, header_subscribe_button_clicked_cb); + gtk_widget_class_bind_template_callback (widget_class, header_unregister_button_clicked_cb); ++ gtk_widget_class_bind_template_callback (widget_class, subscribe_button_clicked_cb); + gtk_widget_class_bind_template_callback (widget_class, unregister_button_clicked_cb); + gtk_widget_class_bind_template_callback (widget_class, dismiss_notification); + } + + static void + on_dialog_cancelled (CcSubscriptionDetailsDialog *self) + { + gtk_dialog_response (GTK_DIALOG (self), GTK_RESPONSE_CLOSE); + } + + CcSubscriptionDetailsDialog * + cc_subscription_details_dialog_new (GDBusProxy *subscription_proxy, + GCancellable *cancellable) + { + CcSubscriptionDetailsDialog *self; + + self = g_object_new (CC_TYPE_SUBSCRIPTION_DETAILS_DIALOG, "use-header-bar", TRUE, NULL); + self->subscription_proxy = g_object_ref (subscription_proxy); + self->cancellable = g_object_ref (cancellable); + + g_signal_connect_object (G_OBJECT (self->cancellable), + "cancelled", + G_CALLBACK (on_dialog_cancelled), + self, + G_CONNECT_SWAPPED); + +- load_installed_products (self); + dialog_reload (self); + + return self; + } +diff --git a/panels/info/cc-subscription-details-dialog.ui b/panels/info/cc-subscription-details-dialog.ui +index 6f0b16930..6cdfc1220 100644 +--- a/panels/info/cc-subscription-details-dialog.ui ++++ b/panels/info/cc-subscription-details-dialog.ui +@@ -6,75 +6,106 @@ + True + True + dialog + Registration Details + 1 + + + True + False + False + + + True + True + True + center + + + + True + False + go-previous-symbolic + + + + + + +- +- _Unregister ++ + True +- True +- True +- True +- True +- False +- True +- center +- +- ++ False ++ slide-left-right ++ ++ ++ _Unregister ++ True ++ True ++ True ++ True ++ True ++ False ++ True ++ center ++ ++ ++ ++ ++ unregister ++ ++ ++ ++ ++ _Subscribe ++ True ++ True ++ True ++ True ++ True ++ False ++ True ++ center ++ ++ ++ ++ ++ subscribe ++ ++ + + + end + + + + + True + False + center + 6 + 6 + + + end + + + + + + + True + False + vertical + 0 + + + True + + +@@ -120,129 +151,275 @@ + Unable to reach developers.redhat.com. Please try again later. + + + + + + + True + start + + + + + True + window-close-symbolic + + + + + + + + + + + True + False + slide-left-right ++ ++ ++ True ++ vertical ++ 24 ++ 32 ++ 12 ++ 12 ++ ++ ++ True ++ False ++ ++ ++ True ++ False ++ This system is subscribed to receive software updates. ++ 45 ++ 45 ++ 0 ++ start ++ True ++ ++ ++ ++ fully-subscribed ++ ++ ++ ++ ++ True ++ False ++ This system lacks subscriptions to receive updates for some installed software. ++ 45 ++ 45 ++ 0 ++ start ++ True ++ ++ ++ ++ partly-subscribed ++ ++ ++ ++ ++ True ++ False ++ This system lacks subscriptions to receive software updates. ++ 45 ++ 45 ++ 0 ++ start ++ True ++ ++ ++ ++ not-subscribed ++ ++ ++ ++ ++ True ++ False ++ This system is registered to receive software updates. ++ 45 ++ 45 ++ 0 ++ start ++ True ++ ++ ++ ++ subscription-not-needed ++ ++ ++ ++ ++ True ++ False ++ This system has no supported software installed. ++ 45 ++ 45 ++ 0 ++ start ++ True ++ ++ ++ ++ no-installed-products ++ ++ ++ ++ ++ ++ ++ True ++ vertical ++ True ++ 6 ++ 6 ++ ++ ++ ++ ++ True ++ False ++ horizontal ++ 12 ++ end ++ ++ ++ _Unregister… ++ True ++ True ++ True ++ False ++ end ++ True ++ ++ ++ ++ ++ ++ ++ True ++ ++ ++ ++ ++ _Subscribe… ++ True ++ True ++ True ++ False ++ end ++ True ++ ++ ++ ++ ++ ++ ++ ++ ++ show-details ++ ++ + + + True + vertical + 24 + 32 + 32 + 20 + + + True + False +- Registration with Red Hat allows this system to receive software updates. ++ Subscribing with Red Hat will allow this system to receive software updates. + 45 + 45 + 0 + start + True +- + + + +- ++ + True + vertical + 6 + 6 + True + + +- +- +- _Unregister… +- True +- True +- True +- False +- end +- True +- +- +- +- + + +- show-details ++ subscribe + + + + + True + vertical + 24 + 32 + 32 + 20 + + + True + False + Warning: unregistering this system will result in it no longer receiving software updates. + 45 + 45 + 0 + start + True + + + +- ++ + True + vertical + 6 + 6 + True + + + + + unregister + + + + + + + False + True + 0 + + + + + + +diff --git a/panels/info/info-overview.ui b/panels/info/info-overview.ui +index e33ba399a..3ed79712a 100644 +--- a/panels/info/info-overview.ui ++++ b/panels/info/info-overview.ui +@@ -366,68 +366,91 @@ + + + + not-registered + + + + + True + False + horizontal + 12 + + + True + False + vertical + + + True + False + 0 + Registered System + + + + + + + +- ++ + True + False +- 0 +- System is registered and able to receive software updates. +- +- +- ++ ++ ++ True ++ False ++ 0 ++ System is registered and able to receive software updates. ++ ++ ++ ++ ++ ++ updates ++ ++ ++ ++ ++ True ++ False ++ 0 ++ System is registered but is unable to receive all software updates. ++ ++ ++ ++ ++ ++ no-updates ++ ++ + + + + + + + _Details + True + True + True + False + True + end + True + + + + + registered + + + + + + + True + + + + +-- +2.28.0 + diff --git a/SOURCES/printers-Update-entries.patch b/SOURCES/printers-Update-entries.patch index 0b8f240..5a82133 100644 --- a/SOURCES/printers-Update-entries.patch +++ b/SOURCES/printers-Update-entries.patch @@ -545,7 +545,7 @@ - self->inklevel->marker_names = g_strcompress (printer.options[i].value); + { + g_free (self->inklevel->marker_names); -+ self->inklevel->marker_names = g_strcompress (g_strdup (printer.options[i].value)); ++ self->inklevel->marker_names = g_strcompress (printer.options[i].value); + } else if (g_strcmp0 (printer.options[i].name, "marker-levels") == 0) - self->inklevel->marker_levels = g_strdup (printer.options[i].value); diff --git a/SPECS/gnome-control-center.spec b/SPECS/gnome-control-center.spec index df35888..3e69449 100644 --- a/SPECS/gnome-control-center.spec +++ b/SPECS/gnome-control-center.spec @@ -1,7 +1,8 @@ %define gnome_online_accounts_version 3.25.3 %define glib2_version 2.53.0 %define gnome_desktop_version 3.27.90 -%define gsd_version 3.25.90 +%define gsd_version 3.32.0-13 + %define gsettings_desktop_schemas_version 3.27.2 %define gtk3_version 3.22.20 %define upower_version 0.99.6 @@ -10,7 +11,7 @@ Name: gnome-control-center Version: 3.28.2 -Release: 24%{?dist} +Release: 26%{?dist} Summary: Utilities to configure the GNOME desktop License: GPLv2+ and CC-BY-SA @@ -19,6 +20,7 @@ Source0: https://download.gnome.org/sources/gnome-control-center/3.28/gno # https://bugzilla.gnome.org/show_bug.cgi?id=695691 Patch0: distro-logo.patch + # thunderbolt panel backported to 3.28.x # https://gitlab.gnome.org/gicmo/gnome-control-center/commits/thunderbolt_3_28_1 Patch1: 0001-shell-Don-t-set-per-panel-icon.patch @@ -33,7 +35,10 @@ Patch6: 0001-wacom-Update-Test-your-settings-button-sensitivity-o.patch Patch7: 0001-wacom-Update-to-newer-output-setting.patch # Subscription management -Patch8: 0001-info-Add-subscription-manager-integration.patch +Patch80001: 0001-info-Add-subscription-manager-integration.patch +Patch80002: 0002-info-Move-helper-for-getting-subscription-status-to-.patch +Patch80003: 0003-info-Update-registration-state-in-panel-when-it-happ.patch +Patch80004: 0004-info-Better-support-registered-but-no-subscriptions-.patch Patch9: 0001-sharing-Fix-warning-when-disabling-sharing.patch Patch10: 0001-network-Use-g_signal_connect_object-when-dealing-wit.patch @@ -228,6 +233,14 @@ chrpath --delete $RPM_BUILD_ROOT%{_bindir}/gnome-control-center %dir %{_datadir}/gnome/wm-properties %changelog +* Sun Jan 24 2021 Ray Strode - 3.28.2-26 +- Support Simple Content Access from subscription manager + Related: #1870837 + +* Thu Dec 03 2020 Marek Kasik - 3.28.2-25 +- Fix a leak found by Coverity +- Related: #1700002 + * Wed Dec 02 2020 Marek Kasik - 3.28.2-24 - Fix crashes when updating printer entries - Related: #1700002