Resolves: #2012699 (Backport changes from Fedora 35)

This commit is contained in:
Milan Crha 2021-10-12 08:18:24 +02:00
parent 14c5d8fad6
commit 2f222a7ddf
7 changed files with 1567 additions and 1 deletions

View File

@ -0,0 +1,116 @@
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

View File

@ -0,0 +1,233 @@
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

View File

@ -0,0 +1,331 @@
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

View File

@ -0,0 +1,163 @@
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

View File

@ -0,0 +1,665 @@
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

View File

@ -0,0 +1,42 @@
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

View File

@ -12,7 +12,7 @@
Name: gnome-software Name: gnome-software
Version: 41.0 Version: 41.0
Release: 1%{?dist} Release: 2%{?dist}
Summary: A software center for GNOME Summary: A software center for GNOME
License: GPLv2+ License: GPLv2+
@ -20,6 +20,12 @@ 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
BuildRequires: appstream-devel >= %{appstream_version} BuildRequires: appstream-devel >= %{appstream_version}
BuildRequires: gcc BuildRequires: gcc
@ -130,6 +136,7 @@ cat >> %{buildroot}%{_datadir}/glib-2.0/schemas/org.gnome.software-fedora.gschem
official-repos = [ 'rhel-%{?rhel}' ] official-repos = [ 'rhel-%{?rhel}' ]
%else %else
official-repos = [ 'anaconda', 'fedora', 'fedora-debuginfo', 'fedora-source', 'koji-override-0', 'koji-override-1', 'rawhide', 'rawhide-debuginfo', 'rawhide-source', 'updates', 'updates-debuginfo', 'updates-source', 'updates-testing', 'updates-testing-debuginfo', 'updates-testing-source', 'fedora-modular', 'fedora-modular-debuginfo', 'fedora-modular-source', 'rawhide-modular', 'rawhide-modular-debuginfo', 'rawhide-modular-source', 'fedora-cisco-openh264', 'fedora-cisco-openh264-debuginfo' ] official-repos = [ 'anaconda', 'fedora', 'fedora-debuginfo', 'fedora-source', 'koji-override-0', 'koji-override-1', 'rawhide', 'rawhide-debuginfo', 'rawhide-source', 'updates', 'updates-debuginfo', 'updates-source', 'updates-testing', 'updates-testing-debuginfo', 'updates-testing-source', 'fedora-modular', 'fedora-modular-debuginfo', 'fedora-modular-source', 'rawhide-modular', 'rawhide-modular-debuginfo', 'rawhide-modular-source', 'fedora-cisco-openh264', 'fedora-cisco-openh264-debuginfo' ]
required-repos = [ 'fedora', 'updates' ]
%endif %endif
FOE FOE
@ -199,6 +206,15 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop
%{_datadir}/gtk-doc/html/gnome-software %{_datadir}/gtk-doc/html/gnome-software
%changelog %changelog
* Tue Oct 12 2021 Milan Crha <mcrha@redhat.com> - 41.0-2
- Resolves: #2012699 (Backport changes from Fedora 35)
- Add patch to mark compulsory only repos, not apps from it
- Resolves: #2011176 (flathub repo can't be added through gnome-software)
- Resolves: #2010660 (gs-repos-dialog: Can show also desktop applications)
- Resolves: #2010353 (Optional repos cannot be disabled)
- Resolves: #2010740 (Refresh on repository setup change)
- Resolves: #2009063 (Correct update notifications)
* Mon Sep 20 2021 Milan Crha <mcrha@redhat.com> - 41.0-1 * Mon Sep 20 2021 Milan Crha <mcrha@redhat.com> - 41.0-1
- Resolves: #2005770 (Update to 41.0) - Resolves: #2005770 (Update to 41.0)