Update to 41.1
This commit is contained in:
parent
77240ed208
commit
856444f98a
@ -1,116 +0,0 @@
|
|||||||
From 1b0c476d66f89332187da2894b06ec2d4b83fa2a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Milan Crha <mcrha@redhat.com>
|
|
||||||
Date: Thu, 30 Sep 2021 16:28:11 +0200
|
|
||||||
Subject: [PATCH 1/2] gs-update-monitor: Use wall-clock time for
|
|
||||||
one-notification-per-day check
|
|
||||||
|
|
||||||
Instead of using the g_timeout_add_seconds(), which uses a monotonic time,
|
|
||||||
which may or may not increase when the machine is suspended, rather use
|
|
||||||
the wall-clock time, to avoid issues with machine suspend where the monotonic
|
|
||||||
time does not increase.
|
|
||||||
---
|
|
||||||
src/gs-update-monitor.c | 31 +++++++++++++------------------
|
|
||||||
1 file changed, 13 insertions(+), 18 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/gs-update-monitor.c b/src/gs-update-monitor.c
|
|
||||||
index bde39fbbb..787c605a1 100644
|
|
||||||
--- a/src/gs-update-monitor.c
|
|
||||||
+++ b/src/gs-update-monitor.c
|
|
||||||
@@ -44,7 +44,8 @@ struct _GsUpdateMonitor {
|
|
||||||
guint check_startup_id; /* 60s after startup */
|
|
||||||
guint check_hourly_id; /* and then every hour */
|
|
||||||
guint check_daily_id; /* every 3rd day */
|
|
||||||
- guint notification_blocked_id; /* rate limit notifications */
|
|
||||||
+
|
|
||||||
+ gint64 last_notification_time_usec; /* to notify once per day only */
|
|
||||||
};
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (GsUpdateMonitor, gs_update_monitor, G_TYPE_OBJECT)
|
|
||||||
@@ -88,14 +89,6 @@ with_app_data_free (WithAppData *data)
|
|
||||||
|
|
||||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(WithAppData, with_app_data_free);
|
|
||||||
|
|
||||||
-static gboolean
|
|
||||||
-reenable_offline_update_notification (gpointer data)
|
|
||||||
-{
|
|
||||||
- GsUpdateMonitor *monitor = data;
|
|
||||||
- monitor->notification_blocked_id = 0;
|
|
||||||
- return G_SOURCE_REMOVE;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
static void
|
|
||||||
check_updates_kind (GsAppList *apps,
|
|
||||||
gboolean *out_has_important,
|
|
||||||
@@ -265,16 +258,22 @@ notify_about_pending_updates (GsUpdateMonitor *monitor,
|
|
||||||
GsAppList *apps)
|
|
||||||
{
|
|
||||||
const gchar *title = NULL, *body = NULL;
|
|
||||||
+ gint64 time_diff_sec;
|
|
||||||
g_autoptr(GNotification) nn = NULL;
|
|
||||||
|
|
||||||
- if (monitor->notification_blocked_id > 0)
|
|
||||||
+ time_diff_sec = (g_get_real_time () - monitor->last_notification_time_usec) / G_USEC_PER_SEC;
|
|
||||||
+ if (time_diff_sec < SECONDS_IN_A_DAY) {
|
|
||||||
+ g_debug ("Skipping update notification daily check, because made one only %" G_GINT64_FORMAT "s ago",
|
|
||||||
+ time_diff_sec);
|
|
||||||
return;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- /* rate limit update notifications to once per day */
|
|
||||||
- monitor->notification_blocked_id = g_timeout_add_seconds (24 * SECONDS_IN_AN_HOUR, reenable_offline_update_notification, monitor);
|
|
||||||
-
|
|
||||||
- if (!should_notify_about_pending_updates (monitor, apps, &title, &body))
|
|
||||||
+ if (!should_notify_about_pending_updates (monitor, apps, &title, &body)) {
|
|
||||||
+ g_debug ("No update notification needed");
|
|
||||||
return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ monitor->last_notification_time_usec = g_get_real_time ();
|
|
||||||
|
|
||||||
g_debug ("Notify about update: '%s'", title);
|
|
||||||
|
|
||||||
@@ -1394,10 +1393,6 @@ gs_update_monitor_dispose (GObject *object)
|
|
||||||
g_source_remove (monitor->check_startup_id);
|
|
||||||
monitor->check_startup_id = 0;
|
|
||||||
}
|
|
||||||
- if (monitor->notification_blocked_id != 0) {
|
|
||||||
- g_source_remove (monitor->notification_blocked_id);
|
|
||||||
- monitor->notification_blocked_id = 0;
|
|
||||||
- }
|
|
||||||
if (monitor->cleanup_notifications_id != 0) {
|
|
||||||
g_source_remove (monitor->cleanup_notifications_id);
|
|
||||||
monitor->cleanup_notifications_id = 0;
|
|
||||||
--
|
|
||||||
GitLab
|
|
||||||
|
|
||||||
|
|
||||||
From 2ff332826f841c4ea1d9458df81648868745ea41 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Milan Crha <mcrha@redhat.com>
|
|
||||||
Date: Thu, 30 Sep 2021 16:47:40 +0200
|
|
||||||
Subject: [PATCH 2/2] gs-update-monitor: Correct last notification timestamp
|
|
||||||
reset
|
|
||||||
|
|
||||||
Do not reset the notification timestamp after the list of updates
|
|
||||||
is received, that should be done when the notification had been shown.
|
|
||||||
|
|
||||||
Reported downstream at:
|
|
||||||
https://bugzilla.redhat.com/show_bug.cgi?id=2009063
|
|
||||||
---
|
|
||||||
src/gs-update-monitor.c | 1 -
|
|
||||||
1 file changed, 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/gs-update-monitor.c b/src/gs-update-monitor.c
|
|
||||||
index 787c605a1..a8421fcc4 100644
|
|
||||||
--- a/src/gs-update-monitor.c
|
|
||||||
+++ b/src/gs-update-monitor.c
|
|
||||||
@@ -613,7 +613,6 @@ get_updates_finished_cb (GObject *object, GAsyncResult *res, gpointer data)
|
|
||||||
notify_list = apps;
|
|
||||||
|
|
||||||
notify_about_pending_updates (monitor, notify_list);
|
|
||||||
- reset_update_notification_timestamp (monitor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
GitLab
|
|
||||||
|
|
@ -1,233 +0,0 @@
|
|||||||
From 5c203ae1b07e2c31ca39c3d6a793534d45c49125 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Milan Crha <mcrha@redhat.com>
|
|
||||||
Date: Tue, 5 Oct 2021 19:42:37 +0200
|
|
||||||
Subject: [PATCH 1/5] gs-shell: Remove left-over function prototype declaration
|
|
||||||
|
|
||||||
The function body does not exist.
|
|
||||||
---
|
|
||||||
src/gs-shell.h | 2 --
|
|
||||||
1 file changed, 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/gs-shell.h b/src/gs-shell.h
|
|
||||||
index bb39fc928..46661db16 100644
|
|
||||||
--- a/src/gs-shell.h
|
|
||||||
+++ b/src/gs-shell.h
|
|
||||||
@@ -43,8 +43,6 @@ typedef enum {
|
|
||||||
|
|
||||||
GsShell *gs_shell_new (void);
|
|
||||||
void gs_shell_activate (GsShell *shell);
|
|
||||||
-void gs_shell_refresh (GsShell *shell,
|
|
||||||
- GCancellable *cancellable);
|
|
||||||
void gs_shell_change_mode (GsShell *shell,
|
|
||||||
GsShellMode mode,
|
|
||||||
gpointer data,
|
|
||||||
--
|
|
||||||
GitLab
|
|
||||||
|
|
||||||
|
|
||||||
From ca49eb3974e220ff17262c6189e3cdf0a92746fe Mon Sep 17 00:00:00 2001
|
|
||||||
From: Milan Crha <mcrha@redhat.com>
|
|
||||||
Date: Tue, 5 Oct 2021 19:45:10 +0200
|
|
||||||
Subject: [PATCH 2/5] gs-application: Introduce gs_application_refresh()
|
|
||||||
|
|
||||||
It can be used to call a non-interactive refresh call for the plugins.
|
|
||||||
---
|
|
||||||
src/gs-application.c | 28 ++++++++++++++++++++++++++++
|
|
||||||
src/gs-application.h | 3 ++-
|
|
||||||
2 files changed, 30 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/gs-application.c b/src/gs-application.c
|
|
||||||
index 90487df62..df982df19 100644
|
|
||||||
--- a/src/gs-application.c
|
|
||||||
+++ b/src/gs-application.c
|
|
||||||
@@ -1371,3 +1371,31 @@ gs_application_emit_install_resources_done (GsApplication *application,
|
|
||||||
{
|
|
||||||
g_signal_emit (application, signals[INSTALL_RESOURCES_DONE], 0, ident, op_error, NULL);
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+static void
|
|
||||||
+gs_application_refresh_cb (GsPluginLoader *plugin_loader,
|
|
||||||
+ GAsyncResult *result,
|
|
||||||
+ GsApplication *self)
|
|
||||||
+{
|
|
||||||
+ gboolean success;
|
|
||||||
+ g_autoptr(GError) error = NULL;
|
|
||||||
+
|
|
||||||
+ success = gs_plugin_loader_job_action_finish (plugin_loader, result, &error);
|
|
||||||
+ if (!success &&
|
|
||||||
+ !g_error_matches (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_CANCELLED))
|
|
||||||
+ g_warning ("failed to refresh: %s", error->message);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+gs_application_refresh (GsApplication *self)
|
|
||||||
+{
|
|
||||||
+ g_autoptr(GsPluginJob) plugin_job = NULL;
|
|
||||||
+ plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_REFRESH,
|
|
||||||
+ "interactive", FALSE,
|
|
||||||
+ "age", (guint64) 1,
|
|
||||||
+ NULL);
|
|
||||||
+ gs_plugin_loader_job_process_async (self->plugin_loader, plugin_job,
|
|
||||||
+ self->cancellable,
|
|
||||||
+ (GAsyncReadyCallback) gs_application_refresh_cb,
|
|
||||||
+ self);
|
|
||||||
+}
|
|
||||||
diff --git a/src/gs-application.h b/src/gs-application.h
|
|
||||||
index 40bad4d4c..92978e1f5 100644
|
|
||||||
--- a/src/gs-application.h
|
|
||||||
+++ b/src/gs-application.h
|
|
||||||
@@ -23,4 +23,5 @@ gboolean gs_application_has_active_window (GsApplication *application);
|
|
||||||
void gs_application_emit_install_resources_done
|
|
||||||
(GsApplication *application,
|
|
||||||
const gchar *ident,
|
|
||||||
- const GError *op_error);
|
|
||||||
\ No newline at end of file
|
|
||||||
+ const GError *op_error);
|
|
||||||
+void gs_application_refresh (GsApplication *self);
|
|
||||||
--
|
|
||||||
GitLab
|
|
||||||
|
|
||||||
|
|
||||||
From 2781d350a9a9ee1fd2078928f4e0933a34e05b9f Mon Sep 17 00:00:00 2001
|
|
||||||
From: Milan Crha <mcrha@redhat.com>
|
|
||||||
Date: Tue, 5 Oct 2021 19:46:17 +0200
|
|
||||||
Subject: [PATCH 3/5] gs-repos-dialog: Call refresh on repository setup change
|
|
||||||
|
|
||||||
When a repository is enabled/disabled/removed, call also the refresh
|
|
||||||
on the plugins, thus the data from those repos are available for the user.
|
|
||||||
|
|
||||||
Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1486
|
|
||||||
---
|
|
||||||
src/gs-repos-dialog.c | 16 ++++++++++++++++
|
|
||||||
1 file changed, 16 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/src/gs-repos-dialog.c b/src/gs-repos-dialog.c
|
|
||||||
index 1d6a82f48..c986ad724 100644
|
|
||||||
--- a/src/gs-repos-dialog.c
|
|
||||||
+++ b/src/gs-repos-dialog.c
|
|
||||||
@@ -13,6 +13,7 @@
|
|
||||||
#include "gs-repos-dialog.h"
|
|
||||||
|
|
||||||
#include "gnome-software-private.h"
|
|
||||||
+#include "gs-application.h"
|
|
||||||
#include "gs-common.h"
|
|
||||||
#include "gs-os-release.h"
|
|
||||||
#include "gs-repo-row.h"
|
|
||||||
@@ -35,6 +36,8 @@ struct _GsReposDialog
|
|
||||||
GtkWidget *content_page;
|
|
||||||
GtkWidget *spinner;
|
|
||||||
GtkWidget *stack;
|
|
||||||
+
|
|
||||||
+ gboolean changed;
|
|
||||||
};
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (GsReposDialog, gs_repos_dialog, HDY_TYPE_WINDOW)
|
|
||||||
@@ -115,6 +118,8 @@ repo_enabled_cb (GObject *source,
|
|
||||||
}
|
|
||||||
|
|
||||||
g_debug ("finished %s repo %s", action_str, gs_app_get_id (install_remove_data->repo));
|
|
||||||
+
|
|
||||||
+ install_remove_data->dialog->changed = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
@@ -710,6 +715,17 @@ gs_repos_dialog_dispose (GObject *object)
|
|
||||||
g_clear_object (&dialog->cancellable);
|
|
||||||
g_clear_object (&dialog->settings);
|
|
||||||
|
|
||||||
+ if (dialog->changed) {
|
|
||||||
+ GApplication *app;
|
|
||||||
+
|
|
||||||
+ dialog->changed = FALSE;
|
|
||||||
+ g_debug ("Repository setup changed, calling refresh...");
|
|
||||||
+
|
|
||||||
+ app = g_application_get_default ();
|
|
||||||
+ if (app)
|
|
||||||
+ gs_application_refresh (GS_APPLICATION (app));
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
G_OBJECT_CLASS (gs_repos_dialog_parent_class)->dispose (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
GitLab
|
|
||||||
|
|
||||||
|
|
||||||
From 4c6f4f20c904600a3c5d8ea446ed3c3b0ef0808d Mon Sep 17 00:00:00 2001
|
|
||||||
From: Milan Crha <mcrha@redhat.com>
|
|
||||||
Date: Wed, 6 Oct 2021 14:41:55 +0200
|
|
||||||
Subject: [PATCH 4/5] gs-application: Invoke page reload after the refresh is
|
|
||||||
finished
|
|
||||||
|
|
||||||
The refresh can cause new applications or alternative sources being
|
|
||||||
found in the newly enabled repositories, thus reload the pages, to
|
|
||||||
reflect the current state.
|
|
||||||
---
|
|
||||||
src/gs-application.c | 3 +++
|
|
||||||
1 file changed, 3 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/src/gs-application.c b/src/gs-application.c
|
|
||||||
index df982df19..6ecc093f1 100644
|
|
||||||
--- a/src/gs-application.c
|
|
||||||
+++ b/src/gs-application.c
|
|
||||||
@@ -1384,6 +1384,9 @@ gs_application_refresh_cb (GsPluginLoader *plugin_loader,
|
|
||||||
if (!success &&
|
|
||||||
!g_error_matches (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_CANCELLED))
|
|
||||||
g_warning ("failed to refresh: %s", error->message);
|
|
||||||
+
|
|
||||||
+ if (success)
|
|
||||||
+ g_signal_emit_by_name (self->plugin_loader, "reload", 0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
--
|
|
||||||
GitLab
|
|
||||||
|
|
||||||
|
|
||||||
From b1277d97ba4495de434eb3be4ea1f17b80ac1ef8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Milan Crha <mcrha@redhat.com>
|
|
||||||
Date: Wed, 6 Oct 2021 14:44:09 +0200
|
|
||||||
Subject: [PATCH 5/5] gs-overview-page: Refresh the application after
|
|
||||||
third-party repositories enable/disable
|
|
||||||
|
|
||||||
The enable/disable can cause other applications being found, thus call
|
|
||||||
the refresh, to update the repositories information.
|
|
||||||
---
|
|
||||||
src/gs-overview-page.c | 7 +++++++
|
|
||||||
1 file changed, 7 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/src/gs-overview-page.c b/src/gs-overview-page.c
|
|
||||||
index 9ba33fb2b..bcf02243d 100644
|
|
||||||
--- a/src/gs-overview-page.c
|
|
||||||
+++ b/src/gs-overview-page.c
|
|
||||||
@@ -13,6 +13,7 @@
|
|
||||||
#include <handy.h>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
+#include "gs-application.h"
|
|
||||||
#include "gs-shell.h"
|
|
||||||
#include "gs-overview-page.h"
|
|
||||||
#include "gs-app-list-private.h"
|
|
||||||
@@ -568,6 +569,8 @@ third_party_response_cb (GtkInfoBar *info_bar,
|
|
||||||
gint response_id,
|
|
||||||
GsOverviewPage *self)
|
|
||||||
{
|
|
||||||
+ GApplication *application;
|
|
||||||
+
|
|
||||||
if (response_id == GTK_RESPONSE_YES)
|
|
||||||
fedora_third_party_enable (self);
|
|
||||||
else
|
|
||||||
@@ -575,6 +578,10 @@ third_party_response_cb (GtkInfoBar *info_bar,
|
|
||||||
|
|
||||||
self->third_party_needs_question = FALSE;
|
|
||||||
refresh_third_party_repo (self);
|
|
||||||
+
|
|
||||||
+ application = g_application_get_default ();
|
|
||||||
+ if (application)
|
|
||||||
+ gs_application_refresh (GS_APPLICATION (application));
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
--
|
|
||||||
GitLab
|
|
||||||
|
|
@ -1,331 +0,0 @@
|
|||||||
From 03ea59cc8db6bec34d56205d62ec495315e9ea96 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Milan Crha <mcrha@redhat.com>
|
|
||||||
Date: Tue, 21 Sep 2021 13:55:57 +0200
|
|
||||||
Subject: [PATCH 1/5] gs-page: Use correct action when install/remove repo app
|
|
||||||
|
|
||||||
Since the split of the install/remove action for apps and repos
|
|
||||||
the GsPage should use correct action too. This can happen for example
|
|
||||||
when installing a .flatpakrepo file.
|
|
||||||
---
|
|
||||||
src/gs-page.c | 10 ++++++++--
|
|
||||||
1 file changed, 8 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/gs-page.c b/src/gs-page.c
|
|
||||||
index ca1fbfc70..dfaadbc39 100644
|
|
||||||
--- a/src/gs-page.c
|
|
||||||
+++ b/src/gs-page.c
|
|
||||||
@@ -280,7 +280,10 @@ gs_page_install_app (GsPage *page,
|
|
||||||
}
|
|
||||||
|
|
||||||
helper = g_slice_new0 (GsPageHelper);
|
|
||||||
- helper->action = GS_PLUGIN_ACTION_INSTALL;
|
|
||||||
+ if (gs_app_get_kind (app) == AS_COMPONENT_KIND_REPOSITORY)
|
|
||||||
+ helper->action = GS_PLUGIN_ACTION_INSTALL_REPO;
|
|
||||||
+ else
|
|
||||||
+ helper->action = GS_PLUGIN_ACTION_INSTALL;
|
|
||||||
helper->app = g_object_ref (app);
|
|
||||||
helper->page = g_object_ref (page);
|
|
||||||
helper->cancellable = g_object_ref (cancellable);
|
|
||||||
@@ -466,7 +469,10 @@ gs_page_remove_app (GsPage *page, GsApp *app, GCancellable *cancellable)
|
|
||||||
|
|
||||||
/* pending install */
|
|
||||||
helper = g_slice_new0 (GsPageHelper);
|
|
||||||
- helper->action = GS_PLUGIN_ACTION_REMOVE;
|
|
||||||
+ if (gs_app_get_kind (app) == AS_COMPONENT_KIND_REPOSITORY)
|
|
||||||
+ helper->action = GS_PLUGIN_ACTION_REMOVE_REPO;
|
|
||||||
+ else
|
|
||||||
+ helper->action = GS_PLUGIN_ACTION_REMOVE;
|
|
||||||
helper->app = g_object_ref (app);
|
|
||||||
helper->page = g_object_ref (page);
|
|
||||||
helper->cancellable = cancellable != NULL ? g_object_ref (cancellable) : NULL;
|
|
||||||
--
|
|
||||||
GitLab
|
|
||||||
|
|
||||||
|
|
||||||
From 576f9e6d25fcd3edd7fdf769e342a382af1307e3 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Milan Crha <mcrha@redhat.com>
|
|
||||||
Date: Tue, 21 Sep 2021 13:58:03 +0200
|
|
||||||
Subject: [PATCH 2/5] flatpak: Save also remote's filter on the flatpak-app
|
|
||||||
|
|
||||||
This can be used when updating existing remote, to reflect the new
|
|
||||||
filter. It can be also used to verify the installed and existing
|
|
||||||
remotes match with its filter.
|
|
||||||
---
|
|
||||||
plugins/flatpak/gs-flatpak-app.c | 12 ++++++++++++
|
|
||||||
plugins/flatpak/gs-flatpak-app.h | 3 +++
|
|
||||||
2 files changed, 15 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/plugins/flatpak/gs-flatpak-app.c b/plugins/flatpak/gs-flatpak-app.c
|
|
||||||
index cf98248a8..b59515b2f 100644
|
|
||||||
--- a/plugins/flatpak/gs-flatpak-app.c
|
|
||||||
+++ b/plugins/flatpak/gs-flatpak-app.c
|
|
||||||
@@ -176,3 +176,15 @@ gs_flatpak_app_get_main_app_ref_name (GsApp *app)
|
|
||||||
{
|
|
||||||
return gs_app_get_metadata_item (app, "flatpak::mainApp");
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+gs_flatpak_app_set_repo_filter (GsApp *app, const gchar *filter)
|
|
||||||
+{
|
|
||||||
+ gs_app_set_metadata (app, "flatpak::RepoFilter", filter);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+const gchar *
|
|
||||||
+gs_flatpak_app_get_repo_filter (GsApp *app)
|
|
||||||
+{
|
|
||||||
+ return gs_app_get_metadata_item (app, "flatpak::RepoFilter");
|
|
||||||
+}
|
|
||||||
diff --git a/plugins/flatpak/gs-flatpak-app.h b/plugins/flatpak/gs-flatpak-app.h
|
|
||||||
index ab6c10af4..610c8a8f3 100644
|
|
||||||
--- a/plugins/flatpak/gs-flatpak-app.h
|
|
||||||
+++ b/plugins/flatpak/gs-flatpak-app.h
|
|
||||||
@@ -58,5 +58,8 @@ void gs_flatpak_app_set_runtime_url (GsApp *app,
|
|
||||||
void gs_flatpak_app_set_main_app_ref_name (GsApp *app,
|
|
||||||
const gchar *main_app_ref);
|
|
||||||
const gchar *gs_flatpak_app_get_main_app_ref_name (GsApp *app);
|
|
||||||
+void gs_flatpak_app_set_repo_filter (GsApp *app,
|
|
||||||
+ const gchar *filter);
|
|
||||||
+const gchar *gs_flatpak_app_get_repo_filter (GsApp *app);
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
--
|
|
||||||
GitLab
|
|
||||||
|
|
||||||
|
|
||||||
From cb809158e81157b53245e4c290ada418d5bcd03d Mon Sep 17 00:00:00 2001
|
|
||||||
From: Milan Crha <mcrha@redhat.com>
|
|
||||||
Date: Tue, 21 Sep 2021 14:02:47 +0200
|
|
||||||
Subject: [PATCH 3/5] flatpak: Store filter and description on a remote app
|
|
||||||
|
|
||||||
Store the description also on an installed remote, not only on the file
|
|
||||||
remote. Similarly store also the filters for the remotes.
|
|
||||||
---
|
|
||||||
plugins/flatpak/gs-flatpak-utils.c | 14 ++++++++++++++
|
|
||||||
1 file changed, 14 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/plugins/flatpak/gs-flatpak-utils.c b/plugins/flatpak/gs-flatpak-utils.c
|
|
||||||
index 8b107b37c..7aa735b0b 100644
|
|
||||||
--- a/plugins/flatpak/gs-flatpak-utils.c
|
|
||||||
+++ b/plugins/flatpak/gs-flatpak-utils.c
|
|
||||||
@@ -72,6 +72,8 @@ gs_flatpak_app_new_from_remote (GsPlugin *plugin,
|
|
||||||
{
|
|
||||||
g_autofree gchar *title = NULL;
|
|
||||||
g_autofree gchar *url = NULL;
|
|
||||||
+ g_autofree gchar *filter = NULL;
|
|
||||||
+ g_autofree gchar *description = NULL;
|
|
||||||
g_autoptr(GsApp) app = NULL;
|
|
||||||
|
|
||||||
app = gs_flatpak_app_new (flatpak_remote_get_name (xremote));
|
|
||||||
@@ -101,11 +103,19 @@ gs_flatpak_app_new_from_remote (GsPlugin *plugin,
|
|
||||||
* not the remote title */
|
|
||||||
gs_app_set_origin_ui (app, _("Applications"));
|
|
||||||
|
|
||||||
+ description = flatpak_remote_get_description (xremote);
|
|
||||||
+ if (description != NULL)
|
|
||||||
+ gs_app_set_description (app, GS_APP_QUALITY_NORMAL, description);
|
|
||||||
+
|
|
||||||
/* url */
|
|
||||||
url = flatpak_remote_get_url (xremote);
|
|
||||||
if (url != NULL)
|
|
||||||
gs_app_set_url (app, AS_URL_KIND_HOMEPAGE, url);
|
|
||||||
|
|
||||||
+ filter = flatpak_remote_get_filter (xremote);
|
|
||||||
+ if (filter != NULL)
|
|
||||||
+ gs_flatpak_app_set_repo_filter (app, filter);
|
|
||||||
+
|
|
||||||
/* success */
|
|
||||||
return g_steal_pointer (&app);
|
|
||||||
}
|
|
||||||
@@ -127,6 +137,7 @@ gs_flatpak_app_new_from_repo_file (GFile *file,
|
|
||||||
g_autofree gchar *repo_id = NULL;
|
|
||||||
g_autofree gchar *repo_title = NULL;
|
|
||||||
g_autofree gchar *repo_url = NULL;
|
|
||||||
+ g_autofree gchar *repo_filter = NULL;
|
|
||||||
g_autoptr(GError) error_local = NULL;
|
|
||||||
g_autoptr(GKeyFile) kf = NULL;
|
|
||||||
g_autoptr(GsApp) app = NULL;
|
|
||||||
@@ -229,6 +240,9 @@ gs_flatpak_app_new_from_repo_file (GFile *file,
|
|
||||||
g_autoptr(GIcon) icon = gs_remote_icon_new (repo_icon);
|
|
||||||
gs_app_add_icon (app, icon);
|
|
||||||
}
|
|
||||||
+ repo_filter = g_key_file_get_string (kf, "Flatpak Repo", "Filter", NULL);
|
|
||||||
+ if (repo_filter != NULL && *repo_filter != '\0')
|
|
||||||
+ gs_flatpak_app_set_repo_filter (app, repo_filter);
|
|
||||||
|
|
||||||
/* success */
|
|
||||||
return g_steal_pointer (&app);
|
|
||||||
--
|
|
||||||
GitLab
|
|
||||||
|
|
||||||
|
|
||||||
From a4f8501e3e54b702b5ff2af4bb9aaf6f8d6c324c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Milan Crha <mcrha@redhat.com>
|
|
||||||
Date: Tue, 21 Sep 2021 14:05:03 +0200
|
|
||||||
Subject: [PATCH 4/5] flatpak: Match existing and file remote only if it
|
|
||||||
matches also the filter
|
|
||||||
|
|
||||||
The filter can change the content, thus match two remotes only if also
|
|
||||||
the filter matches.
|
|
||||||
---
|
|
||||||
plugins/flatpak/gs-plugin-flatpak.c | 2 ++
|
|
||||||
1 file changed, 2 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/plugins/flatpak/gs-plugin-flatpak.c b/plugins/flatpak/gs-plugin-flatpak.c
|
|
||||||
index 9bdfa80bf..29ba29700 100644
|
|
||||||
--- a/plugins/flatpak/gs-plugin-flatpak.c
|
|
||||||
+++ b/plugins/flatpak/gs-plugin-flatpak.c
|
|
||||||
@@ -1287,6 +1287,8 @@ gs_plugin_flatpak_file_to_app_repo (GsPlugin *plugin,
|
|
||||||
g_debug ("%s", error_local->message);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
+ if (g_strcmp0 (gs_flatpak_app_get_repo_filter (app), gs_flatpak_app_get_repo_filter (app_tmp)) != 0)
|
|
||||||
+ continue;
|
|
||||||
return g_steal_pointer (&app_tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
GitLab
|
|
||||||
|
|
||||||
|
|
||||||
From 2a94efbda64d94ba6ac27cfd08190b62f52df000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Milan Crha <mcrha@redhat.com>
|
|
||||||
Date: Tue, 21 Sep 2021 14:06:35 +0200
|
|
||||||
Subject: [PATCH 5/5] flatpak: Update existing remote from a .flatpakref file
|
|
||||||
|
|
||||||
Update existing remote's title, description and filter when installing
|
|
||||||
a .flatpakref file, to match what had been installed, with new-enough
|
|
||||||
flatpak library.
|
|
||||||
|
|
||||||
Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1453
|
|
||||||
---
|
|
||||||
plugins/flatpak/gs-flatpak-utils.c | 6 ++++++
|
|
||||||
plugins/flatpak/gs-flatpak.c | 11 +++++++++--
|
|
||||||
2 files changed, 15 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/plugins/flatpak/gs-flatpak-utils.c b/plugins/flatpak/gs-flatpak-utils.c
|
|
||||||
index 7aa735b0b..ec0b397e3 100644
|
|
||||||
--- a/plugins/flatpak/gs-flatpak-utils.c
|
|
||||||
+++ b/plugins/flatpak/gs-flatpak-utils.c
|
|
||||||
@@ -72,8 +72,10 @@ gs_flatpak_app_new_from_remote (GsPlugin *plugin,
|
|
||||||
{
|
|
||||||
g_autofree gchar *title = NULL;
|
|
||||||
g_autofree gchar *url = NULL;
|
|
||||||
+ #if FLATPAK_CHECK_VERSION(1, 4, 0)
|
|
||||||
g_autofree gchar *filter = NULL;
|
|
||||||
g_autofree gchar *description = NULL;
|
|
||||||
+ #endif
|
|
||||||
g_autoptr(GsApp) app = NULL;
|
|
||||||
|
|
||||||
app = gs_flatpak_app_new (flatpak_remote_get_name (xremote));
|
|
||||||
@@ -103,18 +105,22 @@ gs_flatpak_app_new_from_remote (GsPlugin *plugin,
|
|
||||||
* not the remote title */
|
|
||||||
gs_app_set_origin_ui (app, _("Applications"));
|
|
||||||
|
|
||||||
+ #if FLATPAK_CHECK_VERSION(1, 4, 0)
|
|
||||||
description = flatpak_remote_get_description (xremote);
|
|
||||||
if (description != NULL)
|
|
||||||
gs_app_set_description (app, GS_APP_QUALITY_NORMAL, description);
|
|
||||||
+ #endif
|
|
||||||
|
|
||||||
/* url */
|
|
||||||
url = flatpak_remote_get_url (xremote);
|
|
||||||
if (url != NULL)
|
|
||||||
gs_app_set_url (app, AS_URL_KIND_HOMEPAGE, url);
|
|
||||||
|
|
||||||
+ #if FLATPAK_CHECK_VERSION(1, 4, 0)
|
|
||||||
filter = flatpak_remote_get_filter (xremote);
|
|
||||||
if (filter != NULL)
|
|
||||||
gs_flatpak_app_set_repo_filter (app, filter);
|
|
||||||
+ #endif
|
|
||||||
|
|
||||||
/* success */
|
|
||||||
return g_steal_pointer (&app);
|
|
||||||
diff --git a/plugins/flatpak/gs-flatpak.c b/plugins/flatpak/gs-flatpak.c
|
|
||||||
index 55a91af2a..fa7df00c9 100644
|
|
||||||
--- a/plugins/flatpak/gs-flatpak.c
|
|
||||||
+++ b/plugins/flatpak/gs-flatpak.c
|
|
||||||
@@ -1608,9 +1608,16 @@ gs_flatpak_app_install_source (GsFlatpak *self,
|
|
||||||
gs_app_get_id (app),
|
|
||||||
cancellable, NULL);
|
|
||||||
if (xremote != NULL) {
|
|
||||||
- /* if the remote already exists, just enable it */
|
|
||||||
- g_debug ("enabling existing remote %s", flatpak_remote_get_name (xremote));
|
|
||||||
+ /* if the remote already exists, just enable it and update it */
|
|
||||||
+ g_debug ("modifying existing remote %s", flatpak_remote_get_name (xremote));
|
|
||||||
flatpak_remote_set_disabled (xremote, FALSE);
|
|
||||||
+ if (gs_flatpak_app_get_file_kind (app) == GS_FLATPAK_APP_FILE_KIND_REPO) {
|
|
||||||
+ flatpak_remote_set_title (xremote, gs_app_get_origin_ui (app));
|
|
||||||
+ #if FLATPAK_CHECK_VERSION(1, 4, 0)
|
|
||||||
+ flatpak_remote_set_filter (xremote, gs_flatpak_app_get_repo_filter (app));
|
|
||||||
+ flatpak_remote_set_description (xremote, gs_app_get_description (app));
|
|
||||||
+ #endif
|
|
||||||
+ }
|
|
||||||
} else if (!is_install) {
|
|
||||||
g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "Cannot enable flatpak remote '%s', remote not found", gs_app_get_id (app));
|
|
||||||
} else {
|
|
||||||
--
|
|
||||||
GitLab
|
|
||||||
|
|
||||||
From 1a32bd3eaaf7ec0322c46599e3b949080a410806 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Milan Crha <mcrha@redhat.com>
|
|
||||||
Date: Thu, 7 Oct 2021 19:28:38 +0200
|
|
||||||
Subject: [PATCH] flatpak: Update remote appstream data when its filter changed
|
|
||||||
|
|
||||||
When overwriting existing remote, make sure the appstream data is updated
|
|
||||||
as well when the filter changed, to have shown relevant applications.
|
|
||||||
|
|
||||||
Related to https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1453
|
|
||||||
---
|
|
||||||
plugins/flatpak/gs-flatpak.c | 18 +++++++++++++++++-
|
|
||||||
1 file changed, 17 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/plugins/flatpak/gs-flatpak.c b/plugins/flatpak/gs-flatpak.c
|
|
||||||
index bd87d57ed..88bb69a72 100644
|
|
||||||
--- a/plugins/flatpak/gs-flatpak.c
|
|
||||||
+++ b/plugins/flatpak/gs-flatpak.c
|
|
||||||
@@ -1623,6 +1623,9 @@ gs_flatpak_app_install_source (GsFlatpak *self,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
g_autoptr(FlatpakRemote) xremote = NULL;
|
|
||||||
+ #if FLATPAK_CHECK_VERSION(1, 4, 0)
|
|
||||||
+ gboolean filter_changed = FALSE;
|
|
||||||
+ #endif
|
|
||||||
|
|
||||||
xremote = flatpak_installation_get_remote_by_name (self->installation,
|
|
||||||
gs_app_get_id (app),
|
|
||||||
@@ -1632,11 +1635,13 @@ gs_flatpak_app_install_source (GsFlatpak *self,
|
|
||||||
g_debug ("modifying existing remote %s", flatpak_remote_get_name (xremote));
|
|
||||||
flatpak_remote_set_disabled (xremote, FALSE);
|
|
||||||
if (gs_flatpak_app_get_file_kind (app) == GS_FLATPAK_APP_FILE_KIND_REPO) {
|
|
||||||
- flatpak_remote_set_title (xremote, gs_app_get_origin_ui (app));
|
|
||||||
#if FLATPAK_CHECK_VERSION(1, 4, 0)
|
|
||||||
+ g_autofree gchar *current_filter = flatpak_remote_get_filter (xremote);
|
|
||||||
+ filter_changed = g_strcmp0 (current_filter, gs_flatpak_app_get_repo_filter (app)) != 0;
|
|
||||||
flatpak_remote_set_filter (xremote, gs_flatpak_app_get_repo_filter (app));
|
|
||||||
flatpak_remote_set_description (xremote, gs_app_get_description (app));
|
|
||||||
#endif
|
|
||||||
+ flatpak_remote_set_title (xremote, gs_app_get_origin_ui (app));
|
|
||||||
}
|
|
||||||
} else if (!is_install) {
|
|
||||||
g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "Cannot enable flatpak remote '%s', remote not found", gs_app_get_id (app));
|
|
||||||
@@ -1666,6 +1671,17 @@ gs_flatpak_app_install_source (GsFlatpak *self,
|
|
||||||
/* success */
|
|
||||||
gs_app_set_state (app, GS_APP_STATE_INSTALLED);
|
|
||||||
|
|
||||||
+ #if FLATPAK_CHECK_VERSION(1, 4, 0)
|
|
||||||
+ if (filter_changed) {
|
|
||||||
+ g_autoptr(GError) local_error = NULL;
|
|
||||||
+ const gchar *remote_name = flatpak_remote_get_name (xremote);
|
|
||||||
+ if (!flatpak_installation_update_appstream_sync (self->installation, remote_name, NULL, NULL, cancellable, &local_error) &&
|
|
||||||
+ !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
|
||||||
+ g_warning ("Failed to update appstream data for flatpak remote '%s': %s",
|
|
||||||
+ remote_name, local_error->message);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ #endif
|
|
||||||
gs_plugin_repository_changed (self->plugin, app);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
--
|
|
||||||
GitLab
|
|
||||||
|
|
@ -1,163 +0,0 @@
|
|||||||
From 1338c8f47b7ebd0e3bd360499c7ab42a0da885e8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Milan Crha <mcrha@redhat.com>
|
|
||||||
Date: Tue, 5 Oct 2021 16:12:33 +0200
|
|
||||||
Subject: [PATCH 1/2] packagekit: Update GsApp state and kind only when created
|
|
||||||
the app instance
|
|
||||||
|
|
||||||
The gs_plugin_packagekit_add_results() can reuse GsApp instances from
|
|
||||||
the plugin cache, which can already have set property state and kind,
|
|
||||||
but this was not checked for, which could cause runtime warnings about
|
|
||||||
invalid state or kind change.
|
|
||||||
|
|
||||||
A reproducer is to open Repositories dialog, which lists available repositories
|
|
||||||
and the applications being installed in each of them (added as 'related').
|
|
||||||
These installed applications can have set state 'updatable' or have refined
|
|
||||||
their 'kind' already.
|
|
||||||
---
|
|
||||||
plugins/packagekit/packagekit-common.c | 15 +++++++++------
|
|
||||||
1 file changed, 9 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/plugins/packagekit/packagekit-common.c b/plugins/packagekit/packagekit-common.c
|
|
||||||
index 16b53727a..dc79c2f62 100644
|
|
||||||
--- a/plugins/packagekit/packagekit-common.c
|
|
||||||
+++ b/plugins/packagekit/packagekit-common.c
|
|
||||||
@@ -241,12 +241,14 @@ gs_plugin_packagekit_add_results (GsPlugin *plugin,
|
|
||||||
/* process packages */
|
|
||||||
for (i = 0; i < array_filtered->len; i++) {
|
|
||||||
g_autoptr(GsApp) app = NULL;
|
|
||||||
+ GsAppState state = GS_APP_STATE_UNKNOWN;
|
|
||||||
package = g_ptr_array_index (array_filtered, i);
|
|
||||||
|
|
||||||
app = gs_plugin_cache_lookup (plugin, pk_package_get_id (package));
|
|
||||||
if (app == NULL) {
|
|
||||||
app = gs_app_new (NULL);
|
|
||||||
gs_plugin_packagekit_set_packaging_format (plugin, app);
|
|
||||||
+ gs_app_set_management_plugin (app, "packagekit");
|
|
||||||
gs_app_add_source (app, pk_package_get_name (package));
|
|
||||||
gs_app_add_source_id (app, pk_package_get_id (package));
|
|
||||||
gs_plugin_cache_add (plugin, pk_package_get_id (package), app);
|
|
||||||
@@ -259,14 +261,13 @@ gs_plugin_packagekit_add_results (GsPlugin *plugin,
|
|
||||||
pk_package_get_summary (package));
|
|
||||||
gs_app_set_metadata (app, "GnomeSoftware::Creator",
|
|
||||||
gs_plugin_get_name (plugin));
|
|
||||||
- gs_app_set_management_plugin (app, "packagekit");
|
|
||||||
gs_app_set_version (app, pk_package_get_version (package));
|
|
||||||
switch (pk_package_get_info (package)) {
|
|
||||||
case PK_INFO_ENUM_INSTALLED:
|
|
||||||
- gs_app_set_state (app, GS_APP_STATE_INSTALLED);
|
|
||||||
+ state = GS_APP_STATE_INSTALLED;
|
|
||||||
break;
|
|
||||||
case PK_INFO_ENUM_AVAILABLE:
|
|
||||||
- gs_app_set_state (app, GS_APP_STATE_AVAILABLE);
|
|
||||||
+ state = GS_APP_STATE_AVAILABLE;
|
|
||||||
break;
|
|
||||||
case PK_INFO_ENUM_INSTALLING:
|
|
||||||
case PK_INFO_ENUM_UPDATING:
|
|
||||||
@@ -276,14 +277,16 @@ gs_plugin_packagekit_add_results (GsPlugin *plugin,
|
|
||||||
break;
|
|
||||||
case PK_INFO_ENUM_UNAVAILABLE:
|
|
||||||
case PK_INFO_ENUM_REMOVING:
|
|
||||||
- gs_app_set_state (app, GS_APP_STATE_UNAVAILABLE);
|
|
||||||
+ state = GS_APP_STATE_UNAVAILABLE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
- gs_app_set_state (app, GS_APP_STATE_UNKNOWN);
|
|
||||||
g_warning ("unknown info state of %s",
|
|
||||||
pk_info_enum_to_string (pk_package_get_info (package)));
|
|
||||||
}
|
|
||||||
- gs_app_set_kind (app, AS_COMPONENT_KIND_GENERIC);
|
|
||||||
+ if (state != GS_APP_STATE_UNKNOWN && gs_app_get_state (app) == GS_APP_STATE_UNKNOWN)
|
|
||||||
+ gs_app_set_state (app, state);
|
|
||||||
+ if (gs_app_get_kind (app) == AS_COMPONENT_KIND_UNKNOWN)
|
|
||||||
+ gs_app_set_kind (app, AS_COMPONENT_KIND_GENERIC);
|
|
||||||
gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE);
|
|
||||||
gs_app_list_add (list, app);
|
|
||||||
}
|
|
||||||
--
|
|
||||||
GitLab
|
|
||||||
|
|
||||||
|
|
||||||
From 18a893fa83ebd10cea75831e9d9a7398a60c14ce Mon Sep 17 00:00:00 2001
|
|
||||||
From: Milan Crha <mcrha@redhat.com>
|
|
||||||
Date: Tue, 5 Oct 2021 16:18:22 +0200
|
|
||||||
Subject: [PATCH 2/2] gs-plugin-loader: Ensure correct list is used on the job
|
|
||||||
when refining wildcards
|
|
||||||
|
|
||||||
The plugin job is reused when refining the apps, including the wildcards,
|
|
||||||
but the gs_plugin_loader_run_refine_internal() can be called multiple times,
|
|
||||||
with different lists. Adding refined wildcards to the original list causes
|
|
||||||
invalid data being provided to the called.
|
|
||||||
|
|
||||||
Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1485
|
|
||||||
---
|
|
||||||
lib/gs-plugin-loader.c | 21 ++++++++++++++++++++-
|
|
||||||
1 file changed, 20 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/lib/gs-plugin-loader.c b/lib/gs-plugin-loader.c
|
|
||||||
index 4d5240c32..7f5859a05 100644
|
|
||||||
--- a/lib/gs-plugin-loader.c
|
|
||||||
+++ b/lib/gs-plugin-loader.c
|
|
||||||
@@ -937,14 +937,24 @@ gs_plugin_loader_run_refine_internal (GsPluginLoaderHelper *helper,
|
|
||||||
GCancellable *cancellable,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
+ g_autoptr(GsAppList) previous_list = NULL;
|
|
||||||
+
|
|
||||||
+ if (list != gs_plugin_job_get_list (helper->plugin_job)) {
|
|
||||||
+ previous_list = g_object_ref (gs_plugin_job_get_list (helper->plugin_job));
|
|
||||||
+ gs_plugin_job_set_list (helper->plugin_job, list);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/* try to adopt each application with a plugin */
|
|
||||||
gs_plugin_loader_run_adopt (helper->plugin_loader, list);
|
|
||||||
|
|
||||||
/* run each plugin */
|
|
||||||
if (!gs_plugin_loader_run_refine_filter (helper, list,
|
|
||||||
GS_PLUGIN_REFINE_FLAGS_DEFAULT,
|
|
||||||
- cancellable, error))
|
|
||||||
+ cancellable, error)) {
|
|
||||||
+ if (previous_list != NULL)
|
|
||||||
+ gs_plugin_job_set_list (helper->plugin_job, previous_list);
|
|
||||||
return FALSE;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
/* ensure these are sorted by score */
|
|
||||||
if (gs_plugin_job_has_refine_flags (helper->plugin_job,
|
|
||||||
@@ -983,6 +993,8 @@ gs_plugin_loader_run_refine_internal (GsPluginLoaderHelper *helper,
|
|
||||||
addons_list,
|
|
||||||
cancellable,
|
|
||||||
error)) {
|
|
||||||
+ if (previous_list != NULL)
|
|
||||||
+ gs_plugin_job_set_list (helper->plugin_job, previous_list);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1004,6 +1016,8 @@ gs_plugin_loader_run_refine_internal (GsPluginLoaderHelper *helper,
|
|
||||||
list2,
|
|
||||||
cancellable,
|
|
||||||
error)) {
|
|
||||||
+ if (previous_list != NULL)
|
|
||||||
+ gs_plugin_job_set_list (helper->plugin_job, previous_list);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1032,11 +1046,16 @@ gs_plugin_loader_run_refine_internal (GsPluginLoaderHelper *helper,
|
|
||||||
related_list,
|
|
||||||
cancellable,
|
|
||||||
error)) {
|
|
||||||
+ if (previous_list != NULL)
|
|
||||||
+ gs_plugin_job_set_list (helper->plugin_job, previous_list);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (previous_list != NULL)
|
|
||||||
+ gs_plugin_job_set_list (helper->plugin_job, previous_list);
|
|
||||||
+
|
|
||||||
/* success */
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
--
|
|
||||||
GitLab
|
|
||||||
|
|
@ -1,665 +0,0 @@
|
|||||||
From 429ec744e6cdf2155772d7db463ca193231facdc Mon Sep 17 00:00:00 2001
|
|
||||||
From: Milan Crha <mcrha@redhat.com>
|
|
||||||
Date: Tue, 21 Sep 2021 14:53:27 +0200
|
|
||||||
Subject: gs-repos-dialog: Cannot disable all 3rd-party repositories
|
|
||||||
|
|
||||||
All the 3rd-party repositories should be disable-able, thus the 3rd-party
|
|
||||||
section should not use the heuristics to disallow disable of some of them.
|
|
||||||
This could be seen on a 'flathub' Flatpak repository installed for
|
|
||||||
the system, which is not allowed to be disabled in the Flatpak section.
|
|
||||||
|
|
||||||
diff --git a/src/gs-repo-row.c b/src/gs-repo-row.c
|
|
||||||
index 57493c2c..7df24e0e 100644
|
|
||||||
--- a/src/gs-repo-row.c
|
|
||||||
+++ b/src/gs-repo-row.c
|
|
||||||
@@ -27,6 +27,7 @@ typedef struct
|
|
||||||
guint busy_counter;
|
|
||||||
gboolean supports_remove;
|
|
||||||
gboolean supports_enable_disable;
|
|
||||||
+ gboolean always_allow_enable_disable;
|
|
||||||
} GsRepoRowPrivate;
|
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_PRIVATE (GsRepoRow, gs_repo_row, GTK_TYPE_LIST_BOX_ROW)
|
|
||||||
@@ -86,7 +87,7 @@ refresh_ui (GsRepoRow *row)
|
|
||||||
is_system_repo = gs_app_has_quirk (priv->repo, GS_APP_QUIRK_PROVENANCE);
|
|
||||||
|
|
||||||
/* Disable for the system repos, if installed */
|
|
||||||
- gtk_widget_set_sensitive (priv->disable_switch, priv->supports_enable_disable && (state_sensitive || !is_system_repo));
|
|
||||||
+ gtk_widget_set_sensitive (priv->disable_switch, priv->supports_enable_disable && (state_sensitive || !is_system_repo || priv->always_allow_enable_disable));
|
|
||||||
gtk_widget_set_visible (priv->remove_button, priv->supports_remove && !is_system_repo);
|
|
||||||
|
|
||||||
/* Set only the 'state' to visually indicate the state is not saved yet */
|
|
||||||
@@ -337,13 +338,30 @@ gs_repo_row_class_init (GsRepoRowClass *klass)
|
|
||||||
gtk_widget_class_bind_template_child_private (widget_class, GsRepoRow, disable_switch);
|
|
||||||
}
|
|
||||||
|
|
||||||
+/*
|
|
||||||
+ * gs_repo_row_new:
|
|
||||||
+ * @plugin_loader: a #GsPluginLoader
|
|
||||||
+ * @repo: a #GsApp to represent the repo in the new row
|
|
||||||
+ * @always_allow_enable_disable: always allow enabled/disable of the @repo
|
|
||||||
+ *
|
|
||||||
+ * The @plugin_loader is used to check which operations the associated plugin
|
|
||||||
+ * for the @repo can do and which not, to show only relevant buttons on the row.
|
|
||||||
+ *
|
|
||||||
+ * The @always_allow_enable_disable, when %TRUE, means that the @repo in this row
|
|
||||||
+ * can be always enabled/disabled by the user, if supported by the related plugin,
|
|
||||||
+ * regardless of the other heuristics, which can avoid the repo enable/disable.
|
|
||||||
+ *
|
|
||||||
+ * Returns: (transfer full): a newly created #GsRepoRow
|
|
||||||
+ */
|
|
||||||
GtkWidget *
|
|
||||||
gs_repo_row_new (GsPluginLoader *plugin_loader,
|
|
||||||
- GsApp *repo)
|
|
||||||
+ GsApp *repo,
|
|
||||||
+ gboolean always_allow_enable_disable)
|
|
||||||
{
|
|
||||||
GsRepoRow *row = g_object_new (GS_TYPE_REPO_ROW, NULL);
|
|
||||||
GsRepoRowPrivate *priv = gs_repo_row_get_instance_private (row);
|
|
||||||
priv->plugin_loader = g_object_ref (plugin_loader);
|
|
||||||
+ priv->always_allow_enable_disable = always_allow_enable_disable;
|
|
||||||
gs_repo_row_set_repo (row, repo);
|
|
||||||
return GTK_WIDGET (row);
|
|
||||||
}
|
|
||||||
diff --git a/src/gs-repo-row.h b/src/gs-repo-row.h
|
|
||||||
index e6f24bc8..83c8cdf4 100644
|
|
||||||
--- a/src/gs-repo-row.h
|
|
||||||
+++ b/src/gs-repo-row.h
|
|
||||||
@@ -25,7 +25,8 @@ struct _GsRepoRowClass
|
|
||||||
};
|
|
||||||
|
|
||||||
GtkWidget *gs_repo_row_new (GsPluginLoader *plugin_loader,
|
|
||||||
- GsApp *repo);
|
|
||||||
+ GsApp *repo,
|
|
||||||
+ gboolean always_allow_enable_disable);
|
|
||||||
GsApp *gs_repo_row_get_repo (GsRepoRow *row);
|
|
||||||
void gs_repo_row_mark_busy (GsRepoRow *row);
|
|
||||||
void gs_repo_row_unmark_busy (GsRepoRow *row);
|
|
||||||
diff --git a/src/gs-repos-dialog.c b/src/gs-repos-dialog.c
|
|
||||||
index 98aa0f20..0f24149c 100644
|
|
||||||
--- a/src/gs-repos-dialog.c
|
|
||||||
+++ b/src/gs-repos-dialog.c
|
|
||||||
@@ -484,7 +484,7 @@ add_repo (GsReposDialog *dialog,
|
|
||||||
origin_ui = g_strdup (gs_app_get_management_plugin (repo));
|
|
||||||
section = g_hash_table_lookup (dialog->sections, origin_ui);
|
|
||||||
if (section == NULL) {
|
|
||||||
- section = gs_repos_section_new (dialog->plugin_loader);
|
|
||||||
+ section = gs_repos_section_new (dialog->plugin_loader, FALSE);
|
|
||||||
hdy_preferences_group_set_title (HDY_PREFERENCES_GROUP (section),
|
|
||||||
origin_ui);
|
|
||||||
g_signal_connect_object (section, "remove-clicked",
|
|
||||||
@@ -627,7 +627,7 @@ get_sources_cb (GsPluginLoader *plugin_loader,
|
|
||||||
gtk_container_add (GTK_CONTAINER (widget), row);
|
|
||||||
gtk_container_add (GTK_CONTAINER (dialog->content_page), widget);
|
|
||||||
|
|
||||||
- section = GS_REPOS_SECTION (gs_repos_section_new (dialog->plugin_loader));
|
|
||||||
+ section = GS_REPOS_SECTION (gs_repos_section_new (dialog->plugin_loader, TRUE));
|
|
||||||
gs_repos_section_set_sort_key (section, "900");
|
|
||||||
g_signal_connect_object (section, "switch-clicked",
|
|
||||||
G_CALLBACK (repo_section_switch_clicked_cb), dialog, 0);
|
|
||||||
diff --git a/src/gs-repos-section.c b/src/gs-repos-section.c
|
|
||||||
index 3bf59ad7..a9b08200 100644
|
|
||||||
--- a/src/gs-repos-section.c
|
|
||||||
+++ b/src/gs-repos-section.c
|
|
||||||
@@ -20,6 +20,7 @@ struct _GsReposSection
|
|
||||||
GtkListBox *list;
|
|
||||||
GsPluginLoader *plugin_loader;
|
|
||||||
gchar *sort_key;
|
|
||||||
+ gboolean always_allow_enable_disable;
|
|
||||||
};
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (GsReposSection, gs_repos_section, HDY_TYPE_PREFERENCES_GROUP)
|
|
||||||
@@ -130,8 +131,23 @@ gs_repos_section_init (GsReposSection *self)
|
|
||||||
G_CALLBACK (gs_repos_section_row_activated_cb), self);
|
|
||||||
}
|
|
||||||
|
|
||||||
+/*
|
|
||||||
+ * gs_repos_section_new:
|
|
||||||
+ * @plugin_loader: a #GsPluginLoader
|
|
||||||
+ * @always_allow_enable_disable: always allow enable/disable of the repos in this section
|
|
||||||
+ *
|
|
||||||
+ * Creates a new #GsReposSection. The %plugin_loader is passed
|
|
||||||
+ * to each #GsRepoRow, the same as the @always_allow_enable_disable.
|
|
||||||
+ *
|
|
||||||
+ * The @always_allow_enable_disable, when %TRUE, means that every repo in this section
|
|
||||||
+ * can be enabled/disabled by the user, if supported by the related plugin, regardless
|
|
||||||
+ * of the other heuristics, which can avoid the repo enable/disable.
|
|
||||||
+ *
|
|
||||||
+ * Returns: (transfer full): a newly created #GsReposSection
|
|
||||||
+ */
|
|
||||||
GtkWidget *
|
|
||||||
-gs_repos_section_new (GsPluginLoader *plugin_loader)
|
|
||||||
+gs_repos_section_new (GsPluginLoader *plugin_loader,
|
|
||||||
+ gboolean always_allow_enable_disable)
|
|
||||||
{
|
|
||||||
GsReposSection *self;
|
|
||||||
|
|
||||||
@@ -140,6 +156,7 @@ gs_repos_section_new (GsPluginLoader *plugin_loader)
|
|
||||||
self = g_object_new (GS_TYPE_REPOS_SECTION, NULL);
|
|
||||||
|
|
||||||
self->plugin_loader = g_object_ref (plugin_loader);
|
|
||||||
+ self->always_allow_enable_disable = always_allow_enable_disable;
|
|
||||||
|
|
||||||
return GTK_WIDGET (self);
|
|
||||||
}
|
|
||||||
@@ -159,7 +176,7 @@ gs_repos_section_add_repo (GsReposSection *self,
|
|
||||||
if (!self->sort_key)
|
|
||||||
self->sort_key = g_strdup (gs_app_get_metadata_item (repo, "GnomeSoftware::SortKey"));
|
|
||||||
|
|
||||||
- row = gs_repo_row_new (self->plugin_loader, repo);
|
|
||||||
+ row = gs_repo_row_new (self->plugin_loader, repo, self->always_allow_enable_disable);
|
|
||||||
|
|
||||||
g_signal_connect (row, "remove-clicked",
|
|
||||||
G_CALLBACK (repo_remove_clicked_cb), self);
|
|
||||||
diff --git a/src/gs-repos-section.h b/src/gs-repos-section.h
|
|
||||||
index 6e29769c..9a58a3e1 100644
|
|
||||||
--- a/src/gs-repos-section.h
|
|
||||||
+++ b/src/gs-repos-section.h
|
|
||||||
@@ -20,7 +20,8 @@ G_BEGIN_DECLS
|
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (GsReposSection, gs_repos_section, GS, REPOS_SECTION, HdyPreferencesGroup)
|
|
||||||
|
|
||||||
-GtkWidget *gs_repos_section_new (GsPluginLoader *plugin_loader);
|
|
||||||
+GtkWidget *gs_repos_section_new (GsPluginLoader *plugin_loader,
|
|
||||||
+ gboolean always_allow_enable_disable);
|
|
||||||
void gs_repos_section_add_repo (GsReposSection *self,
|
|
||||||
GsApp *repo);
|
|
||||||
const gchar *gs_repos_section_get_title (GsReposSection *self);
|
|
||||||
From dca731ff0daf904911dd6815fb9a1b181329c887 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Milan Crha <mcrha@redhat.com>
|
|
||||||
Date: Tue, 5 Oct 2021 11:00:20 +0200
|
|
||||||
Subject: [PATCH 1/4] gs-repo-row: Use GS_APP_QUIRK_COMPULSORY to recognize
|
|
||||||
required repositories
|
|
||||||
|
|
||||||
The GS_APP_QUIRK_PROVENANCE quirk does not mean it's also required repository,
|
|
||||||
thus use the GS_APP_QUIRK_COMPULSORY for repos, which cannot be disabled.
|
|
||||||
The GS_APP_QUIRK_PROVENANCE is used only for repositories, which cannot be removed.
|
|
||||||
---
|
|
||||||
src/gs-repo-row.c | 10 ++++++----
|
|
||||||
1 file changed, 6 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/gs-repo-row.c b/src/gs-repo-row.c
|
|
||||||
index 87926092f..bbf67c194 100644
|
|
||||||
--- a/src/gs-repo-row.c
|
|
||||||
+++ b/src/gs-repo-row.c
|
|
||||||
@@ -48,7 +48,8 @@ refresh_ui (GsRepoRow *row)
|
|
||||||
gboolean active = FALSE;
|
|
||||||
gboolean state_sensitive = FALSE;
|
|
||||||
gboolean busy = priv->busy_counter> 0;
|
|
||||||
- gboolean is_system_repo;
|
|
||||||
+ gboolean is_provenance;
|
|
||||||
+ gboolean is_compulsory;
|
|
||||||
|
|
||||||
if (priv->repo == NULL) {
|
|
||||||
gtk_widget_set_sensitive (priv->disable_switch, FALSE);
|
|
||||||
@@ -87,11 +88,12 @@ refresh_ui (GsRepoRow *row)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
- is_system_repo = gs_app_has_quirk (priv->repo, GS_APP_QUIRK_PROVENANCE);
|
|
||||||
+ is_provenance = gs_app_has_quirk (priv->repo, GS_APP_QUIRK_PROVENANCE);
|
|
||||||
+ is_compulsory = gs_app_has_quirk (priv->repo, GS_APP_QUIRK_COMPULSORY);
|
|
||||||
|
|
||||||
/* Disable for the system repos, if installed */
|
|
||||||
- gtk_widget_set_sensitive (priv->disable_switch, priv->supports_enable_disable && (state_sensitive || !is_system_repo || priv->always_allow_enable_disable));
|
|
||||||
- gtk_widget_set_visible (priv->remove_button, priv->supports_remove && !is_system_repo);
|
|
||||||
+ gtk_widget_set_sensitive (priv->disable_switch, priv->supports_enable_disable && (state_sensitive || !is_compulsory || priv->always_allow_enable_disable));
|
|
||||||
+ gtk_widget_set_visible (priv->remove_button, priv->supports_remove && !is_provenance && !is_compulsory);
|
|
||||||
|
|
||||||
/* Set only the 'state' to visually indicate the state is not saved yet */
|
|
||||||
if (busy)
|
|
||||||
--
|
|
||||||
GitLab
|
|
||||||
|
|
||||||
|
|
||||||
From 026218b9d3211de243dfc49eca8b8d46633882b0 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Milan Crha <mcrha@redhat.com>
|
|
||||||
Date: Tue, 5 Oct 2021 11:03:31 +0200
|
|
||||||
Subject: [PATCH 2/4] gs-plugin-provenance: Improve search speed in list of
|
|
||||||
repositories
|
|
||||||
|
|
||||||
Use a GHashTable for bare repository names and a GPtrArray for those
|
|
||||||
with wildcards. This helps with speed, due to not traversing all
|
|
||||||
the repository names with the fnmatch() call.
|
|
||||||
---
|
|
||||||
plugins/core/gs-plugin-provenance.c | 55 ++++++++++++++++++++---------
|
|
||||||
1 file changed, 38 insertions(+), 17 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/plugins/core/gs-plugin-provenance.c b/plugins/core/gs-plugin-provenance.c
|
|
||||||
index 97ff76798..a72c25a27 100644
|
|
||||||
--- a/plugins/core/gs-plugin-provenance.c
|
|
||||||
+++ b/plugins/core/gs-plugin-provenance.c
|
|
||||||
@@ -19,7 +19,8 @@
|
|
||||||
|
|
||||||
struct GsPluginData {
|
|
||||||
GSettings *settings;
|
|
||||||
- gchar **sources;
|
|
||||||
+ GHashTable *repos; /* gchar *name ~> NULL */
|
|
||||||
+ GPtrArray *wildcards; /* non-NULL, when have names with wildcards */
|
|
||||||
};
|
|
||||||
|
|
||||||
static gchar **
|
|
||||||
@@ -42,8 +43,24 @@ gs_plugin_provenance_settings_changed_cb (GSettings *settings,
|
|
||||||
{
|
|
||||||
GsPluginData *priv = gs_plugin_get_data (plugin);
|
|
||||||
if (g_strcmp0 (key, "official-repos") == 0) {
|
|
||||||
- g_strfreev (priv->sources);
|
|
||||||
- priv->sources = gs_plugin_provenance_get_sources (plugin);
|
|
||||||
+ /* The keys are stolen by the hash table, thus free only the array */
|
|
||||||
+ g_autofree gchar **repos = NULL;
|
|
||||||
+ g_hash_table_remove_all (priv->repos);
|
|
||||||
+ g_clear_pointer (&priv->wildcards, g_ptr_array_unref);
|
|
||||||
+ repos = gs_plugin_provenance_get_sources (plugin);
|
|
||||||
+ for (guint ii = 0; repos && repos[ii]; ii++) {
|
|
||||||
+ if (strchr (repos[ii], '*') ||
|
|
||||||
+ strchr (repos[ii], '?') ||
|
|
||||||
+ strchr (repos[ii], '[')) {
|
|
||||||
+ if (priv->wildcards == NULL)
|
|
||||||
+ priv->wildcards = g_ptr_array_new_with_free_func (g_free);
|
|
||||||
+ g_ptr_array_add (priv->wildcards, g_steal_pointer (&(repos[ii])));
|
|
||||||
+ } else {
|
|
||||||
+ g_hash_table_insert (priv->repos, g_steal_pointer (&(repos[ii])), NULL);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ if (priv->wildcards != NULL)
|
|
||||||
+ g_ptr_array_add (priv->wildcards, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -52,9 +69,10 @@ gs_plugin_initialize (GsPlugin *plugin)
|
|
||||||
{
|
|
||||||
GsPluginData *priv = gs_plugin_alloc_data (plugin, sizeof(GsPluginData));
|
|
||||||
priv->settings = g_settings_new ("org.gnome.software");
|
|
||||||
+ priv->repos = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
|
||||||
g_signal_connect (priv->settings, "changed",
|
|
||||||
G_CALLBACK (gs_plugin_provenance_settings_changed_cb), plugin);
|
|
||||||
- priv->sources = gs_plugin_provenance_get_sources (plugin);
|
|
||||||
+ gs_plugin_provenance_settings_changed_cb (priv->settings, "official-repos", plugin);
|
|
||||||
|
|
||||||
/* after the package source is set */
|
|
||||||
gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_RUN_AFTER, "dummy");
|
|
||||||
@@ -66,7 +84,8 @@ void
|
|
||||||
gs_plugin_destroy (GsPlugin *plugin)
|
|
||||||
{
|
|
||||||
GsPluginData *priv = gs_plugin_get_data (plugin);
|
|
||||||
- g_strfreev (priv->sources);
|
|
||||||
+ g_hash_table_unref (priv->repos);
|
|
||||||
+ g_clear_pointer (&priv->wildcards, g_ptr_array_unref);
|
|
||||||
g_object_unref (priv->settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -74,12 +93,12 @@ static gboolean
|
|
||||||
refine_app (GsPlugin *plugin,
|
|
||||||
GsApp *app,
|
|
||||||
GsPluginRefineFlags flags,
|
|
||||||
+ GHashTable *repos,
|
|
||||||
+ GPtrArray *wildcards,
|
|
||||||
GCancellable *cancellable,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
- GsPluginData *priv = gs_plugin_get_data (plugin);
|
|
||||||
const gchar *origin;
|
|
||||||
- gchar **sources;
|
|
||||||
|
|
||||||
/* not required */
|
|
||||||
if ((flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_PROVENANCE) == 0)
|
|
||||||
@@ -87,14 +106,10 @@ refine_app (GsPlugin *plugin,
|
|
||||||
if (gs_app_has_quirk (app, GS_APP_QUIRK_PROVENANCE))
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
- /* nothing to search */
|
|
||||||
- sources = priv->sources;
|
|
||||||
- if (sources == NULL || sources[0] == NULL)
|
|
||||||
- return TRUE;
|
|
||||||
-
|
|
||||||
/* simple case */
|
|
||||||
origin = gs_app_get_origin (app);
|
|
||||||
- if (origin != NULL && gs_utils_strv_fnmatch (sources, origin)) {
|
|
||||||
+ if (origin != NULL && (g_hash_table_contains (repos, origin) ||
|
|
||||||
+ (wildcards != NULL && gs_utils_strv_fnmatch ((gchar **) wildcards->pdata, origin)))) {
|
|
||||||
gs_app_add_quirk (app, GS_APP_QUIRK_PROVENANCE);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
@@ -103,7 +118,8 @@ refine_app (GsPlugin *plugin,
|
|
||||||
* provenance quirk to the system-configured repositories (but not
|
|
||||||
* user-configured ones). */
|
|
||||||
if (gs_app_get_kind (app) == AS_COMPONENT_KIND_REPOSITORY &&
|
|
||||||
- gs_utils_strv_fnmatch (sources, gs_app_get_id (app))) {
|
|
||||||
+ (g_hash_table_contains (repos, gs_app_get_id (app)) ||
|
|
||||||
+ (wildcards != NULL && gs_utils_strv_fnmatch ((gchar **) wildcards->pdata, gs_app_get_id (app))))) {
|
|
||||||
if (gs_app_get_scope (app) != AS_COMPONENT_SCOPE_USER)
|
|
||||||
gs_app_add_quirk (app, GS_APP_QUIRK_PROVENANCE);
|
|
||||||
return TRUE;
|
|
||||||
@@ -118,7 +134,8 @@ refine_app (GsPlugin *plugin,
|
|
||||||
return TRUE;
|
|
||||||
if (g_str_has_prefix (origin + 1, "installed:"))
|
|
||||||
origin += 10;
|
|
||||||
- if (gs_utils_strv_fnmatch (sources, origin + 1)) {
|
|
||||||
+ if (g_hash_table_contains (repos, origin + 1) ||
|
|
||||||
+ (wildcards != NULL && gs_utils_strv_fnmatch ((gchar **) wildcards->pdata, origin + 1))) {
|
|
||||||
gs_app_add_quirk (app, GS_APP_QUIRK_PROVENANCE);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
@@ -133,17 +150,21 @@ gs_plugin_refine (GsPlugin *plugin,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
GsPluginData *priv = gs_plugin_get_data (plugin);
|
|
||||||
+ g_autoptr(GHashTable) repos = NULL;
|
|
||||||
+ g_autoptr(GPtrArray) wildcards = NULL;
|
|
||||||
|
|
||||||
/* nothing to do here */
|
|
||||||
if ((flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_PROVENANCE) == 0)
|
|
||||||
return TRUE;
|
|
||||||
+ repos = g_hash_table_ref (priv->repos);
|
|
||||||
+ wildcards = priv->wildcards != NULL ? g_ptr_array_ref (priv->wildcards) : NULL;
|
|
||||||
/* nothing to search */
|
|
||||||
- if (priv->sources == NULL || priv->sources[0] == NULL)
|
|
||||||
+ if (g_hash_table_size (repos) == 0)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
for (guint i = 0; i < gs_app_list_length (list); i++) {
|
|
||||||
GsApp *app = gs_app_list_index (list, i);
|
|
||||||
- if (!refine_app (plugin, app, flags, cancellable, error))
|
|
||||||
+ if (!refine_app (plugin, app, flags, repos, wildcards, cancellable, error))
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
GitLab
|
|
||||||
|
|
||||||
|
|
||||||
From b5e3356aff5fcd257248f9bb697e272c879249ae Mon Sep 17 00:00:00 2001
|
|
||||||
From: Milan Crha <mcrha@redhat.com>
|
|
||||||
Date: Tue, 5 Oct 2021 13:03:44 +0200
|
|
||||||
Subject: [PATCH 3/4] settings: Add 'required-repos' key
|
|
||||||
|
|
||||||
To be used to list repositories, which cannot be removed or disabled.
|
|
||||||
It's a complementary option for the 'official-repos' key.
|
|
||||||
---
|
|
||||||
data/org.gnome.software.gschema.xml | 4 ++++
|
|
||||||
1 file changed, 4 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/data/org.gnome.software.gschema.xml b/data/org.gnome.software.gschema.xml
|
|
||||||
index db1c27ce4..0e5706b7c 100644
|
|
||||||
--- a/data/org.gnome.software.gschema.xml
|
|
||||||
+++ b/data/org.gnome.software.gschema.xml
|
|
||||||
@@ -94,6 +94,10 @@
|
|
||||||
<default>[]</default>
|
|
||||||
<summary>A list of official repositories that should not be considered 3rd party</summary>
|
|
||||||
</key>
|
|
||||||
+ <key name="required-repos" type="as">
|
|
||||||
+ <default>[]</default>
|
|
||||||
+ <summary>A list of required repositories that cannot be disabled or removed</summary>
|
|
||||||
+ </key>
|
|
||||||
<key name="free-repos" type="as">
|
|
||||||
<default>[]</default>
|
|
||||||
<summary>A list of official repositories that should be considered free software</summary>
|
|
||||||
--
|
|
||||||
GitLab
|
|
||||||
|
|
||||||
|
|
||||||
From d6b8b206a596bb520a0b77066898b44a5ef18920 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Milan Crha <mcrha@redhat.com>
|
|
||||||
Date: Tue, 5 Oct 2021 14:16:56 +0200
|
|
||||||
Subject: [PATCH 4/4] gs-plugin-provenance: Handle also 'required-repos' key
|
|
||||||
|
|
||||||
Let it handle also 'required-repos' settings key, beside the 'official-repos'
|
|
||||||
key, which are close enough to share the same code and memory. With this
|
|
||||||
done the repositories can be marked as compulsory, independently from the official
|
|
||||||
repositories.
|
|
||||||
|
|
||||||
Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1479
|
|
||||||
---
|
|
||||||
plugins/core/gs-plugin-provenance.c | 142 +++++++++++++++++++++-------
|
|
||||||
1 file changed, 108 insertions(+), 34 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/plugins/core/gs-plugin-provenance.c b/plugins/core/gs-plugin-provenance.c
|
|
||||||
index a72c25a27..22f3c98e1 100644
|
|
||||||
--- a/plugins/core/gs-plugin-provenance.c
|
|
||||||
+++ b/plugins/core/gs-plugin-provenance.c
|
|
||||||
@@ -14,26 +14,61 @@
|
|
||||||
/*
|
|
||||||
* SECTION:
|
|
||||||
* Sets the package provenance to TRUE if installed by an official
|
|
||||||
- * software source.
|
|
||||||
+ * software source. Also sets compulsory quirk when a required repository.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct GsPluginData {
|
|
||||||
GSettings *settings;
|
|
||||||
- GHashTable *repos; /* gchar *name ~> NULL */
|
|
||||||
- GPtrArray *wildcards; /* non-NULL, when have names with wildcards */
|
|
||||||
+ GHashTable *repos; /* gchar *name ~> guint flags */
|
|
||||||
+ GPtrArray *provenance_wildcards; /* non-NULL, when have names with wildcards */
|
|
||||||
+ GPtrArray *compulsory_wildcards; /* non-NULL, when have names with wildcards */
|
|
||||||
};
|
|
||||||
|
|
||||||
+static GHashTable *
|
|
||||||
+gs_plugin_provenance_remove_by_flag (GHashTable *old_repos,
|
|
||||||
+ GsAppQuirk quirk)
|
|
||||||
+{
|
|
||||||
+ GHashTable *new_repos = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
|
||||||
+ GHashTableIter iter;
|
|
||||||
+ gpointer key, value;
|
|
||||||
+ g_hash_table_iter_init (&iter, old_repos);
|
|
||||||
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
|
|
||||||
+ guint flags = GPOINTER_TO_UINT (value);
|
|
||||||
+ flags = flags & (~quirk);
|
|
||||||
+ if (flags != 0)
|
|
||||||
+ g_hash_table_insert (new_repos, g_strdup (key), GUINT_TO_POINTER (flags));
|
|
||||||
+ }
|
|
||||||
+ return new_repos;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void
|
|
||||||
+gs_plugin_provenance_add_quirks (GsApp *app,
|
|
||||||
+ guint quirks)
|
|
||||||
+{
|
|
||||||
+ GsAppQuirk array[] = {
|
|
||||||
+ GS_APP_QUIRK_PROVENANCE,
|
|
||||||
+ GS_APP_QUIRK_COMPULSORY
|
|
||||||
+ };
|
|
||||||
+ for (guint ii = 0; ii < G_N_ELEMENTS (array); ii++) {
|
|
||||||
+ if ((quirks & array[ii]) != 0)
|
|
||||||
+ gs_app_add_quirk (app, array[ii]);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static gchar **
|
|
||||||
-gs_plugin_provenance_get_sources (GsPlugin *plugin)
|
|
||||||
+gs_plugin_provenance_get_sources (GsPlugin *plugin,
|
|
||||||
+ const gchar *key)
|
|
||||||
{
|
|
||||||
GsPluginData *priv = gs_plugin_get_data (plugin);
|
|
||||||
const gchar *tmp;
|
|
||||||
tmp = g_getenv ("GS_SELF_TEST_PROVENANCE_SOURCES");
|
|
||||||
if (tmp != NULL) {
|
|
||||||
+ if (g_strcmp0 (key, "required-repos") == 0)
|
|
||||||
+ return NULL;
|
|
||||||
g_debug ("using custom provenance sources of %s", tmp);
|
|
||||||
return g_strsplit (tmp, ",", -1);
|
|
||||||
}
|
|
||||||
- return g_settings_get_strv (priv->settings, "official-repos");
|
|
||||||
+ return g_settings_get_strv (priv->settings, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
@@ -42,25 +77,43 @@ gs_plugin_provenance_settings_changed_cb (GSettings *settings,
|
|
||||||
GsPlugin *plugin)
|
|
||||||
{
|
|
||||||
GsPluginData *priv = gs_plugin_get_data (plugin);
|
|
||||||
+ GsAppQuirk quirk = GS_APP_QUIRK_NONE;
|
|
||||||
+ GPtrArray **pwildcards = NULL;
|
|
||||||
+
|
|
||||||
if (g_strcmp0 (key, "official-repos") == 0) {
|
|
||||||
+ quirk = GS_APP_QUIRK_PROVENANCE;
|
|
||||||
+ pwildcards = &priv->provenance_wildcards;
|
|
||||||
+ } else if (g_strcmp0 (key, "required-repos") == 0) {
|
|
||||||
+ quirk = GS_APP_QUIRK_COMPULSORY;
|
|
||||||
+ pwildcards = &priv->compulsory_wildcards;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (quirk != GS_APP_QUIRK_NONE) {
|
|
||||||
/* The keys are stolen by the hash table, thus free only the array */
|
|
||||||
g_autofree gchar **repos = NULL;
|
|
||||||
- g_hash_table_remove_all (priv->repos);
|
|
||||||
- g_clear_pointer (&priv->wildcards, g_ptr_array_unref);
|
|
||||||
- repos = gs_plugin_provenance_get_sources (plugin);
|
|
||||||
+ g_autoptr(GHashTable) old_repos = priv->repos;
|
|
||||||
+ g_autoptr(GPtrArray) old_wildcards = *pwildcards;
|
|
||||||
+ GHashTable *new_repos = gs_plugin_provenance_remove_by_flag (old_repos, quirk);
|
|
||||||
+ GPtrArray *new_wildcards = NULL;
|
|
||||||
+ repos = gs_plugin_provenance_get_sources (plugin, key);
|
|
||||||
for (guint ii = 0; repos && repos[ii]; ii++) {
|
|
||||||
- if (strchr (repos[ii], '*') ||
|
|
||||||
- strchr (repos[ii], '?') ||
|
|
||||||
- strchr (repos[ii], '[')) {
|
|
||||||
- if (priv->wildcards == NULL)
|
|
||||||
- priv->wildcards = g_ptr_array_new_with_free_func (g_free);
|
|
||||||
- g_ptr_array_add (priv->wildcards, g_steal_pointer (&(repos[ii])));
|
|
||||||
+ gchar *repo = g_steal_pointer (&(repos[ii]));
|
|
||||||
+ if (strchr (repo, '*') ||
|
|
||||||
+ strchr (repo, '?') ||
|
|
||||||
+ strchr (repo, '[')) {
|
|
||||||
+ if (new_wildcards == NULL)
|
|
||||||
+ new_wildcards = g_ptr_array_new_with_free_func (g_free);
|
|
||||||
+ g_ptr_array_add (new_wildcards, repo);
|
|
||||||
} else {
|
|
||||||
- g_hash_table_insert (priv->repos, g_steal_pointer (&(repos[ii])), NULL);
|
|
||||||
+ g_hash_table_insert (new_repos, repo,
|
|
||||||
+ GUINT_TO_POINTER (quirk |
|
|
||||||
+ GPOINTER_TO_UINT (g_hash_table_lookup (new_repos, repo))));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- if (priv->wildcards != NULL)
|
|
||||||
- g_ptr_array_add (priv->wildcards, NULL);
|
|
||||||
+ if (new_wildcards != NULL)
|
|
||||||
+ g_ptr_array_add (new_wildcards, NULL);
|
|
||||||
+ priv->repos = new_repos;
|
|
||||||
+ *pwildcards = new_wildcards;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -73,6 +126,7 @@ gs_plugin_initialize (GsPlugin *plugin)
|
|
||||||
g_signal_connect (priv->settings, "changed",
|
|
||||||
G_CALLBACK (gs_plugin_provenance_settings_changed_cb), plugin);
|
|
||||||
gs_plugin_provenance_settings_changed_cb (priv->settings, "official-repos", plugin);
|
|
||||||
+ gs_plugin_provenance_settings_changed_cb (priv->settings, "required-repos", plugin);
|
|
||||||
|
|
||||||
/* after the package source is set */
|
|
||||||
gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_RUN_AFTER, "dummy");
|
|
||||||
@@ -85,20 +139,42 @@ gs_plugin_destroy (GsPlugin *plugin)
|
|
||||||
{
|
|
||||||
GsPluginData *priv = gs_plugin_get_data (plugin);
|
|
||||||
g_hash_table_unref (priv->repos);
|
|
||||||
- g_clear_pointer (&priv->wildcards, g_ptr_array_unref);
|
|
||||||
+ g_clear_pointer (&priv->provenance_wildcards, g_ptr_array_unref);
|
|
||||||
+ g_clear_pointer (&priv->compulsory_wildcards, g_ptr_array_unref);
|
|
||||||
g_object_unref (priv->settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
+static gboolean
|
|
||||||
+gs_plugin_provenance_find_repo_flags (GHashTable *repos,
|
|
||||||
+ GPtrArray *provenance_wildcards,
|
|
||||||
+ GPtrArray *compulsory_wildcards,
|
|
||||||
+ const gchar *repo,
|
|
||||||
+ guint *out_flags)
|
|
||||||
+{
|
|
||||||
+ if (repo == NULL || *repo == '\0')
|
|
||||||
+ return FALSE;
|
|
||||||
+ *out_flags = GPOINTER_TO_UINT (g_hash_table_lookup (repos, repo));
|
|
||||||
+ if (provenance_wildcards != NULL &&
|
|
||||||
+ gs_utils_strv_fnmatch ((gchar **) provenance_wildcards->pdata, repo))
|
|
||||||
+ *out_flags |= GS_APP_QUIRK_PROVENANCE;
|
|
||||||
+ if (compulsory_wildcards != NULL &&
|
|
||||||
+ gs_utils_strv_fnmatch ((gchar **) compulsory_wildcards->pdata, repo))
|
|
||||||
+ *out_flags |= GS_APP_QUIRK_COMPULSORY;
|
|
||||||
+ return *out_flags != 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static gboolean
|
|
||||||
refine_app (GsPlugin *plugin,
|
|
||||||
GsApp *app,
|
|
||||||
GsPluginRefineFlags flags,
|
|
||||||
GHashTable *repos,
|
|
||||||
- GPtrArray *wildcards,
|
|
||||||
+ GPtrArray *provenance_wildcards,
|
|
||||||
+ GPtrArray *compulsory_wildcards,
|
|
||||||
GCancellable *cancellable,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
const gchar *origin;
|
|
||||||
+ guint quirks;
|
|
||||||
|
|
||||||
/* not required */
|
|
||||||
if ((flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_PROVENANCE) == 0)
|
|
||||||
@@ -108,9 +184,8 @@ refine_app (GsPlugin *plugin,
|
|
||||||
|
|
||||||
/* simple case */
|
|
||||||
origin = gs_app_get_origin (app);
|
|
||||||
- if (origin != NULL && (g_hash_table_contains (repos, origin) ||
|
|
||||||
- (wildcards != NULL && gs_utils_strv_fnmatch ((gchar **) wildcards->pdata, origin)))) {
|
|
||||||
- gs_app_add_quirk (app, GS_APP_QUIRK_PROVENANCE);
|
|
||||||
+ if (gs_plugin_provenance_find_repo_flags (repos, provenance_wildcards, compulsory_wildcards, origin, &quirks)) {
|
|
||||||
+ gs_plugin_provenance_add_quirks (app, quirks);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -118,10 +193,9 @@ refine_app (GsPlugin *plugin,
|
|
||||||
* provenance quirk to the system-configured repositories (but not
|
|
||||||
* user-configured ones). */
|
|
||||||
if (gs_app_get_kind (app) == AS_COMPONENT_KIND_REPOSITORY &&
|
|
||||||
- (g_hash_table_contains (repos, gs_app_get_id (app)) ||
|
|
||||||
- (wildcards != NULL && gs_utils_strv_fnmatch ((gchar **) wildcards->pdata, gs_app_get_id (app))))) {
|
|
||||||
+ gs_plugin_provenance_find_repo_flags (repos, provenance_wildcards, compulsory_wildcards, gs_app_get_id (app), &quirks)) {
|
|
||||||
if (gs_app_get_scope (app) != AS_COMPONENT_SCOPE_USER)
|
|
||||||
- gs_app_add_quirk (app, GS_APP_QUIRK_PROVENANCE);
|
|
||||||
+ gs_plugin_provenance_add_quirks (app, quirks);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -134,11 +208,9 @@ refine_app (GsPlugin *plugin,
|
|
||||||
return TRUE;
|
|
||||||
if (g_str_has_prefix (origin + 1, "installed:"))
|
|
||||||
origin += 10;
|
|
||||||
- if (g_hash_table_contains (repos, origin + 1) ||
|
|
||||||
- (wildcards != NULL && gs_utils_strv_fnmatch ((gchar **) wildcards->pdata, origin + 1))) {
|
|
||||||
- gs_app_add_quirk (app, GS_APP_QUIRK_PROVENANCE);
|
|
||||||
- return TRUE;
|
|
||||||
- }
|
|
||||||
+ if (gs_plugin_provenance_find_repo_flags (repos, provenance_wildcards, compulsory_wildcards, origin + 1, &quirks))
|
|
||||||
+ gs_plugin_provenance_add_quirks (app, quirks);
|
|
||||||
+
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -151,20 +223,22 @@ gs_plugin_refine (GsPlugin *plugin,
|
|
||||||
{
|
|
||||||
GsPluginData *priv = gs_plugin_get_data (plugin);
|
|
||||||
g_autoptr(GHashTable) repos = NULL;
|
|
||||||
- g_autoptr(GPtrArray) wildcards = NULL;
|
|
||||||
+ g_autoptr(GPtrArray) provenance_wildcards = NULL;
|
|
||||||
+ g_autoptr(GPtrArray) compulsory_wildcards = NULL;
|
|
||||||
|
|
||||||
/* nothing to do here */
|
|
||||||
if ((flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_PROVENANCE) == 0)
|
|
||||||
return TRUE;
|
|
||||||
repos = g_hash_table_ref (priv->repos);
|
|
||||||
- wildcards = priv->wildcards != NULL ? g_ptr_array_ref (priv->wildcards) : NULL;
|
|
||||||
+ provenance_wildcards = priv->provenance_wildcards != NULL ? g_ptr_array_ref (priv->provenance_wildcards) : NULL;
|
|
||||||
+ compulsory_wildcards = priv->compulsory_wildcards != NULL ? g_ptr_array_ref (priv->compulsory_wildcards) : NULL;
|
|
||||||
/* nothing to search */
|
|
||||||
- if (g_hash_table_size (repos) == 0)
|
|
||||||
+ if (g_hash_table_size (repos) == 0 && provenance_wildcards == NULL && compulsory_wildcards == NULL)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
for (guint i = 0; i < gs_app_list_length (list); i++) {
|
|
||||||
GsApp *app = gs_app_list_index (list, i);
|
|
||||||
- if (!refine_app (plugin, app, flags, repos, wildcards, cancellable, error))
|
|
||||||
+ if (!refine_app (plugin, app, flags, repos, provenance_wildcards, compulsory_wildcards, cancellable, error))
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
GitLab
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
|||||||
From 895d1ca748f4f33a852853f5f07903fb549fb66f Mon Sep 17 00:00:00 2001
|
|
||||||
From: Milan Crha <mcrha@redhat.com>
|
|
||||||
Date: Mon, 11 Oct 2021 09:13:59 +0200
|
|
||||||
Subject: [PATCH] gs-plugin-provenance: Set COMPULSORY quirk only on REPOSITORY
|
|
||||||
apps
|
|
||||||
|
|
||||||
The compulsory quirk related to repositories, which cannot be removed,
|
|
||||||
not to the applications provided by those repositories, thus set that
|
|
||||||
quirk only on repositories, not on the apps from it.
|
|
||||||
|
|
||||||
Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1488
|
|
||||||
---
|
|
||||||
plugins/core/gs-plugin-provenance.c | 13 +++++--------
|
|
||||||
1 file changed, 5 insertions(+), 8 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/plugins/core/gs-plugin-provenance.c b/plugins/core/gs-plugin-provenance.c
|
|
||||||
index 22f3c98e..e44a55f0 100644
|
|
||||||
--- a/plugins/core/gs-plugin-provenance.c
|
|
||||||
+++ b/plugins/core/gs-plugin-provenance.c
|
|
||||||
@@ -45,14 +45,11 @@ static void
|
|
||||||
gs_plugin_provenance_add_quirks (GsApp *app,
|
|
||||||
guint quirks)
|
|
||||||
{
|
|
||||||
- GsAppQuirk array[] = {
|
|
||||||
- GS_APP_QUIRK_PROVENANCE,
|
|
||||||
- GS_APP_QUIRK_COMPULSORY
|
|
||||||
- };
|
|
||||||
- for (guint ii = 0; ii < G_N_ELEMENTS (array); ii++) {
|
|
||||||
- if ((quirks & array[ii]) != 0)
|
|
||||||
- gs_app_add_quirk (app, array[ii]);
|
|
||||||
- }
|
|
||||||
+ if ((quirks & GS_APP_QUIRK_PROVENANCE) != 0)
|
|
||||||
+ gs_app_add_quirk (app, GS_APP_QUIRK_PROVENANCE);
|
|
||||||
+ if ((quirks & GS_APP_QUIRK_COMPULSORY) != 0 &&
|
|
||||||
+ gs_app_get_kind (app) == AS_COMPONENT_KIND_REPOSITORY)
|
|
||||||
+ gs_app_add_quirk (app, GS_APP_QUIRK_COMPULSORY);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gchar **
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
@ -1,264 +0,0 @@
|
|||||||
From 65551cf41c8d6b3dcf0cf9b2ee2d46201b4e0ea4 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Milan Crha <mcrha@redhat.com>
|
|
||||||
Date: Thu, 14 Oct 2021 15:17:52 +0200
|
|
||||||
Subject: [PATCH] gs-installed-page: Change section on application state change
|
|
||||||
|
|
||||||
When an application is being installed, it's shown in the "In Progress"
|
|
||||||
section, but when the installation is finished it had been left in
|
|
||||||
that section, even it belongs to a different section.
|
|
||||||
|
|
||||||
Similarly with the uninstall, the application was sorted to the top
|
|
||||||
of the section, but it might be better to be added to the "In Progress"
|
|
||||||
section.
|
|
||||||
|
|
||||||
Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1492
|
|
||||||
---
|
|
||||||
src/gs-installed-page.c | 168 +++++++++++++++++++++++++++++++++-------
|
|
||||||
1 file changed, 141 insertions(+), 27 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/gs-installed-page.c b/src/gs-installed-page.c
|
|
||||||
index 67a4b7a51..56bf19df7 100644
|
|
||||||
--- a/src/gs-installed-page.c
|
|
||||||
+++ b/src/gs-installed-page.c
|
|
||||||
@@ -59,6 +59,9 @@ static GParamSpec *obj_props[PROP_IS_NARROW + 1] = { NULL, };
|
|
||||||
|
|
||||||
static void gs_installed_page_pending_apps_changed_cb (GsPluginLoader *plugin_loader,
|
|
||||||
GsInstalledPage *self);
|
|
||||||
+static void gs_installed_page_notify_state_changed_cb (GsApp *app,
|
|
||||||
+ GParamSpec *pspec,
|
|
||||||
+ GsInstalledPage *self);
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
GS_UPDATE_LIST_SECTION_INSTALLING_AND_REMOVING,
|
|
||||||
@@ -91,6 +94,30 @@ gs_installed_page_get_app_section (GsApp *app)
|
|
||||||
return GS_UPDATE_LIST_SECTION_ADDONS;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static GsInstalledPageSection
|
|
||||||
+gs_installed_page_get_row_section (GsInstalledPage *self,
|
|
||||||
+ GsAppRow *app_row)
|
|
||||||
+{
|
|
||||||
+ GtkWidget *parent;
|
|
||||||
+
|
|
||||||
+ g_return_val_if_fail (GS_IS_INSTALLED_PAGE (self), GS_UPDATE_LIST_SECTION_LAST);
|
|
||||||
+ g_return_val_if_fail (GS_IS_APP_ROW (app_row), GS_UPDATE_LIST_SECTION_LAST);
|
|
||||||
+
|
|
||||||
+ parent = gtk_widget_get_parent (GTK_WIDGET (app_row));
|
|
||||||
+ if (parent == self->list_box_install_in_progress)
|
|
||||||
+ return GS_UPDATE_LIST_SECTION_INSTALLING_AND_REMOVING;
|
|
||||||
+ if (parent == self->list_box_install_apps)
|
|
||||||
+ return GS_UPDATE_LIST_SECTION_REMOVABLE_APPS;
|
|
||||||
+ if (parent == self->list_box_install_system_apps)
|
|
||||||
+ return GS_UPDATE_LIST_SECTION_SYSTEM_APPS;
|
|
||||||
+ if (parent == self->list_box_install_addons)
|
|
||||||
+ return GS_UPDATE_LIST_SECTION_ADDONS;
|
|
||||||
+
|
|
||||||
+ g_warn_if_reached ();
|
|
||||||
+
|
|
||||||
+ return GS_UPDATE_LIST_SECTION_LAST;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static void
|
|
||||||
gs_installed_page_invalidate (GsInstalledPage *self)
|
|
||||||
{
|
|
||||||
@@ -121,15 +148,29 @@ row_unrevealed (GObject *row, GParamSpec *pspec, gpointer data)
|
|
||||||
static void
|
|
||||||
gs_installed_page_unreveal_row (GsAppRow *app_row)
|
|
||||||
{
|
|
||||||
- g_signal_connect (app_row, "unrevealed",
|
|
||||||
- G_CALLBACK (row_unrevealed), NULL);
|
|
||||||
- gs_app_row_unreveal (app_row);
|
|
||||||
+ GsApp *app = gs_app_row_get_app (app_row);
|
|
||||||
+ if (app != NULL) {
|
|
||||||
+ g_signal_handlers_disconnect_matched (app, G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
|
|
||||||
+ G_CALLBACK (gs_installed_page_notify_state_changed_cb), NULL);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* This check is required, because GsAppRow does not emit
|
|
||||||
+ * the signal when the row is not realized. This can happen
|
|
||||||
+ * when installing/uninstalling an app without visiting
|
|
||||||
+ * the Installed page. */
|
|
||||||
+ if (!gtk_widget_get_mapped (GTK_WIDGET (app_row))) {
|
|
||||||
+ row_unrevealed (G_OBJECT (app_row), NULL, NULL);
|
|
||||||
+ } else {
|
|
||||||
+ g_signal_connect (app_row, "unrevealed",
|
|
||||||
+ G_CALLBACK (row_unrevealed), NULL);
|
|
||||||
+ gs_app_row_unreveal (app_row);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void
|
|
||||||
-gs_installed_page_app_removed (GsPage *page, GsApp *app)
|
|
||||||
+static GsAppRow * /* (transfer none) */
|
|
||||||
+gs_installed_page_find_app_row (GsInstalledPage *self,
|
|
||||||
+ GsApp *app)
|
|
||||||
{
|
|
||||||
- GsInstalledPage *self = GS_INSTALLED_PAGE (page);
|
|
||||||
GtkWidget *lists[] = {
|
|
||||||
self->list_box_install_in_progress,
|
|
||||||
self->list_box_install_apps,
|
|
||||||
@@ -145,10 +186,22 @@ gs_installed_page_app_removed (GsPage *page, GsApp *app)
|
|
||||||
for (GList *l = children; l; l = l->next) {
|
|
||||||
GsAppRow *app_row = GS_APP_ROW (l->data);
|
|
||||||
if (gs_app_row_get_app (app_row) == app) {
|
|
||||||
- gs_installed_page_unreveal_row (app_row);
|
|
||||||
+ return app_row;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ return NULL;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+static void
|
|
||||||
+gs_installed_page_app_removed (GsPage *page, GsApp *app)
|
|
||||||
+{
|
|
||||||
+ GsInstalledPage *self = GS_INSTALLED_PAGE (page);
|
|
||||||
+ GsAppRow *app_row = gs_installed_page_find_app_row (self, app);
|
|
||||||
+ if (app_row != NULL)
|
|
||||||
+ gs_installed_page_unreveal_row (app_row);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
@@ -161,12 +214,56 @@ gs_installed_page_app_remove_cb (GsAppRow *app_row,
|
|
||||||
gs_page_remove_app (GS_PAGE (self), app, self->cancellable);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static gboolean
|
|
||||||
-gs_installed_page_invalidate_sort_idle (gpointer user_data)
|
|
||||||
+static void
|
|
||||||
+gs_installed_page_maybe_move_app_row (GsInstalledPage *self,
|
|
||||||
+ GsAppRow *app_row)
|
|
||||||
+{
|
|
||||||
+ GsInstalledPageSection current_section, expected_section;
|
|
||||||
+
|
|
||||||
+ current_section = gs_installed_page_get_row_section (self, app_row);
|
|
||||||
+ g_return_if_fail (current_section != GS_UPDATE_LIST_SECTION_LAST);
|
|
||||||
+
|
|
||||||
+ expected_section = gs_installed_page_get_app_section (gs_app_row_get_app (app_row));
|
|
||||||
+ if (expected_section != current_section) {
|
|
||||||
+ GtkWidget *widget = GTK_WIDGET (app_row);
|
|
||||||
+
|
|
||||||
+ g_object_ref (app_row);
|
|
||||||
+ gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (widget)), widget);
|
|
||||||
+ switch (expected_section) {
|
|
||||||
+ case GS_UPDATE_LIST_SECTION_INSTALLING_AND_REMOVING:
|
|
||||||
+ widget = self->list_box_install_in_progress;
|
|
||||||
+ break;
|
|
||||||
+ case GS_UPDATE_LIST_SECTION_REMOVABLE_APPS:
|
|
||||||
+ widget = self->list_box_install_apps;
|
|
||||||
+ break;
|
|
||||||
+ case GS_UPDATE_LIST_SECTION_SYSTEM_APPS:
|
|
||||||
+ widget = self->list_box_install_system_apps;
|
|
||||||
+ break;
|
|
||||||
+ case GS_UPDATE_LIST_SECTION_ADDONS:
|
|
||||||
+ widget = self->list_box_install_addons;
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ g_warn_if_reached ();
|
|
||||||
+ widget = NULL;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (widget != NULL)
|
|
||||||
+ gtk_container_add (GTK_CONTAINER (widget), GTK_WIDGET (app_row));
|
|
||||||
+
|
|
||||||
+ g_object_unref (app_row);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void
|
|
||||||
+gs_installed_page_notify_state_changed_cb (GsApp *app,
|
|
||||||
+ GParamSpec *pspec,
|
|
||||||
+ GsInstalledPage *self)
|
|
||||||
{
|
|
||||||
- GsAppRow *app_row = user_data;
|
|
||||||
- GsApp *app = gs_app_row_get_app (app_row);
|
|
||||||
GsAppState state = gs_app_get_state (app);
|
|
||||||
+ GsAppRow *app_row = gs_installed_page_find_app_row (self, app);
|
|
||||||
+
|
|
||||||
+ g_assert (app_row != NULL);
|
|
||||||
|
|
||||||
gtk_list_box_row_changed (GTK_LIST_BOX_ROW (app_row));
|
|
||||||
|
|
||||||
@@ -177,17 +274,8 @@ gs_installed_page_invalidate_sort_idle (gpointer user_data)
|
|
||||||
state != GS_APP_STATE_UPDATABLE &&
|
|
||||||
state != GS_APP_STATE_UPDATABLE_LIVE)
|
|
||||||
gs_installed_page_unreveal_row (app_row);
|
|
||||||
-
|
|
||||||
- g_object_unref (app_row);
|
|
||||||
- return G_SOURCE_REMOVE;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static void
|
|
||||||
-gs_installed_page_notify_state_changed_cb (GsApp *app,
|
|
||||||
- GParamSpec *pspec,
|
|
||||||
- GsAppRow *app_row)
|
|
||||||
-{
|
|
||||||
- g_idle_add (gs_installed_page_invalidate_sort_idle, g_object_ref (app_row));
|
|
||||||
+ else
|
|
||||||
+ gs_installed_page_maybe_move_app_row (self, app_row);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
@@ -229,7 +317,7 @@ gs_installed_page_add_app (GsInstalledPage *self, GsAppList *list, GsApp *app)
|
|
||||||
G_CALLBACK (gs_installed_page_app_remove_cb), self);
|
|
||||||
g_signal_connect_object (app, "notify::state",
|
|
||||||
G_CALLBACK (gs_installed_page_notify_state_changed_cb),
|
|
||||||
- app_row, 0);
|
|
||||||
+ self, 0);
|
|
||||||
|
|
||||||
switch (gs_installed_page_get_app_section (app)) {
|
|
||||||
case GS_UPDATE_LIST_SECTION_INSTALLING_AND_REMOVING:
|
|
||||||
@@ -294,6 +382,32 @@ out:
|
|
||||||
gs_installed_page_pending_apps_changed_cb (plugin_loader, self);
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void
|
|
||||||
+gs_installed_page_remove_all_cb (GtkWidget *child,
|
|
||||||
+ gpointer user_data)
|
|
||||||
+{
|
|
||||||
+ GtkContainer *container = user_data;
|
|
||||||
+
|
|
||||||
+ if (GS_IS_APP_ROW (child)) {
|
|
||||||
+ GsApp *app = gs_app_row_get_app (GS_APP_ROW (child));
|
|
||||||
+ if (app != NULL) {
|
|
||||||
+ g_signal_handlers_disconnect_matched (app, G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
|
|
||||||
+ G_CALLBACK (gs_installed_page_notify_state_changed_cb), NULL);
|
|
||||||
+ }
|
|
||||||
+ } else {
|
|
||||||
+ g_warn_if_reached ();
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ gtk_container_remove (container, child);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void
|
|
||||||
+gs_container_remove_all_with_cb (GtkContainer *container,
|
|
||||||
+ GtkCallback callback)
|
|
||||||
+{
|
|
||||||
+ gtk_container_foreach (container, callback, container);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static void
|
|
||||||
gs_installed_page_load (GsInstalledPage *self)
|
|
||||||
{
|
|
||||||
@@ -305,10 +419,10 @@ gs_installed_page_load (GsInstalledPage *self)
|
|
||||||
self->waiting = TRUE;
|
|
||||||
|
|
||||||
/* remove old entries */
|
|
||||||
- gs_container_remove_all (GTK_CONTAINER (self->list_box_install_in_progress));
|
|
||||||
- gs_container_remove_all (GTK_CONTAINER (self->list_box_install_apps));
|
|
||||||
- gs_container_remove_all (GTK_CONTAINER (self->list_box_install_system_apps));
|
|
||||||
- gs_container_remove_all (GTK_CONTAINER (self->list_box_install_addons));
|
|
||||||
+ gs_container_remove_all_with_cb (GTK_CONTAINER (self->list_box_install_in_progress), gs_installed_page_remove_all_cb);
|
|
||||||
+ gs_container_remove_all_with_cb (GTK_CONTAINER (self->list_box_install_apps), gs_installed_page_remove_all_cb);
|
|
||||||
+ gs_container_remove_all_with_cb (GTK_CONTAINER (self->list_box_install_system_apps), gs_installed_page_remove_all_cb);
|
|
||||||
+ gs_container_remove_all_with_cb (GTK_CONTAINER (self->list_box_install_addons), gs_installed_page_remove_all_cb);
|
|
||||||
|
|
||||||
flags = GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON |
|
|
||||||
GS_PLUGIN_REFINE_FLAGS_REQUIRE_HISTORY |
|
|
||||||
--
|
|
||||||
GitLab
|
|
||||||
|
|
@ -11,8 +11,8 @@
|
|||||||
%global tarball_version %%(echo %{version} | tr '~' '.')
|
%global tarball_version %%(echo %{version} | tr '~' '.')
|
||||||
|
|
||||||
Name: gnome-software
|
Name: gnome-software
|
||||||
Version: 41.0
|
Version: 41.1
|
||||||
Release: 6%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: A software center for GNOME
|
Summary: A software center for GNOME
|
||||||
|
|
||||||
License: GPLv2+
|
License: GPLv2+
|
||||||
@ -20,13 +20,6 @@ URL: https://wiki.gnome.org/Apps/Software
|
|||||||
Source0: https://download.gnome.org/sources/gnome-software/41/%{name}-%{tarball_version}.tar.xz
|
Source0: https://download.gnome.org/sources/gnome-software/41/%{name}-%{tarball_version}.tar.xz
|
||||||
|
|
||||||
Patch01: 0001-crash-with-broken-theme.patch
|
Patch01: 0001-crash-with-broken-theme.patch
|
||||||
Patch02: 0002-correct-update-notifications.patch
|
|
||||||
Patch03: 0003-refresh-on-repository-change.patch
|
|
||||||
Patch04: 0004-filtered-system-flathub.patch
|
|
||||||
Patch05: 0005-repos-dialog-can-show-apps.patch
|
|
||||||
Patch06: 0006-optional-repos-cannot-be-disabled.patch
|
|
||||||
Patch07: 0007-compulsory-only-for-repos.patch
|
|
||||||
Patch08: 0008-installed-page-section-change.patch
|
|
||||||
|
|
||||||
BuildRequires: appstream-devel >= %{appstream_version}
|
BuildRequires: appstream-devel >= %{appstream_version}
|
||||||
BuildRequires: gcc
|
BuildRequires: gcc
|
||||||
@ -210,6 +203,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop
|
|||||||
%{_datadir}/gtk-doc/html/gnome-software
|
%{_datadir}/gtk-doc/html/gnome-software
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri Oct 29 2021 Milan Crha <mcrha@redhat.com> - 41.1-1
|
||||||
|
- Update to 41.1
|
||||||
|
|
||||||
* Tue Oct 19 2021 Milan Crha <mcrha@redhat.com> - 41.0-6
|
* Tue Oct 19 2021 Milan Crha <mcrha@redhat.com> - 41.0-6
|
||||||
- Resolves: #2012863 (gs-installed-page: Change section on application state change)
|
- Resolves: #2012863 (gs-installed-page: Change section on application state change)
|
||||||
|
|
||||||
|
2
sources
2
sources
@ -1 +1 @@
|
|||||||
SHA512 (gnome-software-41.0.tar.xz) = 6cc090f835e77d64abb0080d3b72494019d6f69c2144abea4dabdc4f52dc570a372159eb1e0b0d98ae33b31c134cc17673fe3fa243eed762eec55620ab146b26
|
SHA512 (gnome-software-41.1.tar.xz) = e5586d901f9b178961a9030cafbc1ec346d3a52e91af11234d28eaeb7d95e12083d8a9e7e90fb7c64e720b7394e83733fcbb6912ca1ef0bcd2c431acad25fe3c
|
||||||
|
Loading…
Reference in New Issue
Block a user