From 0e8e253a86e7cd11ae6b18761cfbf4ceceafa345 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 15 Jan 2024 11:59:49 +0100 Subject: [PATCH] Resolves: RHEL-843 (Rebase GNOME Software to its GNOME 45 version) --- 0001-Lower_glib_dependency_to_2_68.patch | 198 +++++++ 0001-crash-with-broken-theme.patch | 48 -- 0002-Lower-pango-attributes.patch | 42 ++ 0003-Verify-category-sizes.patch | 335 ++++++++++++ 0006-optional-repos-cannot-be-disabled.patch | 498 ------------------ 0007-compulsory-only-for-repos.patch | 42 -- ...-removal-dialog-crrect-property-name.patch | 12 - 0009-hide-some-errors.patch | 70 --- gnome-software.spec | 173 +++--- sources | 2 +- 10 files changed, 687 insertions(+), 733 deletions(-) create mode 100644 0001-Lower_glib_dependency_to_2_68.patch delete mode 100644 0001-crash-with-broken-theme.patch create mode 100644 0002-Lower-pango-attributes.patch create mode 100644 0003-Verify-category-sizes.patch delete mode 100644 0006-optional-repos-cannot-be-disabled.patch delete mode 100644 0007-compulsory-only-for-repos.patch delete mode 100644 0008-gs-removal-dialog-crrect-property-name.patch delete mode 100644 0009-hide-some-errors.patch diff --git a/0001-Lower_glib_dependency_to_2_68.patch b/0001-Lower_glib_dependency_to_2_68.patch new file mode 100644 index 0000000..074dfa1 --- /dev/null +++ b/0001-Lower_glib_dependency_to_2_68.patch @@ -0,0 +1,198 @@ +diff --git a/lib/gs-fedora-third-party.c b/lib/gs-fedora-third-party.c +index e79bba8..9e7115a 100644 +--- a/lib/gs-fedora-third-party.c ++++ b/lib/gs-fedora-third-party.c +@@ -11,6 +11,10 @@ + + #include "gs-fedora-third-party.h" + ++#if !GLIB_CHECK_VERSION(2, 70, 0) ++#define g_spawn_check_wait_status g_spawn_check_exit_status ++#endif ++ + struct _GsFedoraThirdParty + { + GObject parent_instance; +diff --git a/lib/gs-icon-downloader.c b/lib/gs-icon-downloader.c +index a1a669c..577fda2 100644 +--- a/lib/gs-icon-downloader.c ++++ b/lib/gs-icon-downloader.c +@@ -41,7 +41,7 @@ struct _GsIconDownloader + GCancellable *cancellable; /* (owned) */ + }; + +-G_DEFINE_FINAL_TYPE (GsIconDownloader, gs_icon_downloader, G_TYPE_OBJECT) ++G_DEFINE_TYPE (GsIconDownloader, gs_icon_downloader, G_TYPE_OBJECT) + + typedef enum { + PROP_MAXIMUM_SIZE = 1, +diff --git a/lib/gs-job-manager.c b/lib/gs-job-manager.c +index 98d79a7..694a157 100644 +--- a/lib/gs-job-manager.c ++++ b/lib/gs-job-manager.c +@@ -100,7 +100,9 @@ watch_data_unref (WatchData *data) + watch_free_data_cb, + g_steal_pointer (&data), + (GDestroyNotify) watch_data_unref); ++ #if GLIB_CHECK_VERSION(2, 70, 0) + g_source_set_static_name (idle_source, G_STRFUNC); ++ #endif + g_source_attach (idle_source, callback_context); + + /* Freeing will eventually happen in watch_free_data_cb(). */ +@@ -359,7 +361,9 @@ gs_job_manager_add_job (GsJobManager *self, + watch_call_handler_cb, + g_steal_pointer (&idle_data), + (GDestroyNotify) watch_call_handler_data_free); ++ #if GLIB_CHECK_VERSION(2, 70, 0) + g_source_set_static_name (idle_source, G_STRFUNC); ++ #endif + g_source_attach (idle_source, data->callback_context); + } + } +@@ -420,7 +424,9 @@ gs_job_manager_remove_job (GsJobManager *self, + watch_call_handler_cb, + g_steal_pointer (&idle_data), + (GDestroyNotify) watch_call_handler_data_free); ++ #if GLIB_CHECK_VERSION(2, 70, 0) + g_source_set_static_name (idle_source, G_STRFUNC); ++ #endif + g_source_attach (idle_source, data->callback_context); + } + } +diff --git a/lib/gs-plugin-loader.c b/lib/gs-plugin-loader.c +index 93b33f3..204d55f 100644 +--- a/lib/gs-plugin-loader.c ++++ b/lib/gs-plugin-loader.c +@@ -1965,7 +1965,7 @@ get_session_bus_cb (GObject *object, + plugin_loader->session_bus_connection = g_bus_get_finish (result, &local_error); + if (plugin_loader->session_bus_connection == NULL) { + notify_setup_complete (plugin_loader); +- g_prefix_error_literal (&local_error, "Error getting session bus: "); ++ g_prefix_error (&local_error, "%s", "Error getting session bus: "); + g_task_return_error (task, g_steal_pointer (&local_error)); + return; + } +@@ -1987,7 +1987,7 @@ get_system_bus_cb (GObject *object, + plugin_loader->system_bus_connection = g_bus_get_finish (result, &local_error); + if (plugin_loader->system_bus_connection == NULL) { + notify_setup_complete (plugin_loader); +- g_prefix_error_literal (&local_error, "Error getting system bus: "); ++ g_prefix_error (&local_error, "%s", "Error getting system bus: "); + g_task_return_error (task, g_steal_pointer (&local_error)); + return; + } +@@ -2753,12 +2753,21 @@ gs_plugin_loader_init (GsPluginLoader *plugin_loader) + /* Set up a thread pool for running old-style jobs + * FIXME: This will eventually disappear when all jobs are ported to + * be subclasses of #GsPluginJob. */ ++ #if GLIB_CHECK_VERSION(2, 70, 0) + plugin_loader->old_api_thread_pool = g_thread_pool_new_full (gs_plugin_loader_process_old_api_job_cb, + plugin_loader, + (GDestroyNotify) g_object_unref, + 20, + FALSE, + NULL); ++ #else ++ /* pre-glib 2.70.0 - The items will leak when the thread pool is freed before all jobs are finished */ ++ plugin_loader->old_api_thread_pool = g_thread_pool_new (gs_plugin_loader_process_old_api_job_cb, ++ plugin_loader, ++ 20, ++ FALSE, ++ NULL); ++ #endif + + /* get the job manager */ + plugin_loader->job_manager = gs_job_manager_new (); +diff --git a/meson.build b/meson.build +index da9e7ac..4c847c9 100644 +--- a/meson.build ++++ b/meson.build +@@ -156,7 +156,7 @@ gtk = dependency('gtk4', + 'demos=false', + ] + ) +-glib = dependency('glib-2.0', version : '>= 2.70.0') ++glib = dependency('glib-2.0', version : '>= 2.68.0') + json_glib = dependency('json-glib-1.0', version : '>= 1.6.0') + libm = cc.find_library('m', required: false) + if get_option('soup2') +diff --git a/plugins/flatpak/gs-flatpak.c b/plugins/flatpak/gs-flatpak.c +index c84db84..009a425 100644 +--- a/plugins/flatpak/gs-flatpak.c ++++ b/plugins/flatpak/gs-flatpak.c +@@ -4738,7 +4738,7 @@ gs_flatpak_purge_sync (GsFlatpak *self, + g_autoptr(FlatpakTransaction) transaction = NULL; + transaction = gs_flatpak_transaction_new (installation, GS_FLATPAK_ERROR_MODE_STOP_ON_FIRST_ERROR, cancellable, error); + if (transaction == NULL) { +- g_prefix_error_literal (error, "failed to build transaction: "); ++ g_prefix_error (error, "%s", "failed to build transaction: "); + return FALSE; + } + flatpak_transaction_set_no_interaction (transaction, TRUE); +diff --git a/plugins/fwupd/gs-plugin-fwupd.c b/plugins/fwupd/gs-plugin-fwupd.c +index e931b2b..43c4e9f 100644 +--- a/plugins/fwupd/gs-plugin-fwupd.c ++++ b/plugins/fwupd/gs-plugin-fwupd.c +@@ -1653,7 +1653,7 @@ finish_update_apps_op (GTask *task, + g_autoptr(GsPluginEvent) event = NULL; + + event_error = g_error_copy (error_owned); +- g_prefix_error_literal (&event_error, _("Firmware update could not be applied: ")); ++ g_prefix_error (&event_error, "%s", _("Firmware update could not be applied: ")); + gs_plugin_fwupd_error_convert (&event_error); + + event = gs_plugin_event_new ("app", self->app_current, +diff --git a/plugins/packagekit/gs-plugin-packagekit.c b/plugins/packagekit/gs-plugin-packagekit.c +index 3c5f926..409e831 100644 +--- a/plugins/packagekit/gs-plugin-packagekit.c ++++ b/plugins/packagekit/gs-plugin-packagekit.c +@@ -2040,7 +2040,7 @@ search_files_cb (GObject *source_object, + results = pk_client_generic_finish (client, result, &local_error); + + if (!gs_plugin_packagekit_results_valid (results, g_task_get_cancellable (refine_task), &local_error)) { +- g_prefix_error_literal (&local_error, "failed to search files: "); ++ g_prefix_error (&local_error, "%s", "failed to search files: "); + refine_task_complete_operation_with_error (refine_task, g_steal_pointer (&local_error)); + return; + } +@@ -3071,7 +3071,7 @@ gs_plugin_packagekit_convert_error (GError **error, + break; + } + if (prefix != NULL) +- g_prefix_error_literal (error, prefix); ++ g_prefix_error (error, "%s", prefix); + return FALSE; + } + +diff --git a/src/gs-common.c b/src/gs-common.c +index 997025a..d665c98 100644 +--- a/src/gs-common.c ++++ b/src/gs-common.c +@@ -1027,7 +1027,7 @@ gs_utils_invoke_reboot_ready2_got_session_bus_cb (GObject *source_object, + bus = g_bus_get_finish (result, &local_error); + if (bus == NULL) { + g_dbus_error_strip_remote_error (local_error); +- g_prefix_error_literal (&local_error, "Failed to get D-Bus session bus: "); ++ g_prefix_error (&local_error, "%s", "Failed to get D-Bus session bus: "); + g_task_return_error (task, g_steal_pointer (&local_error)); + return; + } +@@ -1098,7 +1098,7 @@ gs_utils_invoke_reboot_ready1_got_system_bus_cb (GObject *source_object, + bus = g_bus_get_finish (result, &local_error); + if (bus == NULL) { + g_dbus_error_strip_remote_error (local_error); +- g_prefix_error_literal (&local_error, "Failed to get D-Bus system bus: "); ++ g_prefix_error (&local_error, "%s", "Failed to get D-Bus system bus: "); + g_task_return_error (task, g_steal_pointer (&local_error)); + return; + } +@@ -1171,7 +1171,7 @@ gs_utils_invoke_reboot_got_session_bus_cb (GObject *source_object, + bus = g_bus_get_finish (result, &local_error); + if (bus == NULL) { + g_dbus_error_strip_remote_error (local_error); +- g_prefix_error_literal (&local_error, "Failed to get D-Bus session bus: "); ++ g_prefix_error (&local_error, "%s", "Failed to get D-Bus session bus: "); + g_task_return_error (task, g_steal_pointer (&local_error)); + return; + } diff --git a/0001-crash-with-broken-theme.patch b/0001-crash-with-broken-theme.patch deleted file mode 100644 index fd37e80..0000000 --- a/0001-crash-with-broken-theme.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 3a644c151f27f439c36170f0958fd21cf1cc54d0 Mon Sep 17 00:00:00 2001 -From: Milan Crha -Date: Thu, 3 Jun 2021 08:33:53 +0200 -Subject: [PATCH] gs-feature-tile: Do not abort when the theme is broken - -Just print a warning when the theme doesn't provide 'theme_fg_color' and -fallback to black color. - -Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1228 ---- - src/gs-feature-tile.c | 14 +++++++++++--- - 1 file changed, 11 insertions(+), 3 deletions(-) - -diff --git a/src/gs-feature-tile.c b/src/gs-feature-tile.c -index 1c85083eb..158af1e56 100644 ---- a/src/gs-feature-tile.c -+++ b/src/gs-feature-tile.c -@@ -268,7 +268,6 @@ gs_feature_tile_refresh (GsAppTile *self) - if (key_colors != tile->key_colors_cache) { - g_autoptr(GArray) colors = NULL; - GdkRGBA fg_rgba; -- gboolean fg_rgba_valid; - GsHSBC fg_hsbc; - - /* Look up the foreground colour for the feature tile, -@@ -283,8 +282,17 @@ gs_feature_tile_refresh (GsAppTile *self) - * @min_abs_contrast contrast with the foreground, so - * that the text is legible. - */ -- fg_rgba_valid = gtk_style_context_lookup_color (context, "theme_fg_color", &fg_rgba); -- g_assert (fg_rgba_valid); -+ if (!gtk_style_context_lookup_color (context, "theme_fg_color", &fg_rgba)) { -+ static gboolean i_know = FALSE; -+ if (!i_know) { -+ i_know = TRUE; -+ g_warning ("The theme doesn't provide 'theme_fg_color', fallbacking to black"); -+ } -+ fg_rgba.red = 0.0; -+ fg_rgba.green = 0.0; -+ fg_rgba.blue = 0.0; -+ fg_rgba.alpha = 1.0; -+ } - - gtk_rgb_to_hsv (fg_rgba.red, fg_rgba.green, fg_rgba.blue, - &fg_hsbc.hue, &fg_hsbc.saturation, &fg_hsbc.brightness); --- -GitLab - diff --git a/0002-Lower-pango-attributes.patch b/0002-Lower-pango-attributes.patch new file mode 100644 index 0000000..f740e21 --- /dev/null +++ b/0002-Lower-pango-attributes.patch @@ -0,0 +1,42 @@ +diff -up gnome-software-45.2/src/gs-origin-popover-row.ui.2 gnome-software-45.2/src/gs-origin-popover-row.ui +--- gnome-software-45.2/src/gs-origin-popover-row.ui.2 2023-12-08 10:14:07.848934874 +0100 ++++ gnome-software-45.2/src/gs-origin-popover-row.ui 2023-12-08 10:14:10.045961688 +0100 +@@ -79,7 +79,7 @@ + 2 + + +- ++ + + + +@@ -110,7 +110,7 @@ + 2 + + +- ++ + + + +@@ -140,7 +140,7 @@ + 2 + + +- ++ + + + +diff -up gnome-software-45.2/src/gs-review-histogram.ui.2 gnome-software-45.2/src/gs-review-histogram.ui +--- gnome-software-45.2/src/gs-review-histogram.ui.2 2023-12-08 10:15:28.246916110 +0100 ++++ gnome-software-45.2/src/gs-review-histogram.ui 2023-12-01 09:58:33.000000000 +0100 +@@ -18,7 +18,7 @@ + + + +- ++ + + + 0 diff --git a/0003-Verify-category-sizes.patch b/0003-Verify-category-sizes.patch new file mode 100644 index 0000000..09b9357 --- /dev/null +++ b/0003-Verify-category-sizes.patch @@ -0,0 +1,335 @@ +From f7e394840ff84ae8b55f13ff9692d6b02e8e6ea5 Mon Sep 17 00:00:00 2001 +Date: Wed, 20 Dec 2023 12:21:24 +0100 +Subject: [PATCH 1/3] gs-appstream: Increase limit to category apps lookup + +The Overview page currently checks for 100 apps in all categories. +Lookup for the same count per category. + +Note: The counts are not accurate, same apps can be in multiple +sub-categories, thus the parent category count suffers of duplicity, +which the following commit will correct in a different way than +checking for id duplicity. +--- + lib/gs-appstream.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/lib/gs-appstream.c b/lib/gs-appstream.c +index f110e3c47..d600cac53 100644 +--- a/lib/gs-appstream.c ++++ b/lib/gs-appstream.c +@@ -1836,7 +1836,8 @@ static guint + gs_appstream_count_component_for_groups (XbSilo *silo, + const gchar *desktop_group) + { +- guint limit = 10; ++ /* the overview page checks for 100 apps, then try to get them */ ++ const guint limit = 100; + g_autofree gchar *xpath = NULL; + g_auto(GStrv) split = g_strsplit (desktop_group, "::", -1); + g_autoptr(GPtrArray) array = NULL; +@@ -1896,7 +1897,6 @@ gs_appstream_refine_category_sizes (XbSilo *silo, + } + } + } +- continue; + } + return TRUE; + } +-- +GitLab + + +From 617af44a56f6f62e07fd3fc13ae43d688aa3b85f Mon Sep 17 00:00:00 2001 +Date: Wed, 20 Dec 2023 12:24:25 +0100 +Subject: [PATCH 2/3] gs-overview-page: Add debug prints about discovered + categories + +For easier debugging, to see what the plugins returned. +--- + src/gs-overview-page.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/gs-overview-page.c b/src/gs-overview-page.c +index 6ef5079e9..72000e257 100644 +--- a/src/gs-overview-page.c ++++ b/src/gs-overview-page.c +@@ -496,6 +496,7 @@ gs_overview_page_get_categories_cb (GObject *source_object, + + if (gs_category_get_icon_name (cat) != NULL) { + found_apps_cnt += gs_category_get_size (cat); ++ g_debug ("overview page found category '%s' which claims %u apps", gs_category_get_name (cat), gs_category_get_size (cat)); + flowbox = GTK_FLOW_BOX (self->flowbox_categories); + } else + flowbox = GTK_FLOW_BOX (self->flowbox_iconless_categories); +@@ -524,6 +525,7 @@ out: + * See https://gitlab.gnome.org/GNOME/gnome-software/-/issues/2053 */ + gtk_widget_set_visible (self->flowbox_categories, found_apps_cnt >= MIN_CATEGORIES_APPS); + ++ g_debug ("overview page found %u category apps", found_apps_cnt); + if (found_apps_cnt < MIN_CATEGORIES_APPS && found_apps_cnt > 0) { + GsPluginListAppsFlags flags = GS_PLUGIN_LIST_APPS_FLAGS_INTERACTIVE; + GatherAppsData *gather_apps_data = g_new0 (GatherAppsData, 1); +-- +GitLab + + +From 98086eca23dbd46284039722887852e8c760a0fe Mon Sep 17 00:00:00 2001 +Date: Wed, 20 Dec 2023 12:32:21 +0100 +Subject: [PATCH 3/3] gs-overview-page: Verify category sizes + +The "list-categories" job can set inaccurate sizes for the categories, +thus check the actual category content to operate with proper numbers. +For example the appstream data can have information about apps, which +no plugin can provide due to disabled repository. +--- + src/gs-overview-page.c | 176 +++++++++++++++++++++++++++++++++++------ + 1 file changed, 153 insertions(+), 23 deletions(-) + +diff --git a/src/gs-overview-page.c b/src/gs-overview-page.c +index 72000e257..3ec689ac1 100644 +--- a/src/gs-overview-page.c ++++ b/src/gs-overview-page.c +@@ -440,6 +440,7 @@ category_activated_cb (GsOverviewPage *self, GsCategoryTile *tile) + typedef struct { + GsOverviewPage *page; /* (unowned) */ + GsPluginJobListCategories *job; /* (owned) */ ++ guint n_pending_ops; + } GetCategoriesData; + + static void +@@ -451,31 +452,18 @@ get_categories_data_free (GetCategoriesData *data) + + G_DEFINE_AUTOPTR_CLEANUP_FUNC (GetCategoriesData, get_categories_data_free) + +-static void +-gs_overview_page_get_categories_cb (GObject *source_object, +- GAsyncResult *res, +- gpointer user_data) ++static guint ++update_categories_sections (GsOverviewPage *self, ++ GPtrArray *list) /* (element-type GsCategory) */ + { +- g_autoptr(GetCategoriesData) data = g_steal_pointer (&user_data); +- GsOverviewPage *self = GS_OVERVIEW_PAGE (data->page); +- GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (source_object); +- guint i; + GsCategory *cat; + GtkFlowBox *flowbox; + GtkWidget *tile; + guint added_cnt = 0; + guint found_apps_cnt = 0; +- g_autoptr(GError) error = NULL; +- GPtrArray *list = NULL; /* (element-type GsCategory) */ + +- if (!gs_plugin_loader_job_action_finish (plugin_loader, res, &error)) { +- if (!g_error_matches (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_CANCELLED) && +- !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) +- g_warning ("failed to get categories: %s", error->message); +- goto out; +- } +- +- list = gs_plugin_job_list_categories_get_result_list (data->job); ++ if (g_cancellable_is_cancelled (self->cancellable)) ++ return found_apps_cnt; + + gs_widget_remove_all (self->flowbox_categories, (GsRemoveFunc) gtk_flow_box_remove); + gs_widget_remove_all (self->flowbox_iconless_categories, (GsRemoveFunc) gtk_flow_box_remove); +@@ -488,7 +476,7 @@ gs_overview_page_get_categories_cb (GObject *source_object, + * be visually important, and are listed near the top of the page. + * Categories without icons are listed in a separate flowbox at the + * bottom of the page. Typically they are addons. */ +- for (i = 0; i < list->len; i++) { ++ for (guint i = 0; list != NULL && i < list->len; i++) { + cat = GS_CATEGORY (g_ptr_array_index (list, i)); + if (gs_category_get_size (cat) == 0) + continue; +@@ -510,7 +498,6 @@ gs_overview_page_get_categories_cb (GObject *source_object, + g_object_ref (cat)); + } + +-out: + /* Show the heading for the iconless categories iff there are any. */ + gtk_widget_set_visible (self->iconless_categories_heading, + gtk_flow_box_get_child_at_index (GTK_FLOW_BOX (self->flowbox_iconless_categories), 0) != NULL); +@@ -525,6 +512,27 @@ out: + * See https://gitlab.gnome.org/GNOME/gnome-software/-/issues/2053 */ + gtk_widget_set_visible (self->flowbox_categories, found_apps_cnt >= MIN_CATEGORIES_APPS); + ++ return found_apps_cnt; ++} ++ ++static void ++finish_verify_category_op (GetCategoriesData *op_data) ++{ ++ g_autoptr(GetCategoriesData) data = g_steal_pointer (&op_data); ++ GsOverviewPage *self = GS_OVERVIEW_PAGE (data->page); ++ guint i, found_apps_cnt; ++ GPtrArray *list; /* (element-type GsCategory) */ ++ ++ data->n_pending_ops--; ++ if (data->n_pending_ops > 0) { ++ /* to not be freed */ ++ g_steal_pointer (&data); ++ return; ++ } ++ ++ list = gs_plugin_job_list_categories_get_result_list (data->job); ++ found_apps_cnt = update_categories_sections (self, list); ++ + g_debug ("overview page found %u category apps", found_apps_cnt); + if (found_apps_cnt < MIN_CATEGORIES_APPS && found_apps_cnt > 0) { + GsPluginListAppsFlags flags = GS_PLUGIN_LIST_APPS_FLAGS_INTERACTIVE; +@@ -534,10 +542,10 @@ out: + gather_apps_data->self = g_object_ref (self); + gather_apps_data->list = gs_app_list_new (); + +- for (i = 0; i < list->len; i++) { ++ for (i = 0; list != NULL && i < list->len; i++) { + g_autoptr(GsPluginJob) plugin_job = NULL; + g_autoptr(GsAppQuery) query = NULL; +- GsCategory *subcat; ++ GsCategory *cat, *subcat; + + cat = GS_CATEGORY (g_ptr_array_index (list, i)); + if (gs_category_get_size (cat) == 0 || +@@ -578,6 +586,128 @@ out: + gs_overview_page_decrement_action_cnt (self); + } + ++typedef struct { ++ GsOverviewPage *page; /* (unowned) */ ++ GetCategoriesData *op_data; /* (unowned) */ ++ GsCategory *category; /* (owned) */ ++} VerifyCategoryData; ++ ++static void ++verify_category_data_free (VerifyCategoryData *data) ++{ ++ g_clear_object (&data->category); ++ g_free (data); ++} ++ ++G_DEFINE_AUTOPTR_CLEANUP_FUNC (VerifyCategoryData, verify_category_data_free) ++ ++static void ++gs_overview_page_verify_category_cb (GObject *source_object, ++ GAsyncResult *res, ++ gpointer user_data) ++{ ++ g_autoptr(VerifyCategoryData) data = user_data; ++ GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (source_object); ++ g_autoptr(GError) local_error = NULL; ++ g_autoptr(GsAppList) list = NULL; ++ ++ list = gs_plugin_loader_job_process_finish (plugin_loader, res, &local_error); ++ if (list == NULL) { ++ if (!g_error_matches (local_error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_CANCELLED) && ++ !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) ++ g_warning ("failed to get apps for category: %s", local_error->message); ++ g_debug ("Failed to get category content '%s' for overview page: %s", gs_category_get_id (data->category), local_error->message); ++ } else { ++ GsCategory *all_subcat = gs_category_find_child (data->category, "all"); ++ guint size = gs_app_list_length (list); ++ g_debug ("overview page verify category '%s' size:%u~>%u subcat:'%s' size:%u~>%u", ++ gs_category_get_id (data->category), gs_category_get_size (data->category), size, ++ gs_category_get_id (all_subcat), gs_category_get_size (all_subcat), size); ++ gs_category_set_size (data->category, size); ++ gs_category_set_size (all_subcat, size); ++ } ++ ++ finish_verify_category_op (data->op_data); ++} ++ ++static void ++gs_overview_page_get_categories_list_cb (GObject *source_object, ++ GAsyncResult *res, ++ gpointer user_data) ++{ ++ g_autoptr(GetCategoriesData) data = g_steal_pointer (&user_data); ++ GsOverviewPage *self = GS_OVERVIEW_PAGE (data->page); ++ GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (source_object); ++ g_autoptr(GError) error = NULL; ++ ++ g_assert (data->n_pending_ops == 0); ++ ++ data->n_pending_ops++; ++ ++ /* The apps can be mentioned in the appstream data, but no plugin may provide actual app, ++ thus try to get the content as the Categories page and fine tune the numbers appropriately. */ ++ if (!gs_plugin_loader_job_action_finish (plugin_loader, res, &error)) { ++ if (!g_error_matches (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_CANCELLED) && ++ !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) ++ g_warning ("failed to get categories: %s", error->message); ++ } else { ++ g_autoptr(GPtrArray) verify_categories = NULL; /* (element-type GsCategory) */ ++ GPtrArray *list = NULL; /* (element-type GsCategory) */ ++ guint found_apps_cnt; ++ ++ list = gs_plugin_job_list_categories_get_result_list (data->job); ++ found_apps_cnt = update_categories_sections (self, list); ++ ++ if (found_apps_cnt >= MIN_CATEGORIES_APPS) { ++ verify_categories = g_ptr_array_new_full (list != NULL ? list->len : 0, g_object_unref); ++ for (guint i = 0; list != NULL && i < list->len; i++) { ++ GsCategory *category = g_ptr_array_index (list, i); ++ if (gs_category_get_size (category) > 0 && ++ gs_category_find_child (category, "all") != NULL) { ++ g_ptr_array_add (verify_categories, g_object_ref (category)); ++ } ++ } ++ } ++ ++ if (verify_categories != NULL && verify_categories->len > 0 && !g_cancellable_is_cancelled (self->cancellable)) { ++ for (guint i = 0; i < verify_categories->len; i++) { ++ GsCategory *category = g_ptr_array_index (verify_categories, i); ++ GsCategory *all_subcat = gs_category_find_child (category, "all"); ++ g_autoptr(GsAppQuery) query = NULL; ++ g_autoptr(GsPluginJob) plugin_job = NULL; ++ VerifyCategoryData *ver_data; ++ ++ g_assert (all_subcat != NULL); ++ ++ data->n_pending_ops++; ++ ++ ver_data = g_new0 (VerifyCategoryData, 1); ++ ver_data->page = self; ++ ver_data->op_data = data; ++ ver_data->category = g_object_ref (category); ++ ++ query = gs_app_query_new ("category", all_subcat, ++ "refine-flags", GS_PLUGIN_REFINE_FLAGS_REQUIRE_ID, ++ "dedupe-flags", GS_APP_LIST_FILTER_FLAG_KEY_ID_PROVIDES, ++ "license-type", gs_page_get_query_license_type (GS_PAGE (self)), ++ /*"developer-verified-type", gs_page_get_query_developer_verified_type (GS_PAGE (self)),*/ ++ NULL); ++ plugin_job = gs_plugin_job_list_apps_new (query, GS_PLUGIN_LIST_APPS_FLAGS_NONE); ++ gs_plugin_loader_job_process_async (plugin_loader, ++ plugin_job, ++ self->cancellable, ++ gs_overview_page_verify_category_cb, ++ ver_data); ++ } ++ ++ finish_verify_category_op (g_steal_pointer (&data)); ++ return; ++ } ++ } ++ ++ finish_verify_category_op (g_steal_pointer (&data)); ++} ++ + static void + third_party_destroy_cb (GtkWindow *window, + GsOverviewPage *self) +@@ -967,7 +1097,7 @@ gs_overview_page_load (GsOverviewPage *self) + data->job = g_object_ref (GS_PLUGIN_JOB_LIST_CATEGORIES (plugin_job)); + + gs_plugin_loader_job_process_async (self->plugin_loader, plugin_job, +- self->cancellable, gs_overview_page_get_categories_cb, ++ self->cancellable, gs_overview_page_get_categories_list_cb, + g_steal_pointer (&data)); + self->action_cnt++; + } +-- +GitLab + diff --git a/0006-optional-repos-cannot-be-disabled.patch b/0006-optional-repos-cannot-be-disabled.patch deleted file mode 100644 index b581147..0000000 --- a/0006-optional-repos-cannot-be-disabled.patch +++ /dev/null @@ -1,498 +0,0 @@ -From dca731ff0daf904911dd6815fb9a1b181329c887 Mon Sep 17 00:00:00 2001 -From: Milan Crha -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 -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 -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 @@ - [] - A list of official repositories that should not be considered 3rd party - -+ -+ [] -+ A list of required repositories that cannot be disabled or removed -+ - - [] - A list of official repositories that should be considered free software --- -GitLab - - -From d6b8b206a596bb520a0b77066898b44a5ef18920 Mon Sep 17 00:00:00 2001 -From: Milan Crha -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 - diff --git a/0007-compulsory-only-for-repos.patch b/0007-compulsory-only-for-repos.patch deleted file mode 100644 index fb266df..0000000 --- a/0007-compulsory-only-for-repos.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 895d1ca748f4f33a852853f5f07903fb549fb66f Mon Sep 17 00:00:00 2001 -From: Milan Crha -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 - diff --git a/0008-gs-removal-dialog-crrect-property-name.patch b/0008-gs-removal-dialog-crrect-property-name.patch deleted file mode 100644 index 47325af..0000000 --- a/0008-gs-removal-dialog-crrect-property-name.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up gnome-software-41.5/src/gs-removal-dialog.ui.4 gnome-software-41.5/src/gs-removal-dialog.ui ---- gnome-software-41.5/src/gs-removal-dialog.ui.4 2022-09-12 08:59:57.819169830 +0200 -+++ gnome-software-41.5/src/gs-removal-dialog.ui 2022-09-12 09:00:25.148201673 +0200 -@@ -20,7 +20,7 @@ - - -