From a0175cb9f497b5145d5d0b95ebb9830f637358e1 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 15 Aug 2022 13:37:14 +0200 Subject: [PATCH 001/116] Add patch for install-queue (RH bug #2118265) --- 0002-install-queue.patch | 112 +++++++++++++++++++++++++++++++++++++++ gnome-software.spec | 6 ++- 2 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 0002-install-queue.patch diff --git a/0002-install-queue.patch b/0002-install-queue.patch new file mode 100644 index 0000000..698d1d0 --- /dev/null +++ b/0002-install-queue.patch @@ -0,0 +1,112 @@ +From d9e28b8cb59c805f2df8954637f2056467ff1be3 Mon Sep 17 00:00:00 2001 +From: Milan Crha +Date: Wed, 10 Aug 2022 13:41:46 +0200 +Subject: [PATCH 1/2] packagekit: Allow install of apps in the "queued for + install" state + +Treat the "queued for install" state the same as if "available/updatable" +state is set. Without that trying to install anything using PackageKit +plugin leads to an "Unsupported" error. +--- + plugins/packagekit/gs-plugin-packagekit.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/plugins/packagekit/gs-plugin-packagekit.c b/plugins/packagekit/gs-plugin-packagekit.c +index 58d627276..85f941648 100644 +--- a/plugins/packagekit/gs-plugin-packagekit.c ++++ b/plugins/packagekit/gs-plugin-packagekit.c +@@ -519,6 +519,7 @@ gs_plugin_app_install (GsPlugin *plugin, + switch (gs_app_get_state (app)) { + case GS_APP_STATE_AVAILABLE: + case GS_APP_STATE_UPDATABLE: ++ case GS_APP_STATE_QUEUED_FOR_INSTALL: + source_ids = gs_app_get_source_ids (app); + if (source_ids->len == 0) { + g_set_error_literal (error, +-- +GitLab + + +From 71ce53a21373670f32b936194d46ab073df77a63 Mon Sep 17 00:00:00 2001 +From: Milan Crha +Date: Wed, 10 Aug 2022 14:24:51 +0200 +Subject: [PATCH 2/2] gs-plugin-loader: Add not removed from the install-queue + file + +The plugin loader has two places, which maintain the pending queue, +but they do not agree on the update of the install-queue file. Let +the functions be re-used, to avoid the problem. +--- + lib/gs-plugin-loader.c | 27 +++++++++++++++++---------- + 1 file changed, 17 insertions(+), 10 deletions(-) + +diff --git a/lib/gs-plugin-loader.c b/lib/gs-plugin-loader.c +index 073008d55..e3f48666a 100644 +--- a/lib/gs-plugin-loader.c ++++ b/lib/gs-plugin-loader.c +@@ -88,6 +88,7 @@ struct _GsPluginLoader + + static void gs_plugin_loader_monitor_network (GsPluginLoader *plugin_loader); + static void add_app_to_install_queue (GsPluginLoader *plugin_loader, GsApp *app); ++static gboolean remove_app_from_install_queue (GsPluginLoader *plugin_loader, GsApp *app); + static void gs_plugin_loader_process_in_thread_pool_cb (gpointer data, gpointer user_data); + static void gs_plugin_loader_status_changed_cb (GsPlugin *plugin, + GsApp *app, +@@ -1078,17 +1079,22 @@ gs_plugin_loader_pending_apps_add (GsPluginLoader *plugin_loader, + GsPluginLoaderHelper *helper) + { + GsAppList *list = gs_plugin_job_get_list (helper->plugin_job); +- g_autoptr(GMutexLocker) locker = g_mutex_locker_new (&plugin_loader->pending_apps_mutex); +- +- if (plugin_loader->pending_apps == NULL) +- plugin_loader->pending_apps = gs_app_list_new (); + + g_assert (gs_app_list_length (list) > 0); + for (guint i = 0; i < gs_app_list_length (list); i++) { + GsApp *app = gs_app_list_index (list, i); +- gs_app_list_add (plugin_loader->pending_apps, app); +- /* make sure the progress is properly initialized */ +- gs_app_set_progress (app, GS_APP_PROGRESS_UNKNOWN); ++ switch (gs_plugin_job_get_action (helper->plugin_job)) { ++ case GS_PLUGIN_ACTION_INSTALL: ++ add_app_to_install_queue (plugin_loader, app); ++ /* make sure the progress is properly initialized */ ++ gs_app_set_progress (app, GS_APP_PROGRESS_UNKNOWN); ++ break; ++ case GS_PLUGIN_ACTION_REMOVE: ++ remove_app_from_install_queue (plugin_loader, app); ++ break; ++ default: ++ break; ++ } + } + g_idle_add (emit_pending_apps_idle, g_object_ref (plugin_loader)); + } +@@ -1098,13 +1104,11 @@ gs_plugin_loader_pending_apps_remove (GsPluginLoader *plugin_loader, + GsPluginLoaderHelper *helper) + { + GsAppList *list = gs_plugin_job_get_list (helper->plugin_job); +- g_autoptr(GMutexLocker) locker = g_mutex_locker_new (&plugin_loader->pending_apps_mutex); + + g_assert (gs_app_list_length (list) > 0); + for (guint i = 0; i < gs_app_list_length (list); i++) { + GsApp *app = gs_app_list_index (list, i); +- if (plugin_loader->pending_apps != NULL) +- gs_app_list_remove (plugin_loader->pending_apps, app); ++ remove_app_from_install_queue (plugin_loader, app); + + /* check the app is not still in an action helper */ + switch (gs_app_get_state (app)) { +@@ -1272,6 +1276,9 @@ remove_app_from_install_queue (GsPluginLoader *plugin_loader, GsApp *app) + g_mutex_unlock (&plugin_loader->pending_apps_mutex); + + if (ret) { ++ if (gs_app_get_state (app) == GS_APP_STATE_QUEUED_FOR_INSTALL) ++ gs_app_set_state (app, GS_APP_STATE_UNKNOWN); ++ + id = g_idle_add (emit_pending_apps_idle, g_object_ref (plugin_loader)); + g_source_set_name_by_id (id, "[gnome-software] emit_pending_apps_idle"); + save_install_queue (plugin_loader); +-- +GitLab + diff --git a/gnome-software.spec b/gnome-software.spec index 59d9ebe..e141c89 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -18,7 +18,7 @@ Name: gnome-software Version: 43.beta -Release: 1%{?dist} +Release: 2%{?dist} Summary: A software center for GNOME License: GPLv2+ @@ -26,6 +26,7 @@ URL: https://wiki.gnome.org/Apps/Software Source0: https://download.gnome.org/sources/gnome-software/43/%{name}-%{tarball_version}.tar.xz Patch01: 0001-crash-with-broken-theme.patch +Patch02: 0002-install-queue.patch BuildRequires: docbook-style-xsl BuildRequires: desktop-file-utils @@ -212,6 +213,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Mon Aug 15 2022 Milan Crha - 43.beta-2 +- Add patch for install-queue + * Fri Aug 05 2022 Milan Crha - 43.beta-1 - Update to 43.beta From f7afad3f86e9b27c1532fb1e52c55eb27b680532 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 15 Aug 2022 13:37:14 +0200 Subject: [PATCH 002/116] Add patch for install-queue (RH bug #2118265) --- 0002-install-queue.patch | 112 +++++++++++++++++++++++++++++++++++++++ gnome-software.spec | 6 ++- 2 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 0002-install-queue.patch diff --git a/0002-install-queue.patch b/0002-install-queue.patch new file mode 100644 index 0000000..698d1d0 --- /dev/null +++ b/0002-install-queue.patch @@ -0,0 +1,112 @@ +From d9e28b8cb59c805f2df8954637f2056467ff1be3 Mon Sep 17 00:00:00 2001 +From: Milan Crha +Date: Wed, 10 Aug 2022 13:41:46 +0200 +Subject: [PATCH 1/2] packagekit: Allow install of apps in the "queued for + install" state + +Treat the "queued for install" state the same as if "available/updatable" +state is set. Without that trying to install anything using PackageKit +plugin leads to an "Unsupported" error. +--- + plugins/packagekit/gs-plugin-packagekit.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/plugins/packagekit/gs-plugin-packagekit.c b/plugins/packagekit/gs-plugin-packagekit.c +index 58d627276..85f941648 100644 +--- a/plugins/packagekit/gs-plugin-packagekit.c ++++ b/plugins/packagekit/gs-plugin-packagekit.c +@@ -519,6 +519,7 @@ gs_plugin_app_install (GsPlugin *plugin, + switch (gs_app_get_state (app)) { + case GS_APP_STATE_AVAILABLE: + case GS_APP_STATE_UPDATABLE: ++ case GS_APP_STATE_QUEUED_FOR_INSTALL: + source_ids = gs_app_get_source_ids (app); + if (source_ids->len == 0) { + g_set_error_literal (error, +-- +GitLab + + +From 71ce53a21373670f32b936194d46ab073df77a63 Mon Sep 17 00:00:00 2001 +From: Milan Crha +Date: Wed, 10 Aug 2022 14:24:51 +0200 +Subject: [PATCH 2/2] gs-plugin-loader: Add not removed from the install-queue + file + +The plugin loader has two places, which maintain the pending queue, +but they do not agree on the update of the install-queue file. Let +the functions be re-used, to avoid the problem. +--- + lib/gs-plugin-loader.c | 27 +++++++++++++++++---------- + 1 file changed, 17 insertions(+), 10 deletions(-) + +diff --git a/lib/gs-plugin-loader.c b/lib/gs-plugin-loader.c +index 073008d55..e3f48666a 100644 +--- a/lib/gs-plugin-loader.c ++++ b/lib/gs-plugin-loader.c +@@ -88,6 +88,7 @@ struct _GsPluginLoader + + static void gs_plugin_loader_monitor_network (GsPluginLoader *plugin_loader); + static void add_app_to_install_queue (GsPluginLoader *plugin_loader, GsApp *app); ++static gboolean remove_app_from_install_queue (GsPluginLoader *plugin_loader, GsApp *app); + static void gs_plugin_loader_process_in_thread_pool_cb (gpointer data, gpointer user_data); + static void gs_plugin_loader_status_changed_cb (GsPlugin *plugin, + GsApp *app, +@@ -1078,17 +1079,22 @@ gs_plugin_loader_pending_apps_add (GsPluginLoader *plugin_loader, + GsPluginLoaderHelper *helper) + { + GsAppList *list = gs_plugin_job_get_list (helper->plugin_job); +- g_autoptr(GMutexLocker) locker = g_mutex_locker_new (&plugin_loader->pending_apps_mutex); +- +- if (plugin_loader->pending_apps == NULL) +- plugin_loader->pending_apps = gs_app_list_new (); + + g_assert (gs_app_list_length (list) > 0); + for (guint i = 0; i < gs_app_list_length (list); i++) { + GsApp *app = gs_app_list_index (list, i); +- gs_app_list_add (plugin_loader->pending_apps, app); +- /* make sure the progress is properly initialized */ +- gs_app_set_progress (app, GS_APP_PROGRESS_UNKNOWN); ++ switch (gs_plugin_job_get_action (helper->plugin_job)) { ++ case GS_PLUGIN_ACTION_INSTALL: ++ add_app_to_install_queue (plugin_loader, app); ++ /* make sure the progress is properly initialized */ ++ gs_app_set_progress (app, GS_APP_PROGRESS_UNKNOWN); ++ break; ++ case GS_PLUGIN_ACTION_REMOVE: ++ remove_app_from_install_queue (plugin_loader, app); ++ break; ++ default: ++ break; ++ } + } + g_idle_add (emit_pending_apps_idle, g_object_ref (plugin_loader)); + } +@@ -1098,13 +1104,11 @@ gs_plugin_loader_pending_apps_remove (GsPluginLoader *plugin_loader, + GsPluginLoaderHelper *helper) + { + GsAppList *list = gs_plugin_job_get_list (helper->plugin_job); +- g_autoptr(GMutexLocker) locker = g_mutex_locker_new (&plugin_loader->pending_apps_mutex); + + g_assert (gs_app_list_length (list) > 0); + for (guint i = 0; i < gs_app_list_length (list); i++) { + GsApp *app = gs_app_list_index (list, i); +- if (plugin_loader->pending_apps != NULL) +- gs_app_list_remove (plugin_loader->pending_apps, app); ++ remove_app_from_install_queue (plugin_loader, app); + + /* check the app is not still in an action helper */ + switch (gs_app_get_state (app)) { +@@ -1272,6 +1276,9 @@ remove_app_from_install_queue (GsPluginLoader *plugin_loader, GsApp *app) + g_mutex_unlock (&plugin_loader->pending_apps_mutex); + + if (ret) { ++ if (gs_app_get_state (app) == GS_APP_STATE_QUEUED_FOR_INSTALL) ++ gs_app_set_state (app, GS_APP_STATE_UNKNOWN); ++ + id = g_idle_add (emit_pending_apps_idle, g_object_ref (plugin_loader)); + g_source_set_name_by_id (id, "[gnome-software] emit_pending_apps_idle"); + save_install_queue (plugin_loader); +-- +GitLab + diff --git a/gnome-software.spec b/gnome-software.spec index 59d9ebe..e141c89 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -18,7 +18,7 @@ Name: gnome-software Version: 43.beta -Release: 1%{?dist} +Release: 2%{?dist} Summary: A software center for GNOME License: GPLv2+ @@ -26,6 +26,7 @@ URL: https://wiki.gnome.org/Apps/Software Source0: https://download.gnome.org/sources/gnome-software/43/%{name}-%{tarball_version}.tar.xz Patch01: 0001-crash-with-broken-theme.patch +Patch02: 0002-install-queue.patch BuildRequires: docbook-style-xsl BuildRequires: desktop-file-utils @@ -212,6 +213,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Mon Aug 15 2022 Milan Crha - 43.beta-2 +- Add patch for install-queue + * Fri Aug 05 2022 Milan Crha - 43.beta-1 - Update to 43.beta From 6a61ae4b2d97cf5a3905bd6da6efc88538a9087d Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Wed, 17 Aug 2022 15:52:58 +0200 Subject: [PATCH 003/116] Resolves: #2119089 (No enough apps to show for the "Editor's Choice" section) --- gnome-software.spec | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index e141c89..cd0dec2 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -18,7 +18,7 @@ Name: gnome-software Version: 43.beta -Release: 2%{?dist} +Release: 3%{?dist} Summary: A software center for GNOME License: GPLv2+ @@ -130,9 +130,6 @@ This package includes the rpm-ostree backend. # remove unneeded dpkg plugin rm %{buildroot}%{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_dpkg.so -# not meant to be installed by the distros -rm %{buildroot}%{_datadir}/swcatalog/xml/org.gnome.Software.Curated.xml - # make the software center load faster desktop-file-edit %{buildroot}%{_datadir}/applications/org.gnome.Software.desktop \ --set-key=X-AppInstall-Package --set-value=%{name} @@ -191,6 +188,7 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %dir %{_datadir}/swcatalog %dir %{_datadir}/swcatalog/xml %{_datadir}/swcatalog/xml/gnome-pwa-list-foss.xml +%{_datadir}/swcatalog/xml/org.gnome.Software.Curated.xml %{_datadir}/swcatalog/xml/org.gnome.Software.Featured.xml %{_datadir}/dbus-1/services/org.freedesktop.PackageKit.service %{_datadir}/dbus-1/services/org.gnome.Software.service @@ -213,6 +211,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Wed Aug 17 2022 Milan Crha - 43.beta-3 +- Resolves: #2119089 (No enough apps to show for the "Editor's Choice" section) + * Mon Aug 15 2022 Milan Crha - 43.beta-2 - Add patch for install-queue From b9716a4ef70ab8bad6b2ad02df3bb17ce004a9e5 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Wed, 17 Aug 2022 15:52:58 +0200 Subject: [PATCH 004/116] Resolves: #2119089 (No enough apps to show for the "Editor's Choice" section) --- gnome-software.spec | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index e141c89..cd0dec2 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -18,7 +18,7 @@ Name: gnome-software Version: 43.beta -Release: 2%{?dist} +Release: 3%{?dist} Summary: A software center for GNOME License: GPLv2+ @@ -130,9 +130,6 @@ This package includes the rpm-ostree backend. # remove unneeded dpkg plugin rm %{buildroot}%{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_dpkg.so -# not meant to be installed by the distros -rm %{buildroot}%{_datadir}/swcatalog/xml/org.gnome.Software.Curated.xml - # make the software center load faster desktop-file-edit %{buildroot}%{_datadir}/applications/org.gnome.Software.desktop \ --set-key=X-AppInstall-Package --set-value=%{name} @@ -191,6 +188,7 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %dir %{_datadir}/swcatalog %dir %{_datadir}/swcatalog/xml %{_datadir}/swcatalog/xml/gnome-pwa-list-foss.xml +%{_datadir}/swcatalog/xml/org.gnome.Software.Curated.xml %{_datadir}/swcatalog/xml/org.gnome.Software.Featured.xml %{_datadir}/dbus-1/services/org.freedesktop.PackageKit.service %{_datadir}/dbus-1/services/org.gnome.Software.service @@ -213,6 +211,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Wed Aug 17 2022 Milan Crha - 43.beta-3 +- Resolves: #2119089 (No enough apps to show for the "Editor's Choice" section) + * Mon Aug 15 2022 Milan Crha - 43.beta-2 - Add patch for install-queue From f744223b09eef29afe8c6084e973bc4c99d43110 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Thu, 18 Aug 2022 07:37:04 +0200 Subject: [PATCH 005/116] Add rpminspect.yaml (settings for the RUNPATH test) --- rpminspect.yaml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 rpminspect.yaml diff --git a/rpminspect.yaml b/rpminspect.yaml new file mode 100644 index 0000000..ef70fcd --- /dev/null +++ b/rpminspect.yaml @@ -0,0 +1,7 @@ +--- +runpath: + allowed_paths: + - /usr/lib/gnome-software + - /usr/lib/rpm-ostree + - /usr/lib64/gnome-software + - /usr/lib64/rpm-ostree From 869c9002d622e6711efad7b57b204b806fc892f3 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Thu, 18 Aug 2022 07:37:04 +0200 Subject: [PATCH 006/116] Add rpminspect.yaml (settings for the RUNPATH test) --- rpminspect.yaml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 rpminspect.yaml diff --git a/rpminspect.yaml b/rpminspect.yaml new file mode 100644 index 0000000..ef70fcd --- /dev/null +++ b/rpminspect.yaml @@ -0,0 +1,7 @@ +--- +runpath: + allowed_paths: + - /usr/lib/gnome-software + - /usr/lib/rpm-ostree + - /usr/lib64/gnome-software + - /usr/lib64/rpm-ostree From 17177232497d1c236a81f7d699853b5e2cb4f3b2 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 2 Sep 2022 10:51:15 +0200 Subject: [PATCH 007/116] Update to 43.rc --- 0002-install-queue.patch | 112 --------------------------------------- gnome-software.spec | 13 +++-- sources | 2 +- 3 files changed, 9 insertions(+), 118 deletions(-) delete mode 100644 0002-install-queue.patch diff --git a/0002-install-queue.patch b/0002-install-queue.patch deleted file mode 100644 index 698d1d0..0000000 --- a/0002-install-queue.patch +++ /dev/null @@ -1,112 +0,0 @@ -From d9e28b8cb59c805f2df8954637f2056467ff1be3 Mon Sep 17 00:00:00 2001 -From: Milan Crha -Date: Wed, 10 Aug 2022 13:41:46 +0200 -Subject: [PATCH 1/2] packagekit: Allow install of apps in the "queued for - install" state - -Treat the "queued for install" state the same as if "available/updatable" -state is set. Without that trying to install anything using PackageKit -plugin leads to an "Unsupported" error. ---- - plugins/packagekit/gs-plugin-packagekit.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/plugins/packagekit/gs-plugin-packagekit.c b/plugins/packagekit/gs-plugin-packagekit.c -index 58d627276..85f941648 100644 ---- a/plugins/packagekit/gs-plugin-packagekit.c -+++ b/plugins/packagekit/gs-plugin-packagekit.c -@@ -519,6 +519,7 @@ gs_plugin_app_install (GsPlugin *plugin, - switch (gs_app_get_state (app)) { - case GS_APP_STATE_AVAILABLE: - case GS_APP_STATE_UPDATABLE: -+ case GS_APP_STATE_QUEUED_FOR_INSTALL: - source_ids = gs_app_get_source_ids (app); - if (source_ids->len == 0) { - g_set_error_literal (error, --- -GitLab - - -From 71ce53a21373670f32b936194d46ab073df77a63 Mon Sep 17 00:00:00 2001 -From: Milan Crha -Date: Wed, 10 Aug 2022 14:24:51 +0200 -Subject: [PATCH 2/2] gs-plugin-loader: Add not removed from the install-queue - file - -The plugin loader has two places, which maintain the pending queue, -but they do not agree on the update of the install-queue file. Let -the functions be re-used, to avoid the problem. ---- - lib/gs-plugin-loader.c | 27 +++++++++++++++++---------- - 1 file changed, 17 insertions(+), 10 deletions(-) - -diff --git a/lib/gs-plugin-loader.c b/lib/gs-plugin-loader.c -index 073008d55..e3f48666a 100644 ---- a/lib/gs-plugin-loader.c -+++ b/lib/gs-plugin-loader.c -@@ -88,6 +88,7 @@ struct _GsPluginLoader - - static void gs_plugin_loader_monitor_network (GsPluginLoader *plugin_loader); - static void add_app_to_install_queue (GsPluginLoader *plugin_loader, GsApp *app); -+static gboolean remove_app_from_install_queue (GsPluginLoader *plugin_loader, GsApp *app); - static void gs_plugin_loader_process_in_thread_pool_cb (gpointer data, gpointer user_data); - static void gs_plugin_loader_status_changed_cb (GsPlugin *plugin, - GsApp *app, -@@ -1078,17 +1079,22 @@ gs_plugin_loader_pending_apps_add (GsPluginLoader *plugin_loader, - GsPluginLoaderHelper *helper) - { - GsAppList *list = gs_plugin_job_get_list (helper->plugin_job); -- g_autoptr(GMutexLocker) locker = g_mutex_locker_new (&plugin_loader->pending_apps_mutex); -- -- if (plugin_loader->pending_apps == NULL) -- plugin_loader->pending_apps = gs_app_list_new (); - - g_assert (gs_app_list_length (list) > 0); - for (guint i = 0; i < gs_app_list_length (list); i++) { - GsApp *app = gs_app_list_index (list, i); -- gs_app_list_add (plugin_loader->pending_apps, app); -- /* make sure the progress is properly initialized */ -- gs_app_set_progress (app, GS_APP_PROGRESS_UNKNOWN); -+ switch (gs_plugin_job_get_action (helper->plugin_job)) { -+ case GS_PLUGIN_ACTION_INSTALL: -+ add_app_to_install_queue (plugin_loader, app); -+ /* make sure the progress is properly initialized */ -+ gs_app_set_progress (app, GS_APP_PROGRESS_UNKNOWN); -+ break; -+ case GS_PLUGIN_ACTION_REMOVE: -+ remove_app_from_install_queue (plugin_loader, app); -+ break; -+ default: -+ break; -+ } - } - g_idle_add (emit_pending_apps_idle, g_object_ref (plugin_loader)); - } -@@ -1098,13 +1104,11 @@ gs_plugin_loader_pending_apps_remove (GsPluginLoader *plugin_loader, - GsPluginLoaderHelper *helper) - { - GsAppList *list = gs_plugin_job_get_list (helper->plugin_job); -- g_autoptr(GMutexLocker) locker = g_mutex_locker_new (&plugin_loader->pending_apps_mutex); - - g_assert (gs_app_list_length (list) > 0); - for (guint i = 0; i < gs_app_list_length (list); i++) { - GsApp *app = gs_app_list_index (list, i); -- if (plugin_loader->pending_apps != NULL) -- gs_app_list_remove (plugin_loader->pending_apps, app); -+ remove_app_from_install_queue (plugin_loader, app); - - /* check the app is not still in an action helper */ - switch (gs_app_get_state (app)) { -@@ -1272,6 +1276,9 @@ remove_app_from_install_queue (GsPluginLoader *plugin_loader, GsApp *app) - g_mutex_unlock (&plugin_loader->pending_apps_mutex); - - if (ret) { -+ if (gs_app_get_state (app) == GS_APP_STATE_QUEUED_FOR_INSTALL) -+ gs_app_set_state (app, GS_APP_STATE_UNKNOWN); -+ - id = g_idle_add (emit_pending_apps_idle, g_object_ref (plugin_loader)); - g_source_set_name_by_id (id, "[gnome-software] emit_pending_apps_idle"); - save_install_queue (plugin_loader); --- -GitLab - diff --git a/gnome-software.spec b/gnome-software.spec index cd0dec2..9545378 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -17,8 +17,8 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 43.beta -Release: 3%{?dist} +Version: 43.rc +Release: 1%{?dist} Summary: A software center for GNOME License: GPLv2+ @@ -26,7 +26,6 @@ URL: https://wiki.gnome.org/Apps/Software Source0: https://download.gnome.org/sources/gnome-software/43/%{name}-%{tarball_version}.tar.xz Patch01: 0001-crash-with-broken-theme.patch -Patch02: 0002-install-queue.patch BuildRequires: docbook-style-xsl BuildRequires: desktop-file-utils @@ -56,7 +55,6 @@ BuildRequires: pkgconfig(polkit-gobject-1) BuildRequires: pkgconfig(rpm) BuildRequires: pkgconfig(rpm-ostree-1) BuildRequires: pkgconfig(sysprof-capture-4) -BuildRequires: pkgconfig(valgrind) BuildRequires: pkgconfig(xmlb) >= %{libxmlb_version} Requires: appstream-data @@ -154,7 +152,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %doc AUTHORS README.md %license COPYING %{_bindir}/gnome-software -%{_datadir}/applications/gnome-software-local-file.desktop +%{_datadir}/applications/gnome-software-local-file-flatpak.desktop +%{_datadir}/applications/gnome-software-local-file-fwupd.desktop +%{_datadir}/applications/gnome-software-local-file-packagekit.desktop %{_datadir}/applications/org.gnome.Software.desktop %{_mandir}/man1/gnome-software.1* %{_datadir}/icons/hicolor/*/apps/org.gnome.Software.svg @@ -211,6 +211,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Sep 02 2022 Milan Crha - 43.rc-1 +- Update to 43.rc + * Wed Aug 17 2022 Milan Crha - 43.beta-3 - Resolves: #2119089 (No enough apps to show for the "Editor's Choice" section) diff --git a/sources b/sources index 27a6c41..edd91e5 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-43.beta.tar.xz) = 9dd2d1f3bebf4715dfbe4db636ca068ac53ae4d463d20f02421eb2990edc75e3b29b78436b8539027056042b6dda2ff55e9d6add1c5c9f8693899ce7a80065de +SHA512 (gnome-software-43.rc.tar.xz) = b843e30ad842500cbab19ce32566162961ce50d7ef2e4a9f7cdf969acb2ce074de6928dfa8c3813a1e89fb91868d7fc17daa6e9c36db7c45255e6e8b80552340 From a266972be3ad2757dbdc6aa625b7eb3c401d51c4 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 2 Sep 2022 10:51:15 +0200 Subject: [PATCH 008/116] Update to 43.rc --- 0002-install-queue.patch | 112 --------------------------------------- gnome-software.spec | 13 +++-- sources | 2 +- 3 files changed, 9 insertions(+), 118 deletions(-) delete mode 100644 0002-install-queue.patch diff --git a/0002-install-queue.patch b/0002-install-queue.patch deleted file mode 100644 index 698d1d0..0000000 --- a/0002-install-queue.patch +++ /dev/null @@ -1,112 +0,0 @@ -From d9e28b8cb59c805f2df8954637f2056467ff1be3 Mon Sep 17 00:00:00 2001 -From: Milan Crha -Date: Wed, 10 Aug 2022 13:41:46 +0200 -Subject: [PATCH 1/2] packagekit: Allow install of apps in the "queued for - install" state - -Treat the "queued for install" state the same as if "available/updatable" -state is set. Without that trying to install anything using PackageKit -plugin leads to an "Unsupported" error. ---- - plugins/packagekit/gs-plugin-packagekit.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/plugins/packagekit/gs-plugin-packagekit.c b/plugins/packagekit/gs-plugin-packagekit.c -index 58d627276..85f941648 100644 ---- a/plugins/packagekit/gs-plugin-packagekit.c -+++ b/plugins/packagekit/gs-plugin-packagekit.c -@@ -519,6 +519,7 @@ gs_plugin_app_install (GsPlugin *plugin, - switch (gs_app_get_state (app)) { - case GS_APP_STATE_AVAILABLE: - case GS_APP_STATE_UPDATABLE: -+ case GS_APP_STATE_QUEUED_FOR_INSTALL: - source_ids = gs_app_get_source_ids (app); - if (source_ids->len == 0) { - g_set_error_literal (error, --- -GitLab - - -From 71ce53a21373670f32b936194d46ab073df77a63 Mon Sep 17 00:00:00 2001 -From: Milan Crha -Date: Wed, 10 Aug 2022 14:24:51 +0200 -Subject: [PATCH 2/2] gs-plugin-loader: Add not removed from the install-queue - file - -The plugin loader has two places, which maintain the pending queue, -but they do not agree on the update of the install-queue file. Let -the functions be re-used, to avoid the problem. ---- - lib/gs-plugin-loader.c | 27 +++++++++++++++++---------- - 1 file changed, 17 insertions(+), 10 deletions(-) - -diff --git a/lib/gs-plugin-loader.c b/lib/gs-plugin-loader.c -index 073008d55..e3f48666a 100644 ---- a/lib/gs-plugin-loader.c -+++ b/lib/gs-plugin-loader.c -@@ -88,6 +88,7 @@ struct _GsPluginLoader - - static void gs_plugin_loader_monitor_network (GsPluginLoader *plugin_loader); - static void add_app_to_install_queue (GsPluginLoader *plugin_loader, GsApp *app); -+static gboolean remove_app_from_install_queue (GsPluginLoader *plugin_loader, GsApp *app); - static void gs_plugin_loader_process_in_thread_pool_cb (gpointer data, gpointer user_data); - static void gs_plugin_loader_status_changed_cb (GsPlugin *plugin, - GsApp *app, -@@ -1078,17 +1079,22 @@ gs_plugin_loader_pending_apps_add (GsPluginLoader *plugin_loader, - GsPluginLoaderHelper *helper) - { - GsAppList *list = gs_plugin_job_get_list (helper->plugin_job); -- g_autoptr(GMutexLocker) locker = g_mutex_locker_new (&plugin_loader->pending_apps_mutex); -- -- if (plugin_loader->pending_apps == NULL) -- plugin_loader->pending_apps = gs_app_list_new (); - - g_assert (gs_app_list_length (list) > 0); - for (guint i = 0; i < gs_app_list_length (list); i++) { - GsApp *app = gs_app_list_index (list, i); -- gs_app_list_add (plugin_loader->pending_apps, app); -- /* make sure the progress is properly initialized */ -- gs_app_set_progress (app, GS_APP_PROGRESS_UNKNOWN); -+ switch (gs_plugin_job_get_action (helper->plugin_job)) { -+ case GS_PLUGIN_ACTION_INSTALL: -+ add_app_to_install_queue (plugin_loader, app); -+ /* make sure the progress is properly initialized */ -+ gs_app_set_progress (app, GS_APP_PROGRESS_UNKNOWN); -+ break; -+ case GS_PLUGIN_ACTION_REMOVE: -+ remove_app_from_install_queue (plugin_loader, app); -+ break; -+ default: -+ break; -+ } - } - g_idle_add (emit_pending_apps_idle, g_object_ref (plugin_loader)); - } -@@ -1098,13 +1104,11 @@ gs_plugin_loader_pending_apps_remove (GsPluginLoader *plugin_loader, - GsPluginLoaderHelper *helper) - { - GsAppList *list = gs_plugin_job_get_list (helper->plugin_job); -- g_autoptr(GMutexLocker) locker = g_mutex_locker_new (&plugin_loader->pending_apps_mutex); - - g_assert (gs_app_list_length (list) > 0); - for (guint i = 0; i < gs_app_list_length (list); i++) { - GsApp *app = gs_app_list_index (list, i); -- if (plugin_loader->pending_apps != NULL) -- gs_app_list_remove (plugin_loader->pending_apps, app); -+ remove_app_from_install_queue (plugin_loader, app); - - /* check the app is not still in an action helper */ - switch (gs_app_get_state (app)) { -@@ -1272,6 +1276,9 @@ remove_app_from_install_queue (GsPluginLoader *plugin_loader, GsApp *app) - g_mutex_unlock (&plugin_loader->pending_apps_mutex); - - if (ret) { -+ if (gs_app_get_state (app) == GS_APP_STATE_QUEUED_FOR_INSTALL) -+ gs_app_set_state (app, GS_APP_STATE_UNKNOWN); -+ - id = g_idle_add (emit_pending_apps_idle, g_object_ref (plugin_loader)); - g_source_set_name_by_id (id, "[gnome-software] emit_pending_apps_idle"); - save_install_queue (plugin_loader); --- -GitLab - diff --git a/gnome-software.spec b/gnome-software.spec index cd0dec2..9545378 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -17,8 +17,8 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 43.beta -Release: 3%{?dist} +Version: 43.rc +Release: 1%{?dist} Summary: A software center for GNOME License: GPLv2+ @@ -26,7 +26,6 @@ URL: https://wiki.gnome.org/Apps/Software Source0: https://download.gnome.org/sources/gnome-software/43/%{name}-%{tarball_version}.tar.xz Patch01: 0001-crash-with-broken-theme.patch -Patch02: 0002-install-queue.patch BuildRequires: docbook-style-xsl BuildRequires: desktop-file-utils @@ -56,7 +55,6 @@ BuildRequires: pkgconfig(polkit-gobject-1) BuildRequires: pkgconfig(rpm) BuildRequires: pkgconfig(rpm-ostree-1) BuildRequires: pkgconfig(sysprof-capture-4) -BuildRequires: pkgconfig(valgrind) BuildRequires: pkgconfig(xmlb) >= %{libxmlb_version} Requires: appstream-data @@ -154,7 +152,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %doc AUTHORS README.md %license COPYING %{_bindir}/gnome-software -%{_datadir}/applications/gnome-software-local-file.desktop +%{_datadir}/applications/gnome-software-local-file-flatpak.desktop +%{_datadir}/applications/gnome-software-local-file-fwupd.desktop +%{_datadir}/applications/gnome-software-local-file-packagekit.desktop %{_datadir}/applications/org.gnome.Software.desktop %{_mandir}/man1/gnome-software.1* %{_datadir}/icons/hicolor/*/apps/org.gnome.Software.svg @@ -211,6 +211,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Sep 02 2022 Milan Crha - 43.rc-1 +- Update to 43.rc + * Wed Aug 17 2022 Milan Crha - 43.beta-3 - Resolves: #2119089 (No enough apps to show for the "Editor's Choice" section) diff --git a/sources b/sources index 27a6c41..edd91e5 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-43.beta.tar.xz) = 9dd2d1f3bebf4715dfbe4db636ca068ac53ae4d463d20f02421eb2990edc75e3b29b78436b8539027056042b6dda2ff55e9d6add1c5c9f8693899ce7a80065de +SHA512 (gnome-software-43.rc.tar.xz) = b843e30ad842500cbab19ce32566162961ce50d7ef2e4a9f7cdf969acb2ce074de6928dfa8c3813a1e89fb91868d7fc17daa6e9c36db7c45255e6e8b80552340 From d1659f7e1159459e1a2ea168bd4f1519d231b133 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Tue, 13 Sep 2022 09:11:57 +0200 Subject: [PATCH 009/116] Resolves: #2124869 (Cannot install RPM package file) --- 0002-install-rpm-file.patch | 108 ++++++++++++++++++++++++++++++++++++ gnome-software.spec | 6 +- 2 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 0002-install-rpm-file.patch diff --git a/0002-install-rpm-file.patch b/0002-install-rpm-file.patch new file mode 100644 index 0000000..745ceb7 --- /dev/null +++ b/0002-install-rpm-file.patch @@ -0,0 +1,108 @@ +From e706a530aeeba360fd60fa7ccde63a147f1e14d4 Mon Sep 17 00:00:00 2001 +Date: Wed, 7 Sep 2022 16:18:50 +0200 +Subject: [PATCH 1/2] gs-details-page: Filter out alternatives without origin + +When an alternative app has no origin set, it cannot be installed or +even shown in the GUI, thus filter such alternatives out. + +Helps https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1895 +--- + src/gs-details-page.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/src/gs-details-page.c b/src/gs-details-page.c +index cfe3cc797..d35ee0a98 100644 +--- a/src/gs-details-page.c ++++ b/src/gs-details-page.c +@@ -1637,6 +1637,16 @@ _set_app (GsDetailsPage *self, GsApp *app) + self, 0); + } + ++static gboolean ++gs_details_page_filter_origin (GsApp *app, ++ gpointer user_data) ++{ ++ /* Keep only local apps or those, which have an origin set */ ++ return gs_app_get_state (app) == GS_APP_STATE_AVAILABLE_LOCAL || ++ gs_app_get_local_file (app) != NULL || ++ gs_app_get_origin (app) != NULL; ++} ++ + /* show the UI and do operations that should not block page load */ + static void + gs_details_page_load_stage2 (GsDetailsPage *self, +@@ -1676,6 +1686,7 @@ gs_details_page_load_stage2 (GsDetailsPage *self, + query = gs_app_query_new ("alternate-of", self->app, + "refine-flags", GS_DETAILS_PAGE_REFINE_FLAGS, + "dedupe-flags", GS_APP_LIST_FILTER_FLAG_NONE, ++ "filter-func", gs_details_page_filter_origin, + "sort-func", gs_utils_app_sort_priority, + NULL); + plugin_job2 = gs_plugin_job_list_apps_new (query, GS_PLUGIN_LIST_APPS_FLAGS_INTERACTIVE); +-- +GitLab + + +From 7962414c7ef62494512a93df5855249debc39415 Mon Sep 17 00:00:00 2001 +Date: Wed, 7 Sep 2022 16:58:34 +0200 +Subject: [PATCH 2/2] gs-details-page: Include local file as an alternative + when not installed + +It's not enough to add the local file to the GsAppList, because it can +contain an app with the same ID, thus the local file app won't be added +to the list. + +Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1895 +--- + src/gs-details-page.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/src/gs-details-page.c b/src/gs-details-page.c +index d35ee0a98..50b80e159 100644 +--- a/src/gs-details-page.c ++++ b/src/gs-details-page.c +@@ -645,6 +645,7 @@ gs_details_page_get_alternates_cb (GObject *source_object, + GtkWidget *select_row = NULL; + GtkWidget *origin_row_by_packaging_format = NULL; + gint origin_row_by_packaging_format_index = 0; ++ guint n_rows = 0; + + self->origin_by_packaging_format = FALSE; + gs_widget_remove_all (self->origin_popover_list_box, (GsRemoveFunc) gtk_list_box_remove); +@@ -699,7 +700,15 @@ gs_details_page_get_alternates_cb (GObject *source_object, + /* add the local file to the list so that we can carry it over when + * switching between alternates */ + if (self->app_local_file != NULL) { +- gs_app_list_add (list, self->app_local_file); ++ if (gs_app_get_state (self->app_local_file) != GS_APP_STATE_INSTALLED) { ++ GtkWidget *row = gs_origin_popover_row_new (self->app_local_file); ++ gtk_widget_show (row); ++ gtk_list_box_append (GTK_LIST_BOX (self->origin_popover_list_box), row); ++ first_row = row; ++ select_row = row; ++ n_rows++; ++ } ++ + /* Do not allow change of the app by the packaging format when it's a local file */ + origin_by_packaging_format = FALSE; + } +@@ -716,6 +725,7 @@ gs_details_page_get_alternates_cb (GObject *source_object, + GsApp *app = gs_app_list_index (list, i); + GtkWidget *row = gs_origin_popover_row_new (app); + gtk_widget_show (row); ++ n_rows++; + if (first_row == NULL) + first_row = row; + if (app == self->app || ( +@@ -766,7 +776,7 @@ gs_details_page_get_alternates_cb (GObject *source_object, + } + + /* Do not show the "selected" check when there's only one app in the list */ +- if (select_row && gs_app_list_length (list) > 1) ++ if (select_row && n_rows > 1) + gs_origin_popover_row_set_selected (GS_ORIGIN_POPOVER_ROW (select_row), TRUE); + else if (select_row) + gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (select_row), FALSE); +-- +GitLab + diff --git a/gnome-software.spec b/gnome-software.spec index 9545378..6979b0c 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -18,7 +18,7 @@ Name: gnome-software Version: 43.rc -Release: 1%{?dist} +Release: 2%{?dist} Summary: A software center for GNOME License: GPLv2+ @@ -26,6 +26,7 @@ URL: https://wiki.gnome.org/Apps/Software Source0: https://download.gnome.org/sources/gnome-software/43/%{name}-%{tarball_version}.tar.xz Patch01: 0001-crash-with-broken-theme.patch +Patch02: 0002-install-rpm-file.patch BuildRequires: docbook-style-xsl BuildRequires: desktop-file-utils @@ -211,6 +212,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Tue Sep 13 2022 Milan Crha - 43.rc-2 +- Resolves: #2124869 (Cannot install RPM package file) + * Fri Sep 02 2022 Milan Crha - 43.rc-1 - Update to 43.rc From f19bd39d0e3de43e25dd637233fb584ff1f554cb Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Tue, 13 Sep 2022 09:11:57 +0200 Subject: [PATCH 010/116] Resolves: #2124869 (Cannot install RPM package file) --- 0002-install-rpm-file.patch | 108 ++++++++++++++++++++++++++++++++++++ gnome-software.spec | 6 +- 2 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 0002-install-rpm-file.patch diff --git a/0002-install-rpm-file.patch b/0002-install-rpm-file.patch new file mode 100644 index 0000000..745ceb7 --- /dev/null +++ b/0002-install-rpm-file.patch @@ -0,0 +1,108 @@ +From e706a530aeeba360fd60fa7ccde63a147f1e14d4 Mon Sep 17 00:00:00 2001 +Date: Wed, 7 Sep 2022 16:18:50 +0200 +Subject: [PATCH 1/2] gs-details-page: Filter out alternatives without origin + +When an alternative app has no origin set, it cannot be installed or +even shown in the GUI, thus filter such alternatives out. + +Helps https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1895 +--- + src/gs-details-page.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/src/gs-details-page.c b/src/gs-details-page.c +index cfe3cc797..d35ee0a98 100644 +--- a/src/gs-details-page.c ++++ b/src/gs-details-page.c +@@ -1637,6 +1637,16 @@ _set_app (GsDetailsPage *self, GsApp *app) + self, 0); + } + ++static gboolean ++gs_details_page_filter_origin (GsApp *app, ++ gpointer user_data) ++{ ++ /* Keep only local apps or those, which have an origin set */ ++ return gs_app_get_state (app) == GS_APP_STATE_AVAILABLE_LOCAL || ++ gs_app_get_local_file (app) != NULL || ++ gs_app_get_origin (app) != NULL; ++} ++ + /* show the UI and do operations that should not block page load */ + static void + gs_details_page_load_stage2 (GsDetailsPage *self, +@@ -1676,6 +1686,7 @@ gs_details_page_load_stage2 (GsDetailsPage *self, + query = gs_app_query_new ("alternate-of", self->app, + "refine-flags", GS_DETAILS_PAGE_REFINE_FLAGS, + "dedupe-flags", GS_APP_LIST_FILTER_FLAG_NONE, ++ "filter-func", gs_details_page_filter_origin, + "sort-func", gs_utils_app_sort_priority, + NULL); + plugin_job2 = gs_plugin_job_list_apps_new (query, GS_PLUGIN_LIST_APPS_FLAGS_INTERACTIVE); +-- +GitLab + + +From 7962414c7ef62494512a93df5855249debc39415 Mon Sep 17 00:00:00 2001 +Date: Wed, 7 Sep 2022 16:58:34 +0200 +Subject: [PATCH 2/2] gs-details-page: Include local file as an alternative + when not installed + +It's not enough to add the local file to the GsAppList, because it can +contain an app with the same ID, thus the local file app won't be added +to the list. + +Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1895 +--- + src/gs-details-page.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/src/gs-details-page.c b/src/gs-details-page.c +index d35ee0a98..50b80e159 100644 +--- a/src/gs-details-page.c ++++ b/src/gs-details-page.c +@@ -645,6 +645,7 @@ gs_details_page_get_alternates_cb (GObject *source_object, + GtkWidget *select_row = NULL; + GtkWidget *origin_row_by_packaging_format = NULL; + gint origin_row_by_packaging_format_index = 0; ++ guint n_rows = 0; + + self->origin_by_packaging_format = FALSE; + gs_widget_remove_all (self->origin_popover_list_box, (GsRemoveFunc) gtk_list_box_remove); +@@ -699,7 +700,15 @@ gs_details_page_get_alternates_cb (GObject *source_object, + /* add the local file to the list so that we can carry it over when + * switching between alternates */ + if (self->app_local_file != NULL) { +- gs_app_list_add (list, self->app_local_file); ++ if (gs_app_get_state (self->app_local_file) != GS_APP_STATE_INSTALLED) { ++ GtkWidget *row = gs_origin_popover_row_new (self->app_local_file); ++ gtk_widget_show (row); ++ gtk_list_box_append (GTK_LIST_BOX (self->origin_popover_list_box), row); ++ first_row = row; ++ select_row = row; ++ n_rows++; ++ } ++ + /* Do not allow change of the app by the packaging format when it's a local file */ + origin_by_packaging_format = FALSE; + } +@@ -716,6 +725,7 @@ gs_details_page_get_alternates_cb (GObject *source_object, + GsApp *app = gs_app_list_index (list, i); + GtkWidget *row = gs_origin_popover_row_new (app); + gtk_widget_show (row); ++ n_rows++; + if (first_row == NULL) + first_row = row; + if (app == self->app || ( +@@ -766,7 +776,7 @@ gs_details_page_get_alternates_cb (GObject *source_object, + } + + /* Do not show the "selected" check when there's only one app in the list */ +- if (select_row && gs_app_list_length (list) > 1) ++ if (select_row && n_rows > 1) + gs_origin_popover_row_set_selected (GS_ORIGIN_POPOVER_ROW (select_row), TRUE); + else if (select_row) + gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (select_row), FALSE); +-- +GitLab + diff --git a/gnome-software.spec b/gnome-software.spec index 9545378..6979b0c 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -18,7 +18,7 @@ Name: gnome-software Version: 43.rc -Release: 1%{?dist} +Release: 2%{?dist} Summary: A software center for GNOME License: GPLv2+ @@ -26,6 +26,7 @@ URL: https://wiki.gnome.org/Apps/Software Source0: https://download.gnome.org/sources/gnome-software/43/%{name}-%{tarball_version}.tar.xz Patch01: 0001-crash-with-broken-theme.patch +Patch02: 0002-install-rpm-file.patch BuildRequires: docbook-style-xsl BuildRequires: desktop-file-utils @@ -211,6 +212,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Tue Sep 13 2022 Milan Crha - 43.rc-2 +- Resolves: #2124869 (Cannot install RPM package file) + * Fri Sep 02 2022 Milan Crha - 43.rc-1 - Update to 43.rc From ddac1027ad5b1180b1dfdf2e62694a778c48cb4e Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 16 Sep 2022 08:39:15 +0200 Subject: [PATCH 011/116] Update to 43.0 --- gnome-software.spec | 7 +++++-- sources | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index 6979b0c..063211e 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -17,8 +17,8 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 43.rc -Release: 2%{?dist} +Version: 43.0 +Release: 1%{?dist} Summary: A software center for GNOME License: GPLv2+ @@ -212,6 +212,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Sep 16 2022 Milan Crha - 43.0-1 +- Update to 43.0 + * Tue Sep 13 2022 Milan Crha - 43.rc-2 - Resolves: #2124869 (Cannot install RPM package file) diff --git a/sources b/sources index edd91e5..2cc3ac4 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-43.rc.tar.xz) = b843e30ad842500cbab19ce32566162961ce50d7ef2e4a9f7cdf969acb2ce074de6928dfa8c3813a1e89fb91868d7fc17daa6e9c36db7c45255e6e8b80552340 +SHA512 (gnome-software-43.0.tar.xz) = bcf64e4d3d847c660fd1c1a2356235569560bc315fb6b0d2e459dfb1bbee7bf97d9a14f7c8ef1129e01241385cd1540d1499f9cc9ad99a996965feb48e698d6a From 8de47672c8ad3ac2eda974e8ab9ef657ae62fa43 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 16 Sep 2022 08:39:15 +0200 Subject: [PATCH 012/116] Update to 43.0 --- gnome-software.spec | 7 +++++-- sources | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index 6979b0c..063211e 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -17,8 +17,8 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 43.rc -Release: 2%{?dist} +Version: 43.0 +Release: 1%{?dist} Summary: A software center for GNOME License: GPLv2+ @@ -212,6 +212,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Sep 16 2022 Milan Crha - 43.0-1 +- Update to 43.0 + * Tue Sep 13 2022 Milan Crha - 43.rc-2 - Resolves: #2124869 (Cannot install RPM package file) diff --git a/sources b/sources index edd91e5..2cc3ac4 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-43.rc.tar.xz) = b843e30ad842500cbab19ce32566162961ce50d7ef2e4a9f7cdf969acb2ce074de6928dfa8c3813a1e89fb91868d7fc17daa6e9c36db7c45255e6e8b80552340 +SHA512 (gnome-software-43.0.tar.xz) = bcf64e4d3d847c660fd1c1a2356235569560bc315fb6b0d2e459dfb1bbee7bf97d9a14f7c8ef1129e01241385cd1540d1499f9cc9ad99a996965feb48e698d6a From a63799d564aa7df4c1472d7fe6363bad29a81929 Mon Sep 17 00:00:00 2001 From: Kalev Lember Date: Tue, 27 Sep 2022 18:53:43 +0200 Subject: [PATCH 013/116] Rebuild to fix sysprof-capture symbols leaking into libraries consuming it --- gnome-software.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gnome-software.spec b/gnome-software.spec index 063211e..ffcafcf 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -18,7 +18,7 @@ Name: gnome-software Version: 43.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: A software center for GNOME License: GPLv2+ @@ -212,6 +212,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Tue Sep 27 2022 Kalev Lember - 43.0-2 +- Rebuild to fix sysprof-capture symbols leaking into libraries consuming it + * Fri Sep 16 2022 Milan Crha - 43.0-1 - Update to 43.0 From 89923f63dcf1b2c9456f02bdd94db47c7b36a037 Mon Sep 17 00:00:00 2001 From: Kalev Lember Date: Tue, 27 Sep 2022 18:53:43 +0200 Subject: [PATCH 014/116] Rebuild to fix sysprof-capture symbols leaking into libraries consuming it --- gnome-software.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gnome-software.spec b/gnome-software.spec index 063211e..ffcafcf 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -18,7 +18,7 @@ Name: gnome-software Version: 43.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: A software center for GNOME License: GPLv2+ @@ -212,6 +212,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Tue Sep 27 2022 Kalev Lember - 43.0-2 +- Rebuild to fix sysprof-capture symbols leaking into libraries consuming it + * Fri Sep 16 2022 Milan Crha - 43.0-1 - Update to 43.0 From 1cc4989f9873aeccb514af0dd102a34a1954e96e Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Wed, 5 Oct 2022 18:52:53 +0200 Subject: [PATCH 015/116] Resolves: #2132292 (rpm-ostree plugin refuses to update) --- 0003-rpm-ostree-download-size.patch | 38 +++++++++++++++++++++++++++++ gnome-software.spec | 6 ++++- 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 0003-rpm-ostree-download-size.patch diff --git a/0003-rpm-ostree-download-size.patch b/0003-rpm-ostree-download-size.patch new file mode 100644 index 0000000..e353dd1 --- /dev/null +++ b/0003-rpm-ostree-download-size.patch @@ -0,0 +1,38 @@ +From 823f49dc59eb1a6a00c80084a8ac37782df124fa Mon Sep 17 00:00:00 2001 +Date: Mon, 26 Sep 2022 15:11:25 +0200 +Subject: [PATCH] rpm-ostree: Mark apps as downloaded + +There was a typo in the changes of the gs_app_set_size_download() API, +the `0` meant the app is downloaded, not that the size is unknown. +With this fixed, the Updates page offers to `Restart & Update`, instead +of `Download`, which does nothing, because the rpm-stree plugin +does not implement corresponding GsPlugin function. +--- + plugins/rpm-ostree/gs-plugin-rpm-ostree.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c +index 6984ff95b..1b4f758da 100644 +--- a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c ++++ b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c +@@ -749,7 +749,7 @@ app_from_modified_pkg_variant (GsPlugin *plugin, GVariant *variant) + gs_app_set_management_plugin (app, plugin); + gs_app_add_quirk (app, GS_APP_QUIRK_NEEDS_REBOOT); + app_set_rpm_ostree_packaging_format (app); +- gs_app_set_size_download (app, GS_SIZE_TYPE_UNKNOWN, 0); ++ gs_app_set_size_download (app, GS_SIZE_TYPE_VALID, 0); + gs_app_set_kind (app, AS_COMPONENT_KIND_GENERIC); + gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE); + gs_app_set_scope (app, AS_COMPONENT_SCOPE_SYSTEM); +@@ -788,7 +788,7 @@ app_from_single_pkg_variant (GsPlugin *plugin, GVariant *variant, gboolean addit + gs_app_set_management_plugin (app, plugin); + gs_app_add_quirk (app, GS_APP_QUIRK_NEEDS_REBOOT); + app_set_rpm_ostree_packaging_format (app); +- gs_app_set_size_download (app, GS_SIZE_TYPE_UNKNOWN, 0); ++ gs_app_set_size_download (app, GS_SIZE_TYPE_VALID, 0); + gs_app_set_kind (app, AS_COMPONENT_KIND_GENERIC); + gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE); + gs_app_set_scope (app, AS_COMPONENT_SCOPE_SYSTEM); +-- +GitLab + diff --git a/gnome-software.spec b/gnome-software.spec index ffcafcf..40d50e3 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -18,7 +18,7 @@ Name: gnome-software Version: 43.0 -Release: 2%{?dist} +Release: 3%{?dist} Summary: A software center for GNOME License: GPLv2+ @@ -27,6 +27,7 @@ Source0: https://download.gnome.org/sources/gnome-software/43/%{name}-%{tarbal Patch01: 0001-crash-with-broken-theme.patch Patch02: 0002-install-rpm-file.patch +Patch03: 0003-rpm-ostree-download-size.patch BuildRequires: docbook-style-xsl BuildRequires: desktop-file-utils @@ -212,6 +213,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Wed Oct 05 2022 Milan Crha - 43.0-3 +- Resolves: #2132292 (rpm-ostree plugin refuses to update) + * Tue Sep 27 2022 Kalev Lember - 43.0-2 - Rebuild to fix sysprof-capture symbols leaking into libraries consuming it From b0d5dd5afa7b7ca84a624367b6a333533a2cc9a1 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Wed, 5 Oct 2022 18:52:53 +0200 Subject: [PATCH 016/116] Resolves: #2132292 (rpm-ostree plugin refuses to update) --- 0003-rpm-ostree-download-size.patch | 38 +++++++++++++++++++++++++++++ gnome-software.spec | 6 ++++- 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 0003-rpm-ostree-download-size.patch diff --git a/0003-rpm-ostree-download-size.patch b/0003-rpm-ostree-download-size.patch new file mode 100644 index 0000000..e353dd1 --- /dev/null +++ b/0003-rpm-ostree-download-size.patch @@ -0,0 +1,38 @@ +From 823f49dc59eb1a6a00c80084a8ac37782df124fa Mon Sep 17 00:00:00 2001 +Date: Mon, 26 Sep 2022 15:11:25 +0200 +Subject: [PATCH] rpm-ostree: Mark apps as downloaded + +There was a typo in the changes of the gs_app_set_size_download() API, +the `0` meant the app is downloaded, not that the size is unknown. +With this fixed, the Updates page offers to `Restart & Update`, instead +of `Download`, which does nothing, because the rpm-stree plugin +does not implement corresponding GsPlugin function. +--- + plugins/rpm-ostree/gs-plugin-rpm-ostree.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c +index 6984ff95b..1b4f758da 100644 +--- a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c ++++ b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c +@@ -749,7 +749,7 @@ app_from_modified_pkg_variant (GsPlugin *plugin, GVariant *variant) + gs_app_set_management_plugin (app, plugin); + gs_app_add_quirk (app, GS_APP_QUIRK_NEEDS_REBOOT); + app_set_rpm_ostree_packaging_format (app); +- gs_app_set_size_download (app, GS_SIZE_TYPE_UNKNOWN, 0); ++ gs_app_set_size_download (app, GS_SIZE_TYPE_VALID, 0); + gs_app_set_kind (app, AS_COMPONENT_KIND_GENERIC); + gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE); + gs_app_set_scope (app, AS_COMPONENT_SCOPE_SYSTEM); +@@ -788,7 +788,7 @@ app_from_single_pkg_variant (GsPlugin *plugin, GVariant *variant, gboolean addit + gs_app_set_management_plugin (app, plugin); + gs_app_add_quirk (app, GS_APP_QUIRK_NEEDS_REBOOT); + app_set_rpm_ostree_packaging_format (app); +- gs_app_set_size_download (app, GS_SIZE_TYPE_UNKNOWN, 0); ++ gs_app_set_size_download (app, GS_SIZE_TYPE_VALID, 0); + gs_app_set_kind (app, AS_COMPONENT_KIND_GENERIC); + gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE); + gs_app_set_scope (app, AS_COMPONENT_SCOPE_SYSTEM); +-- +GitLab + diff --git a/gnome-software.spec b/gnome-software.spec index ffcafcf..40d50e3 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -18,7 +18,7 @@ Name: gnome-software Version: 43.0 -Release: 2%{?dist} +Release: 3%{?dist} Summary: A software center for GNOME License: GPLv2+ @@ -27,6 +27,7 @@ Source0: https://download.gnome.org/sources/gnome-software/43/%{name}-%{tarbal Patch01: 0001-crash-with-broken-theme.patch Patch02: 0002-install-rpm-file.patch +Patch03: 0003-rpm-ostree-download-size.patch BuildRequires: docbook-style-xsl BuildRequires: desktop-file-utils @@ -212,6 +213,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Wed Oct 05 2022 Milan Crha - 43.0-3 +- Resolves: #2132292 (rpm-ostree plugin refuses to update) + * Tue Sep 27 2022 Kalev Lember - 43.0-2 - Rebuild to fix sysprof-capture symbols leaking into libraries consuming it From 7d5bc8727e89f7171c0a4472c2e3bd8eeb52e877 Mon Sep 17 00:00:00 2001 From: Tomas Popela Date: Mon, 17 Oct 2022 10:40:58 +0200 Subject: [PATCH 017/116] Resolves: #2135289 (RPMs preferred over Flatpak on Silverblue) --- ...et-the-plugin-better-than-rpm-ostree.patch | 28 ++++++++++ ...app-plugin-priority-in-gs_app_compar.patch | 52 +++++++++++++++++++ ...ob-list-apps-Filter-out-invalid-apps.patch | 49 +++++++++++++++++ gnome-software.spec | 9 +++- 4 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 0001-flatpak-Set-the-plugin-better-than-rpm-ostree.patch create mode 100644 0001-gs-app-Use-real-app-plugin-priority-in-gs_app_compar.patch create mode 100644 0001-gs-plugin-job-list-apps-Filter-out-invalid-apps.patch diff --git a/0001-flatpak-Set-the-plugin-better-than-rpm-ostree.patch b/0001-flatpak-Set-the-plugin-better-than-rpm-ostree.patch new file mode 100644 index 0000000..5c9b573 --- /dev/null +++ b/0001-flatpak-Set-the-plugin-better-than-rpm-ostree.patch @@ -0,0 +1,28 @@ +From 604e2e976ee678e7e31e0f9ff60058e9036967fc Mon Sep 17 00:00:00 2001 +From: Milan Crha +Date: Fri, 14 Oct 2022 09:29:30 +0200 +Subject: [PATCH] flatpak: Set the plugin better than rpm-ostree + +It's already set better than packagekit, thus it's better than rpm-ostree +as well. + +Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1941 +--- + plugins/flatpak/gs-plugin-flatpak.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/plugins/flatpak/gs-plugin-flatpak.c b/plugins/flatpak/gs-plugin-flatpak.c +index 8bb612fcd..7c893ef67 100644 +--- a/plugins/flatpak/gs-plugin-flatpak.c ++++ b/plugins/flatpak/gs-plugin-flatpak.c +@@ -96,6 +96,7 @@ gs_plugin_flatpak_init (GsPluginFlatpak *self) + + /* prioritize over packages */ + gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_BETTER_THAN, "packagekit"); ++ gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_BETTER_THAN, "rpm-ostree"); + + /* set name of MetaInfo file */ + gs_plugin_set_appstream_id (plugin, "org.gnome.Software.Plugin.Flatpak"); +-- +2.37.3 + diff --git a/0001-gs-app-Use-real-app-plugin-priority-in-gs_app_compar.patch b/0001-gs-app-Use-real-app-plugin-priority-in-gs_app_compar.patch new file mode 100644 index 0000000..b15420e --- /dev/null +++ b/0001-gs-app-Use-real-app-plugin-priority-in-gs_app_compar.patch @@ -0,0 +1,52 @@ +From 39be84f7e4c903f6973115f809e3a288731e2d11 Mon Sep 17 00:00:00 2001 +From: Milan Crha +Date: Fri, 14 Oct 2022 09:18:28 +0200 +Subject: [PATCH] gs-app: Use real app/plugin priority in + gs_app_compare_priority() + +As Owen found out and reported in #1940, change in https://gitlab.gnome.org/GNOME/gnome-software/-/commit/e11a60b4a2ddadacbfbb1a8325b1e8daee574138 +did not consider the fact that gs_app_compare_priority() bypasses +the gs_app_get_priority(), thus the plugin priority was not +considered anymore. + +Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1940 +--- + lib/gs-app.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/lib/gs-app.c b/lib/gs-app.c +index d4b3f912a..51215c7e0 100644 +--- a/lib/gs-app.c ++++ b/lib/gs-app.c +@@ -400,14 +400,17 @@ gs_app_compare_priority (GsApp *app1, GsApp *app2) + { + GsAppPrivate *priv1 = gs_app_get_instance_private (app1); + GsAppPrivate *priv2 = gs_app_get_instance_private (app2); ++ guint prio1, prio2; + + g_return_val_if_fail (GS_IS_APP (app1), 0); + g_return_val_if_fail (GS_IS_APP (app2), 0); + + /* prefer prio */ +- if (priv1->priority > priv2->priority) ++ prio1 = gs_app_get_priority (app1); ++ prio2 = gs_app_get_priority (app2); ++ if (prio1 > prio2) + return -1; +- if (priv1->priority < priv2->priority) ++ if (prio1 < prio2) + return 1; + + /* fall back to bundle kind */ +@@ -5143,7 +5146,7 @@ gs_app_get_priority (GsApp *app) + if (priv->priority == 0) { + g_autoptr(GsPlugin) plugin = gs_app_dup_management_plugin (app); + if (plugin != NULL) +- return gs_plugin_get_priority (plugin); ++ priv->priority = gs_plugin_get_priority (plugin); + } + + return priv->priority; +-- +2.37.3 + diff --git a/0001-gs-plugin-job-list-apps-Filter-out-invalid-apps.patch b/0001-gs-plugin-job-list-apps-Filter-out-invalid-apps.patch new file mode 100644 index 0000000..1597f92 --- /dev/null +++ b/0001-gs-plugin-job-list-apps-Filter-out-invalid-apps.patch @@ -0,0 +1,49 @@ +From 79515873a275fff8f3f0713fb232e463358865bf Mon Sep 17 00:00:00 2001 +From: Georges Basile Stavracas Neto +Date: Thu, 29 Sep 2022 10:18:22 -0300 +Subject: [PATCH] gs-plugin-job-list-apps: Filter out invalid apps + +This filtering was lost with 7d54958d4e46e27af2cbdfc7f529611f4709d7fe. + +Filter out invalid apps as it did before. + +Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1932 +--- + lib/gs-plugin-job-list-apps.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/lib/gs-plugin-job-list-apps.c b/lib/gs-plugin-job-list-apps.c +index 811c7c08f..a556387e5 100644 +--- a/lib/gs-plugin-job-list-apps.c ++++ b/lib/gs-plugin-job-list-apps.c +@@ -136,6 +136,19 @@ gs_plugin_job_list_apps_set_property (GObject *object, + } + } + ++static gboolean ++filter_valid_apps (GsApp *app, ++ gpointer user_data) ++{ ++ GsPluginJobListApps *self = GS_PLUGIN_JOB_LIST_APPS (user_data); ++ GsPluginRefineFlags refine_flags = GS_PLUGIN_REFINE_FLAGS_NONE; ++ ++ if (self->query) ++ refine_flags = gs_app_query_get_refine_flags (self->query); ++ ++ return gs_plugin_loader_app_is_valid (app, refine_flags); ++} ++ + static gboolean + app_filter_qt_for_gtk_and_compatible (GsApp *app, + gpointer user_data) +@@ -345,6 +358,7 @@ finish_task (GTask *task, + /* Standard filtering. + * + * FIXME: It feels like this filter should be done in a different layer. */ ++ gs_app_list_filter (merged_list, filter_valid_apps, self); + gs_app_list_filter (merged_list, app_filter_qt_for_gtk_and_compatible, plugin_loader); + + /* Caller-specified filtering. */ +-- +2.37.3 + diff --git a/gnome-software.spec b/gnome-software.spec index 40d50e3..e127318 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -18,7 +18,7 @@ Name: gnome-software Version: 43.0 -Release: 3%{?dist} +Release: 4%{?dist} Summary: A software center for GNOME License: GPLv2+ @@ -28,6 +28,9 @@ Source0: https://download.gnome.org/sources/gnome-software/43/%{name}-%{tarbal Patch01: 0001-crash-with-broken-theme.patch Patch02: 0002-install-rpm-file.patch Patch03: 0003-rpm-ostree-download-size.patch +Patch04: 0001-gs-plugin-job-list-apps-Filter-out-invalid-apps.patch +Patch05: 0001-gs-app-Use-real-app-plugin-priority-in-gs_app_compar.patch +Patch06: 0001-flatpak-Set-the-plugin-better-than-rpm-ostree.patch BuildRequires: docbook-style-xsl BuildRequires: desktop-file-utils @@ -213,6 +216,10 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Mon Oct 17 2022 Tomas Popela - 43.0-4 +- Resolves: #2135289 (RPM packaged applications are presented in + GNOME Software and preferred over Flatpaks on Silverblue) + * Wed Oct 05 2022 Milan Crha - 43.0-3 - Resolves: #2132292 (rpm-ostree plugin refuses to update) From aca6555662c7b01db55fed0b1e42500c657acc3c Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 24 Oct 2022 07:53:55 +0200 Subject: [PATCH 018/116] Update to 43.1 --- 0002-install-rpm-file.patch | 108 ---------------------------- 0003-rpm-ostree-download-size.patch | 38 ---------- gnome-software.spec | 9 +-- sources | 2 +- 4 files changed, 6 insertions(+), 151 deletions(-) delete mode 100644 0002-install-rpm-file.patch delete mode 100644 0003-rpm-ostree-download-size.patch diff --git a/0002-install-rpm-file.patch b/0002-install-rpm-file.patch deleted file mode 100644 index 745ceb7..0000000 --- a/0002-install-rpm-file.patch +++ /dev/null @@ -1,108 +0,0 @@ -From e706a530aeeba360fd60fa7ccde63a147f1e14d4 Mon Sep 17 00:00:00 2001 -Date: Wed, 7 Sep 2022 16:18:50 +0200 -Subject: [PATCH 1/2] gs-details-page: Filter out alternatives without origin - -When an alternative app has no origin set, it cannot be installed or -even shown in the GUI, thus filter such alternatives out. - -Helps https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1895 ---- - src/gs-details-page.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/src/gs-details-page.c b/src/gs-details-page.c -index cfe3cc797..d35ee0a98 100644 ---- a/src/gs-details-page.c -+++ b/src/gs-details-page.c -@@ -1637,6 +1637,16 @@ _set_app (GsDetailsPage *self, GsApp *app) - self, 0); - } - -+static gboolean -+gs_details_page_filter_origin (GsApp *app, -+ gpointer user_data) -+{ -+ /* Keep only local apps or those, which have an origin set */ -+ return gs_app_get_state (app) == GS_APP_STATE_AVAILABLE_LOCAL || -+ gs_app_get_local_file (app) != NULL || -+ gs_app_get_origin (app) != NULL; -+} -+ - /* show the UI and do operations that should not block page load */ - static void - gs_details_page_load_stage2 (GsDetailsPage *self, -@@ -1676,6 +1686,7 @@ gs_details_page_load_stage2 (GsDetailsPage *self, - query = gs_app_query_new ("alternate-of", self->app, - "refine-flags", GS_DETAILS_PAGE_REFINE_FLAGS, - "dedupe-flags", GS_APP_LIST_FILTER_FLAG_NONE, -+ "filter-func", gs_details_page_filter_origin, - "sort-func", gs_utils_app_sort_priority, - NULL); - plugin_job2 = gs_plugin_job_list_apps_new (query, GS_PLUGIN_LIST_APPS_FLAGS_INTERACTIVE); --- -GitLab - - -From 7962414c7ef62494512a93df5855249debc39415 Mon Sep 17 00:00:00 2001 -Date: Wed, 7 Sep 2022 16:58:34 +0200 -Subject: [PATCH 2/2] gs-details-page: Include local file as an alternative - when not installed - -It's not enough to add the local file to the GsAppList, because it can -contain an app with the same ID, thus the local file app won't be added -to the list. - -Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1895 ---- - src/gs-details-page.c | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - -diff --git a/src/gs-details-page.c b/src/gs-details-page.c -index d35ee0a98..50b80e159 100644 ---- a/src/gs-details-page.c -+++ b/src/gs-details-page.c -@@ -645,6 +645,7 @@ gs_details_page_get_alternates_cb (GObject *source_object, - GtkWidget *select_row = NULL; - GtkWidget *origin_row_by_packaging_format = NULL; - gint origin_row_by_packaging_format_index = 0; -+ guint n_rows = 0; - - self->origin_by_packaging_format = FALSE; - gs_widget_remove_all (self->origin_popover_list_box, (GsRemoveFunc) gtk_list_box_remove); -@@ -699,7 +700,15 @@ gs_details_page_get_alternates_cb (GObject *source_object, - /* add the local file to the list so that we can carry it over when - * switching between alternates */ - if (self->app_local_file != NULL) { -- gs_app_list_add (list, self->app_local_file); -+ if (gs_app_get_state (self->app_local_file) != GS_APP_STATE_INSTALLED) { -+ GtkWidget *row = gs_origin_popover_row_new (self->app_local_file); -+ gtk_widget_show (row); -+ gtk_list_box_append (GTK_LIST_BOX (self->origin_popover_list_box), row); -+ first_row = row; -+ select_row = row; -+ n_rows++; -+ } -+ - /* Do not allow change of the app by the packaging format when it's a local file */ - origin_by_packaging_format = FALSE; - } -@@ -716,6 +725,7 @@ gs_details_page_get_alternates_cb (GObject *source_object, - GsApp *app = gs_app_list_index (list, i); - GtkWidget *row = gs_origin_popover_row_new (app); - gtk_widget_show (row); -+ n_rows++; - if (first_row == NULL) - first_row = row; - if (app == self->app || ( -@@ -766,7 +776,7 @@ gs_details_page_get_alternates_cb (GObject *source_object, - } - - /* Do not show the "selected" check when there's only one app in the list */ -- if (select_row && gs_app_list_length (list) > 1) -+ if (select_row && n_rows > 1) - gs_origin_popover_row_set_selected (GS_ORIGIN_POPOVER_ROW (select_row), TRUE); - else if (select_row) - gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (select_row), FALSE); --- -GitLab - diff --git a/0003-rpm-ostree-download-size.patch b/0003-rpm-ostree-download-size.patch deleted file mode 100644 index e353dd1..0000000 --- a/0003-rpm-ostree-download-size.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 823f49dc59eb1a6a00c80084a8ac37782df124fa Mon Sep 17 00:00:00 2001 -Date: Mon, 26 Sep 2022 15:11:25 +0200 -Subject: [PATCH] rpm-ostree: Mark apps as downloaded - -There was a typo in the changes of the gs_app_set_size_download() API, -the `0` meant the app is downloaded, not that the size is unknown. -With this fixed, the Updates page offers to `Restart & Update`, instead -of `Download`, which does nothing, because the rpm-stree plugin -does not implement corresponding GsPlugin function. ---- - plugins/rpm-ostree/gs-plugin-rpm-ostree.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c -index 6984ff95b..1b4f758da 100644 ---- a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c -+++ b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c -@@ -749,7 +749,7 @@ app_from_modified_pkg_variant (GsPlugin *plugin, GVariant *variant) - gs_app_set_management_plugin (app, plugin); - gs_app_add_quirk (app, GS_APP_QUIRK_NEEDS_REBOOT); - app_set_rpm_ostree_packaging_format (app); -- gs_app_set_size_download (app, GS_SIZE_TYPE_UNKNOWN, 0); -+ gs_app_set_size_download (app, GS_SIZE_TYPE_VALID, 0); - gs_app_set_kind (app, AS_COMPONENT_KIND_GENERIC); - gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE); - gs_app_set_scope (app, AS_COMPONENT_SCOPE_SYSTEM); -@@ -788,7 +788,7 @@ app_from_single_pkg_variant (GsPlugin *plugin, GVariant *variant, gboolean addit - gs_app_set_management_plugin (app, plugin); - gs_app_add_quirk (app, GS_APP_QUIRK_NEEDS_REBOOT); - app_set_rpm_ostree_packaging_format (app); -- gs_app_set_size_download (app, GS_SIZE_TYPE_UNKNOWN, 0); -+ gs_app_set_size_download (app, GS_SIZE_TYPE_VALID, 0); - gs_app_set_kind (app, AS_COMPONENT_KIND_GENERIC); - gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE); - gs_app_set_scope (app, AS_COMPONENT_SCOPE_SYSTEM); --- -GitLab - diff --git a/gnome-software.spec b/gnome-software.spec index 40d50e3..885915d 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -17,8 +17,8 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 43.0 -Release: 3%{?dist} +Version: 43.1 +Release: 1%{?dist} Summary: A software center for GNOME License: GPLv2+ @@ -26,8 +26,6 @@ URL: https://wiki.gnome.org/Apps/Software Source0: https://download.gnome.org/sources/gnome-software/43/%{name}-%{tarball_version}.tar.xz Patch01: 0001-crash-with-broken-theme.patch -Patch02: 0002-install-rpm-file.patch -Patch03: 0003-rpm-ostree-download-size.patch BuildRequires: docbook-style-xsl BuildRequires: desktop-file-utils @@ -213,6 +211,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Mon Oct 24 2022 Milan Crha - 43.1-1 +- Update to 43.1 + * Wed Oct 05 2022 Milan Crha - 43.0-3 - Resolves: #2132292 (rpm-ostree plugin refuses to update) diff --git a/sources b/sources index 2cc3ac4..d76eee5 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-43.0.tar.xz) = bcf64e4d3d847c660fd1c1a2356235569560bc315fb6b0d2e459dfb1bbee7bf97d9a14f7c8ef1129e01241385cd1540d1499f9cc9ad99a996965feb48e698d6a +SHA512 (gnome-software-43.1.tar.xz) = 5494622e1c52bcf660df8ab83cd73720ccab3c767f8870b6a23bd83c396972c508beb365e6df143055e3a7d9e77b42f01ea73a49d8dcdcf97aaeada0fe9f03e5 From 6fc4db5ad2ded917b9245ab098464ff0c40c227f Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 24 Oct 2022 07:57:57 +0200 Subject: [PATCH 019/116] Update to 43.1 --- ...et-the-plugin-better-than-rpm-ostree.patch | 28 ---------- ...app-plugin-priority-in-gs_app_compar.patch | 52 ------------------- ...ob-list-apps-Filter-out-invalid-apps.patch | 49 ----------------- gnome-software.spec | 12 ++--- sources | 2 +- 5 files changed, 6 insertions(+), 137 deletions(-) delete mode 100644 0001-flatpak-Set-the-plugin-better-than-rpm-ostree.patch delete mode 100644 0001-gs-app-Use-real-app-plugin-priority-in-gs_app_compar.patch delete mode 100644 0001-gs-plugin-job-list-apps-Filter-out-invalid-apps.patch diff --git a/0001-flatpak-Set-the-plugin-better-than-rpm-ostree.patch b/0001-flatpak-Set-the-plugin-better-than-rpm-ostree.patch deleted file mode 100644 index 5c9b573..0000000 --- a/0001-flatpak-Set-the-plugin-better-than-rpm-ostree.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 604e2e976ee678e7e31e0f9ff60058e9036967fc Mon Sep 17 00:00:00 2001 -From: Milan Crha -Date: Fri, 14 Oct 2022 09:29:30 +0200 -Subject: [PATCH] flatpak: Set the plugin better than rpm-ostree - -It's already set better than packagekit, thus it's better than rpm-ostree -as well. - -Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1941 ---- - plugins/flatpak/gs-plugin-flatpak.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/plugins/flatpak/gs-plugin-flatpak.c b/plugins/flatpak/gs-plugin-flatpak.c -index 8bb612fcd..7c893ef67 100644 ---- a/plugins/flatpak/gs-plugin-flatpak.c -+++ b/plugins/flatpak/gs-plugin-flatpak.c -@@ -96,6 +96,7 @@ gs_plugin_flatpak_init (GsPluginFlatpak *self) - - /* prioritize over packages */ - gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_BETTER_THAN, "packagekit"); -+ gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_BETTER_THAN, "rpm-ostree"); - - /* set name of MetaInfo file */ - gs_plugin_set_appstream_id (plugin, "org.gnome.Software.Plugin.Flatpak"); --- -2.37.3 - diff --git a/0001-gs-app-Use-real-app-plugin-priority-in-gs_app_compar.patch b/0001-gs-app-Use-real-app-plugin-priority-in-gs_app_compar.patch deleted file mode 100644 index b15420e..0000000 --- a/0001-gs-app-Use-real-app-plugin-priority-in-gs_app_compar.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 39be84f7e4c903f6973115f809e3a288731e2d11 Mon Sep 17 00:00:00 2001 -From: Milan Crha -Date: Fri, 14 Oct 2022 09:18:28 +0200 -Subject: [PATCH] gs-app: Use real app/plugin priority in - gs_app_compare_priority() - -As Owen found out and reported in #1940, change in https://gitlab.gnome.org/GNOME/gnome-software/-/commit/e11a60b4a2ddadacbfbb1a8325b1e8daee574138 -did not consider the fact that gs_app_compare_priority() bypasses -the gs_app_get_priority(), thus the plugin priority was not -considered anymore. - -Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1940 ---- - lib/gs-app.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/lib/gs-app.c b/lib/gs-app.c -index d4b3f912a..51215c7e0 100644 ---- a/lib/gs-app.c -+++ b/lib/gs-app.c -@@ -400,14 +400,17 @@ gs_app_compare_priority (GsApp *app1, GsApp *app2) - { - GsAppPrivate *priv1 = gs_app_get_instance_private (app1); - GsAppPrivate *priv2 = gs_app_get_instance_private (app2); -+ guint prio1, prio2; - - g_return_val_if_fail (GS_IS_APP (app1), 0); - g_return_val_if_fail (GS_IS_APP (app2), 0); - - /* prefer prio */ -- if (priv1->priority > priv2->priority) -+ prio1 = gs_app_get_priority (app1); -+ prio2 = gs_app_get_priority (app2); -+ if (prio1 > prio2) - return -1; -- if (priv1->priority < priv2->priority) -+ if (prio1 < prio2) - return 1; - - /* fall back to bundle kind */ -@@ -5143,7 +5146,7 @@ gs_app_get_priority (GsApp *app) - if (priv->priority == 0) { - g_autoptr(GsPlugin) plugin = gs_app_dup_management_plugin (app); - if (plugin != NULL) -- return gs_plugin_get_priority (plugin); -+ priv->priority = gs_plugin_get_priority (plugin); - } - - return priv->priority; --- -2.37.3 - diff --git a/0001-gs-plugin-job-list-apps-Filter-out-invalid-apps.patch b/0001-gs-plugin-job-list-apps-Filter-out-invalid-apps.patch deleted file mode 100644 index 1597f92..0000000 --- a/0001-gs-plugin-job-list-apps-Filter-out-invalid-apps.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 79515873a275fff8f3f0713fb232e463358865bf Mon Sep 17 00:00:00 2001 -From: Georges Basile Stavracas Neto -Date: Thu, 29 Sep 2022 10:18:22 -0300 -Subject: [PATCH] gs-plugin-job-list-apps: Filter out invalid apps - -This filtering was lost with 7d54958d4e46e27af2cbdfc7f529611f4709d7fe. - -Filter out invalid apps as it did before. - -Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1932 ---- - lib/gs-plugin-job-list-apps.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/lib/gs-plugin-job-list-apps.c b/lib/gs-plugin-job-list-apps.c -index 811c7c08f..a556387e5 100644 ---- a/lib/gs-plugin-job-list-apps.c -+++ b/lib/gs-plugin-job-list-apps.c -@@ -136,6 +136,19 @@ gs_plugin_job_list_apps_set_property (GObject *object, - } - } - -+static gboolean -+filter_valid_apps (GsApp *app, -+ gpointer user_data) -+{ -+ GsPluginJobListApps *self = GS_PLUGIN_JOB_LIST_APPS (user_data); -+ GsPluginRefineFlags refine_flags = GS_PLUGIN_REFINE_FLAGS_NONE; -+ -+ if (self->query) -+ refine_flags = gs_app_query_get_refine_flags (self->query); -+ -+ return gs_plugin_loader_app_is_valid (app, refine_flags); -+} -+ - static gboolean - app_filter_qt_for_gtk_and_compatible (GsApp *app, - gpointer user_data) -@@ -345,6 +358,7 @@ finish_task (GTask *task, - /* Standard filtering. - * - * FIXME: It feels like this filter should be done in a different layer. */ -+ gs_app_list_filter (merged_list, filter_valid_apps, self); - gs_app_list_filter (merged_list, app_filter_qt_for_gtk_and_compatible, plugin_loader); - - /* Caller-specified filtering. */ --- -2.37.3 - diff --git a/gnome-software.spec b/gnome-software.spec index e127318..4b60ca8 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -17,8 +17,8 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 43.0 -Release: 4%{?dist} +Version: 43.1 +Release: 1%{?dist} Summary: A software center for GNOME License: GPLv2+ @@ -26,11 +26,6 @@ URL: https://wiki.gnome.org/Apps/Software Source0: https://download.gnome.org/sources/gnome-software/43/%{name}-%{tarball_version}.tar.xz Patch01: 0001-crash-with-broken-theme.patch -Patch02: 0002-install-rpm-file.patch -Patch03: 0003-rpm-ostree-download-size.patch -Patch04: 0001-gs-plugin-job-list-apps-Filter-out-invalid-apps.patch -Patch05: 0001-gs-app-Use-real-app-plugin-priority-in-gs_app_compar.patch -Patch06: 0001-flatpak-Set-the-plugin-better-than-rpm-ostree.patch BuildRequires: docbook-style-xsl BuildRequires: desktop-file-utils @@ -216,6 +211,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Mon Oct 24 2022 Milan Crha - 43.1-1 +- Update to 43.1 + * Mon Oct 17 2022 Tomas Popela - 43.0-4 - Resolves: #2135289 (RPM packaged applications are presented in GNOME Software and preferred over Flatpaks on Silverblue) diff --git a/sources b/sources index 2cc3ac4..d76eee5 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-43.0.tar.xz) = bcf64e4d3d847c660fd1c1a2356235569560bc315fb6b0d2e459dfb1bbee7bf97d9a14f7c8ef1129e01241385cd1540d1499f9cc9ad99a996965feb48e698d6a +SHA512 (gnome-software-43.1.tar.xz) = 5494622e1c52bcf660df8ab83cd73720ccab3c767f8870b6a23bd83c396972c508beb365e6df143055e3a7d9e77b42f01ea73a49d8dcdcf97aaeada0fe9f03e5 From a9d9eb9799f07be7a52d4bcae69e6b16623268cf Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 24 Oct 2022 07:58:55 +0200 Subject: [PATCH 020/116] Delete obsolete patches --- 0002-install-rpm-file.patch | 108 ---------------------------- 0003-rpm-ostree-download-size.patch | 38 ---------- 2 files changed, 146 deletions(-) delete mode 100644 0002-install-rpm-file.patch delete mode 100644 0003-rpm-ostree-download-size.patch diff --git a/0002-install-rpm-file.patch b/0002-install-rpm-file.patch deleted file mode 100644 index 745ceb7..0000000 --- a/0002-install-rpm-file.patch +++ /dev/null @@ -1,108 +0,0 @@ -From e706a530aeeba360fd60fa7ccde63a147f1e14d4 Mon Sep 17 00:00:00 2001 -Date: Wed, 7 Sep 2022 16:18:50 +0200 -Subject: [PATCH 1/2] gs-details-page: Filter out alternatives without origin - -When an alternative app has no origin set, it cannot be installed or -even shown in the GUI, thus filter such alternatives out. - -Helps https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1895 ---- - src/gs-details-page.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/src/gs-details-page.c b/src/gs-details-page.c -index cfe3cc797..d35ee0a98 100644 ---- a/src/gs-details-page.c -+++ b/src/gs-details-page.c -@@ -1637,6 +1637,16 @@ _set_app (GsDetailsPage *self, GsApp *app) - self, 0); - } - -+static gboolean -+gs_details_page_filter_origin (GsApp *app, -+ gpointer user_data) -+{ -+ /* Keep only local apps or those, which have an origin set */ -+ return gs_app_get_state (app) == GS_APP_STATE_AVAILABLE_LOCAL || -+ gs_app_get_local_file (app) != NULL || -+ gs_app_get_origin (app) != NULL; -+} -+ - /* show the UI and do operations that should not block page load */ - static void - gs_details_page_load_stage2 (GsDetailsPage *self, -@@ -1676,6 +1686,7 @@ gs_details_page_load_stage2 (GsDetailsPage *self, - query = gs_app_query_new ("alternate-of", self->app, - "refine-flags", GS_DETAILS_PAGE_REFINE_FLAGS, - "dedupe-flags", GS_APP_LIST_FILTER_FLAG_NONE, -+ "filter-func", gs_details_page_filter_origin, - "sort-func", gs_utils_app_sort_priority, - NULL); - plugin_job2 = gs_plugin_job_list_apps_new (query, GS_PLUGIN_LIST_APPS_FLAGS_INTERACTIVE); --- -GitLab - - -From 7962414c7ef62494512a93df5855249debc39415 Mon Sep 17 00:00:00 2001 -Date: Wed, 7 Sep 2022 16:58:34 +0200 -Subject: [PATCH 2/2] gs-details-page: Include local file as an alternative - when not installed - -It's not enough to add the local file to the GsAppList, because it can -contain an app with the same ID, thus the local file app won't be added -to the list. - -Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1895 ---- - src/gs-details-page.c | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - -diff --git a/src/gs-details-page.c b/src/gs-details-page.c -index d35ee0a98..50b80e159 100644 ---- a/src/gs-details-page.c -+++ b/src/gs-details-page.c -@@ -645,6 +645,7 @@ gs_details_page_get_alternates_cb (GObject *source_object, - GtkWidget *select_row = NULL; - GtkWidget *origin_row_by_packaging_format = NULL; - gint origin_row_by_packaging_format_index = 0; -+ guint n_rows = 0; - - self->origin_by_packaging_format = FALSE; - gs_widget_remove_all (self->origin_popover_list_box, (GsRemoveFunc) gtk_list_box_remove); -@@ -699,7 +700,15 @@ gs_details_page_get_alternates_cb (GObject *source_object, - /* add the local file to the list so that we can carry it over when - * switching between alternates */ - if (self->app_local_file != NULL) { -- gs_app_list_add (list, self->app_local_file); -+ if (gs_app_get_state (self->app_local_file) != GS_APP_STATE_INSTALLED) { -+ GtkWidget *row = gs_origin_popover_row_new (self->app_local_file); -+ gtk_widget_show (row); -+ gtk_list_box_append (GTK_LIST_BOX (self->origin_popover_list_box), row); -+ first_row = row; -+ select_row = row; -+ n_rows++; -+ } -+ - /* Do not allow change of the app by the packaging format when it's a local file */ - origin_by_packaging_format = FALSE; - } -@@ -716,6 +725,7 @@ gs_details_page_get_alternates_cb (GObject *source_object, - GsApp *app = gs_app_list_index (list, i); - GtkWidget *row = gs_origin_popover_row_new (app); - gtk_widget_show (row); -+ n_rows++; - if (first_row == NULL) - first_row = row; - if (app == self->app || ( -@@ -766,7 +776,7 @@ gs_details_page_get_alternates_cb (GObject *source_object, - } - - /* Do not show the "selected" check when there's only one app in the list */ -- if (select_row && gs_app_list_length (list) > 1) -+ if (select_row && n_rows > 1) - gs_origin_popover_row_set_selected (GS_ORIGIN_POPOVER_ROW (select_row), TRUE); - else if (select_row) - gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (select_row), FALSE); --- -GitLab - diff --git a/0003-rpm-ostree-download-size.patch b/0003-rpm-ostree-download-size.patch deleted file mode 100644 index e353dd1..0000000 --- a/0003-rpm-ostree-download-size.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 823f49dc59eb1a6a00c80084a8ac37782df124fa Mon Sep 17 00:00:00 2001 -Date: Mon, 26 Sep 2022 15:11:25 +0200 -Subject: [PATCH] rpm-ostree: Mark apps as downloaded - -There was a typo in the changes of the gs_app_set_size_download() API, -the `0` meant the app is downloaded, not that the size is unknown. -With this fixed, the Updates page offers to `Restart & Update`, instead -of `Download`, which does nothing, because the rpm-stree plugin -does not implement corresponding GsPlugin function. ---- - plugins/rpm-ostree/gs-plugin-rpm-ostree.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c -index 6984ff95b..1b4f758da 100644 ---- a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c -+++ b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c -@@ -749,7 +749,7 @@ app_from_modified_pkg_variant (GsPlugin *plugin, GVariant *variant) - gs_app_set_management_plugin (app, plugin); - gs_app_add_quirk (app, GS_APP_QUIRK_NEEDS_REBOOT); - app_set_rpm_ostree_packaging_format (app); -- gs_app_set_size_download (app, GS_SIZE_TYPE_UNKNOWN, 0); -+ gs_app_set_size_download (app, GS_SIZE_TYPE_VALID, 0); - gs_app_set_kind (app, AS_COMPONENT_KIND_GENERIC); - gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE); - gs_app_set_scope (app, AS_COMPONENT_SCOPE_SYSTEM); -@@ -788,7 +788,7 @@ app_from_single_pkg_variant (GsPlugin *plugin, GVariant *variant, gboolean addit - gs_app_set_management_plugin (app, plugin); - gs_app_add_quirk (app, GS_APP_QUIRK_NEEDS_REBOOT); - app_set_rpm_ostree_packaging_format (app); -- gs_app_set_size_download (app, GS_SIZE_TYPE_UNKNOWN, 0); -+ gs_app_set_size_download (app, GS_SIZE_TYPE_VALID, 0); - gs_app_set_kind (app, AS_COMPONENT_KIND_GENERIC); - gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE); - gs_app_set_scope (app, AS_COMPONENT_SCOPE_SYSTEM); --- -GitLab - From a6313db9a145ae25b99ece3db717393f7c75a59d Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Tue, 8 Nov 2022 17:09:16 +0100 Subject: [PATCH 021/116] Disable WebApps for RHEL builds --- gnome-software.spec | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/gnome-software.spec b/gnome-software.spec index 885915d..7670999 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -9,6 +9,9 @@ %global libxmlb_version 0.1.7 %global packagekit_version 1.1.1 +# Disable WebApps for RHEL builds +%{!?with_webapps: %global with_webapps !0%{?rhel}} + # this is not a library version %define gs_plugin_version 19 @@ -18,7 +21,7 @@ Name: gnome-software Version: 43.1 -Release: 1%{?dist} +Release: 2%{?dist} Summary: A software center for GNOME License: GPLv2+ @@ -59,7 +62,9 @@ BuildRequires: pkgconfig(xmlb) >= %{libxmlb_version} Requires: appstream-data Requires: appstream%{?_isa} >= %{appstream_version} +%if %{with_webapps} Requires: epiphany-runtime%{?_isa} +%endif Requires: flatpak%{?_isa} >= %{flatpak_version} Requires: flatpak-libs%{?_isa} >= %{flatpak_version} Requires: fwupd%{?_isa} >= %{fwupd_version} @@ -116,9 +121,15 @@ This package includes the rpm-ostree backend. -Dpackagekit_autoremove=true \ -Dexternal_appstream=false \ -Drpm_ostree=true \ +%if %{with_webapps} -Dwebapps=true \ -Dhardcoded_foss_webapps=true \ -Dhardcoded_proprietary_webapps=false \ +%else + -Dwebapps=false \ + -Dhardcoded_foss_webapps=false \ + -Dhardcoded_proprietary_webapps=false \ +%endif -Dtests=false %meson_build @@ -161,14 +172,18 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/icons/hicolor/symbolic/apps/org.gnome.Software-symbolic.svg %{_datadir}/icons/hicolor/scalable/actions/app-remove-symbolic.svg %{_datadir}/metainfo/org.gnome.Software.metainfo.xml +%if %{with_webapps} %{_datadir}/metainfo/org.gnome.Software.Plugin.Epiphany.metainfo.xml +%endif %{_datadir}/metainfo/org.gnome.Software.Plugin.Flatpak.metainfo.xml %{_datadir}/metainfo/org.gnome.Software.Plugin.Fwupd.metainfo.xml %dir %{_libdir}/gnome-software/plugins-%{gs_plugin_version} %{_libdir}/gnome-software/libgnomesoftware.so.%{gs_plugin_version} %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_appstream.so %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_dummy.so +%if %{with_webapps} %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_epiphany.so +%endif %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_fedora-langpacks.so %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_fedora-pkgdb-collections.so %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_flatpak.so @@ -211,6 +226,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Tue Nov 08 2022 Milan Crha - 43.1-2 +- Disable WebApps for RHEL builds + * Mon Oct 24 2022 Milan Crha - 43.1-1 - Update to 43.1 From 7cb12d79d3c23319198252ca98191231ef2838d3 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Tue, 8 Nov 2022 18:41:35 +0100 Subject: [PATCH 022/116] Also skip gnome-pwa-list-foss.xml when building without WebApps --- gnome-software.spec | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gnome-software.spec b/gnome-software.spec index 7670999..6db479d 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -21,7 +21,7 @@ Name: gnome-software Version: 43.1 -Release: 2%{?dist} +Release: 3%{?dist} Summary: A software center for GNOME License: GPLv2+ @@ -202,7 +202,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_sysconfdir}/xdg/autostart/org.gnome.Software.desktop %dir %{_datadir}/swcatalog %dir %{_datadir}/swcatalog/xml +%if %{with_webapps} %{_datadir}/swcatalog/xml/gnome-pwa-list-foss.xml +%endif %{_datadir}/swcatalog/xml/org.gnome.Software.Curated.xml %{_datadir}/swcatalog/xml/org.gnome.Software.Featured.xml %{_datadir}/dbus-1/services/org.freedesktop.PackageKit.service @@ -226,6 +228,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Tue Nov 08 2022 Milan Crha - 43.1-3 +- Also skip gnome-pwa-list-foss.xml when building without WebApps + * Tue Nov 08 2022 Milan Crha - 43.1-2 - Disable WebApps for RHEL builds From 082bd5162c14a42cefe791af2c507ad0f49d61fb Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Thu, 10 Nov 2022 11:13:20 +0100 Subject: [PATCH 023/116] Update License tag to SPDX --- gnome-software.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gnome-software.spec b/gnome-software.spec index 6db479d..d0bec88 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -24,7 +24,7 @@ Version: 43.1 Release: 3%{?dist} Summary: A software center for GNOME -License: GPLv2+ +License: GPL-2.0-or-later URL: https://wiki.gnome.org/Apps/Software Source0: https://download.gnome.org/sources/gnome-software/43/%{name}-%{tarball_version}.tar.xz From b692d2f960bce0a6e87906fad5f146bfdf6de9fe Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 2 Dec 2022 12:56:50 +0100 Subject: [PATCH 024/116] Update to 43.2 --- gnome-software.spec | 7 +++++-- sources | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index d0bec88..4ffb38d 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -20,8 +20,8 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 43.1 -Release: 3%{?dist} +Version: 43.2 +Release: 1%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -228,6 +228,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Dec 02 2022 Milan Crha - 43.2-1 +- Update to 43.2 + * Tue Nov 08 2022 Milan Crha - 43.1-3 - Also skip gnome-pwa-list-foss.xml when building without WebApps diff --git a/sources b/sources index d76eee5..9799f5b 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-43.1.tar.xz) = 5494622e1c52bcf660df8ab83cd73720ccab3c767f8870b6a23bd83c396972c508beb365e6df143055e3a7d9e77b42f01ea73a49d8dcdcf97aaeada0fe9f03e5 +SHA512 (gnome-software-43.2.tar.xz) = d011418536706d2c5693581bd322008b5eb0fdf766ec96f1775135efb0fecec42dbc126ea2a66465b2169afb38b48fed1246516197e3bbf9d75b96e339d6ba33 From 2b59804686a453e1f778e39a85cb737fc3e43de1 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 2 Dec 2022 12:59:29 +0100 Subject: [PATCH 025/116] Update to 43.2 --- gnome-software.spec | 5 ++++- sources | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index 4b60ca8..00f7621 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -17,7 +17,7 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 43.1 +Version: 43.2 Release: 1%{?dist} Summary: A software center for GNOME @@ -211,6 +211,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Dec 02 2022 Milan Crha - 43.2-1 +- Update to 43.2 + * Mon Oct 24 2022 Milan Crha - 43.1-1 - Update to 43.1 diff --git a/sources b/sources index d76eee5..9799f5b 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-43.1.tar.xz) = 5494622e1c52bcf660df8ab83cd73720ccab3c767f8870b6a23bd83c396972c508beb365e6df143055e3a7d9e77b42f01ea73a49d8dcdcf97aaeada0fe9f03e5 +SHA512 (gnome-software-43.2.tar.xz) = d011418536706d2c5693581bd322008b5eb0fdf766ec96f1775135efb0fecec42dbc126ea2a66465b2169afb38b48fed1246516197e3bbf9d75b96e339d6ba33 From de5f7834c219407b8f6426076e2453285f2c7d48 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 9 Jan 2023 09:52:04 +0100 Subject: [PATCH 026/116] Update to 44.alpha --- 0001-crash-with-broken-theme.patch | 27 +++++++++++---------------- gnome-software.spec | 7 +++++-- sources | 2 +- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/0001-crash-with-broken-theme.patch b/0001-crash-with-broken-theme.patch index ddbef4a..d41a916 100644 --- a/0001-crash-with-broken-theme.patch +++ b/0001-crash-with-broken-theme.patch @@ -1,25 +1,20 @@ -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 - -diff -up gnome-software-42.rc/src/gs-feature-tile.c.1 gnome-software-42.rc/src/gs-feature-tile.c ---- gnome-software-42.rc/src/gs-feature-tile.c.1 2022-03-04 16:23:58.566735700 +0100 -+++ gnome-software-42.rc/src/gs-feature-tile.c 2022-03-07 08:06:29.046595524 +0100 -@@ -411,7 +411,6 @@ gs_feature_tile_refresh (GsAppTile *self +diff -up gnome-software-devel/src/gs-feature-tile.c.1 gnome-software-devel/src/gs-feature-tile.c +--- gnome-software-devel/src/gs-feature-tile.c.1 2023-01-02 17:08:54.157641969 +0100 ++++ gnome-software-devel/src/gs-feature-tile.c 2023-01-02 17:09:36.881632780 +0100 +@@ -397,9 +397,6 @@ gs_feature_tile_refresh (GsAppTile *self if (key_colors != tile->key_colors_cache) { g_autoptr(GArray) colors = NULL; GdkRGBA fg_rgba; +-#if !GTK_CHECK_VERSION(4, 9, 2) - gboolean fg_rgba_valid; +-#endif GsHSBC fg_hsbc; const GsHSBC *chosen_hsbc; GsHSBC chosen_hsbc_modified; -@@ -429,8 +428,17 @@ gs_feature_tile_refresh (GsAppTile *self - * @min_abs_contrast contrast with the foreground, so - * that the text is legible. - */ +@@ -424,8 +421,17 @@ gs_feature_tile_refresh (GsAppTile *self + gtk_widget_get_color (GTK_WIDGET (self), &fg_rgba); + #else + context = gtk_widget_get_style_context (GTK_WIDGET (self)); - 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)) { @@ -33,6 +28,6 @@ diff -up gnome-software-42.rc/src/gs-feature-tile.c.1 gnome-software-42.rc/src/g + fg_rgba.blue = 0.0; + fg_rgba.alpha = 1.0; + } + #endif gtk_rgb_to_hsv (fg_rgba.red, fg_rgba.green, fg_rgba.blue, - &fg_hsbc.hue, &fg_hsbc.saturation, &fg_hsbc.brightness); diff --git a/gnome-software.spec b/gnome-software.spec index 4ffb38d..7ec95f7 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -20,13 +20,13 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 43.2 +Version: 44~alpha Release: 1%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later URL: https://wiki.gnome.org/Apps/Software -Source0: https://download.gnome.org/sources/gnome-software/43/%{name}-%{tarball_version}.tar.xz +Source0: https://download.gnome.org/sources/gnome-software/44/%{name}-%{tarball_version}.tar.xz Patch01: 0001-crash-with-broken-theme.patch @@ -228,6 +228,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Mon Jan 09 2023 Milan Crha - 44.alpha-1 +- Update to 44.alpha + * Fri Dec 02 2022 Milan Crha - 43.2-1 - Update to 43.2 diff --git a/sources b/sources index 9799f5b..15996c7 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-43.2.tar.xz) = d011418536706d2c5693581bd322008b5eb0fdf766ec96f1775135efb0fecec42dbc126ea2a66465b2169afb38b48fed1246516197e3bbf9d75b96e339d6ba33 +SHA512 (gnome-software-44.alpha.tar.xz) = 4c6d71bca4c5f17d34b1d1c6083ade966ac0f43c9ae00fff1f05a51faca117647d71e48045ebbc697e1e4106dedfe45ce442973dad5f4a947c5dfe416232a776 From b4fb103d8804d45538d6d06c6b4f93b03512b6d0 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 9 Jan 2023 09:54:04 +0100 Subject: [PATCH 027/116] Update to 43.3 --- gnome-software.spec | 5 ++++- sources | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index 00f7621..10e291e 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -17,7 +17,7 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 43.2 +Version: 43.3 Release: 1%{?dist} Summary: A software center for GNOME @@ -211,6 +211,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Mon Jan 09 2023 Milan Crha - 43.3-1 +- Update to 43.3 + * Fri Dec 02 2022 Milan Crha - 43.2-1 - Update to 43.2 diff --git a/sources b/sources index 9799f5b..91f45b0 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-43.2.tar.xz) = d011418536706d2c5693581bd322008b5eb0fdf766ec96f1775135efb0fecec42dbc126ea2a66465b2169afb38b48fed1246516197e3bbf9d75b96e339d6ba33 +SHA512 (gnome-software-43.3.tar.xz) = e80c57d75a1805897913c6e5216c610556cbee2617a3e44dd83c366d10b8ae05ffe5f2ac79490ff77bb7a6f8c25ae91477543da26fa3f7794de01ba93ab26591 From db9647bdbd42e908b965b0066c3c6f35d15f98f6 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 19 Jan 2023 05:39:31 +0000 Subject: [PATCH 028/116] Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- gnome-software.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gnome-software.spec b/gnome-software.spec index 7ec95f7..090dad5 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -21,7 +21,7 @@ Name: gnome-software Version: 44~alpha -Release: 1%{?dist} +Release: 2%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -228,6 +228,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Thu Jan 19 2023 Fedora Release Engineering - 44~alpha-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + * Mon Jan 09 2023 Milan Crha - 44.alpha-1 - Update to 44.alpha From 203bf248ec3b693f18770e6eb32e7cc70a4284e0 Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Thu, 9 Feb 2023 11:03:29 -0600 Subject: [PATCH 029/116] Switch to libsoup 3 --- gnome-software.spec | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index 090dad5..e0a9fa6 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -21,7 +21,7 @@ Name: gnome-software Version: 44~alpha -Release: 2%{?dist} +Release: 3%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -50,7 +50,7 @@ BuildRequires: pkgconfig(gudev-1.0) BuildRequires: pkgconfig(json-glib-1.0) >= %{json_glib_version} BuildRequires: pkgconfig(libadwaita-1) >= %{libadwaita_version} BuildRequires: pkgconfig(libdnf) -BuildRequires: pkgconfig(libsoup-2.4) +BuildRequires: pkgconfig(libsoup-3.0) BuildRequires: pkgconfig(malcontent-0) BuildRequires: pkgconfig(ostree-1) BuildRequires: pkgconfig(packagekit-glib2) >= %{packagekit_version} @@ -113,7 +113,7 @@ This package includes the rpm-ostree backend. %build %meson \ - -Dsoup2=true \ + -Dsoup2=false \ -Dsnap=false \ -Dmalcontent=true \ -Dgudev=true \ @@ -228,6 +228,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Thu Feb 09 2023 Michael Catanzaro - 44~alpha-3 +- Switch to libsoup 3 + * Thu Jan 19 2023 Fedora Release Engineering - 44~alpha-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild From 82988db3a2a26a59c6ba350d1a5063264784ffd0 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 10 Feb 2023 09:29:52 +0100 Subject: [PATCH 030/116] Update to 43.4 --- gnome-software.spec | 5 ++++- sources | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index 10e291e..3c5728f 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -17,7 +17,7 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 43.3 +Version: 43.4 Release: 1%{?dist} Summary: A software center for GNOME @@ -211,6 +211,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Feb 10 2023 Milan Crha - 43.4-1 +- Update to 43.4 + * Mon Jan 09 2023 Milan Crha - 43.3-1 - Update to 43.3 diff --git a/sources b/sources index 91f45b0..e2d22ca 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-43.3.tar.xz) = e80c57d75a1805897913c6e5216c610556cbee2617a3e44dd83c366d10b8ae05ffe5f2ac79490ff77bb7a6f8c25ae91477543da26fa3f7794de01ba93ab26591 +SHA512 (gnome-software-43.4.tar.xz) = 3e4c8d29569238ffa116beb8e711f05172572b9b31de7d6f5ff1e26465c9f5be97e465f44ea2f6889e1a6c2b626a2de13b99d2e348a4ef150dca3d56c84ab5cd From e710d3931e8db0f904b040d1638a53b2f3e986cf Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Tue, 14 Feb 2023 08:09:00 +0100 Subject: [PATCH 031/116] Update to 44.beta --- gnome-software.spec | 13 ++++++++----- sources | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index e0a9fa6..a8e2a96 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -2,9 +2,9 @@ %global flatpak_version 1.5.1 %global fwupd_version 1.3.3 %global glib2_version 2.61.1 -%global gtk4_version 4.4.0 +%global gtk4_version 4.9.2 %global json_glib_version 1.2.0 -%global libadwaita_version 1.0.1 +%global libadwaita_version 1.3~alpha %global libsoup_version 2.52.0 %global libxmlb_version 0.1.7 %global packagekit_version 1.1.1 @@ -13,15 +13,15 @@ %{!?with_webapps: %global with_webapps !0%{?rhel}} # this is not a library version -%define gs_plugin_version 19 +%define gs_plugin_version 20 %global tarball_version %%(echo %{version} | tr '~' '.') %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 44~alpha -Release: 3%{?dist} +Version: 44~beta +Release: 1%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -228,6 +228,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Tue Feb 14 2023 Milan Crha - 44.beta-1 +- Update to 44.beta + * Thu Feb 09 2023 Michael Catanzaro - 44~alpha-3 - Switch to libsoup 3 diff --git a/sources b/sources index 15996c7..57a6efa 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-44.alpha.tar.xz) = 4c6d71bca4c5f17d34b1d1c6083ade966ac0f43c9ae00fff1f05a51faca117647d71e48045ebbc697e1e4106dedfe45ce442973dad5f4a947c5dfe416232a776 +SHA512 (gnome-software-44.beta.tar.xz) = 0d5f65f513e10d2db2590a9f0a9a5f0eb911ef8ae3a823115cbbc79e08c347faa0f7d07bac3bab0e9fc26b32bc2e60e35b2c7263a9cffb89c5a4c156623657d7 From 6e1e4a25c991a12ddb81da4c1cb3a3c8c27d44c6 Mon Sep 17 00:00:00 2001 From: Adam Williamson Date: Thu, 23 Feb 2023 13:19:04 -0800 Subject: [PATCH 032/116] Backport MR #1635 to fix update notifications --- ...r-No-notification-of-prepared-update.patch | 45 +++++++++++++++++++ gnome-software.spec | 9 +++- 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 0001-gs-update-monitor-No-notification-of-prepared-update.patch diff --git a/0001-gs-update-monitor-No-notification-of-prepared-update.patch b/0001-gs-update-monitor-No-notification-of-prepared-update.patch new file mode 100644 index 0000000..bbb2276 --- /dev/null +++ b/0001-gs-update-monitor-No-notification-of-prepared-update.patch @@ -0,0 +1,45 @@ +From f6594bb461617a92801cfbe5dd4017898119b72d Mon Sep 17 00:00:00 2001 +From: Milan Crha +Date: Thu, 23 Feb 2023 16:10:33 +0100 +Subject: [PATCH] gs-update-monitor: No notification of prepared updates + +This is a regression in 44.beta, the job returns empty list of apps, +because its existence only indicates success or failure. Due to that +there was not recognized any online nor offline update, thus no notification +was done afterwards. Check the app list used in the update job instead. +--- + src/gs-update-monitor.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/src/gs-update-monitor.c b/src/gs-update-monitor.c +index 6361ddbbb..b7ed2c344 100644 +--- a/src/gs-update-monitor.c ++++ b/src/gs-update-monitor.c +@@ -486,8 +486,9 @@ download_finished_cb (GObject *object, GAsyncResult *res, gpointer user_data) + g_autoptr(GsAppList) list = NULL; + g_autoptr(GsAppList) update_online = NULL; + g_autoptr(GsAppList) update_offline = NULL; ++ GsAppList *job_apps; + +- /* get result */ ++ /* the returned list is always empty, the existence indicates success */ + list = gs_plugin_loader_job_process_finish (plugin_loader, res, &error); + if (list == NULL) { + gs_plugin_loader_claim_job_error (plugin_loader, +@@ -497,10 +498,11 @@ download_finished_cb (GObject *object, GAsyncResult *res, gpointer user_data) + return; + } + ++ job_apps = gs_plugin_job_update_apps_get_apps (GS_PLUGIN_JOB_UPDATE_APPS (data->job)); + update_online = gs_app_list_new (); + update_offline = gs_app_list_new (); +- for (guint i = 0; i < gs_app_list_length (list); i++) { +- GsApp *app = gs_app_list_index (list, i); ++ for (guint i = 0; i < gs_app_list_length (job_apps); i++) { ++ GsApp *app = gs_app_list_index (job_apps, i); + if (_should_auto_update (app)) { + g_debug ("auto-updating %s", gs_app_get_unique_id (app)); + gs_app_list_add (update_online, app); +-- +2.39.2 + diff --git a/gnome-software.spec b/gnome-software.spec index a8e2a96..0cd68f2 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -21,7 +21,7 @@ Name: gnome-software Version: 44~beta -Release: 1%{?dist} +Release: 2%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -29,6 +29,10 @@ URL: https://wiki.gnome.org/Apps/Software Source0: https://download.gnome.org/sources/gnome-software/44/%{name}-%{tarball_version}.tar.xz Patch01: 0001-crash-with-broken-theme.patch +# https://gitlab.gnome.org/GNOME/gnome-software/-/merge_requests/1635 +# https://bugzilla.redhat.com/show_bug.cgi?id=2172662 +# Fix update notifications +Patch02: 0001-gs-update-monitor-No-notification-of-prepared-update.patch BuildRequires: docbook-style-xsl BuildRequires: desktop-file-utils @@ -228,6 +232,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Thu Feb 23 2023 Adam Williamson - 44~beta-2 +- Backport MR #1635 to fix update notifications + * Tue Feb 14 2023 Milan Crha - 44.beta-1 - Update to 44.beta From 15e94382f2fd36d24faa1813b3cccaad972568d5 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 3 Mar 2023 13:56:53 +0100 Subject: [PATCH 033/116] Update to 43.5 --- gnome-software.spec | 5 ++++- sources | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index 3c5728f..68c4d73 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -17,7 +17,7 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 43.4 +Version: 43.5 Release: 1%{?dist} Summary: A software center for GNOME @@ -211,6 +211,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Mar 03 2023 Milan Crha - 43.5-1 +- Update to 43.5 + * Fri Feb 10 2023 Milan Crha - 43.4-1 - Update to 43.4 diff --git a/sources b/sources index e2d22ca..8f77711 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-43.4.tar.xz) = 3e4c8d29569238ffa116beb8e711f05172572b9b31de7d6f5ff1e26465c9f5be97e465f44ea2f6889e1a6c2b626a2de13b99d2e348a4ef150dca3d56c84ab5cd +SHA512 (gnome-software-43.5.tar.xz) = c3d0b05122f5444b1db00719b99f80771ac2ee25ac3caea053bdc734e9faa9730263d20408d4bd87430141392613504b8dff59917eb6a97765302f04ff4306d0 From cb6e4371958d1a7dc595dec68606acc89a458a24 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 3 Mar 2023 13:59:50 +0100 Subject: [PATCH 034/116] Update to 44.rc --- ...r-No-notification-of-prepared-update.patch | 45 ------------------- gnome-software.spec | 13 +++--- sources | 2 +- 3 files changed, 7 insertions(+), 53 deletions(-) delete mode 100644 0001-gs-update-monitor-No-notification-of-prepared-update.patch diff --git a/0001-gs-update-monitor-No-notification-of-prepared-update.patch b/0001-gs-update-monitor-No-notification-of-prepared-update.patch deleted file mode 100644 index bbb2276..0000000 --- a/0001-gs-update-monitor-No-notification-of-prepared-update.patch +++ /dev/null @@ -1,45 +0,0 @@ -From f6594bb461617a92801cfbe5dd4017898119b72d Mon Sep 17 00:00:00 2001 -From: Milan Crha -Date: Thu, 23 Feb 2023 16:10:33 +0100 -Subject: [PATCH] gs-update-monitor: No notification of prepared updates - -This is a regression in 44.beta, the job returns empty list of apps, -because its existence only indicates success or failure. Due to that -there was not recognized any online nor offline update, thus no notification -was done afterwards. Check the app list used in the update job instead. ---- - src/gs-update-monitor.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/src/gs-update-monitor.c b/src/gs-update-monitor.c -index 6361ddbbb..b7ed2c344 100644 ---- a/src/gs-update-monitor.c -+++ b/src/gs-update-monitor.c -@@ -486,8 +486,9 @@ download_finished_cb (GObject *object, GAsyncResult *res, gpointer user_data) - g_autoptr(GsAppList) list = NULL; - g_autoptr(GsAppList) update_online = NULL; - g_autoptr(GsAppList) update_offline = NULL; -+ GsAppList *job_apps; - -- /* get result */ -+ /* the returned list is always empty, the existence indicates success */ - list = gs_plugin_loader_job_process_finish (plugin_loader, res, &error); - if (list == NULL) { - gs_plugin_loader_claim_job_error (plugin_loader, -@@ -497,10 +498,11 @@ download_finished_cb (GObject *object, GAsyncResult *res, gpointer user_data) - return; - } - -+ job_apps = gs_plugin_job_update_apps_get_apps (GS_PLUGIN_JOB_UPDATE_APPS (data->job)); - update_online = gs_app_list_new (); - update_offline = gs_app_list_new (); -- for (guint i = 0; i < gs_app_list_length (list); i++) { -- GsApp *app = gs_app_list_index (list, i); -+ for (guint i = 0; i < gs_app_list_length (job_apps); i++) { -+ GsApp *app = gs_app_list_index (job_apps, i); - if (_should_auto_update (app)) { - g_debug ("auto-updating %s", gs_app_get_unique_id (app)); - gs_app_list_add (update_online, app); --- -2.39.2 - diff --git a/gnome-software.spec b/gnome-software.spec index 0cd68f2..d525c64 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -4,7 +4,7 @@ %global glib2_version 2.61.1 %global gtk4_version 4.9.2 %global json_glib_version 1.2.0 -%global libadwaita_version 1.3~alpha +%global libadwaita_version 1.3.alpha %global libsoup_version 2.52.0 %global libxmlb_version 0.1.7 %global packagekit_version 1.1.1 @@ -20,8 +20,8 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 44~beta -Release: 2%{?dist} +Version: 44~rc +Release: 1%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -29,10 +29,6 @@ URL: https://wiki.gnome.org/Apps/Software Source0: https://download.gnome.org/sources/gnome-software/44/%{name}-%{tarball_version}.tar.xz Patch01: 0001-crash-with-broken-theme.patch -# https://gitlab.gnome.org/GNOME/gnome-software/-/merge_requests/1635 -# https://bugzilla.redhat.com/show_bug.cgi?id=2172662 -# Fix update notifications -Patch02: 0001-gs-update-monitor-No-notification-of-prepared-update.patch BuildRequires: docbook-style-xsl BuildRequires: desktop-file-utils @@ -232,6 +228,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Mar 03 2023 Milan Crha - 44~rc-1 +- Update to 44.rc + * Thu Feb 23 2023 Adam Williamson - 44~beta-2 - Backport MR #1635 to fix update notifications diff --git a/sources b/sources index 57a6efa..0ad486a 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-44.beta.tar.xz) = 0d5f65f513e10d2db2590a9f0a9a5f0eb911ef8ae3a823115cbbc79e08c347faa0f7d07bac3bab0e9fc26b32bc2e60e35b2c7263a9cffb89c5a4c156623657d7 +SHA512 (gnome-software-44.rc.tar.xz) = 15d40987a001af58dd0a671c8aa7399a1397a21bcd62ff5850e5dde4cee67cb64d53408492d8da0990cee301bf535b5c1954257d8dcbb0f49ba74ee1347ec843 From 1293c4db156be33d8bf471de4a1617903a23cd06 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 17 Mar 2023 07:44:25 +0100 Subject: [PATCH 035/116] Update to 44.0 --- 0002-update-czech-translation.patch | 4889 +++++++++++++++++++++++++++ gnome-software.spec | 6 +- sources | 2 +- 3 files changed, 4895 insertions(+), 2 deletions(-) create mode 100644 0002-update-czech-translation.patch diff --git a/0002-update-czech-translation.patch b/0002-update-czech-translation.patch new file mode 100644 index 0000000..86b6304 --- /dev/null +++ b/0002-update-czech-translation.patch @@ -0,0 +1,4889 @@ +diff --git a/po/cs.po b/po/cs.po +index 3301fcaf4..b532ac8a9 100644 +--- a/po/cs.po ++++ b/po/cs.po +@@ -4,22 +4,23 @@ + # + # Petr Kovar , 2015. + # Marek Černocký , 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022. +-# Vojtěch Perník , 2021-2022. ++# Vojtěch Perník , 2021-2023. ++# Daniel Rusek , 2023. + # + msgid "" + msgstr "" + "Project-Id-Version: gnome-software\n" + "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-software/issues\n" +-"POT-Creation-Date: 2022-11-10 08:39+0000\n" +-"PO-Revision-Date: 2022-08-28 11:45+0200\n" +-"Last-Translator: Vojtěch Perník \n" ++"POT-Creation-Date: 2023-03-16 13:07+0000\n" ++"PO-Revision-Date: 2023-03-16 12:54+0100\n" ++"Last-Translator: Daniel Rusek \n" + "Language-Team: Czech \n" + "Language: cs\n" + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" + "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +-"X-Generator: Poedit 3.1.1\n" ++"X-Generator: Poedit 3.2.2\n" + "X-Project-Style: gnome\n" + + #: data/metainfo/org.gnome.Software.metainfo.xml.in:7 src/gs-shell.ui:21 +@@ -33,18 +34,18 @@ msgstr "Instalujte a aktualizujte aplikace" + + #: data/metainfo/org.gnome.Software.metainfo.xml.in:10 + msgid "" +-"Software allows you to find and install new applications and system " +-"extensions and remove existing installed applications." ++"Software allows you to find and install new apps and system extensions and " ++"remove existing installed apps." + msgstr "" + "Aplikace Software umožňuje vyhledávat a instalovat aplikace a systémová " + "rozšíření a odebírat stávající nainstalované aplikace." + + #: data/metainfo/org.gnome.Software.metainfo.xml.in:14 + msgid "" +-"Software showcases featured and popular applications with useful " +-"descriptions and multiple screenshots per application. Applications can be " +-"found either through browsing the list of categories or by searching. It " +-"also allows you to update your system using an offline update." ++"Software showcases featured and popular apps with useful descriptions and " ++"multiple screenshots per app. Apps can be found either through browsing the " ++"list of categories or by searching. It also allows you to update your system " ++"using an offline update." + msgstr "" + "Aplikace Software vám představí významné a oblíbené aplikace pomocí " + "srozumitelného popisu a několika snímků obrazovky. Aplikace můžete najít buď " +@@ -73,7 +74,7 @@ msgstr "Panel s aktualizacemi" + msgid "The update details" + msgstr "Podrobnosti o aktualizaci" + +-#: data/metainfo/org.gnome.Software.metainfo.xml.in:2076 ++#: data/metainfo/org.gnome.Software.metainfo.xml.in:2222 + #: src/gs-application.c:264 + msgid "The GNOME Project" + msgstr "Projekt GNOME" +@@ -195,17 +196,12 @@ msgid "The last update timestamp" + msgstr "Datum a čas poslední aktualizace" + + #: data/org.gnome.software.gschema.xml:67 +-msgid "The last timestamp when the system was online and got any updates" +-msgstr "" +-"Datum a čas, kdy byl systém naposledy on-line a dostal nějaké aktualizace" +- +-#: data/org.gnome.software.gschema.xml:71 + msgid "The age in seconds to verify the upstream screenshot is still valid" + msgstr "" + "Doba v sekundách, po které se má ověřit, jestli je snímek obrazovky z " + "hlavního zdroje stále platný" + +-#: data/org.gnome.software.gschema.xml:72 ++#: data/org.gnome.software.gschema.xml:68 + msgid "" + "Choosing a larger value will mean less round-trips to the remote server but " + "updates to the screenshots may take longer to show to the user. A value of 0 " +@@ -216,75 +212,75 @@ msgstr "" + "znamená, že se kontroly na serveru nemají provádět vůbec, pokud je již " + "snímek v mezipaměti." + +-#: data/org.gnome.software.gschema.xml:81 ++#: data/org.gnome.software.gschema.xml:77 + msgid "The server to use for application reviews" + msgstr "Server, který se má používat pro recenze aktualizací" + +-#: data/org.gnome.software.gschema.xml:85 ++#: data/org.gnome.software.gschema.xml:81 + msgid "The minimum karma score for reviews" + msgstr "Minimální karma pro recenze" + +-#: data/org.gnome.software.gschema.xml:86 ++#: data/org.gnome.software.gschema.xml:82 + msgid "Reviews with karma less than this number will not be shown." + msgstr "Recenze s karmou nižší než toto číslo nebudou zobrazovány." + +-#: data/org.gnome.software.gschema.xml:90 ++#: data/org.gnome.software.gschema.xml:86 + msgid "A list of official repositories that should not be considered 3rd party" + msgstr "" + "Seznam oficiálních repozitářů, které by neměly být považovány za třetí stranu" + +-#: data/org.gnome.software.gschema.xml:94 ++#: data/org.gnome.software.gschema.xml:90 + msgid "A list of required repositories that cannot be disabled or removed" + msgstr "" + "Seznam vyžadovaných repozitářů, které nemohou být zakázány nebo odebrány" + +-#: data/org.gnome.software.gschema.xml:98 ++#: data/org.gnome.software.gschema.xml:94 + msgid "A list of official repositories that should be considered free software" + msgstr "" + "Seznam oficiálních repozitářů, které by měly být považovány za svobodný " + "software" + +-#: data/org.gnome.software.gschema.xml:102 ++#: data/org.gnome.software.gschema.xml:98 + msgid "" + "The licence URL to use when an application should be considered free software" + msgstr "" + "Adresa URL licence, která se má použít, když má aplikace považována za " + "svobodný software" + +-#: data/org.gnome.software.gschema.xml:106 ++#: data/org.gnome.software.gschema.xml:102 + msgid "Install bundled applications for all users on the system where possible" + msgstr "" + "Kde je to možné, instalovat všem uživatelům v systému přibalené aplikace" + +-#: data/org.gnome.software.gschema.xml:110 ++#: data/org.gnome.software.gschema.xml:106 + msgid "Allow access to the Software Repositories dialog" + msgstr "Umožnit přístup k dialogovému oknu s repozitáři softwaru" + +-#: data/org.gnome.software.gschema.xml:114 ++#: data/org.gnome.software.gschema.xml:110 + msgid "Offer upgrades for pre-releases" + msgstr "Nabízet povýšení na předběžná vydání" + +-#: data/org.gnome.software.gschema.xml:118 ++#: data/org.gnome.software.gschema.xml:114 + msgid "Show some UI elements informing the user that an app is non-free" + msgstr "" + "Zobrazovat v rozhraní prvky, které informují uživatele, že aplikace není " + "svobodná" + +-#: data/org.gnome.software.gschema.xml:122 ++#: data/org.gnome.software.gschema.xml:118 + msgid "Show the installed size for apps in the list of installed applications" + msgstr "" + "Zobrazovat velikost instalace pro aplikace v seznamu nainstalovaných aplikací" + + #. Translators: Replace the link with a version in your language, e.g. 'https://de.wikipedia.org/wiki/Proprietäre_Software'. Remember to include ''. +-#: data/org.gnome.software.gschema.xml:126 ++#: data/org.gnome.software.gschema.xml:122 + msgid "'https://en.wikipedia.org/wiki/Proprietary_software'" + msgstr "'https://cs.wikipedia.org/wiki/Propriet%C3%A1rn%C3%AD_software'" + +-#: data/org.gnome.software.gschema.xml:127 ++#: data/org.gnome.software.gschema.xml:123 + msgid "The URI that explains nonfree and proprietary software" + msgstr "Adresa URI, která vysvětluje nesvobodný a komerční software" + +-#: data/org.gnome.software.gschema.xml:131 ++#: data/org.gnome.software.gschema.xml:127 + msgid "" + "A list of URLs pointing to appstream files that will be downloaded into an " + "swcatalog folder" +@@ -292,7 +288,7 @@ msgstr "" + "Seznam adres URL ukazujících na soubory appstream, které byly stažené do " + "složky swcatalog" + +-#: data/org.gnome.software.gschema.xml:135 ++#: data/org.gnome.software.gschema.xml:131 + msgid "" + "Install the AppStream files to a system-wide location for all users. If " + "false, files are installed in non-standard $XDG_DATA_HOME/swcatalog/xml " +@@ -302,13 +298,7 @@ msgstr "" + "uživatele. Pokud je vypnuto, budou soubory instalovány do nestandardní " + "složky $XDG_DATA_HOME/swcatalog/xmls" + +-#: data/org.gnome.software.gschema.xml:139 +-#, fuzzy +-#| msgid "" +-#| "Priority order of packaging formats to prefer, with more important " +-#| "formats listed first. An empty array means the default order. Omitted " +-#| "formats are assumed to be listed last. Example packaging formats are: " +-#| "deb, flatpak, rpm, snap." ++#: data/org.gnome.software.gschema.xml:135 + msgid "" + "Priority order of packaging formats to prefer, with more important formats " + "listed first. An empty array means the default order. Omitted formats are " +@@ -319,9 +309,24 @@ msgstr "" + "Prioritní pořadí formátů balíčků, kterým dáváte přednost, přičemž " + "důležitější formáty jsou uvedeny na prvním místě. Prázdné pole znamená " + "výchozí pořadí. Předpokládá se, že vynechané formáty budou uvedeny jako " +-"poslední. Příklady balíčkovacích formátů: deb, flatpak, rpm, snap." ++"poslední. Příklady balíčkovacích formátů: deb, flatpak, rpm, snap. Formáty " ++"mohou být nepovinně specifikovány s názvem původu odděleného dvojtečkou, " ++"například „flatpak:flathub“." ++ ++#: data/org.gnome.software.gschema.xml:139 ++msgid "The timestamp of the last attempt to remove unused Flatpak runtimes" ++msgstr "" ++"Datum a čas posledního pokusu odebrat nepoužívaná běhová prostředí Flatpak" ++ ++#: data/org.gnome.software.gschema.xml:143 ++msgid "" ++"Set to 'true' to show only freely licensed apps and hide any proprietary " ++"apps." ++msgstr "" ++"Nastavte na „true“, chcete-li zobrazit pouze aplikace s otevřenou licencí a " ++"skrýt všechny proprietární aplikace." + +-#: data/org.gnome.software.gschema.xml:146 ++#: data/org.gnome.software.gschema.xml:150 + msgid "A string storing the gnome-online-account id used to login" + msgstr "Řetězec uchovávající ID gnome-online-account pro přihlášení" + +@@ -710,7 +715,7 @@ msgstr "%s • %s" + + #. Translators: The app is considered suitable to be run by all ages of people. + #. * This is displayed in a context tile, so the string should be short. +-#: src/gs-age-rating-context-dialog.c:936 ++#: src/gs-age-rating-context-dialog.c:935 + msgctxt "Age rating" + msgid "All" + msgstr "Vše" +@@ -719,44 +724,44 @@ msgstr "Vše" + #. * app’s context tile if the size is unknown. It should be short + #. * (at most a couple of characters wide). + #. Translators: This is shown in a bubble if the storage +-#. * size of an application is not known. The bubble is small, ++#. * size of an app is not known. The bubble is small, + #. * so the string should be as short as possible. +-#: src/gs-age-rating-context-dialog.c:949 src/gs-app-context-bar.c:206 ++#: src/gs-age-rating-context-dialog.c:948 src/gs-app-context-bar.c:206 + #: src/gs-storage-context-dialog.c:89 + msgid "?" + msgstr "?" + + #. Translators: This is a dialogue title which indicates that an app is suitable + #. * for all ages. The placeholder is the app name. +-#: src/gs-age-rating-context-dialog.c:1023 ++#: src/gs-age-rating-context-dialog.c:1020 + #, c-format + msgid "%s is suitable for everyone" + msgstr "Aplikace %s je vhodná pro každého" + + #. Translators: This is a dialogue title which indicates that an app is suitable + #. * for children up to around age 3. The placeholder is the app name. +-#: src/gs-age-rating-context-dialog.c:1027 ++#: src/gs-age-rating-context-dialog.c:1024 + #, c-format + msgid "%s is suitable for toddlers" + msgstr "Aplikace %s je vhodná pro batolata" + + #. Translators: This is a dialogue title which indicates that an app is suitable + #. * for children up to around age 5. The placeholder is the app name. +-#: src/gs-age-rating-context-dialog.c:1031 ++#: src/gs-age-rating-context-dialog.c:1028 + #, c-format + msgid "%s is suitable for young children" + msgstr "Aplikace %s je vhodná pro malé děti" + + #. Translators: This is a dialogue title which indicates that an app is suitable + #. * for people up to around age 18. The placeholder is the app name. +-#: src/gs-age-rating-context-dialog.c:1039 ++#: src/gs-age-rating-context-dialog.c:1036 + #, c-format + msgid "%s is suitable for teenagers" + msgstr "Aplikace %s je vhodná pro dospívající mládež" + + #. Translators: This is a dialogue title which indicates that an app is suitable + #. * for people aged up to and over 18. The placeholder is the app name. +-#: src/gs-age-rating-context-dialog.c:1043 ++#: src/gs-age-rating-context-dialog.c:1040 + #, c-format + msgid "%s is suitable for adults" + msgstr "Aplikace %s je vhodná pro dospělé" +@@ -764,14 +769,14 @@ msgstr "Aplikace %s je vhodná pro dospělé" + #. Translators: This is a dialogue title which indicates that an app is suitable + #. * for a specified age group. The first placeholder is the app name, the second + #. * is the age group. +-#: src/gs-age-rating-context-dialog.c:1048 ++#: src/gs-age-rating-context-dialog.c:1045 + #, c-format + msgid "%s is suitable for %s" + msgstr "Aplikace %s je vhodná pro %s" + + #. Translators: This is the title of the dialog which contains information about the suitability of an app for different ages. + #. this one’s not a placeholder +-#: src/gs-age-rating-context-dialog.ui:5 src/gs-app-context-bar.ui:211 ++#: src/gs-age-rating-context-dialog.ui:5 src/gs-app-context-bar.ui:217 + msgid "Age Rating" + msgstr "Vhodné od věku" + +@@ -781,7 +786,7 @@ msgstr "Vhodné od věku" + msgid "How to contribute missing information" + msgstr "Jak přidat chybějící informace" + +-#: lib/gs-app.c:6178 ++#: lib/gs-app.c:6256 + msgid "Local file" + msgstr "Místní soubor" + +@@ -790,44 +795,51 @@ msgstr "Místní soubor" + #. Example string: "Local file (RPM)" + #. Translators: The first placeholder is an app runtime + #. * name, the second is its version number. +-#: lib/gs-app.c:6197 src/gs-safety-context-dialog.c:439 ++#: lib/gs-app.c:6275 src/gs-safety-context-dialog.c:443 + #, c-format + msgid "%s (%s)" + msgstr "%s (%s)" + +-#: lib/gs-app.c:6274 ++#: lib/gs-app.c:6352 + msgid "Package" + msgstr "Balíček" + +-#: src/gs-app-addon-row.c:97 src/gs-app-row.c:460 ++#: src/gs-app-addon-row.c:95 src/gs-app-row.c:452 + msgid "Pending" + msgstr "Čeká na zpracování" + +-#: src/gs-app-addon-row.c:101 src/gs-app-row.c:464 src/gs-details-page.c:369 ++#: src/gs-app-addon-row.c:99 src/gs-app-row.c:456 src/gs-details-page.c:379 + msgid "Pending install" + msgstr "Čeká na instalaci" + +-#: src/gs-app-addon-row.c:105 src/gs-app-row.c:468 src/gs-details-page.c:376 ++#: src/gs-app-addon-row.c:103 src/gs-app-row.c:460 src/gs-details-page.c:386 + msgid "Pending remove" + msgstr "Čeká na odebrání" + +-#: src/gs-app-addon-row.c:111 src/gs-app-row.ui:197 src/gs-app-tile.ui:50 +-#: src/gs-feature-tile.c:535 +-msgctxt "Single app" +-msgid "Installed" +-msgstr "Nainstalováno" +- + #. TRANSLATORS: this is a button next to the search results that +-#. * shows the status of an application being installed +-#: src/gs-app-addon-row.c:115 src/gs-app-row.c:208 src/gs-details-page.c:362 ++#. * shows the status of an app being installed ++#: src/gs-app-addon-row.c:107 src/gs-app-row.c:207 src/gs-details-page.c:372 + msgid "Installing" + msgstr "Instaluje se" + +-#: src/gs-app-addon-row.c:119 ++#: src/gs-app-addon-row.c:111 + msgid "Removing" + msgstr "Odebírá se" + +-#: src/gs-app-addon-row.ui:64 src/gs-details-page.c:1015 ++#. TRANSLATORS: button text ++#. TRANSLATORS: button text in the header when an app ++#. * can be installed ++#. TRANSLATORS: button text in the header when firmware ++#. * can be live-installed ++#. TRANSLATORS: update the fw ++#: src/gs-app-addon-row.ui:66 src/gs-common.c:303 src/gs-details-page.c:924 ++#: src/gs-details-page.c:950 src/gs-details-page.ui:209 src/gs-page.c:412 ++#: plugins/packagekit/gs-packagekit-task.c:149 ++msgid "_Install" ++msgstr "_Instalovat" ++ ++#. TRANSLATORS: this is button text to remove the app ++#: src/gs-app-addon-row.ui:73 src/gs-page.c:551 + msgid "_Uninstall" + msgstr "_Odinstalovat" + +@@ -855,116 +867,120 @@ msgstr "Služby sezení" + msgid "Can access D-Bus services on the session bus" + msgstr "Může přistupovat k službám D-Bus na sběrnici sezení" + +-#: src/gs-app-details-page.c:71 ++#: src/gs-app-details-page.c:71 src/gs-app-details-page.c:72 + msgid "Devices" + msgstr "Zařízení" + + #: src/gs-app-details-page.c:71 ++msgid "Can access arbitrary devices such as webcams" ++msgstr "Může přistupovat k libovolným zařízením, například webovým kamerám" ++ ++#: src/gs-app-details-page.c:72 + msgid "Can access system device files" + msgstr "Může přistupovat k souborům na systémovém zařízení" + +-#: src/gs-app-details-page.c:72 src/gs-app-details-page.c:73 ++#: src/gs-app-details-page.c:73 src/gs-app-details-page.c:74 + msgid "Home folder" + msgstr "Domovská složka" + +-#: src/gs-app-details-page.c:72 src/gs-app-details-page.c:74 +-#: src/gs-app-details-page.c:77 src/gs-app-details-page.c:150 ++#: src/gs-app-details-page.c:73 src/gs-app-details-page.c:75 ++#: src/gs-app-details-page.c:78 src/gs-app-details-page.c:151 + msgid "Can view, edit and create files" + msgstr "Může zobrazovat, upravovat a vytvářet soubory" + +-#: src/gs-app-details-page.c:73 src/gs-app-details-page.c:75 +-#: src/gs-app-details-page.c:78 src/gs-app-details-page.c:145 ++#: src/gs-app-details-page.c:74 src/gs-app-details-page.c:76 ++#: src/gs-app-details-page.c:79 src/gs-app-details-page.c:146 + msgid "Can view files" + msgstr "Může zobrazovat soubory" + +-#: src/gs-app-details-page.c:74 src/gs-app-details-page.c:75 ++#: src/gs-app-details-page.c:75 src/gs-app-details-page.c:76 + msgid "File system" + msgstr "Souborový systém" + + #. The GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_OTHER is used only as a flag, with actual files being part of the read/full lists +-#: src/gs-app-details-page.c:77 src/gs-app-details-page.c:78 ++#: src/gs-app-details-page.c:78 src/gs-app-details-page.c:79 + msgid "Downloads folder" + msgstr "Složka se staženými soubory" + +-#: src/gs-app-details-page.c:79 ++#: src/gs-app-details-page.c:80 + msgid "Settings" + msgstr "Nastavení" + +-#: src/gs-app-details-page.c:79 ++#: src/gs-app-details-page.c:80 + msgid "Can view and change any settings" + msgstr "Může zobrazovat a měnit libovolná nastavení" + +-#: src/gs-app-details-page.c:80 ++#: src/gs-app-details-page.c:81 + msgid "Legacy display system" + msgstr "Zastaralý zobrazovací systém" + +-#: src/gs-app-details-page.c:80 ++#: src/gs-app-details-page.c:81 + msgid "Uses an old, insecure display system" + msgstr "Používá starý, ne zcela bezpečný, zobrazovací systém" + +-#: src/gs-app-details-page.c:81 ++#: src/gs-app-details-page.c:82 + msgid "Sandbox escape" + msgstr "Opuštění izolovaného prostředí" + +-#: src/gs-app-details-page.c:81 ++#: src/gs-app-details-page.c:82 + msgid "Can escape the sandbox and circumvent any other restrictions" + msgstr "Může opustit izolované prostředí a obejít další omezení" + + #. FIXME support app == NULL + #. set window title +-#: src/gs-app-details-page.c:166 ++#: src/gs-app-details-page.c:167 + msgid "Update Details" + msgstr "Podrobnosti o aktualizaci" + + #. TRANSLATORS: this is where the packager did not write + #. * a description for the update +-#: src/gs-app-details-page.c:174 ++#: src/gs-app-details-page.c:175 + msgid "No update description available." + msgstr "Není k dispozici žádný popis aktualizace." + + #: src/gs-app-details-page.ui:25 src/gs-os-update-page.ui:25 +-#: src/gs-shell.ui:369 src/gs-shell.ui:460 ++#: src/gs-shell.ui:348 src/gs-shell.ui:439 + msgid "Go back" + msgstr "Přejít zpět" + +-#: src/gs-app-details-page.ui:48 src/gs-app-row.c:523 ++#: src/gs-app-details-page.ui:48 src/gs-app-row.c:515 + msgid "Requires additional permissions" + msgstr "Vyžaduje dodatečná oprávnění" + + #. Translators: Header of the section with other users' opinions about the app. +-#: src/gs-app-reviews-dialog.ui:6 src/gs-details-page.ui:867 ++#: src/gs-app-reviews-dialog.ui:6 src/gs-details-page.ui:930 + msgid "Reviews" + msgstr "Recenze" + + #: src/gs-app-reviews-dialog.ui:25 +-msgid "No reviews were found for this application." ++msgid "No reviews were found for this app." + msgstr "Pro tuto aplikaci nebyly nalezeny žádné recenze." + + #: src/gs-app-reviews-dialog.ui:27 + msgid "No Reviews" + msgstr "Bez recenzí" + +-#: src/gs-app-version-history-dialog.ui:6 src/gs-details-page.ui:545 ++#: src/gs-app-version-history-dialog.ui:6 src/gs-details-page.ui:529 + msgid "Version History" + msgstr "Historie verzí" + +-#: src/gs-app-version-history-row.c:71 ++#: src/gs-app-version-history-row.c:133 + #, c-format + msgid "New in Version %s" + msgstr "Novinky ve verzi %s" + +-#: src/gs-app-version-history-row.c:78 ++#: src/gs-app-version-history-row.c:140 + #, c-format + msgid "Version %s" + msgstr "Verze %s" + +-#: src/gs-app-version-history-row.c:80 ++#: src/gs-app-version-history-row.c:142 + msgid "No details for this release" + msgstr "K tomuto vydání nejsou k dispozici žádné podrobnosti." + + #. TRANSLATORS: This is the date string with: day number, month name, year. + #. i.e. "25 May 2012" +-#: src/gs-app-version-history-row.c:94 src/gs-review-row.c:63 ++#: src/gs-app-version-history-row.c:156 src/gs-review-row.c:67 + msgid "%e %B %Y" + msgstr "%e. %B %Y" + +@@ -1040,8 +1056,8 @@ msgid "Installs any pending updates in the background" + msgstr "Nainstalovat na pozadí případné čekající aktualizace" + + #: src/gs-application.c:147 +-msgid "Show update preferences" +-msgstr "Zobrazit předvolby aktualizací" ++msgid "Show preferences" ++msgstr "Zobrazit předvolby" + + #: src/gs-application.c:149 + msgid "Quit the running instance" +@@ -1056,8 +1072,8 @@ msgid "Show version number" + msgstr "Zobrazit číslo verze" + + #: src/gs-application.c:271 src/gs-application.c:279 +-msgid "Copyright © 2016–2022 GNOME Software contributors" +-msgstr "Copyright © 2016 – 2022 přispěvatelé Softwaru GNOME" ++msgid "Copyright © 2016–2023 GNOME Software contributors" ++msgstr "Copyright © 2016 – 2023 přispěvatelé Softwaru GNOME" + + #: src/gs-application.c:273 src/gs-application.c:282 + msgid "translator-credits" +@@ -1067,7 +1083,7 @@ msgstr "" + + #. TRANSLATORS: this is the title of the about window + #. TRANSLATORS: this is the menu item that opens the about window +-#: src/gs-application.c:287 src/gs-shell.c:2163 ++#: src/gs-application.c:287 src/gs-shell.c:2127 + msgid "About Software" + msgstr "O aplikaci Software" + +@@ -1077,11 +1093,11 @@ msgid "A nice way to manage the software on your system." + msgstr "Elegantní způsob správy softwaru ve vašem počítači." + + #. TRANSLATORS: we tried to show an app that did not exist +-#: src/gs-application.c:478 ++#: src/gs-application.c:507 + msgid "Sorry! There are no details for that application." + msgstr "Omlouváme se, ale pro tuto aplikaci nejsou k dispozici detaily." + +-#. Translators: The disk usage of an application when installed. ++#. Translators: The disk usage of an app when installed. + #. * This is displayed in a context tile, so the string should be short. + #: src/gs-app-context-bar.c:162 src/gs-storage-context-dialog.c:133 + msgid "Installed Size" +@@ -1106,7 +1122,7 @@ msgstr "Obsahuje %s mezipaměti" + msgid "Cache and data usage unknown" + msgstr "Využití mezipaměti a dat není známo" + +-#. Translators: The download size of an application. ++#. Translators: The download size of an app. + #. * This is displayed in a context tile, so the string should be short. + #: src/gs-app-context-bar.c:187 src/gs-storage-context-dialog.c:165 + msgid "Download Size" +@@ -1136,117 +1152,123 @@ msgstr "Velikost je neznámá" + + #. Translators: This indicates an app requires no permissions to run. + #. * It’s used in a context tile, so should be short. +-#: src/gs-app-context-bar.c:282 ++#: src/gs-app-context-bar.c:281 + msgid "No permissions" + msgstr "Žádná oprávnění" + + #. Translators: This indicates an app uses the network. + #. * It’s used in a context tile, so should be short. +-#: src/gs-app-context-bar.c:293 ++#: src/gs-app-context-bar.c:292 + msgid "Has network access" + msgstr "Má přístup k síti" + + #. Translators: This indicates an app uses D-Bus system services. + #. * It’s used in a context tile, so should be short. +-#: src/gs-app-context-bar.c:300 ++#: src/gs-app-context-bar.c:299 + msgid "Uses system services" + msgstr "Využívá služby systému" + + #. Translators: This indicates an app uses D-Bus session services. + #. * It’s used in a context tile, so should be short. +-#: src/gs-app-context-bar.c:307 ++#: src/gs-app-context-bar.c:306 + msgid "Uses session services" + msgstr "Využívá služby sezení" + + #. Translators: This indicates an app can access arbitrary hardware devices. + #. * It’s used in a context tile, so should be short. +-#: src/gs-app-context-bar.c:314 ++#: src/gs-app-context-bar.c:313 + msgid "Can access hardware devices" + msgstr "Může přistupovat k hardwarovým zařízením" + ++#. Translators: This indicates an app can access system devices such as /dev/shm. ++#. * It’s used in a context tile, so should be short. ++#: src/gs-app-context-bar.c:320 ++msgid "Can access system devices" ++msgstr "Může přistupovat k systémovým zařízením" ++ + #. Translators: This indicates an app can read/write to the user’s home or the entire filesystem. + #. * It’s used in a context tile, so should be short. +-#: src/gs-app-context-bar.c:326 ++#: src/gs-app-context-bar.c:332 + msgid "Can read/write all your data" + msgstr "Může číst/zapisovat všechna vaše data" + + #. Translators: This indicates an app can read (but not write) from the user’s home or the entire filesystem. + #. * It’s used in a context tile, so should be short. +-#: src/gs-app-context-bar.c:338 ++#: src/gs-app-context-bar.c:344 + msgid "Can read all your data" + msgstr "Může číst všechna vaše data" + + #. Translators: This indicates an app can read/write to the user’s Downloads directory. + #. * It’s used in a context tile, so should be short. +-#: src/gs-app-context-bar.c:345 ++#: src/gs-app-context-bar.c:351 + msgid "Can read/write your downloads" + msgstr "Může zapisovat do všech vašich dat" + + #. Translators: This indicates an app can read (but not write) from the user’s Downloads directory. + #. * It’s used in a context tile, so should be short. +-#: src/gs-app-context-bar.c:352 ++#: src/gs-app-context-bar.c:358 + msgid "Can read your downloads" + msgstr "Může číst vaše stažené soubory" + + #. Translators: This indicates an app can access data in the system unknown to the Software. + #. * It’s used in a context tile, so should be short. +-#: src/gs-app-context-bar.c:359 ++#: src/gs-app-context-bar.c:365 + msgid "Can access arbitrary files" + msgstr "Může přistupovat k libovolným souborům" + + #. Translators: This indicates an app can access or change user settings. + #. * It’s used in a context tile, so should be short. +-#: src/gs-app-context-bar.c:366 src/gs-safety-context-dialog.c:227 ++#: src/gs-app-context-bar.c:372 src/gs-safety-context-dialog.c:234 + msgid "Can access and change user settings" + msgstr "Může zobrazovat a měnit uživatelská nastavení" + + #. Translators: This indicates an app uses the X11 windowing system. + #. * It’s used in a context tile, so should be short. +-#: src/gs-app-context-bar.c:373 src/gs-safety-context-dialog.c:211 ++#: src/gs-app-context-bar.c:379 src/gs-safety-context-dialog.c:218 + msgid "Uses a legacy windowing system" + msgstr "Používá starý zobrazovací systém" + + #. Translators: This indicates an app can escape its sandbox. + #. * It’s used in a context tile, so should be short. +-#: src/gs-app-context-bar.c:380 src/gs-safety-context-dialog.c:219 ++#: src/gs-app-context-bar.c:386 src/gs-safety-context-dialog.c:226 + msgid "Can acquire arbitrary permissions" + msgstr "Může získat libovolná oprávnění" + +-#. Translators: This indicates that an application has been packaged ++#. Translators: This indicates that an app has been packaged + #. * by the user’s distribution and is safe. + #. * It’s used in a context tile, so should be short. +-#: src/gs-app-context-bar.c:406 src/gs-safety-context-dialog.c:146 ++#: src/gs-app-context-bar.c:412 src/gs-safety-context-dialog.c:145 + msgid "Reviewed by your distribution" + msgstr "Zkontrolováno vaší distribucí" + +-#. Translators: This indicates that an application has been packaged ++#. Translators: This indicates that an app has been packaged + #. * by someone other than the user’s distribution, so might not be safe. + #. * It’s used in a context tile, so should be short. +-#: src/gs-app-context-bar.c:413 src/gs-safety-context-dialog.c:143 ++#: src/gs-app-context-bar.c:419 src/gs-safety-context-dialog.c:142 + msgid "Provided by a third party" + msgstr "Poskytováno třetí stranou" + + #. Translators: This indicates an app is not licensed under a free software license. + #. * It’s used in a context tile, so should be short. +-#: src/gs-app-context-bar.c:425 ++#: src/gs-app-context-bar.c:431 + msgid "Proprietary code" + msgstr "Uzavřený kód" + + #. Translators: This indicates an app’s source code is freely available, so can be audited for security. + #. * It’s used in a context tile, so should be short. +-#: src/gs-app-context-bar.c:431 ++#: src/gs-app-context-bar.c:437 + msgid "Auditable code" + msgstr "Otevřený kód" + + #. Translators: This indicates an app was written and released by a developer who has been verified. + #. * It’s used in a context tile, so should be short. +-#: src/gs-app-context-bar.c:438 ++#: src/gs-app-context-bar.c:444 + msgid "Software developer is verified" + msgstr "Vývojář softwaru je ověřený" + + #. Translators: This indicates an app or its runtime reached its end of life. + #. * It’s used in a context tile, so should be short. +-#: src/gs-app-context-bar.c:447 ++#: src/gs-app-context-bar.c:453 + msgid "Software no longer supported" + msgstr "Software není nadále podporován" + +@@ -1264,180 +1286,180 @@ msgstr "Software není nadále podporován" + #. * If concatenating strings as a list using a separator like this is not + #. * possible in your language, please file an issue against gnome-software: + #. * https://gitlab.gnome.org/GNOME/gnome-software/-/issues/new +-#: src/gs-app-context-bar.c:459 src/gs-app-context-bar.c:730 ++#: src/gs-app-context-bar.c:465 src/gs-app-context-bar.c:731 + msgid "; " + msgstr "; " + + #. Translators: The app is considered safe to install and run. + #. * This is displayed in a context tile, so the string should be short. +-#: src/gs-app-context-bar.c:467 ++#: src/gs-app-context-bar.c:473 + msgid "Safe" + msgstr "Bezpečné" + + #. Translators: The app is considered potentially unsafe to install and run. + #. * This is displayed in a context tile, so the string should be short. +-#: src/gs-app-context-bar.c:474 ++#: src/gs-app-context-bar.c:480 + msgid "Potentially Unsafe" + msgstr "Potenciálně nebezpečné" + + #. Translators: The app is considered unsafe to install and run. + #. * This is displayed in a context tile, so the string should be short. +-#: src/gs-app-context-bar.c:481 ++#: src/gs-app-context-bar.c:487 + msgid "Unsafe" + msgstr "Nebezpečné" + +-#: src/gs-app-context-bar.c:560 src/gs-app-context-bar.c:592 +-#: src/gs-hardware-support-context-dialog.c:603 ++#: src/gs-app-context-bar.c:563 src/gs-app-context-bar.c:595 ++#: src/gs-hardware-support-context-dialog.c:602 + msgid "Mobile Only" + msgstr "Jen pro mobilní zařízení" + +-#: src/gs-app-context-bar.c:561 ++#: src/gs-app-context-bar.c:564 + msgid "Only works on a small screen" + msgstr "Funguje pouze na malé obrazovce" + +-#: src/gs-app-context-bar.c:566 src/gs-app-context-bar.c:599 +-#: src/gs-app-context-bar.c:606 src/gs-app-context-bar.c:656 +-#: src/gs-app-context-bar.c:661 src/gs-hardware-support-context-dialog.c:583 ++#: src/gs-app-context-bar.c:569 src/gs-app-context-bar.c:602 ++#: src/gs-app-context-bar.c:609 src/gs-app-context-bar.c:659 ++#: src/gs-app-context-bar.c:664 src/gs-hardware-support-context-dialog.c:582 + msgid "Desktop Only" + msgstr "Pouze pro PC" + +-#: src/gs-app-context-bar.c:567 ++#: src/gs-app-context-bar.c:570 + msgid "Only works on a large screen" + msgstr "Funguje pouze na velké obrazovce" + +-#: src/gs-app-context-bar.c:571 src/gs-hardware-support-context-dialog.c:621 ++#: src/gs-app-context-bar.c:574 src/gs-hardware-support-context-dialog.c:620 + msgid "Screen Size Mismatch" + msgstr "Nesoulad velikosti obrazovky" + +-#: src/gs-app-context-bar.c:572 src/gs-hardware-support-context-dialog.c:622 ++#: src/gs-app-context-bar.c:575 src/gs-hardware-support-context-dialog.c:621 + msgid "Doesn’t support your current screen size" + msgstr "Nepodporuje vaši současnou velikost obrazovky" + +-#: src/gs-app-context-bar.c:593 src/gs-hardware-support-context-dialog.c:674 +-#: src/gs-hardware-support-context-dialog.c:680 ++#: src/gs-app-context-bar.c:596 src/gs-hardware-support-context-dialog.c:673 ++#: src/gs-hardware-support-context-dialog.c:679 + msgid "Requires a touchscreen" + msgstr "Vyžaduje dotykovou obrazovku" + +-#: src/gs-app-context-bar.c:600 src/gs-hardware-support-context-dialog.c:634 +-#: src/gs-hardware-support-context-dialog.c:640 ++#: src/gs-app-context-bar.c:603 src/gs-hardware-support-context-dialog.c:633 ++#: src/gs-hardware-support-context-dialog.c:639 + msgid "Requires a keyboard" + msgstr "Vyžaduje klávesnici" + +-#: src/gs-app-context-bar.c:607 ++#: src/gs-app-context-bar.c:610 + msgid "Requires a mouse" + msgstr "Vyžaduje myš" + +-#: src/gs-app-context-bar.c:618 ++#: src/gs-app-context-bar.c:621 + msgid "Gamepad Needed" + msgstr "Vyžaduje herní ovladač" + +-#: src/gs-app-context-bar.c:619 ++#: src/gs-app-context-bar.c:622 + msgid "Requires a gamepad to play" + msgstr "Ke hraní vyžaduje herní ovladač" + + #. Translators: This is used in a context tile to indicate that + #. * an app works on phones, tablets *and* desktops. It should be + #. * short and in title case. +-#: src/gs-app-context-bar.c:643 ++#: src/gs-app-context-bar.c:646 + msgid "Adaptive" + msgstr "Adaptivní" + +-#: src/gs-app-context-bar.c:644 ++#: src/gs-app-context-bar.c:647 + msgid "Works on phones, tablets and desktops" + msgstr "Funguje na telefonech, tabletech a PC" + +-#: src/gs-app-context-bar.c:657 ++#: src/gs-app-context-bar.c:660 + msgid "Probably requires a keyboard or mouse" + msgstr "Pravděpodobně vyžaduje klávesnici nebo myš" + +-#: src/gs-app-context-bar.c:662 ++#: src/gs-app-context-bar.c:665 + msgid "Works on desktops and laptops" + msgstr "Funguje na PC a laptopech" + + #. Translators: This indicates that the content rating for an + #. * app says it can be used by all ages of people, as it contains + #. * no objectionable content. +-#: src/gs-app-context-bar.c:705 ++#: src/gs-app-context-bar.c:706 + msgid "Contains no age-inappropriate content" + msgstr "Neobsahuje žádný věkově nevhodný obsah" + +-#: src/gs-app-context-bar.c:753 ++#: src/gs-app-context-bar.c:754 + msgid "No age rating information available" + msgstr "Informace o věkové kategorii nejsou k dispozici" + + #. TRANSLATORS: this is a button next to the search results that +-#. * allows the application to be easily installed +-#: src/gs-app-row.c:155 ++#. * allows the app to be easily installed ++#: src/gs-app-row.c:154 + msgid "Visit Website" + msgstr "Navštívit webové stránky" + + #. TRANSLATORS: this is a button next to the search results that +-#. * allows the application to be easily installed. ++#. * allows the app to be easily installed. + #. * The ellipsis indicates that further steps are required +-#: src/gs-app-row.c:161 ++#: src/gs-app-row.c:160 + msgid "Install…" + msgstr "Instalovat…" + + #. TRANSLATORS: this is a button next to the search results that +-#. * allows to cancel a queued install of the application +-#: src/gs-app-row.c:169 src/gs-updates-section.ui:62 ++#. * allows to cancel a queued install of the app ++#: src/gs-app-row.c:168 src/gs-updates-section.ui:63 + msgid "Cancel" + msgstr "Zrušit" + + #. TRANSLATORS: this is a button next to the search results that +-#. * allows the application to be easily installed +-#. TRANSLATORS: button text +-#. TRANSLATORS: update the fw +-#: src/gs-app-row.c:177 src/gs-common.c:307 src/gs-page.c:374 ++#. * allows the app to be easily installed ++#: src/gs-app-row.c:176 + msgid "Install" + msgstr "Instalovat" + + #. TRANSLATORS: this is a button in the updates panel + #. * that allows the app to be easily updated live +-#: src/gs-app-row.c:185 ++#: src/gs-app-row.c:184 + msgid "Update" + msgstr "Aktualizovat" + + #. TRANSLATORS: this is a button next to the search results that +-#. * allows the application to be easily removed +-#. TRANSLATORS: button text in the header when an application can be erased +-#. TRANSLATORS: this is button text to remove the application +-#: src/gs-app-row.c:191 src/gs-app-row.c:201 src/gs-details-page.ui:280 +-#: src/gs-details-page.ui:290 src/gs-page.c:549 +-msgid "Uninstall" +-msgstr "Odinstalovat" ++#. * allows the app to be easily removed ++#: src/gs-app-row.c:190 src/gs-app-row.c:200 ++msgid "Uninstall…" ++msgstr "Odinstalovat…" + + #. TRANSLATORS: this is a button next to the search results that +-#. * shows the status of an application being erased +-#: src/gs-app-row.c:215 ++#. * shows the status of an app being erased ++#: src/gs-app-row.c:214 + msgid "Uninstalling" + msgstr "Odinstalovává se" + + #. TRANSLATORS: during the update the device + #. * will restart into a special update-only mode +-#: src/gs-app-row.c:330 ++#: src/gs-app-row.c:327 + msgid "Device cannot be used during update." + msgstr "Zařízení nelze během aktualizace používat." + + #. TRANSLATORS: this refers to where the app came from +-#: src/gs-app-row.c:340 src/gs-shell-search-provider.c:264 ++#: src/gs-app-row.c:337 src/gs-shell-search-provider.c:268 + #, c-format + msgid "Source: %s" + msgstr "Zdroj: %s" + + #. Translators: A message to indicate that an app has been renamed. The placeholder is the old human-readable name. +-#: src/gs-app-row.c:530 ++#: src/gs-app-row.c:522 + #, c-format + msgid "Renamed from %s" + msgstr "Přejmenováno z %s" + +-#. Translators: The placeholder is an application name ++#: src/gs-app-row.ui:197 src/gs-app-tile.ui:50 src/gs-feature-tile.c:543 ++msgctxt "Single app" ++msgid "Installed" ++msgstr "Nainstalováno" ++ ++#. Translators: The placeholder is an app name + #: src/gs-app-translation-dialog.c:67 + #, c-format + msgid "Help Translate %s" + msgstr "Pomozte přeložit %s" + +-#. Translators: The placeholder is an application name ++#. Translators: The placeholder is an app name + #: src/gs-app-translation-dialog.c:70 + #, c-format + msgid "" +@@ -1451,7 +1473,7 @@ msgstr "" + "dobrovolníků.\n" + "\n" + "To znamená, že i když ještě není k dispozici ve vašem jazyce, můžete se " +-"zapojit a pomoci s jeho překladem." ++"zapojit a pomoci s jejím překladem." + + #: src/gs-app-translation-dialog.ui:5 + msgid "Translations" +@@ -1467,29 +1489,35 @@ msgstr "_Stránka překladu" + msgid "Login required remote %s (realm %s)" + msgstr "Vyžadováno přihlášení vzdáleným %s (sféra %s)" + +-#: src/gs-basic-auth-dialog.ui:13 ++#: src/gs-basic-auth-dialog.ui:6 + msgid "Login Required" + msgstr "Vyžadováno přihlášení" + +-#: src/gs-basic-auth-dialog.ui:21 src/gs-common.c:721 +-#: src/gs-details-page.ui:306 src/gs-removal-dialog.ui:28 +-#: src/gs-review-dialog.ui:18 ++#. TRANSLATORS: button text ++#: src/gs-basic-auth-dialog.ui:12 src/gs-common.c:296 src/gs-common.c:697 ++#: src/gs-details-page.ui:297 src/gs-page.c:410 src/gs-page.c:549 ++#: src/gs-removal-dialog.ui:28 src/gs-repos-dialog.c:171 ++#: src/gs-repos-dialog.c:249 src/gs-review-dialog.ui:18 src/gs-review-row.c:237 ++#: src/gs-updates-page.c:847 src/gs-updates-page.c:864 + msgid "_Cancel" + msgstr "_Zrušit" + +-#: src/gs-basic-auth-dialog.ui:35 ++#: src/gs-basic-auth-dialog.ui:24 + msgid "_Login" + msgstr "Přih_lásit" + +-#: src/gs-basic-auth-dialog.ui:88 +-msgid "_User" +-msgstr "_Uživatel" ++#. Translators: Placeholder text for a login entry. ++#. Translators: It's an origin scope, 'User' or 'System' installation ++#: src/gs-basic-auth-dialog.ui:60 src/gs-origin-popover-row.ui:138 ++msgid "User" ++msgstr "Uživatel" + +-#: src/gs-basic-auth-dialog.ui:107 +-msgid "_Password" +-msgstr "_Heslo" ++#. Translators: Placeholder text for a login entry. ++#: src/gs-basic-auth-dialog.ui:73 ++msgid "Password" ++msgstr "Heslo" + +-#. TRANSLATORS: this is where all applications that don't ++#. TRANSLATORS: this is where all apps that don't + #. * fit in other groups are put + #: lib/gs-category.c:209 + msgid "Other" +@@ -1509,13 +1537,13 @@ msgstr "Významné" + + #. Heading for featured apps on a category page + #. Translators: This is a heading for software which has been featured ('picked') by the distribution. +-#: src/gs-category-page.ui:41 src/gs-overview-page.ui:106 ++#: src/gs-category-page.ui:41 src/gs-overview-page.ui:69 + msgid "Editor’s Choice" + msgstr "Výběr od distribuce" + + #. Heading for recently updated apps on a category page + #. Translators: This is a heading for software which has been recently released upstream. +-#: src/gs-category-page.ui:69 src/gs-overview-page.ui:129 ++#: src/gs-category-page.ui:69 src/gs-overview-page.ui:92 + msgid "New & Updated" + msgstr "Nové a aktualizované" + +@@ -1530,14 +1558,14 @@ msgid "Other Software" + msgstr "Ostatní" + + #. TRANSLATORS: the user isn't reading the question +-#: lib/gs-cmd.c:194 ++#: lib/gs-cmd.c:195 + #, c-format + msgid "Please enter a number from 1 to %u: " + msgstr "Zadejte prosím číslo od 1 do %u: " + + #. TRANSLATORS: asking the user to choose an app from a list +-#: lib/gs-cmd.c:266 +-msgid "Choose an application:" ++#: lib/gs-cmd.c:283 ++msgid "Choose an app:" + msgstr "Vyberte aplikaci:" + + #: lib/gs-desktop-data.c:16 +@@ -1910,7 +1938,7 @@ msgstr "Jazykové balíčky" + msgid "Localization" + msgstr "Lokalizace" + +-#. TRANSLATORS: this is the summary of a notification that an application ++#. TRANSLATORS: this is the summary of a notification that an app + #. * has been successfully installed + #. TRANSLATORS: this is the summary of a notification that a component + #. * has been successfully installed +@@ -1919,16 +1947,16 @@ msgstr "Lokalizace" + msgid "%s is now installed" + msgstr "Aplikace %s je nyní nainstalována" + +-#. TRANSLATORS: an application has been installed, but ++#. TRANSLATORS: an app has been installed, but + #. * needs a reboot to complete the installation + #: src/gs-common.c:73 src/gs-common.c:96 + msgid "A restart is required for the changes to take effect." + msgstr "Aby se změny projevily, je zapotřebí provést restart." + +-#. TRANSLATORS: this is the body of a notification that an application ++#. TRANSLATORS: this is the body of a notification that an app + #. * has been successfully installed + #: src/gs-common.c:77 +-msgid "Application is ready to be used." ++msgid "App is ready to be used." + msgstr "Aplikace je připravená k použití." + + #. TRANSLATORS: this is the summary of a notification that OS updates +@@ -1944,7 +1972,7 @@ msgid "Recently installed updates are available to review" + msgstr "Nedávno nainstalované aktualizace jsou k dispozici pro recenze" + + #. TRANSLATORS: button text +-#: src/gs-common.c:107 src/gs-common.c:884 ++#: src/gs-common.c:107 src/gs-common.c:860 + msgid "Restart" + msgstr "Restartovat" + +@@ -1953,97 +1981,98 @@ msgid "Launch" + msgstr "Spustit" + + #. TRANSLATORS: window title +-#: src/gs-common.c:234 +-#, fuzzy +-#| msgid "Install Unsigned Software?" ++#: src/gs-common.c:230 + msgid "Install Software?" +-msgstr "Nainstalovat nepodepsaný software?" ++msgstr "Nainstalovat software?" + + #. TRANSLATORS: window title +-#: src/gs-common.c:236 ++#: src/gs-common.c:232 + msgid "Install Third-Party Software?" + msgstr "Instalovat software třetí strany?" + + #. TRANSLATORS: window title +-#: src/gs-common.c:241 +-#, fuzzy +-#| msgid "Enable Third-Party Software Repository?" ++#: src/gs-common.c:236 + msgid "Enable Software Repository?" +-msgstr "Povolit repozitář softwaru třetí strany?" ++msgstr "Povolit repozitář softwaru?" + + #. TRANSLATORS: window title +-#: src/gs-common.c:243 src/gs-repos-dialog.c:168 ++#: src/gs-common.c:238 src/gs-repos-dialog.c:168 + msgid "Enable Third-Party Software Repository?" + msgstr "Povolit repozitář softwaru třetí strany?" + + #. TRANSLATORS: the replacements are as follows: +-#. * 1. Application name, e.g. "Firefox" ++#. * 1. App name, e.g. "Firefox" + #. * 2. Software repository name, e.g. fedora-optional + #. +-#: src/gs-common.c:261 ++#: src/gs-common.c:250 + #, c-format + msgid "" + "%s is not free and open source software, and is provided by “%s”." + msgstr "" +-"%s není svobodný a otevřený software a poskytuje jej „%s“." ++"%s není svobodný a otevřený software a poskytuje jej „%s“." + + #. TRANSLATORS: the replacements are as follows: +-#. * 1. Application name, e.g. "Firefox" ++#. * 1. App name, e.g. "Firefox" + #. * 2. Software repository name, e.g. fedora-optional +-#: src/gs-common.c:271 ++#: src/gs-common.c:260 + #, c-format + msgid "%s is provided by “%s”." + msgstr "%s poskytuje „%s“." + +-#: src/gs-common.c:280 ++#: src/gs-common.c:269 + msgid "This software repository must be enabled to continue installation." + msgstr "" + "Aby bylo možné pokračovat v instalaci, je nutné povolit tento repozitář " + "softwaru." + + #. TRANSLATORS: Laws are geographical, urgh... +-#: src/gs-common.c:290 ++#: src/gs-common.c:279 + #, c-format + msgid "It may be illegal to install or use %s in some countries." + msgstr "" + "V některých zemích nemusí být instalace a používání softwaru %s legální." + + #. TRANSLATORS: Laws are geographical, urgh... +-#: src/gs-common.c:296 ++#: src/gs-common.c:285 + msgid "It may be illegal to install or use this codec in some countries." + msgstr "" + "V některých zemích nemusí být instalace a používání tohoto kodeku legální." + + #. TRANSLATORS: this is button text to not ask about non-free content again +-#: src/gs-common.c:303 +-msgid "Don’t Warn Again" +-msgstr "Příště nevarovat" ++#: src/gs-common.c:299 ++msgid "Don’t _Warn Again" ++msgstr "Příště _nevarovat" + + #. TRANSLATORS: button text +-#: src/gs-common.c:312 +-msgid "Enable and Install" +-msgstr "Povolit a nainstalovat" ++#: src/gs-common.c:308 ++msgid "Enable and _Install" ++msgstr "Povolit a na_instalovat" + + #. TRANSLATORS: these are show_detailed_error messages from the + #. * package manager no mortal is supposed to understand, + #. * but google might know what they mean +-#: src/gs-common.c:514 ++#: src/gs-common.c:511 + msgid "Detailed errors from the package manager follow:" + msgstr "Dále jsou uvedeny podrobnosti o chybě získané od správy balíčků:" + +-#: src/gs-common.c:530 src/gs-safety-context-dialog.ui:72 ++#: src/gs-common.c:518 src/gs-safety-context-dialog.ui:72 + msgid "Details" + msgstr "Podrobnosti" + ++#. TRANSLATORS: button text ++#: src/gs-common.c:567 ++msgid "_Close" ++msgstr "_Zavřít" ++ + #. Translators: an accept button label, in a Cancel/Accept dialog +-#: src/gs-common.c:709 ++#: src/gs-common.c:689 + msgid "_Accept" + msgstr "_Přijmout" + + #. TRANSLATORS: we've just live-updated some apps +-#: src/gs-common.c:859 ++#: src/gs-common.c:835 + msgid "An update has been installed" + msgid_plural "Updates have been installed" + msgstr[0] "Aktualizace byla nainstalována" +@@ -2051,15 +2080,15 @@ msgstr[1] "Aktualizace byly nainstalovány" + msgstr[2] "Aktualizace byly nainstalovány" + + #. TRANSLATORS: we've just removed some apps +-#: src/gs-common.c:869 +-msgid "An application has been removed" +-msgid_plural "Applications have been removed" ++#: src/gs-common.c:845 ++msgid "An app has been removed" ++msgid_plural "Apps have been removed" + msgstr[0] "Aplikace byla odebrána" + msgstr[1] "Aplikace byly odebrány" + msgstr[2] "Aplikace byly odebrány" + + #. TRANSLATORS: the new apps will not be run until we restart +-#: src/gs-common.c:875 ++#: src/gs-common.c:851 + msgid "A restart is required for it to take effect." + msgid_plural "A restart is required for them to take effect." + msgstr[0] "Aby se projevila, je zapotřebí provést restart." +@@ -2067,16 +2096,16 @@ msgstr[1] "Aby se projevily, je zapotřebí provést restart." + msgstr[2] "Aby se projevily, je zapotřebí provést restart." + + #. TRANSLATORS: button text +-#: src/gs-common.c:882 ++#: src/gs-common.c:858 + msgid "Not Now" + msgstr "Nyní ne" + + #. TRANSLATORS: something happened less than 5 minutes ago +-#: src/gs-common.c:978 ++#: src/gs-common.c:954 + msgid "Just now" + msgstr "právě teď" + +-#: src/gs-common.c:980 ++#: src/gs-common.c:956 + #, c-format + msgid "%d minute ago" + msgid_plural "%d minutes ago" +@@ -2084,7 +2113,7 @@ msgstr[0] "před %d minutou" + msgstr[1] "před %d minutami" + msgstr[2] "před %d minutami" + +-#: src/gs-common.c:984 ++#: src/gs-common.c:960 + #, c-format + msgid "%d hour ago" + msgid_plural "%d hours ago" +@@ -2092,7 +2121,7 @@ msgstr[0] "před %d hodinou" + msgstr[1] "před %d hodinami" + msgstr[2] "před %d hodinami" + +-#: src/gs-common.c:988 ++#: src/gs-common.c:964 + #, c-format + msgid "%d day ago" + msgid_plural "%d days ago" +@@ -2100,7 +2129,7 @@ msgstr[0] "před %d dnem" + msgstr[1] "před %d dny" + msgstr[2] "před %d dny" + +-#: src/gs-common.c:992 ++#: src/gs-common.c:968 + #, c-format + msgid "%d week ago" + msgid_plural "%d weeks ago" +@@ -2108,7 +2137,7 @@ msgstr[0] "před %d týdnem" + msgstr[1] "před %d týdny" + msgstr[2] "před %d týdny" + +-#: src/gs-common.c:996 ++#: src/gs-common.c:972 + #, c-format + msgid "%d month ago" + msgid_plural "%d months ago" +@@ -2116,7 +2145,7 @@ msgstr[0] "před %d měsícem" + msgstr[1] "před %d měsíci" + msgstr[2] "před %d měsíci" + +-#: src/gs-common.c:1000 ++#: src/gs-common.c:976 + #, c-format + msgid "%d year ago" + msgid_plural "%d years ago" +@@ -2128,7 +2157,7 @@ msgstr[2] "před %d lety" + #. * the unit is drawn with a smaller font. If you need to flip the order, then you can use "%2$s %1$s". + #. * Make sure you'll preserve the no break space between the values. + #. * Example result: "13.0 MB" +-#: src/gs-common.c:1364 ++#: src/gs-common.c:1340 + #, c-format + msgctxt "format-size" + msgid "%s %s" +@@ -2136,7 +2165,7 @@ msgstr "%s %s" + + #. TRANSLATORS: this is a what we use in notifications if the app's name is unknown + #: src/gs-dbus-helper.c:291 +-msgid "An application" ++msgid "An app" + msgstr "Nějaká aplikace" + + #. TRANSLATORS: this is a notification displayed when an app needs additional MIME types. +@@ -2199,58 +2228,49 @@ msgstr "Požadavek na dodatečné balíčky" + msgid "Find in Software" + msgstr "Najít v aplikaci Software" + +-#: src/gs-description-box.c:67 src/gs-description-box.c:269 ++#: src/gs-description-box.c:87 src/gs-description-box.c:335 + msgid "_Show More" + msgstr "Zobrazit _více" + +-#: src/gs-description-box.c:67 ++#: src/gs-description-box.c:87 + msgid "_Show Less" + msgstr "Zobrazit _méně" + +-#: src/gs-details-page.c:357 ++#: src/gs-details-page.c:367 + msgid "Removing…" + msgstr "Odebírá se…" + +-#: src/gs-details-page.c:367 ++#: src/gs-details-page.c:377 + msgid "Requires restart to finish install" + msgstr "Vyžaduje restart k dokončení instalace" + +-#: src/gs-details-page.c:374 ++#: src/gs-details-page.c:384 + msgid "Requires restart to finish remove" + msgstr "Vyžaduje restart k dokončení odebírání" + + #. TRANSLATORS: This is a label on top of the app's progress + #. * bar to inform the user that the app should be installed soon +-#: src/gs-details-page.c:391 ++#: src/gs-details-page.c:401 + msgid "Pending installation…" + msgstr "Probíhá instalace…" + + #. TRANSLATORS: This is a label on top of the app's progress + #. * bar to inform the user that the app should be updated soon +-#: src/gs-details-page.c:398 ++#: src/gs-details-page.c:407 + msgid "Pending update…" + msgstr "Probíhá aktualizace…" + + #. Translators: This string is shown when preparing to download and install an app. +-#: src/gs-details-page.c:414 ++#: src/gs-details-page.c:421 + msgid "Preparing…" + msgstr "Připravuje se…" + + #. Translators: This string is shown when uninstalling an app. +-#: src/gs-details-page.c:417 ++#: src/gs-details-page.c:424 + msgid "Uninstalling…" + msgstr "Odinstalovává se…" + +-#. TRANSLATORS: button text in the header when an application +-#. * can be installed +-#. TRANSLATORS: button text in the header when firmware +-#. * can be live-installed +-#: src/gs-details-page.c:908 src/gs-details-page.c:934 +-#: src/gs-details-page.ui:229 plugins/packagekit/gs-packagekit-task.c:150 +-msgid "_Install" +-msgstr "_Instalovat" +- +-#: src/gs-details-page.c:924 ++#: src/gs-details-page.c:940 + msgid "_Restart" + msgstr "_Restartovat" + +@@ -2258,22 +2278,40 @@ msgstr "_Restartovat" + #. * be installed. + #. * The ellipsis indicates that further steps are required, + #. * e.g. enabling software repositories or the like +-#: src/gs-details-page.c:948 ++#: src/gs-details-page.c:964 + msgid "_Install…" + msgstr "_Instalovat…" + ++#: src/gs-details-page.c:1031 ++msgid "_Uninstall…" ++msgstr "_Odinstalovat…" ++ ++#. Translators: %s is the user-visible app name ++#: src/gs-details-page.c:1175 ++#, c-format ++msgid "%s will appear in US English" ++msgstr "Aplikace %s se zobrazí v americké angličtině" ++ ++#: src/gs-details-page.c:1181 ++msgid "This app will appear in US English" ++msgstr "Tato aplikace se zobrazí v americké angličtině" ++ ++#: src/gs-details-page.c:1196 src/gs-details-page.ui:59 ++msgid "Help _Translate" ++msgstr "_Pomoci přeložit" ++ + #. Translators: the '%s' is replaced with a developer name or a project group +-#: src/gs-details-page.c:1237 ++#: src/gs-details-page.c:1260 + #, c-format + msgid "Other Apps by %s" + msgstr "Co dalšího nabízí %s" + + #. TRANSLATORS: we need a remote server to process +-#: src/gs-details-page.c:1620 ++#: src/gs-details-page.c:1637 + msgid "You need internet access to write a review" + msgstr "Abyste mohli napsat recenzi, musíte být připojeni k Internetu" + +-#: src/gs-details-page.c:1790 src/gs-details-page.c:1806 ++#: src/gs-details-page.c:1822 src/gs-details-page.c:1838 + #, c-format + msgid "Unable to find “%s”" + msgstr "Nelze najít „%s“" +@@ -2283,74 +2321,61 @@ msgid "Details page" + msgstr "Stránka s podrobnostmi" + + #: src/gs-details-page.ui:39 +-msgid "Loading application details…" ++msgid "Loading app details…" + msgstr "Načítají se podrobnosti o aplikaci…" + +-#: src/gs-details-page.ui:77 +-msgid "" +-"This software is not available in your language and will appear in US " +-"English." +-msgstr "" +-"Tento software není dostupný ve vašem jazyce a zobrazí se v americké " +-"angličtině." +- +-#: src/gs-details-page.ui:83 +-msgid "Help _Translate" +-msgstr "_Pomoci přeložit" +- +-#. TRANSLATORS: A label for a button to execute the selected application. +-#: src/gs-details-page.ui:246 ++#. TRANSLATORS: A label for a button to execute the selected app. ++#: src/gs-details-page.ui:226 + msgid "_Open" + msgstr "_Otevřít" + +-#: src/gs-details-page.ui:262 plugins/packagekit/gs-packagekit-task.c:160 ++#: src/gs-details-page.ui:242 plugins/packagekit/gs-packagekit-task.c:159 + msgid "_Update" + msgstr "_Aktualizovat" + +-#: src/gs-details-page.ui:331 ++#. TRANSLATORS: button text in the header when an app can be erased ++#: src/gs-details-page.ui:260 src/gs-details-page.ui:270 ++msgid "Uninstall" ++msgstr "Odinstalovat" ++ ++#: src/gs-details-page.ui:322 + msgid "Downloading" + msgstr "Stahuje se" + +-#: src/gs-details-page.ui:468 src/gs-installed-page.ui:135 ++#: src/gs-details-page.ui:459 src/gs-installed-page.ui:135 + msgid "Add-ons" + msgstr "Doplňky" + +-#: src/gs-details-page.ui:479 +-msgid "Selected add-ons will be installed with the application." +-msgstr "Vybrané doplňky budou nainstalovány spolu s aplikací." +- +-#: src/gs-details-page.ui:579 +-msgid "" +-"This application can only be used when there is an active internet " +-"connection." ++#: src/gs-details-page.ui:563 ++msgid "This app can only be used when there is an active internet connection." + msgstr "" + "Tuto aplikaci je možné používat, jen když je funkční připojení k Internetu." + +-#: src/gs-details-page.ui:599 ++#: src/gs-details-page.ui:586 + msgid "Software Repository Included" + msgstr "Součástí je repozitář softwaru" + +-#: src/gs-details-page.ui:600 ++#: src/gs-details-page.ui:596 + msgid "" +-"This application includes a software repository which provides updates, as " +-"well as access to other software." ++"This app includes a software repository which provides updates, as well as " ++"access to other software." + msgstr "" + "Součástí této aplikace je repozitář softwaru, který poskytuje aktualizace a " + "přístup k dalšímu softwaru." + +-#: src/gs-details-page.ui:617 ++#: src/gs-details-page.ui:624 + msgid "No Software Repository Included" + msgstr "Součástí není žádný repozitář softwaru" + +-#: src/gs-details-page.ui:618 ++#: src/gs-details-page.ui:634 + msgid "" +-"This application does not include a software repository. It will not be " +-"updated with new versions." ++"This app does not include a software repository. It will not be updated with " ++"new versions." + msgstr "" + "Součástí této aplikace není žádný repozitář softwaru. Nebude tak průběžně " + "aktualizována na novější verze." + +-#: src/gs-details-page.ui:636 ++#: src/gs-details-page.ui:662 + msgid "" + "This software is already provided by your distribution and should not be " + "replaced." +@@ -2358,11 +2383,11 @@ msgstr "" + "Tento software již poskytuje vaše distribuce a neměli byste jej nahrazovat." + + #. Translators: a repository file used for installing software has been discovered. +-#: src/gs-details-page.ui:653 ++#: src/gs-details-page.ui:693 + msgid "Software Repository Identified" + msgstr "Rozpoznán repozitář softwaru" + +-#: src/gs-details-page.ui:654 ++#: src/gs-details-page.ui:703 + msgid "" + "Adding this software repository will give you access to additional software " + "and upgrades." +@@ -2370,15 +2395,15 @@ msgstr "" + "Přídáním tohoto repozitáře softwaru získáte přístup k dalšímu softwaru a " + "aktualizacím." + +-#: src/gs-details-page.ui:655 ++#: src/gs-details-page.ui:710 + msgid "Only use software repositories that you trust." + msgstr "Používejte pouze repozitáře softwaru, kterým věříte." + +-#: src/gs-details-page.ui:720 ++#: src/gs-details-page.ui:783 + msgid "No Metadata" + msgstr "Žádná metadata" + +-#: src/gs-details-page.ui:729 ++#: src/gs-details-page.ui:792 + msgid "" + "This software doesn’t provide any links to a website, code repository or " + "issue tracker." +@@ -2386,33 +2411,33 @@ msgstr "" + "Tento software neposkytuje žádné odkazy na webové stránky, repozitáře kódu " + "ani nástroj pro sledování problémů." + +-#: src/gs-details-page.ui:757 ++#: src/gs-details-page.ui:820 + msgid "Project _Website" + msgstr "_Webové stránky projektu" + +-#: src/gs-details-page.ui:774 ++#: src/gs-details-page.ui:837 + msgid "_Donate" + msgstr "Věnovat _dar" + +-#: src/gs-details-page.ui:791 ++#: src/gs-details-page.ui:854 + msgid "Contribute _Translations" + msgstr "_Přispět k překladu" + +-#: src/gs-details-page.ui:808 ++#: src/gs-details-page.ui:871 + msgid "_Report an Issue" + msgstr "_Nahlásit chybu" + +-#: src/gs-details-page.ui:825 ++#: src/gs-details-page.ui:888 + msgid "_Help" + msgstr "_Nápověda" + + #. Translators: Button opening a dialog where the users can write and publish their opinions about the apps. +-#: src/gs-details-page.ui:919 +-msgid "_Write Review" ++#: src/gs-details-page.ui:982 ++msgid "Write R_eview" + msgstr "Nap_sat recenzi" + + #. Translators: Button opening a dialog showing all reviews for an app. +-#: src/gs-details-page.ui:956 ++#: src/gs-details-page.ui:1019 + msgid "All Reviews" + msgstr "Všechny recenze" + +@@ -2431,7 +2456,7 @@ msgstr " a " + msgid ", " + msgstr ", " + +-#. TRANSLATORS: Application window title for fonts installation. ++#. TRANSLATORS: App window title for fonts installation. + #. %s will be replaced by name of the script we're searching for. + #: src/gs-extras-page.c:171 + #, c-format +@@ -2441,7 +2466,7 @@ msgstr[0] "Dostupné fonty pro písmo %s" + msgstr[1] "Dostupné fonty pro písma %s" + msgstr[2] "Dostupné fonty pro písma %s" + +-#. TRANSLATORS: Application window title for codec installation. ++#. TRANSLATORS: App window title for codec installation. + #. %s will be replaced by actual codec name(s) + #: src/gs-extras-page.c:179 + #, c-format +@@ -2470,11 +2495,11 @@ msgstr "%s nebyl nalezen" + msgid "on the website" + msgstr "na webových stránkách" + +-#. TRANSLATORS: this is when we know about an application or ++#. TRANSLATORS: this is when we know about an app or + #. * addon, but it can't be listed for some reason + #: src/gs-extras-page.c:354 + #, c-format +-msgid "No applications are available that provide the file %s." ++msgid "No apps are available that provide the file %s." + msgstr "Nejsou k dispozici žádné aplikace, které by poskytovaly soubor %s." + + #. TRANSLATORS: first %s is the codec name, and second %s is a +@@ -2482,20 +2507,20 @@ msgstr "Nejsou k dispozici žádné aplikace, které by poskytovaly soubor %s." + #: src/gs-extras-page.c:358 src/gs-extras-page.c:369 src/gs-extras-page.c:380 + #, c-format + msgid "" +-"Information about %s, as well as options for how to get missing applications " +-"might be found %s." ++"Information about %s, as well as options for how to get missing apps might " ++"be found %s." + msgstr "" + "Informace o formátu %s, včetně toho, jak získat chybějící aplikace, najdete " + "%s." + +-#. TRANSLATORS: this is when we know about an application or ++#. TRANSLATORS: this is when we know about an app or + #. * addon, but it can't be listed for some reason + #: src/gs-extras-page.c:365 src/gs-extras-page.c:387 + #, c-format +-msgid "No applications are available for %s support." ++msgid "No apps are available for %s support." + msgstr "Pro podporu %s nejsou k dispozici žádné aplikace." + +-#. TRANSLATORS: this is when we know about an application or ++#. TRANSLATORS: this is when we know about an app or + #. * addon, but it can't be listed for some reason + #: src/gs-extras-page.c:376 + #, c-format +@@ -2507,13 +2532,13 @@ msgstr "%s není k dispozici." + #: src/gs-extras-page.c:391 + #, c-format + msgid "" +-"Information about %s, as well as options for how to get an application that " +-"can support this format might be found %s." ++"Information about %s, as well as options for how to get an app that can " ++"support this format might be found %s." + msgstr "" +-"Informace o formátu %s, včetně toho, jak získat aplikaci, který umí tento " +-"tento formát podporovat, najdete %s." ++"Informace o formátu %s, včetně toho, jak získat aplikaci, který tento tento " ++"formát podporuje, najdete %s." + +-#. TRANSLATORS: this is when we know about an application or ++#. TRANSLATORS: this is when we know about an app or + #. * addon, but it can't be listed for some reason + #: src/gs-extras-page.c:398 + #, c-format +@@ -2530,7 +2555,7 @@ msgid "" + msgstr "" + "Informace o písmu %s, včetně toho, jak získat dodatečná písma, najdete %s." + +-#. TRANSLATORS: this is when we know about an application or ++#. TRANSLATORS: this is when we know about an app or + #. * addon, but it can't be listed for some reason + #: src/gs-extras-page.c:409 + #, c-format +@@ -2548,7 +2573,7 @@ msgstr "" + "Informace o kodeku %s, včetně toho, jak získat kodek, který umí tento formát " + "přehrát, najdete %s." + +-#. TRANSLATORS: this is when we know about an application or ++#. TRANSLATORS: this is when we know about an app or + #. * addon, but it can't be listed for some reason + #: src/gs-extras-page.c:420 + #, c-format +@@ -2566,7 +2591,7 @@ msgstr "" + "Informace o kodeku %s, včetně toho, jak získat dodatečné prostředky Plasma, " + "najdete %s." + +-#. TRANSLATORS: this is when we know about an application or ++#. TRANSLATORS: this is when we know about an app or + #. * addon, but it can't be listed for some reason + #: src/gs-extras-page.c:431 + #, c-format +@@ -2590,7 +2615,7 @@ msgid "the documentation" + msgstr "dokumentace" + + #. TRANSLATORS: no codecs were found. The first %s will be replaced by actual codec name(s), +-#. the second %s is the application name, which requested the codecs, the third %s is a link titled "the documentation" ++#. the second %s is the app name, which requested the codecs, the third %s is a link titled "the documentation" + #: src/gs-extras-page.c:487 + #, c-format + msgid "" +@@ -2631,12 +2656,12 @@ msgstr[2] "" + msgid "Failed to find any search results: %s" + msgstr "Selhalo získání jakýchkoliv výsledků hledání: %s" + +-#: src/gs-extras-page.c:874 ++#: src/gs-extras-page.c:878 + #, c-format + msgid "%s file format" + msgstr "formát souboru %s" + +-#: src/gs-extras-page.c:1254 ++#: src/gs-extras-page.c:1258 + msgid "Unable to Find Requested Software" + msgstr "Nelze najít požadovaný software" + +@@ -2656,206 +2681,206 @@ msgstr "Další" + msgid "Featured Apps List" + msgstr "Seznam významných aplikací" + +-#: src/gs-hardware-support-context-dialog.c:577 +-#: src/gs-hardware-support-context-dialog.c:586 ++#: src/gs-hardware-support-context-dialog.c:576 ++#: src/gs-hardware-support-context-dialog.c:585 + msgid "Desktop Support" + msgstr "Podpora pro PC" + +-#: src/gs-hardware-support-context-dialog.c:578 +-#: src/gs-hardware-support-context-dialog.c:587 ++#: src/gs-hardware-support-context-dialog.c:577 ++#: src/gs-hardware-support-context-dialog.c:586 + msgid "Supports being used on a large screen" + msgstr "Podporuje použití na velké obrazovce" + +-#: src/gs-hardware-support-context-dialog.c:580 ++#: src/gs-hardware-support-context-dialog.c:579 + msgid "Desktop Support Unknown" + msgstr "Neznámá podpora pro PC" + +-#: src/gs-hardware-support-context-dialog.c:581 ++#: src/gs-hardware-support-context-dialog.c:580 + msgid "Not enough information to know if large screens are supported" + msgstr "" + "Není dostatek informací, abychom věděli, zda jsou podporovány velké obrazovky" + +-#: src/gs-hardware-support-context-dialog.c:584 ++#: src/gs-hardware-support-context-dialog.c:583 + msgid "Requires a large screen" + msgstr "Vyžaduje velkou obrazovku" + +-#: src/gs-hardware-support-context-dialog.c:589 ++#: src/gs-hardware-support-context-dialog.c:588 + msgid "Desktop Not Supported" + msgstr "Nepodporuje stolní počítače" + +-#: src/gs-hardware-support-context-dialog.c:590 ++#: src/gs-hardware-support-context-dialog.c:589 + msgid "Cannot be used on a large screen" + msgstr "Nelze použít na velké obrazovce" + +-#: src/gs-hardware-support-context-dialog.c:597 +-#: src/gs-hardware-support-context-dialog.c:606 ++#: src/gs-hardware-support-context-dialog.c:596 ++#: src/gs-hardware-support-context-dialog.c:605 + msgid "Mobile Support" + msgstr "Podpora pro mobilní zařízení" + +-#: src/gs-hardware-support-context-dialog.c:598 +-#: src/gs-hardware-support-context-dialog.c:607 ++#: src/gs-hardware-support-context-dialog.c:597 ++#: src/gs-hardware-support-context-dialog.c:606 + msgid "Supports being used on a small screen" + msgstr "Podporuje použití na malé obrazovce" + +-#: src/gs-hardware-support-context-dialog.c:600 ++#: src/gs-hardware-support-context-dialog.c:599 + msgid "Mobile Support Unknown" + msgstr "Neznámá podpora pro mobilní zařízení" + +-#: src/gs-hardware-support-context-dialog.c:601 ++#: src/gs-hardware-support-context-dialog.c:600 + msgid "Not enough information to know if small screens are supported" + msgstr "" + "Není dostatek informací, abychom věděli, zda jsou podporovány malé obrazovky" + +-#: src/gs-hardware-support-context-dialog.c:604 ++#: src/gs-hardware-support-context-dialog.c:603 + msgid "Requires a small screen" + msgstr "Vyžaduje malou obrazovku" + +-#: src/gs-hardware-support-context-dialog.c:609 ++#: src/gs-hardware-support-context-dialog.c:608 + msgid "Mobile Not Supported" + msgstr "Nepodporuje mobily" + +-#: src/gs-hardware-support-context-dialog.c:610 ++#: src/gs-hardware-support-context-dialog.c:609 + msgid "Cannot be used on a small screen" + msgstr "Nelze použít na malé obrazovce" + +-#: src/gs-hardware-support-context-dialog.c:633 +-#: src/gs-hardware-support-context-dialog.c:642 ++#: src/gs-hardware-support-context-dialog.c:632 ++#: src/gs-hardware-support-context-dialog.c:641 + msgid "Keyboard Support" + msgstr "Podpora klávesnice" + +-#: src/gs-hardware-support-context-dialog.c:636 ++#: src/gs-hardware-support-context-dialog.c:635 + msgid "Keyboard Support Unknown" + msgstr "Neznámá podpora klávesnice" + +-#: src/gs-hardware-support-context-dialog.c:637 ++#: src/gs-hardware-support-context-dialog.c:636 + msgid "Not enough information to know if keyboards are supported" + msgstr "" + "Není dostatek informací, abychom věděli, zda jsou podporovány klávesnice" + +-#: src/gs-hardware-support-context-dialog.c:639 ++#: src/gs-hardware-support-context-dialog.c:638 + msgid "Keyboard Required" + msgstr "Vyžaduje klávesnici" + +-#: src/gs-hardware-support-context-dialog.c:643 ++#: src/gs-hardware-support-context-dialog.c:642 + msgid "Supports keyboards" + msgstr "Podporuje klávesnice" + +-#: src/gs-hardware-support-context-dialog.c:645 ++#: src/gs-hardware-support-context-dialog.c:644 + msgid "Keyboard Not Supported" + msgstr "Nepodporuje klávesnici" + +-#: src/gs-hardware-support-context-dialog.c:646 ++#: src/gs-hardware-support-context-dialog.c:645 + msgid "Cannot be used with a keyboard" + msgstr "Nelze použít s klávesnicí" + +-#: src/gs-hardware-support-context-dialog.c:653 +-#: src/gs-hardware-support-context-dialog.c:662 ++#: src/gs-hardware-support-context-dialog.c:652 ++#: src/gs-hardware-support-context-dialog.c:661 + msgid "Mouse Support" + msgstr "Podpora myši" + +-#: src/gs-hardware-support-context-dialog.c:654 +-#: src/gs-hardware-support-context-dialog.c:660 ++#: src/gs-hardware-support-context-dialog.c:653 ++#: src/gs-hardware-support-context-dialog.c:659 + msgid "Requires a mouse or pointing device" + msgstr "Vyžaduje myš nebo ukazovátko" + +-#: src/gs-hardware-support-context-dialog.c:656 ++#: src/gs-hardware-support-context-dialog.c:655 + msgid "Mouse Support Unknown" + msgstr "Neznámá podpora myši" + +-#: src/gs-hardware-support-context-dialog.c:657 ++#: src/gs-hardware-support-context-dialog.c:656 + msgid "" + "Not enough information to know if mice or pointing devices are supported" + msgstr "" + "Není dostatek informací, abychom věděli, zda jsou podporovány myši nebo " + "ukazovátka" + +-#: src/gs-hardware-support-context-dialog.c:659 ++#: src/gs-hardware-support-context-dialog.c:658 + msgid "Mouse Required" + msgstr "Vyžaduje myš" + +-#: src/gs-hardware-support-context-dialog.c:663 ++#: src/gs-hardware-support-context-dialog.c:662 + msgid "Supports mice and pointing devices" + msgstr "Podporuje myši a ukazovátka" + +-#: src/gs-hardware-support-context-dialog.c:665 ++#: src/gs-hardware-support-context-dialog.c:664 + msgid "Mouse Not Supported" + msgstr "Nepodporuje myš" + +-#: src/gs-hardware-support-context-dialog.c:666 ++#: src/gs-hardware-support-context-dialog.c:665 + msgid "Cannot be used with a mouse or pointing device" + msgstr "Nelze použít s myší nebo ukazovátkem" + +-#: src/gs-hardware-support-context-dialog.c:673 +-#: src/gs-hardware-support-context-dialog.c:682 ++#: src/gs-hardware-support-context-dialog.c:672 ++#: src/gs-hardware-support-context-dialog.c:681 + msgid "Touchscreen Support" + msgstr "Podpora dotykové obrazovky" + +-#: src/gs-hardware-support-context-dialog.c:676 ++#: src/gs-hardware-support-context-dialog.c:675 + msgid "Touchscreen Support Unknown" + msgstr "Neznámá podpora dotykové obrazovky" + +-#: src/gs-hardware-support-context-dialog.c:677 ++#: src/gs-hardware-support-context-dialog.c:676 + msgid "Not enough information to know if touchscreens are supported" + msgstr "" + "Není dostatek informací, abychom věděli, zda jsou podporovány dotykové " + "obrazovky" + +-#: src/gs-hardware-support-context-dialog.c:679 ++#: src/gs-hardware-support-context-dialog.c:678 + msgid "Touchscreen Required" + msgstr "Vyžaduje dotykovou obrazovku" + +-#: src/gs-hardware-support-context-dialog.c:683 ++#: src/gs-hardware-support-context-dialog.c:682 + msgid "Supports touchscreens" + msgstr "Podporuje dotykové obrazovky" + +-#: src/gs-hardware-support-context-dialog.c:685 ++#: src/gs-hardware-support-context-dialog.c:684 + msgid "Touchscreen Not Supported" + msgstr "Nepodporuje dotykovou obrazovku" + +-#: src/gs-hardware-support-context-dialog.c:686 ++#: src/gs-hardware-support-context-dialog.c:685 + msgid "Cannot be used with a touchscreen" + msgstr "Nelze použít s dotykovou obrazovkou" + +-#: src/gs-hardware-support-context-dialog.c:699 ++#: src/gs-hardware-support-context-dialog.c:698 + msgid "Gamepad Required" + msgstr "Vyžadován herní ovladač" + +-#: src/gs-hardware-support-context-dialog.c:700 ++#: src/gs-hardware-support-context-dialog.c:699 + msgid "Requires a gamepad" + msgstr "Vyžaduje herní ovladač" + +-#: src/gs-hardware-support-context-dialog.c:702 ++#: src/gs-hardware-support-context-dialog.c:701 + msgid "Gamepad Support" + msgstr "Podpora herního ovladače" + +-#: src/gs-hardware-support-context-dialog.c:703 ++#: src/gs-hardware-support-context-dialog.c:702 + msgid "Supports gamepads" + msgstr "Podporuje herní ovladače" + + #. Translators: It’s unknown whether this app is supported on + #. * the current hardware. The placeholder is the app name. +-#: src/gs-hardware-support-context-dialog.c:712 ++#: src/gs-hardware-support-context-dialog.c:711 + #, c-format + msgid "%s probably works on this device" + msgstr "Aplikace %s na tomto zařízení pravděpodobně funguje" + + #. Translators: The app will work on the current hardware. + #. * The placeholder is the app name. +-#: src/gs-hardware-support-context-dialog.c:719 ++#: src/gs-hardware-support-context-dialog.c:718 + #, c-format + msgid "%s works on this device" + msgstr "Aplikace %s na tomto zařízení funguje" + + #. Translators: The app may not work fully on the current hardware. + #. * The placeholder is the app name. +-#: src/gs-hardware-support-context-dialog.c:726 ++#: src/gs-hardware-support-context-dialog.c:725 + #, c-format + msgid "%s will not work properly on this device" + msgstr "Aplikace %s na tomto zařízení nebude fungovat správně" + + #. Translators: The app will not work properly on the current hardware. + #. * The placeholder is the app name. +-#: src/gs-hardware-support-context-dialog.c:733 ++#: src/gs-hardware-support-context-dialog.c:732 + #, c-format + msgid "%s will not work on this device" + msgstr "Aplikace %s na tomto zařízení nebude fungovat" +@@ -2866,8 +2891,7 @@ msgid "Hardware Support" + msgstr "Podpora hardwaru" + + #. Translators: This is in the context of a list of apps which are installed on the system. +-#. Translators: A label for a button to show only software which is already installed. +-#: src/gs-installed-page.c:813 src/gs-shell.ui:309 ++#: src/gs-installed-page.c:813 + msgctxt "List of installed apps" + msgid "Installed" + msgstr "Nainstalováno" +@@ -2883,27 +2907,27 @@ msgstr "S probíhající změnou" + #. origin_ui on a remote is the repo dialogue section name, + #. * not the remote title + #: src/gs-installed-page.ui:75 plugins/flatpak/gs-flatpak-utils.c:107 +-msgid "Applications" ++msgid "Apps" + msgstr "Aplikace" + + #: src/gs-installed-page.ui:95 +-msgid "Web Applications" ++msgid "Web Apps" + msgstr "Webové aplikace" + + #: src/gs-installed-page.ui:115 +-msgid "System Applications" ++msgid "System Apps" + msgstr "Systémové aplikace" + +-#: src/gs-license-tile.c:96 ++#: src/gs-license-tile.c:97 + msgid "Community Built" + msgstr "Vybudováno komunitou" + +-#: src/gs-license-tile.c:107 src/gs-license-tile.ui:98 ++#: src/gs-license-tile.c:108 src/gs-license-tile.ui:98 + msgid "_Get Involved" + msgstr "_Zapojit se" + + #. Translators: The first placeholder here is a link to information about the license, and the second placeholder here is the name of a software license. +-#: src/gs-license-tile.c:114 ++#: src/gs-license-tile.c:115 + #, c-format + msgid "" + "This software is developed in the open by a community of volunteers, and " +@@ -2917,7 +2941,7 @@ msgstr "" + "Můžete přispět a pomoci jej ještě vylepšit." + + #. Translators: The placeholder here is the name of a software license. +-#: src/gs-license-tile.c:121 ++#: src/gs-license-tile.c:122 + #, c-format + msgid "" + "This software is developed in the open by a community of volunteers, and " +@@ -2930,15 +2954,15 @@ msgstr "" + "\n" + "Můžete přispět a pomoci jej ještě vylepšit." + +-#: src/gs-license-tile.c:127 ++#: src/gs-license-tile.c:128 + msgid "Proprietary" + msgstr "Uzavřený software" + +-#: src/gs-license-tile.c:133 ++#: src/gs-license-tile.c:134 + msgid "_Learn More" + msgstr "Zjistit _více" + +-#: src/gs-license-tile.c:135 ++#: src/gs-license-tile.c:136 + msgid "" + "This software is not developed in the open, so only its developers know how " + "it works. It may be insecure in ways that are hard to detect, and it may " +@@ -2965,7 +2989,7 @@ msgstr "Načítá se stránka" + msgid "Starting up…" + msgstr "Spouští se…" + +-#: src/gs-metered-data-dialog.ui:5 src/gs-shell.ui:258 ++#: src/gs-metered-data-dialog.ui:5 + msgid "Automatic Updates Paused" + msgstr "Automatické aktualizace jsou pozastaveny" + +@@ -3012,62 +3036,72 @@ msgstr "Neznámý zdroj" + msgid "Beta" + msgstr "Beta" + +-#. Translators: It's an origin scope, 'User' or 'System' installation +-#: src/gs-origin-popover-row.ui:138 +-msgid "User" +-msgstr "Uživatel" +- + #. TRANSLATORS: This is the header for package additions during + #. * a system update +-#: src/gs-os-update-page.c:250 ++#: src/gs-os-update-page.c:249 + msgid "Additions" + msgstr "Přidávání" + + #. TRANSLATORS: This is the header for package removals during + #. * a system update +-#: src/gs-os-update-page.c:254 ++#: src/gs-os-update-page.c:253 + msgid "Removals" + msgstr "Odstraňování" + + #. TRANSLATORS: This is the header for package updates during + #. * a system update +-#: src/gs-os-update-page.c:258 ++#: src/gs-os-update-page.c:257 + msgctxt "Packages to be updated during a system upgrade" + msgid "Updates" + msgstr "Aktualizace" + + #. TRANSLATORS: This is the header for package downgrades during + #. * a system update +-#: src/gs-os-update-page.c:262 ++#: src/gs-os-update-page.c:261 + msgid "Downgrades" + msgstr "Ponižování" + +-#. Translators: This is a clickable link on the third party repositories info bar. It's ++#. Translators: This is a clickable link on the third party repositories message dialog. It's + #. part of a constructed sentence: "Provides access to additional software from [selected external sources]. + #. Some proprietary software is included." +-#: src/gs-overview-page.c:876 ++#: src/gs-overview-page.c:475 + msgid "selected external sources" + msgstr "vybraných externích zdrojů" + +-#. Translators: This is the third party repositories info bar. The %s is replaced with "selected external sources" link. +-#: src/gs-overview-page.c:878 ++#. Translators: This is the third party repositories message dialog. ++#. The %s is replaced with "selected external sources" link. ++#. Repositories Preferences is an item from Software's main menu. ++#: src/gs-overview-page.c:479 + #, c-format + msgid "" + "Provides access to additional software from %s. Some proprietary software is " +-"included." ++"included.\n" ++"\n" ++"You can enable those repositories later in Software Repositories preferences." + msgstr "" + "Poskytuje přístup k dalšímu softwaru z %s. Součástí je i některý uzavřený " +-"software." ++"software.\n" ++"\n" ++"Tyto repozitáře můžete později povolit v předvolbách Softwarových repozitářů." ++ ++#. TRANSLATORS: Heading asking whether to turn third party software repositories on of off. ++#: src/gs-overview-page.c:485 ++msgid "Enable Third Party Software Repositories?" ++msgstr "Povolit repozitáře softwaru třetích stran?" ++ ++#. TRANSLATORS: button to keep the third party software repositories off ++#: src/gs-overview-page.c:490 ++msgid "_Ignore" ++msgstr "_Ignorovat" + + #. TRANSLATORS: button to turn on third party software repositories + #. TRANSLATORS: button to accept the agreement +-#: src/gs-overview-page.c:887 src/gs-repos-dialog.c:173 +-msgid "Enable" +-msgstr "Povolit" ++#: src/gs-overview-page.c:492 src/gs-repos-dialog.c:173 ++msgid "_Enable" ++msgstr "_Povolit" + + #. Translators: This is the title of the main page of the UI. +-#. Translators: A label for a button to show all available software. +-#: src/gs-overview-page.c:946 src/gs-shell.ui:296 ++#: src/gs-overview-page.c:985 + msgid "Explore" + msgstr "Procházet" + +@@ -3075,61 +3109,62 @@ msgstr "Procházet" + msgid "Overview page" + msgstr "Stránka s přehledem" + +-#: src/gs-overview-page.ui:35 +-msgid "Enable Third Party Software Repositories?" +-msgstr "Povolit repozitáře softwaru třetích stran?" +- + #. Translators: This is a heading for a list of categories. +-#: src/gs-overview-page.ui:180 ++#: src/gs-overview-page.ui:143 + msgid "Other Categories" + msgstr "Ostatní kategorie" + +-#: src/gs-overview-page.ui:221 +-msgid "No Application Data Found" ++#: src/gs-overview-page.ui:184 ++msgid "No App Data Found" + msgstr "O aplikaci nebyly nalezeny žádné informace" + +-#: lib/gs-plugin-loader.c:2836 ++#: lib/gs-plugin-loader.c:2771 + msgctxt "Distribution name" + msgid "Unknown" + msgstr "neznámá" + +-#: src/gs-page.c:274 ++#. TRANSLATORS: button text ++#: src/gs-page.c:92 ++msgid "_OK" ++msgstr "_Budiž" ++ ++#: src/gs-page.c:271 + msgid "User declined installation" + msgstr "Uživatel odmítl instalaci" + + #. TRANSLATORS: this is a prompt message, and +-#. * '%s' is an application summary, e.g. 'GNOME Clocks' +-#: src/gs-page.c:365 ++#. * '%s' is an app summary, e.g. 'GNOME Clocks' ++#: src/gs-page.c:404 + #, c-format + msgid "Prepare %s" + msgstr "Příprava aplikace %s" + + #. TRANSLATORS: this is a prompt message, and '%s' is an + #. * repository name, e.g. 'GNOME Nightly' +-#: src/gs-page.c:518 ++#: src/gs-page.c:523 + #, c-format + msgid "Are you sure you want to remove the %s repository?" + msgstr "Opravdu chcete odebrat repozitář %s?" + + #. TRANSLATORS: longer dialog text +-#: src/gs-page.c:522 ++#: src/gs-page.c:527 + #, c-format + msgid "" +-"All applications from %s will be uninstalled, and you will have to re-" +-"install the repository to use them again." ++"All apps from %s will be uninstalled, and you will have to re-install the " ++"repository to use them again." + msgstr "" +-"Všechny aplikace pocházející ze repozitáře %s budou odinstalovány. Abyste je " ++"Všechny aplikace pocházející z repozitáře %s budou odinstalovány. Abyste je " + "mohli znovu použít, budete muset repozitář znovu nainstalovat." + + #. TRANSLATORS: this is a prompt message, and '%s' is an +-#. * application summary, e.g. 'GNOME Clocks' +-#: src/gs-page.c:530 ++#. * app summary, e.g. 'GNOME Clocks' ++#: src/gs-page.c:535 + #, c-format + msgid "Are you sure you want to uninstall %s?" + msgstr "Opravdu chcete odinstalovat %s?" + + #. TRANSLATORS: longer dialog text +-#: src/gs-page.c:533 ++#: src/gs-page.c:538 + #, c-format + msgid "" + "%s will be uninstalled, and you will have to install it to use it again." +@@ -3138,8 +3173,8 @@ msgstr "" + "muset provést novou instalaci." + + #: src/gs-prefs-dialog.ui:5 +-msgid "Update Preferences" +-msgstr "Předvolby aktualizací" ++msgid "Preferences" ++msgstr "Předvolby" + + #: src/gs-prefs-dialog.ui:16 + msgid "" +@@ -3150,65 +3185,69 @@ msgstr "" + "automaticky stahovány na mobilních nebo měřených připojeních." + + #: src/gs-prefs-dialog.ui:19 +-msgid "Automatic Updates" +-msgstr "Automatické aktualizace" ++msgid "Automatic _Updates" ++msgstr "Automatické _aktualizace" + + #: src/gs-prefs-dialog.ui:20 + msgid "" +-"Downloads and installs software updates in the background, when possible." ++"Downloads and installs software updates in the background, when possible" + msgstr "Stahuje a instaluje aktualizace softwaru na pozadí, pokud je to možné." + +-#: src/gs-prefs-dialog.ui:32 +-msgid "Automatic Update Notifications" +-msgstr "Oznamovat automatické aktualizace" +- + #: src/gs-prefs-dialog.ui:33 +-msgid "Show notifications when updates have been automatically installed." ++msgid "Automatic Update _Notifications" ++msgstr "_Oznamovat automatické aktualizace" ++ ++#: src/gs-prefs-dialog.ui:34 ++msgid "Show notifications when updates have been automatically installed" + msgstr "Zobrazovat oznámení, když jsou automaticky nainstalovány aplikace." + ++#: src/gs-prefs-dialog.ui:47 ++msgid "Show Only _Free Apps" ++msgstr "Zobrazit _pouze svobodné aplikace" ++ ++#: src/gs-prefs-dialog.ui:48 ++msgid "Show only freely licensed apps and hide any proprietary apps" ++msgstr "" ++"Zobrazit pouze aplikace se svobodnou licencí a skrýt všechny proprietární " ++"aplikace." ++ + #. TRANSLATORS: This is a text displayed during a distro upgrade. %s + #. will be replaced by the name and version of distro, e.g. 'Fedora 23'. + #: src/gs-removal-dialog.c:96 +-#, fuzzy, c-format +-#| msgid "" +-#| "Some of the currently installed software is not compatible with %s. If " +-#| "you continue, the following will be automatically removed during the " +-#| "upgrade:" ++#, c-format + msgid "" + "Installed software is incompatible with %s, and will be automatically " + "removed during upgrade." + msgstr "" + "Některý z právě instalovaného softwaru není kompatibilní s distribucí %s. " +-"Pokud budete pokračovat, následujíc se během povýšení odstraní:" ++"Pokud budete pokračovat, během povýšení se odstraní." + + #: src/gs-removal-dialog.ui:7 + msgid "Incompatible Software" + msgstr "Nekompatibilní software" + + #: src/gs-removal-dialog.ui:37 +-#, fuzzy +-#| msgid "_Restart & Upgrade" + msgid "_Upgrade" +-msgstr "_Restartovat a aktualizovat" ++msgstr "_Aktualizovat" + + #. TRANSLATORS: The '%s' is replaced with a repository name, like "Fedora Modular - x86_64" +-#: src/gs-repos-dialog.c:239 ++#: src/gs-repos-dialog.c:241 + #, c-format + msgid "" + "Software that has been installed from “%s” will cease to receive updates." + msgstr "" + "Software, který byl nainstalován z „%s“, přestane dostávat aktualizace." + +-#: src/gs-repos-dialog.c:248 ++#: src/gs-repos-dialog.c:246 + msgid "Disable Repository?" + msgstr "Zakázat repozitář?" + +-#: src/gs-repos-dialog.c:248 ++#: src/gs-repos-dialog.c:246 + msgid "Remove Repository?" + msgstr "Odebrat repozitář?" + + #. TRANSLATORS: this is button text to disable a repo +-#: src/gs-repos-dialog.c:254 ++#: src/gs-repos-dialog.c:253 + msgid "_Disable" + msgstr "_Zakázat" + +@@ -3217,41 +3256,41 @@ msgstr "_Zakázat" + msgid "_Remove" + msgstr "_Odebrat" + +-#: src/gs-repos-dialog.c:508 ++#: src/gs-repos-dialog.c:507 + msgid "Enable New Repositories" + msgstr "Povolit nové repozitáře" + +-#: src/gs-repos-dialog.c:509 ++#: src/gs-repos-dialog.c:508 + msgid "Turn on new repositories when they are added." + msgstr "Zapnout nové repozitáře při jejich přidání." + + #. TRANSLATORS: this is the clickable + #. * link on the third party repositories info bar +-#: src/gs-repos-dialog.c:518 ++#: src/gs-repos-dialog.c:517 + msgid "more information" + msgstr "více informací" + + #. TRANSLATORS: this is the third party repositories info bar. The '%s' is replaced + #. with a link consisting a text "more information", which constructs a sentence: + #. "Additional repositories from selected third parties - more information." +-#: src/gs-repos-dialog.c:523 ++#: src/gs-repos-dialog.c:522 + #, c-format + msgid "Additional repositories from selected third parties — %s." + msgstr "Další repozitáře od vybraných třetích stran — %s." + +-#: src/gs-repos-dialog.c:528 ++#: src/gs-repos-dialog.c:527 + msgid "Fedora Third Party Repositories" + msgstr "Repozitáře třetích stran Fedory" + + #. TRANSLATORS: this is the fallback text we use if we can't + #. figure out the name of the operating system +-#: src/gs-repos-dialog.c:670 ++#: src/gs-repos-dialog.c:669 + msgid "the operating system" + msgstr "operačního systému" + + #. TRANSLATORS: This is the description text displayed in the Software Repositories dialog. + #. %s gets replaced by the name of the actual distro, e.g. Fedora. +-#: src/gs-repos-dialog.c:728 ++#: src/gs-repos-dialog.c:727 + #, c-format + msgid "These repositories supplement the default software provided by %s." + msgstr "" +@@ -3259,7 +3298,7 @@ msgstr "" + "%s." + + #. button in the info bar +-#: src/gs-repos-dialog.ui:8 src/gs-shell.ui:88 ++#: src/gs-repos-dialog.ui:8 src/gs-shell.ui:99 + msgid "Software Repositories" + msgstr "Softwarové repozitáře" + +@@ -3267,19 +3306,21 @@ msgstr "Softwarové repozitáře" + msgid "No Repositories" + msgstr "Žádné repozitáře" + +-#. TRANSLATORS: This string is used to construct the 'X applications +-#. installed' sentence, describing a software repository. +-#: src/gs-repo-row.c:160 ++#. TRANSLATORS: This string states how many apps have been ++#. * installed from a particular repo, and is displayed on a row ++#. * describing that repo. The placeholder is the number of apps. ++#: src/gs-repo-row.c:161 + #, c-format +-msgid "%u application installed" +-msgid_plural "%u applications installed" ++msgid "%u app installed" ++msgid_plural "%u apps installed" + msgstr[0] "Nainstalována %u aplikace" + msgstr[1] "Nainstalovány %u aplikace" + msgstr[2] "Nainstalováno %u aplikací" + +-#. TRANSLATORS: This string is used to construct the 'X add-ons +-#. installed' sentence, describing a software repository. +-#: src/gs-repo-row.c:167 ++#. TRANSLATORS: This string states how many add-ons have been ++#. * installed from a particular repo, and is displayed on a row ++#. * describing that repo. The placeholder is the number of add-ons. ++#: src/gs-repo-row.c:169 + #, c-format + msgid "%u add-on installed" + msgid_plural "%u add-ons installed" +@@ -3287,21 +3328,27 @@ msgstr[0] "Nainstalován %u doplněk" + msgstr[1] "Nainstalovány %u doplňky" + msgstr[2] "Nainstalováno %u doplňků" + +-#. TRANSLATORS: This string is used to construct the 'X applications +-#. and y add-ons installed' sentence, describing a software repository. +-#. The correct form here depends on the number of applications. +-#: src/gs-repo-row.c:175 ++#. TRANSLATORS: This string is used to construct the 'X apps ++#. and Y add-ons installed' sentence, stating how many things have been ++#. * installed from a particular repo. It’s displayed on a row describing ++#. * that repo. The placeholder is the number of apps, and the translated ++#. * string will be substituted in for the first placeholder in the ++#. * string “%s and %s installed”. ++#: src/gs-repo-row.c:180 + #, c-format +-msgid "%u application" +-msgid_plural "%u applications" ++msgid "%u app" ++msgid_plural "%u apps" + msgstr[0] "%u aplikace" + msgstr[1] "%u aplikace" + msgstr[2] "%u aplikací" + +-#. TRANSLATORS: This string is used to construct the 'X applications +-#. and y add-ons installed' sentence, describing a software repository. +-#. The correct form here depends on the number of add-ons. +-#: src/gs-repo-row.c:181 ++#. TRANSLATORS: This string is used to construct the 'X apps ++#. and Y add-ons installed' sentence, stating how many things have been ++#. * installed from a particular repo. It’s displayed on a row describing ++#. * that repo. The placeholder is the number of add-ons, and the translated ++#. * string will be substituted in for the second placeholder in the ++#. * string “%s and %s installed”. ++#: src/gs-repo-row.c:189 + #, c-format + msgid "%u add-on" + msgid_plural "%u add-ons" +@@ -3309,11 +3356,20 @@ msgstr[0] "%u doplněk" + msgstr[1] "%u doplňky" + msgstr[2] "%u doplňků" + +-#. TRANSLATORS: This string is used to construct the 'X applications +-#. and y add-ons installed' sentence, describing a software repository. +-#. The correct form here depends on the total number of +-#. applications and add-ons. +-#: src/gs-repo-row.c:188 ++#. TRANSLATORS: This string is used to construct the 'X apps ++#. and Y add-ons installed' sentence, stating how many things have been ++#. * installed from a particular repo. It’s displayed on a row describing ++#. * that repo. The first placeholder is the translated string “%u app” or ++#. * “%u apps”. The second placeholder is the translated string “%u add-on” ++#. * or “%u add-ons”. ++#. * ++#. * The choice of plural form for this string is determined by the total ++#. * number of apps plus add-ons. For example, ++#. * - “1 app and 2 add-ons installed” - uses count 3 ++#. * - “2 apps and 1 add-on installed” - uses count 3 ++#. * - “4 apps and 5 add-ons installed” - uses count 9 ++#. ++#: src/gs-repo-row.c:205 + #, c-format + msgid "%s and %s installed" + msgid_plural "%s and %s installed" +@@ -3321,120 +3377,117 @@ msgstr[0] "%s a %s" + msgstr[1] "%s a %s" + msgstr[2] "%s a %s" + +-#. Translators: The first '%s' is replaced with a text like '10 applications installed', ++#. Translators: The first '%s' is replaced with a text like '10 apps installed', + #. the second '%s' is replaced with installation kind, like in case of Flatpak 'User Installation'. +-#: src/gs-repo-row.c:243 ++#: src/gs-repo-row.c:260 + #, c-format + msgctxt "repo-row" + msgid "%s • %s" + msgstr "%s • %s" + +-#: src/gs-repo-row.c:314 +-#, fuzzy +-#| msgid "_Remove" ++#: src/gs-repo-row.c:331 + msgid "Remove" +-msgstr "_Odebrat" ++msgstr "Odebrat" + + #. TRANSLATORS: lighthearted star rating description; +-#. * A really bad application ++#. * A really bad app + #: src/gs-review-dialog.c:78 + msgid "Hate it" + msgstr "Nenávidím ji" + + #. TRANSLATORS: lighthearted star rating description; +-#. * Not a great application ++#. * Not a great app + #: src/gs-review-dialog.c:82 + msgid "Don’t like it" + msgstr "Nemám ji rád" + + #. TRANSLATORS: lighthearted star rating description; +-#. * A fairly-good application ++#. * A fairly-good app + #: src/gs-review-dialog.c:86 + msgid "It’s OK" + msgstr "Běžná aplikace" + + #. TRANSLATORS: lighthearted star rating description; +-#. * A good application ++#. * A good app + #: src/gs-review-dialog.c:90 + msgid "Like it" + msgstr "Mám ji rád" + + #. TRANSLATORS: lighthearted star rating description; +-#. * A really awesome application ++#. * A really awesome app + #: src/gs-review-dialog.c:94 + msgid "Love it" + msgstr "Zbožňuji ji" + ++#. TRANSLATORS: lighthearted star rating description; ++#. * No star has been clicked yet ++#: src/gs-review-dialog.c:98 ++msgid "Select a Star to Leave a Rating" ++msgstr "Chcete-li zanechat hodnocení, vyberte hvězdičku" ++ + #. TRANSLATORS: the review can't just be copied and pasted +-#: src/gs-review-dialog.c:118 ++#: src/gs-review-dialog.c:119 + msgid "Please take more time writing the review" + msgstr "Věnujte prosím trochu času napsaní recenze" + + #. TRANSLATORS: the review is not acceptable +-#: src/gs-review-dialog.c:122 ++#: src/gs-review-dialog.c:123 + msgid "Please choose a star rating" + msgstr "Ohodnoťte prosím hvězdičkami" + + #. TRANSLATORS: the review is not acceptable +-#: src/gs-review-dialog.c:126 ++#: src/gs-review-dialog.c:127 + msgid "The summary is too short" + msgstr "Celkové hodnocení je příliš krátké" + + #. TRANSLATORS: the review is not acceptable +-#: src/gs-review-dialog.c:130 ++#: src/gs-review-dialog.c:131 + msgid "The summary is too long" + msgstr "Celkové hodnocení je příliš dlouhé" + + #. TRANSLATORS: the review is not acceptable +-#: src/gs-review-dialog.c:134 ++#: src/gs-review-dialog.c:135 + msgid "The description is too short" + msgstr "Recenze je příliš krátká" + + #. TRANSLATORS: the review is not acceptable +-#: src/gs-review-dialog.c:138 ++#: src/gs-review-dialog.c:139 + msgid "The description is too long" + msgstr "Recenze je příliš dlouhá" + + #. Translators: Title of the dialog box where the users can write and publish their opinions about the apps. + #: src/gs-review-dialog.ui:10 +-msgid "Post Review" +-msgstr "Příspěvek do recenzí" ++msgid "Write a Review" ++msgstr "Napsat recenzi" + + #. Translators: A button to publish the user's opinion about the app. + #: src/gs-review-dialog.ui:26 +-msgid "_Post" ++msgid "_Send" + msgstr "_Odeslat" + +-#: src/gs-review-dialog.ui:56 +-msgid "Rating" +-msgstr "Hodnocení" +- +-#: src/gs-review-dialog.ui:88 +-msgid "Summary" +-msgstr "Celkový dojem" +- +-#: src/gs-review-dialog.ui:97 ++#: src/gs-review-dialog.ui:71 + msgid "" +-"Give a short summary of your review, for example: “Great app, would " +-"recommend”." ++"What did you like about this app? Leaving your feedback along with your " ++"reasons for leaving a review is helpful for others." + msgstr "" +-"Uveďte krátké shrnutí své recenze, například: „Skvělá aplikace, doporučuji“." ++"Co se vám na této aplikaci líbilo? Zanechání zpětné vazby společně s důvody " ++"pro zanechání recenze je pro ostatní užitečné." ++ ++#: src/gs-review-dialog.ui:84 ++msgid "Review Summary" ++msgstr "Celkový dojem" + + #. Translators: This is where the users enter their opinions about the apps. +-#: src/gs-review-dialog.ui:119 ++#: src/gs-review-dialog.ui:116 + msgctxt "app review" +-msgid "Review" +-msgstr "Recenze" ++msgid "Write a short review" ++msgstr "Napište krátkou recenzi" + +-#: src/gs-review-dialog.ui:128 +-msgid "What do you think of the app? Try to give reasons for your views." +-msgstr "Co si o aplikaci myslíte? Snažte se uvést důvody svého hodnocení." +- +-#: src/gs-review-dialog.ui:156 ++#: src/gs-review-dialog.ui:160 + msgid "" +-"Find what data is sent in our privacy policy. The full name attached to your account will be shown " +-"publicly." ++"Find what data is sent in our privacy policy. The full name attached to your account will be " ++"shown publicly." + msgstr "" + "Najděte si v našich zásadách " + "soukromí, jaká data jsou odesílána. Celé jméno přiřazené k vašemu účtu " +@@ -3448,24 +3501,24 @@ msgstr[0] "celkem %u recenze" + msgstr[1] "celkem %u recenze" + msgstr[2] "celkem %u recenzí" + +-#: src/gs-review-histogram.ui:93 ++#: src/gs-review-histogram.ui:88 + msgid "out of 5 stars" + msgstr "z 5 hvězdiček" + + #. TRANSLATORS: this is when a user doesn't specify a name +-#: src/gs-review-row.c:56 ++#: src/gs-review-row.c:60 + msgctxt "Reviewer name" + msgid "Unknown" + msgstr "anonym" + + #. TRANSLATORS: we explain what the action is going to do +-#: src/gs-review-row.c:220 ++#: src/gs-review-row.c:222 + msgid "You can report reviews for abusive, rude, or discriminatory behavior." + msgstr "" + "Můžete nahlásit recenze, které jsou urážlivé, sprosté nebo diskriminační." + + #. TRANSLATORS: we ask the user if they really want to do this +-#: src/gs-review-row.c:225 ++#: src/gs-review-row.c:227 + msgid "" + "Once reported, a review will be hidden until it has been checked by an " + "administrator." +@@ -3474,15 +3527,15 @@ msgstr "Po nahlášení bude recenze skryta, dokud ji nezkontroluje správce." + #. TRANSLATORS: window title when + #. * reporting a user-submitted review + #. * for moderation +-#: src/gs-review-row.c:239 ++#: src/gs-review-row.c:235 + msgid "Report Review?" + msgstr "Nahlásit recenzi?" + + #. TRANSLATORS: button text when + #. * sending a review for moderation +-#: src/gs-review-row.c:243 +-msgid "Report" +-msgstr "Nahlásit" ++#: src/gs-review-row.c:240 ++msgid "_Report" ++msgstr "_Nahlásit" + + #. Translators: Users can express their opinions about other users' opinions about the apps. + #: src/gs-review-row.ui:84 +@@ -3510,175 +3563,184 @@ msgstr "Nahlásit…" + msgid "Remove…" + msgstr "Odebrat…" + +-#: src/gs-safety-context-dialog.c:144 +-msgid "Check that you trust the vendor, as the application isn’t sandboxed" ++#: src/gs-safety-context-dialog.c:143 ++msgid "Check that you trust the vendor, as the app isn’t sandboxed" + msgstr "" + "Zkontrolujte si, že důvěřujete dodavateli, protože aplikace není v " +-"izolovaném prostředí." ++"izolovaném prostředí" + +-#: src/gs-safety-context-dialog.c:147 ++#: src/gs-safety-context-dialog.c:146 + msgid "" +-"Application isn’t sandboxed but the distribution has checked that it is not " +-"malicious" ++"App isn’t sandboxed but the distribution has checked that it is not malicious" + msgstr "" + "Aplikace není v izolovaném prostředí, ale je prověřená v distribuci, že " +-"neobsahuje škodlivý kód." ++"neobsahuje škodlivý kód" + + #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. +-#: src/gs-safety-context-dialog.c:160 ++#: src/gs-safety-context-dialog.c:159 + msgid "No Permissions" + msgstr "Žádná oprávnění" + +-#: src/gs-safety-context-dialog.c:161 ++#: src/gs-safety-context-dialog.c:160 + msgid "App is fully sandboxed" + msgstr "Aplikace je v plně izolovaném prostředí" + + #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. +-#: src/gs-safety-context-dialog.c:172 ++#: src/gs-safety-context-dialog.c:171 + msgid "Network Access" + msgstr "Přístup k síti" + +-#: src/gs-safety-context-dialog.c:173 ++#: src/gs-safety-context-dialog.c:172 + msgid "Can access the internet" + msgstr "Může přistupovat k internetu" + + #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. +-#: src/gs-safety-context-dialog.c:176 ++#: src/gs-safety-context-dialog.c:175 + msgid "No Network Access" + msgstr "Žádný přístup k síti" + +-#: src/gs-safety-context-dialog.c:177 ++#: src/gs-safety-context-dialog.c:176 + msgid "Cannot access the internet" + msgstr "Nemůže přistupovat k internetu" + + #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. +-#: src/gs-safety-context-dialog.c:183 ++#: src/gs-safety-context-dialog.c:182 + msgid "Uses System Services" + msgstr "Využívá služby systému" + +-#: src/gs-safety-context-dialog.c:184 ++#: src/gs-safety-context-dialog.c:183 + msgid "Can request data from system services" + msgstr "Může si vyžádat data ze služeb systému" + + #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. +-#: src/gs-safety-context-dialog.c:191 ++#: src/gs-safety-context-dialog.c:190 + msgid "Uses Session Services" + msgstr "Využívá služby sezení" + +-#: src/gs-safety-context-dialog.c:192 ++#: src/gs-safety-context-dialog.c:191 + msgid "Can request data from session services" + msgstr "Může si vyžádat data ze služeb sezení" + + #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. +-#: src/gs-safety-context-dialog.c:199 +-msgid "Device Access" +-msgstr "Přístup k zařízení" ++#: src/gs-safety-context-dialog.c:198 ++msgid "User Device Access" ++msgstr "Přístup k uživatelským zařízením" + +-#: src/gs-safety-context-dialog.c:200 ++#: src/gs-safety-context-dialog.c:199 + msgid "Can access devices such as webcams or gaming controllers" + msgstr "Může přistupovat k zařízením jako jsou webkamery nebo herní ovladače" + + #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. +-#: src/gs-safety-context-dialog.c:203 +-msgid "No Device Access" +-msgstr "Žádný přístup k zařízení" ++#: src/gs-safety-context-dialog.c:202 ++msgid "No User Device Access" ++msgstr "Žádný přístup k uživatelským zařízením" + +-#: src/gs-safety-context-dialog.c:204 ++#: src/gs-safety-context-dialog.c:203 + msgid "Cannot access devices such as webcams or gaming controllers" + msgstr "Nemůže přistupovat k zařízením jako jsou webkamery nebo herní ovladače" + + #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. ++#: src/gs-safety-context-dialog.c:209 ++msgid "System Device Access" ++msgstr "Přístup k systémovým zařízením" ++ + #: src/gs-safety-context-dialog.c:210 ++msgid "Can access system devices which require elevated permissions" ++msgstr "" ++"Může přistupovat k systémovým zařízením, která vyžadují zvýšená oprávnění" ++ ++#. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. ++#: src/gs-safety-context-dialog.c:217 + msgid "Legacy Windowing System" + msgstr "Zastaralý zobrazovací systém" + + #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. +-#: src/gs-safety-context-dialog.c:218 ++#: src/gs-safety-context-dialog.c:225 + msgid "Arbitrary Permissions" + msgstr "Libovolná oprávnění" + + #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. +-#: src/gs-safety-context-dialog.c:226 ++#: src/gs-safety-context-dialog.c:233 + msgid "User Settings" + msgstr "Uživatelská nastavení" + + #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. +-#: src/gs-safety-context-dialog.c:238 ++#: src/gs-safety-context-dialog.c:245 + msgid "Full File System Read/Write Access" + msgstr "Plný přístup k souborovému systému pro čtení/zápis" + +-#: src/gs-safety-context-dialog.c:239 ++#: src/gs-safety-context-dialog.c:246 + msgid "Can read and write all data on the file system" + msgstr "Může číst a zapisovat všechna data v souborovém systému" + + #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. +-#: src/gs-safety-context-dialog.c:247 ++#: src/gs-safety-context-dialog.c:254 + msgid "Home Folder Read/Write Access" + msgstr "Přístup k domovské složce pro čtení/zápis" + +-#: src/gs-safety-context-dialog.c:248 ++#: src/gs-safety-context-dialog.c:255 + msgid "Can read and write all data in your home directory" + msgstr "Může číst a zapisovat všechna data ve vaší domovské složce" + + #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. +-#: src/gs-safety-context-dialog.c:256 ++#: src/gs-safety-context-dialog.c:263 + msgid "Full File System Read Access" + msgstr "Plný přístup k souborovému systému pro čtení" + +-#: src/gs-safety-context-dialog.c:257 ++#: src/gs-safety-context-dialog.c:264 + msgid "Can read all data on the file system" + msgstr "Může číst všechna data v souborovém systému" + + #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. +-#: src/gs-safety-context-dialog.c:266 ++#: src/gs-safety-context-dialog.c:273 + msgid "Home Folder Read Access" + msgstr "Přístup k domovské složce pro čtení" + +-#: src/gs-safety-context-dialog.c:267 ++#: src/gs-safety-context-dialog.c:274 + msgid "Can read all data in your home directory" + msgstr "Může číst všechna data ve vaší domovské složce" + + #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. +-#: src/gs-safety-context-dialog.c:276 ++#: src/gs-safety-context-dialog.c:283 + msgid "Download Folder Read/Write Access" + msgstr "Přístup ke složce se staženými soubory pro čtení/zápis" + +-#: src/gs-safety-context-dialog.c:277 ++#: src/gs-safety-context-dialog.c:284 + msgid "Can read and write all data in your downloads directory" + msgstr "Může číst a zapisovat všechna data ve vaší složce se staženými soubory" + + #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. +-#: src/gs-safety-context-dialog.c:288 ++#: src/gs-safety-context-dialog.c:295 + msgid "Download Folder Read Access" + msgstr "Přístup ke složce se staženými soubory pro čtení" + +-#: src/gs-safety-context-dialog.c:289 ++#: src/gs-safety-context-dialog.c:296 + msgid "Can read all data in your downloads directory" + msgstr "Může číst všechna data ve vaší složce se staženými soubory" + +-#: src/gs-safety-context-dialog.c:299 ++#: src/gs-safety-context-dialog.c:306 + msgid "Can read and write all data in the directory" + msgstr "Může číst a zapisovat všechna data ve složce" + +-#: src/gs-safety-context-dialog.c:310 ++#: src/gs-safety-context-dialog.c:317 + msgid "Can read all data in the directory" + msgstr "Může číst všechna data ve složce" + + #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. +-#: src/gs-safety-context-dialog.c:326 ++#: src/gs-safety-context-dialog.c:333 + msgid "No File System Access" + msgstr "Žádný přístup k souborovému systému" + +-#: src/gs-safety-context-dialog.c:327 ++#: src/gs-safety-context-dialog.c:334 + msgid "Cannot access the file system at all" + msgstr "Vůbec nemůže přistupovat k souborovému systému" + + #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. +-#: src/gs-safety-context-dialog.c:341 ++#: src/gs-safety-context-dialog.c:348 + msgid "Proprietary Code" + msgstr "uzavřená" + +-#: src/gs-safety-context-dialog.c:342 ++#: src/gs-safety-context-dialog.c:349 + msgid "" + "The source code is not public, so it cannot be independently audited and " + "might be unsafe" +@@ -3687,11 +3749,11 @@ msgstr "" + "nebezpečný." + + #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. +-#: src/gs-safety-context-dialog.c:345 ++#: src/gs-safety-context-dialog.c:352 + msgid "Auditable Code" + msgstr "otevřený kód" + +-#: src/gs-safety-context-dialog.c:346 ++#: src/gs-safety-context-dialog.c:353 + msgid "" + "The source code is public and can be independently audited, which makes the " + "app more likely to be safe" +@@ -3701,21 +3763,21 @@ msgstr "" + + #. Translators: This indicates an app was written and released by a developer who has been verified. + #. * It’s used in a context tile, so should be short. +-#: src/gs-safety-context-dialog.c:354 ++#: src/gs-safety-context-dialog.c:361 + msgid "App developer is verified" + msgstr "Vývojář aplikace je ověřený" + +-#: src/gs-safety-context-dialog.c:355 ++#: src/gs-safety-context-dialog.c:362 + msgid "The developer of this app has been verified to be who they say they are" + msgstr "Bylo ověřeno, že vývojář této aplikace je tím, za koho se vydává" + + #. Translators: This indicates an app uses an outdated SDK. + #. * It’s used in a context tile, so should be short. +-#: src/gs-safety-context-dialog.c:366 ++#: src/gs-safety-context-dialog.c:373 + msgid "Insecure Dependencies" + msgstr "Bezpečnostní rizika v závislostech" + +-#: src/gs-safety-context-dialog.c:367 ++#: src/gs-safety-context-dialog.c:374 + msgid "" + "Software or its dependencies are no longer supported and may be insecure" + msgstr "" +@@ -3724,21 +3786,21 @@ msgstr "" + + #. Translators: The app is considered safe to install and run. + #. * The placeholder is the app name. +-#: src/gs-safety-context-dialog.c:376 ++#: src/gs-safety-context-dialog.c:383 + #, c-format + msgid "%s is safe" + msgstr "Aplikace %s je bezpečná" + + #. Translators: The app is considered potentially unsafe to install and run. + #. * The placeholder is the app name. +-#: src/gs-safety-context-dialog.c:383 ++#: src/gs-safety-context-dialog.c:390 + #, c-format + msgid "%s is potentially unsafe" + msgstr "Aplikace %s je potenciálně nebezpečná" + + #. Translators: The app is considered unsafe to install and run. + #. * The placeholder is the app name. +-#: src/gs-safety-context-dialog.c:390 ++#: src/gs-safety-context-dialog.c:397 + #, c-format + msgid "%s is unsafe" + msgstr "Aplikace %s je nebezpečná" +@@ -3775,42 +3837,43 @@ msgstr "Předchozí snímek obrazovky" + msgid "Next Screenshot" + msgstr "Následující snímek obrazovky" + +-#: src/gs-screenshot-carousel.ui:127 +-msgid "No screenshot provided" +-msgstr "Nemá snímek obrazovky" ++#. Translators: Shortened form of “no screenshots available” when showing an app’s details. ++#: src/gs-screenshot-carousel.ui:130 ++msgid "No Screenshots" ++msgstr "Žádné snímky obrazovky" + + #. TRANSLATORS: this is when we try to download a screenshot and + #. * we get back 404 +-#: src/gs-screenshot-image.c:362 src/gs-screenshot-image.c:419 +-#: src/gs-screenshot-image.c:623 ++#: src/gs-screenshot-image.c:359 src/gs-screenshot-image.c:416 ++#: src/gs-screenshot-image.c:620 + msgid "Screenshot not found" + msgstr "Snímek nebyl nalezen" + + #. TRANSLATORS: possibly image file corrupt or not an image +-#: src/gs-screenshot-image.c:438 ++#: src/gs-screenshot-image.c:435 + msgid "Failed to load image" + msgstr "Selhalo načtení obrázku" + + #. TRANSLATORS: this is when we request a screenshot size that + #. * the generator did not create or the parser did not add +-#: src/gs-screenshot-image.c:651 ++#: src/gs-screenshot-image.c:648 + msgid "Screenshot size not found" + msgstr "Velikost snímku nebyla nalezena" + + #. TRANSLATORS: this is when we try create the cache directory + #. * but we were out of space or permission was denied +-#: src/gs-screenshot-image.c:733 ++#: src/gs-screenshot-image.c:730 + msgid "Could not create cache" + msgstr "Nelze vytvoři mezipaměť" + + #. TRANSLATORS: this is when we try to download a screenshot + #. * that was not a valid URL +-#: src/gs-screenshot-image.c:747 ++#: src/gs-screenshot-image.c:744 + msgid "Screenshot not valid" + msgstr "Snímek není platný" + + #. TRANSLATORS: this is when networking is not available +-#: src/gs-screenshot-image.c:797 ++#: src/gs-screenshot-image.c:794 + msgid "Screenshot not available" + msgstr "Snímek není k dispozici" + +@@ -3820,7 +3883,7 @@ msgstr "Snímek" + + #. TRANSLATORS: this is when there are too many search results + #. * to show in in the search page +-#: src/gs-search-page.c:180 ++#: src/gs-search-page.c:179 + #, c-format + msgid "%u more match" + msgid_plural "%u more matches" +@@ -3837,7 +3900,7 @@ msgid "Search for Apps" + msgstr "Hledat aplikace" + + #: src/gs-search-page.ui:46 +-msgid "No Application Found" ++msgid "No App Found" + msgstr "Žádná aplikace nebyla nalezena" + + #. TRANSLATORS: this is part of the in-app notification, +@@ -3848,33 +3911,33 @@ msgstr "Žádná aplikace nebyla nalezena" + #. TRANSLATORS: this is part of the in-app notification, + #. * where the %s is a multi-word localised app name + #. * e.g. 'Getting things GNOME!" +-#: src/gs-shell.c:1209 src/gs-shell.c:1214 src/gs-shell.c:1229 +-#: src/gs-shell.c:1233 ++#: src/gs-shell.c:1170 src/gs-shell.c:1175 src/gs-shell.c:1190 ++#: src/gs-shell.c:1194 + #, c-format + msgid "“%s”" + msgstr "„%s“" + + #. TRANSLATORS: failure text for the in-app notification, + #. * where the %s is the source (e.g. "alt.fedoraproject.org") +-#: src/gs-shell.c:1285 ++#: src/gs-shell.c:1246 + #, c-format + msgid "Unable to download firmware updates from %s" + msgstr "Nelze stáhnout aktualizace firmwaru z %s" + + #. TRANSLATORS: failure text for the in-app notification, + #. * where the %s is the source (e.g. "alt.fedoraproject.org") +-#: src/gs-shell.c:1291 ++#: src/gs-shell.c:1252 + #, c-format + msgid "Unable to download updates from %s" + msgstr "Nelze stáhnout aktualizace z %s" + + #. TRANSLATORS: failure text for the in-app notification +-#: src/gs-shell.c:1298 src/gs-shell.c:1338 ++#: src/gs-shell.c:1259 src/gs-shell.c:1300 + msgid "Unable to download updates" + msgstr "Nelze stáhnout aktualizace" + + #. TRANSLATORS: failure text for the in-app notification +-#: src/gs-shell.c:1303 ++#: src/gs-shell.c:1264 + msgid "" + "Unable to download updates: internet access was required but wasn’t available" + msgstr "" +@@ -3883,124 +3946,124 @@ msgstr "" + + #. TRANSLATORS: failure text for the in-app notification, + #. * where the %s is the source (e.g. "alt.fedoraproject.org") +-#: src/gs-shell.c:1311 ++#: src/gs-shell.c:1272 + #, c-format + msgid "Unable to download updates from %s: not enough disk space" + msgstr "Nelze stáhnout aktualizace z %s: není dostatek místa na disku" + + #. TRANSLATORS: failure text for the in-app notification +-#: src/gs-shell.c:1316 ++#: src/gs-shell.c:1277 + msgid "Unable to download updates: not enough disk space" + msgstr "Nelze stáhnout aktualizace: není dostatek místa na disku" + + #. TRANSLATORS: failure text for the in-app notification +-#: src/gs-shell.c:1322 ++#: src/gs-shell.c:1283 + msgid "Unable to download updates: authentication was required" + msgstr "Nelze stáhnout aktualizace: je vyžadováno ověření" + + #. TRANSLATORS: failure text for the in-app notification +-#: src/gs-shell.c:1326 ++#: src/gs-shell.c:1287 + msgid "Unable to download updates: authentication was invalid" + msgstr "Nelze stáhnout aktualizace: ověření nebylo platné" + + #. TRANSLATORS: failure text for the in-app notification +-#: src/gs-shell.c:1330 ++#: src/gs-shell.c:1291 + msgid "" + "Unable to download updates: you do not have permission to install software" + msgstr "Nelze stáhnout aktualizace: nemáte oprávnění instalovat software" + + #. TRANSLATORS: failure text for the in-app notification +-#: src/gs-shell.c:1341 ++#: src/gs-shell.c:1303 + msgid "Unable to get list of updates" + msgstr "Nelze získat seznam aktualizací" + + #. TRANSLATORS: failure text for the in-app notification, +-#. * where the first %s is the application name (e.g. "GIMP") and ++#. * where the first %s is the app name (e.g. "GIMP") and + #. * the second %s is the origin, e.g. "Fedora Project [fedoraproject.org]" +-#: src/gs-shell.c:1377 ++#: src/gs-shell.c:1339 + #, c-format + msgid "Unable to install %s as download failed from %s" + msgstr "Nelze nainstalovat balíček %s, protože selhalo jeho stažení z %s" + + #. TRANSLATORS: failure text for the in-app notification, +-#. * where the %s is the application name (e.g. "GIMP") +-#: src/gs-shell.c:1383 ++#. * where the %s is the app name (e.g. "GIMP") ++#: src/gs-shell.c:1345 + #, c-format + msgid "Unable to install %s as download failed" + msgstr "Nelze nainstalovat balíček %s, protože selhalo stažení" + + #. TRANSLATORS: failure text for the in-app notification, +-#. * where the first %s is the application name (e.g. "GIMP") ++#. * where the first %s is the app name (e.g. "GIMP") + #. * and the second %s is the name of the runtime, e.g. + #. * "GNOME SDK [flatpak.gnome.org]" +-#: src/gs-shell.c:1395 ++#: src/gs-shell.c:1357 + #, c-format + msgid "Unable to install %s as runtime %s not available" + msgstr "" + "Nelze nainstalovat balíček %s, protože není k dispozici běhové prostředí %s" + + #. TRANSLATORS: failure text for the in-app notification, +-#. * where the %s is the application name (e.g. "GIMP") +-#: src/gs-shell.c:1401 ++#. * where the %s is the app name (e.g. "GIMP") ++#: src/gs-shell.c:1363 + #, c-format + msgid "Unable to install %s as not supported" + msgstr "Nelze nainstalovat balíček %s, protože není podporovaný" + + #. TRANSLATORS: failure text for the in-app notification +-#: src/gs-shell.c:1407 ++#: src/gs-shell.c:1369 + msgid "Unable to install: internet access was required but wasn’t available" + msgstr "" + "Nelze nainstalovat: přístup k internetu je nezbytný, ale není k dispozici" + + #. TRANSLATORS: failure text for the in-app notification +-#: src/gs-shell.c:1412 +-msgid "Unable to install: the application has an invalid format" ++#: src/gs-shell.c:1374 ++msgid "Unable to install: the app has an invalid format" + msgstr "Nelze nainstalovat: aplikace má neplatný formát" + + #. TRANSLATORS: failure text for the in-app notification, +-#. * where the %s is the application name (e.g. "GIMP") +-#: src/gs-shell.c:1416 ++#. * where the %s is the app name (e.g. "GIMP") ++#: src/gs-shell.c:1378 + #, c-format + msgid "Unable to install %s: not enough disk space" + msgstr "Nelze nainstalovat balíček %s: není dostatek místa na disku" + + #. TRANSLATORS: failure text for the in-app notification +-#: src/gs-shell.c:1422 ++#: src/gs-shell.c:1384 + #, c-format + msgid "Unable to install %s: authentication was required" + msgstr "Nelze nainstalovat balíček %s: je vyžadováno ověření" + + #. TRANSLATORS: failure text for the in-app notification, +-#. * where the %s is the application name (e.g. "GIMP") +-#: src/gs-shell.c:1428 ++#. * where the %s is the app name (e.g. "GIMP") ++#: src/gs-shell.c:1390 + #, c-format + msgid "Unable to install %s: authentication was invalid" + msgstr "Nelze nainstalovat balíček %s: ověření nebylo platné" + + #. TRANSLATORS: failure text for the in-app notification, +-#. * where the %s is the application name (e.g. "GIMP") +-#: src/gs-shell.c:1434 ++#. * where the %s is the app name (e.g. "GIMP") ++#: src/gs-shell.c:1396 + #, c-format + msgid "Unable to install %s: you do not have permission to install software" + msgstr "Nelze nainstalovat balíček %s: nemáte oprávnění k instalaci softwaru" + + #. TRANSLATORS: failure text for the in-app notification, +-#. * where the %s is the application name (e.g. "Dell XPS 13") +-#: src/gs-shell.c:1441 ++#. * where the %s is the app name (e.g. "Dell XPS 13") ++#: src/gs-shell.c:1403 + #, c-format + msgid "Unable to install %s: AC power is required" + msgstr "Nelze nainstalovat balíček %s: je vyžadováno připojené napájení" + + #. TRANSLATORS: failure text for the in-app notification, +-#. * where the %s is the application name (e.g. "Dell XPS 13") +-#: src/gs-shell.c:1447 ++#. * where the %s is the app name (e.g. "Dell XPS 13") ++#: src/gs-shell.c:1409 + #, c-format + msgid "Unable to install %s: The battery level is too low" + msgstr "Nelze nainstalovat balíček %s: úroveň nabití baterie je příliš nízká" + + #. TRANSLATORS: failure text for the in-app notification, +-#. * where the %s is the application name (e.g. "GIMP") +-#: src/gs-shell.c:1456 ++#. * where the %s is the app name (e.g. "GIMP") ++#: src/gs-shell.c:1418 + #, c-format + msgid "Unable to install %s" + msgstr "Nelze nainstalovat balíček %s" +@@ -4009,14 +4072,14 @@ msgstr "Nelze nainstalovat balíček %s" + #. * where the first %s is the app name (e.g. "GIMP") and + #. * the second %s is the origin, e.g. "Fedora" or + #. * "Fedora Project [fedoraproject.org]" +-#: src/gs-shell.c:1495 ++#: src/gs-shell.c:1457 + #, c-format + msgid "Unable to update %s from %s as download failed" + msgstr "Nelze aktualizovat balíček %s z %s, protože selhalo stažení" + + #. TRANSLATORS: failure text for the in-app notification, +-#. * where the %s is the application name (e.g. "GIMP") +-#: src/gs-shell.c:1502 ++#. * where the %s is the app name (e.g. "GIMP") ++#: src/gs-shell.c:1464 + #, c-format + msgid "Unable to update %s as download failed" + msgstr "Nelze aktualizovat balíček %s, protože selhalo stažení" +@@ -4024,71 +4087,71 @@ msgstr "Nelze aktualizovat balíček %s, protože selhalo stažení" + #. TRANSLATORS: failure text for the in-app notification, + #. * where the %s is the origin, e.g. "Fedora" or + #. * "Fedora Project [fedoraproject.org]" +-#: src/gs-shell.c:1509 ++#: src/gs-shell.c:1471 + #, c-format + msgid "Unable to install updates from %s as download failed" + msgstr "Nelze nainstalovat aktualizace z %s, protože selhalo stažení" + + #. TRANSLATORS: failure text for the in-app notification +-#: src/gs-shell.c:1513 ++#: src/gs-shell.c:1475 + #, c-format + msgid "Unable to install updates as download failed" + msgstr "Nelze nainstalovat aktualizace, protože selhalo stažení" + + #. TRANSLATORS: failure text for the in-app notification +-#: src/gs-shell.c:1518 ++#: src/gs-shell.c:1480 + msgid "Unable to update: internet access was required but wasn’t available" + msgstr "" + "Nelze aktualizovat: přístup k internetu je nezbytný, ale není k dispozici" + + #. TRANSLATORS: failure text for the in-app notification, +-#. * where the %s is the application name (e.g. "GIMP") +-#: src/gs-shell.c:1527 ++#. * where the %s is the app name (e.g. "GIMP") ++#: src/gs-shell.c:1489 + #, c-format + msgid "Unable to update %s: not enough disk space" + msgstr "Nelze aktualizovat balíček %s: nedostatek místa na disku" + + #. TRANSLATORS: failure text for the in-app notification +-#: src/gs-shell.c:1532 ++#: src/gs-shell.c:1494 + #, c-format + msgid "Unable to install updates: not enough disk space" + msgstr "Nelze nainstalovat aktualizace: nedostatek místa na disku" + + #. TRANSLATORS: failure text for the in-app notification, +-#. * where the %s is the application name (e.g. "GIMP") +-#: src/gs-shell.c:1541 ++#. * where the %s is the app name (e.g. "GIMP") ++#: src/gs-shell.c:1503 + #, c-format + msgid "Unable to update %s: authentication was required" + msgstr "Nelze aktualizovat balíček %s: je vyžadováno ověření" + + #. TRANSLATORS: failure text for the in-app notification +-#: src/gs-shell.c:1546 ++#: src/gs-shell.c:1508 + #, c-format + msgid "Unable to install updates: authentication was required" + msgstr "Nelze nainstalovat aktualizace: je vyžadováno ověření" + + #. TRANSLATORS: failure text for the in-app notification, +-#. * where the %s is the application name (e.g. "GIMP") +-#: src/gs-shell.c:1554 ++#. * where the %s is the app name (e.g. "GIMP") ++#: src/gs-shell.c:1516 + #, c-format + msgid "Unable to update %s: authentication was invalid" + msgstr "Nelze aktualizovat balíček %s: ověření bylo neplatné" + + #. TRANSLATORS: failure text for the in-app notification +-#: src/gs-shell.c:1559 ++#: src/gs-shell.c:1521 + #, c-format + msgid "Unable to install updates: authentication was invalid" + msgstr "Nelze nainstalovat aktualizace: ověření bylo neplatné" + + #. TRANSLATORS: failure text for the in-app notification, +-#. * where the %s is the application name (e.g. "GIMP") +-#: src/gs-shell.c:1567 ++#. * where the %s is the app name (e.g. "GIMP") ++#: src/gs-shell.c:1529 + #, c-format + msgid "Unable to update %s: you do not have permission to update software" + msgstr "Nelze aktualizovat balíček %s: nemáte oprávnění k aktualizaci softwaru" + + #. TRANSLATORS: failure text for the in-app notification +-#: src/gs-shell.c:1573 ++#: src/gs-shell.c:1535 + #, c-format + msgid "" + "Unable to install updates: you do not have permission to update software" +@@ -4096,44 +4159,44 @@ msgstr "" + "Nelze nainstalovat aktualizace: nemáte oprávnění k aktualizaci softwaru" + + #. TRANSLATORS: failure text for the in-app notification, +-#. * where the %s is the application name (e.g. "Dell XPS 13") +-#: src/gs-shell.c:1582 ++#. * where the %s is the app name (e.g. "Dell XPS 13") ++#: src/gs-shell.c:1544 + #, c-format + msgid "Unable to update %s: AC power is required" + msgstr "" + "Nelze aktualizovat balíček %s: je vyžadováno napájení z elektrické sítě" + + #. TRANSLATORS: failure text for the in-app notification, +-#. * where the %s is the application name (e.g. "Dell XPS 13") +-#: src/gs-shell.c:1588 ++#. * where the %s is the app name (e.g. "Dell XPS 13") ++#: src/gs-shell.c:1550 + #, c-format + msgid "Unable to install updates: AC power is required" + msgstr "" + "Nelze nainstalovat aktualizace: je vyžadováno napájení z elektrické sítě" + + #. TRANSLATORS: failure text for the in-app notification, +-#. * where the %s is the application name (e.g. "Dell XPS 13") +-#: src/gs-shell.c:1596 ++#. * where the %s is the app name (e.g. "Dell XPS 13") ++#: src/gs-shell.c:1558 + #, c-format + msgid "Unable to update %s: The battery level is too low" + msgstr "Nelze aktualizovat balíček %s: úroveň nabití baterie je příliš nízká" + + #. TRANSLATORS: failure text for the in-app notification, +-#. * where the %s is the application name (e.g. "Dell XPS 13") +-#: src/gs-shell.c:1602 ++#. * where the %s is the app name (e.g. "Dell XPS 13") ++#: src/gs-shell.c:1564 + #, c-format + msgid "Unable to install updates: The battery level is too low" + msgstr "Nelze nainstalovat aktualizace: úroveň nabití baterie je příliš nízká" + + #. TRANSLATORS: failure text for the in-app notification, +-#. * where the %s is the application name (e.g. "GIMP") +-#: src/gs-shell.c:1613 ++#. * where the %s is the app name (e.g. "GIMP") ++#: src/gs-shell.c:1575 + #, c-format + msgid "Unable to update %s" + msgstr "Nelze aktualizovat balíček %s" + + #. TRANSLATORS: failure text for the in-app notification +-#: src/gs-shell.c:1616 ++#: src/gs-shell.c:1578 + #, c-format + msgid "Unable to install updates" + msgstr "Nelze nainstalovat aktualizace" +@@ -4141,21 +4204,21 @@ msgstr "Nelze nainstalovat aktualizace" + #. TRANSLATORS: failure text for the in-app notification, + #. * where the first %s is the distro name (e.g. "Fedora 25") and + #. * the second %s is the origin, e.g. "Fedora Project [fedoraproject.org]" +-#: src/gs-shell.c:1652 ++#: src/gs-shell.c:1614 + #, c-format + msgid "Unable to upgrade to %s from %s" + msgstr "Nelze povýšit na %s z %s" + + #. TRANSLATORS: failure text for the in-app notification, + #. * where the %s is the app name (e.g. "GIMP") +-#: src/gs-shell.c:1657 ++#: src/gs-shell.c:1619 + #, c-format + msgid "Unable to upgrade to %s as download failed" + msgstr "Nelze povýšit na %s, protože selhalo stažení" + + #. TRANSLATORS: failure text for the in-app notification, + #. * where the %s is the distro name (e.g. "Fedora 25") +-#: src/gs-shell.c:1665 ++#: src/gs-shell.c:1627 + #, c-format + msgid "" + "Unable to upgrade to %s: internet access was required but wasn’t available" +@@ -4165,159 +4228,159 @@ msgstr "" + + #. TRANSLATORS: failure text for the in-app notification, + #. * where the %s is the distro name (e.g. "Fedora 25") +-#: src/gs-shell.c:1673 ++#: src/gs-shell.c:1635 + #, c-format + msgid "Unable to upgrade to %s: not enough disk space" + msgstr "Nelze povýšit na %s: není dostatek místa na disku" + + #. TRANSLATORS: failure text for the in-app notification, + #. * where the %s is the distro name (e.g. "Fedora 25") +-#: src/gs-shell.c:1680 ++#: src/gs-shell.c:1642 + #, c-format + msgid "Unable to upgrade to %s: authentication was required" + msgstr "Nelze povýšit na %s: je vyžadováno ověření" + + #. TRANSLATORS: failure text for the in-app notification, + #. * where the %s is the distro name (e.g. "Fedora 25") +-#: src/gs-shell.c:1686 ++#: src/gs-shell.c:1648 + #, c-format + msgid "Unable to upgrade to %s: authentication was invalid" + msgstr "Nelze povýšit na %s: ověření nebylo platné" + + #. TRANSLATORS: failure text for the in-app notification, + #. * where the %s is the distro name (e.g. "Fedora 25") +-#: src/gs-shell.c:1692 ++#: src/gs-shell.c:1654 + #, c-format + msgid "Unable to upgrade to %s: you do not have permission to upgrade" + msgstr "Nelze povýšit na %s: nemáte oprávnění k povyšování" + + #. TRANSLATORS: failure text for the in-app notification, + #. * where the %s is the distro name (e.g. "Fedora 25") +-#: src/gs-shell.c:1698 ++#: src/gs-shell.c:1660 + #, c-format + msgid "Unable to upgrade to %s: AC power is required" + msgstr "Nelze povýšit na %s: je vyžadováno připojené napájení" + + #. TRANSLATORS: failure text for the in-app notification, + #. * where the %s is the distro name (e.g. "Fedora 25") +-#: src/gs-shell.c:1704 ++#: src/gs-shell.c:1666 + #, c-format + msgid "Unable to upgrade to %s: The battery level is too low" + msgstr "Nelze povýšit na %s: úroveň nabití baterie je příliš nízká" + + #. TRANSLATORS: failure text for the in-app notification, + #. * where the %s is the distro name (e.g. "Fedora 25") +-#: src/gs-shell.c:1713 ++#: src/gs-shell.c:1675 + #, c-format + msgid "Unable to upgrade to %s" + msgstr "Nelze povýšit na %s" + + #. TRANSLATORS: failure text for the in-app notification, +-#. * where the %s is the application name (e.g. "GIMP") +-#: src/gs-shell.c:1744 ++#. * where the %s is the app name (e.g. "GIMP") ++#: src/gs-shell.c:1706 + #, c-format + msgid "Unable to remove %s: authentication was required" + msgstr "Nelze odstranit balíček %s: je vyžadováno ověření" + + #. TRANSLATORS: failure text for the in-app notification, +-#. * where the %s is the application name (e.g. "GIMP") +-#: src/gs-shell.c:1749 ++#. * where the %s is the app name (e.g. "GIMP") ++#: src/gs-shell.c:1711 + #, c-format + msgid "Unable to remove %s: authentication was invalid" + msgstr "Nelze odstranit balíček %s: ověření nebylo platné" + + #. TRANSLATORS: failure text for the in-app notification, +-#. * where the %s is the application name (e.g. "GIMP") +-#: src/gs-shell.c:1754 ++#. * where the %s is the app name (e.g. "GIMP") ++#: src/gs-shell.c:1716 + #, c-format + msgid "Unable to remove %s: you do not have permission to remove software" + msgstr "Nelze odstranit balíček %s: nemáte oprávnění k odstranění softwaru" + + #. TRANSLATORS: failure text for the in-app notification, +-#. * where the %s is the application name (e.g. "GIMP") +-#: src/gs-shell.c:1760 ++#. * where the %s is the app name (e.g. "GIMP") ++#: src/gs-shell.c:1722 + #, c-format + msgid "Unable to remove %s: AC power is required" + msgstr "Nelze odstranit balíček %s: je vyžadováno připojené napájení" + + #. TRANSLATORS: failure text for the in-app notification, +-#. * where the %s is the application name (e.g. "GIMP") +-#: src/gs-shell.c:1766 ++#. * where the %s is the app name (e.g. "GIMP") ++#: src/gs-shell.c:1728 + #, c-format + msgid "Unable to remove %s: The battery level is too low" + msgstr "Nelze odstranit balíček %s: úroveň nabití baterie je příliš nízká" + + #. TRANSLATORS: failure text for the in-app notification, +-#. * where the %s is the application name (e.g. "GIMP") +-#: src/gs-shell.c:1778 ++#. * where the %s is the app name (e.g. "GIMP") ++#: src/gs-shell.c:1740 + #, c-format + msgid "Unable to remove %s" + msgstr "Nelze odstranit balíček %s" + + #. TRANSLATORS: failure text for the in-app notification, +-#. * where the first %s is the application name (e.g. "GIMP") ++#. * where the first %s is the app name (e.g. "GIMP") + #. * and the second %s is the name of the runtime, e.g. + #. * "GNOME SDK [flatpak.gnome.org]" +-#: src/gs-shell.c:1813 ++#: src/gs-shell.c:1775 + #, c-format + msgid "Unable to launch %s: %s is not installed" + msgstr "Nelze spustit aplikaci %s: balíček %s není nainstalovaný" + + #. TRANSLATORS: we failed to get a proper error code +-#: src/gs-shell.c:1821 src/gs-shell.c:1837 src/gs-shell.c:1879 +-#: src/gs-shell.c:1921 src/gs-shell.c:1978 ++#: src/gs-shell.c:1783 src/gs-shell.c:1799 src/gs-shell.c:1841 ++#: src/gs-shell.c:1883 src/gs-shell.c:1940 + msgid "Sorry, something went wrong" + msgstr "Litujeme, ale něco se stalo špatně" + + #. TRANSLATORS: failure text for the in-app notification +-#: src/gs-shell.c:1826 src/gs-shell.c:1868 src/gs-shell.c:1910 +-#: src/gs-shell.c:1957 ++#: src/gs-shell.c:1788 src/gs-shell.c:1830 src/gs-shell.c:1872 ++#: src/gs-shell.c:1919 + msgid "Not enough disk space — free up some space and try again" + msgstr "" + "Nebyl dostatek místa na disku – uvolněte nějaké místo a pak to zkuste znovu" + + #. TRANSLATORS: failure text for the in-app notification +-#: src/gs-shell.c:1862 ++#: src/gs-shell.c:1824 + msgid "Failed to install file: not supported" + msgstr "Selhala instalace souboru: není podporován" + + #. TRANSLATORS: failure text for the in-app notification +-#: src/gs-shell.c:1865 ++#: src/gs-shell.c:1827 + msgid "Failed to install file: authentication failed" + msgstr "Selhala instalace souboru: selhalo ověření" + + #. TRANSLATORS: failure text for the in-app notification +-#: src/gs-shell.c:1904 ++#: src/gs-shell.c:1866 + msgid "Failed to install: not supported" + msgstr "Selhala instalace: není podporováno" + + #. TRANSLATORS: failure text for the in-app notification +-#: src/gs-shell.c:1907 ++#: src/gs-shell.c:1869 + msgid "Failed to install: authentication failed" + msgstr "Selhala instalace: selhalo ověření" + + #. TRANSLATORS: failure text for the in-app notification, + #. * the %s is the origin, e.g. "Fedora" or + #. * "Fedora Project [fedoraproject.org]" +-#: src/gs-shell.c:1952 ++#: src/gs-shell.c:1914 + #, c-format + msgid "Unable to contact %s" + msgstr "Nelze kontaktovat %s" + +-#. TRANSLATORS: failure text for the in-app notification, where the 'Software' means this application, aka 'GNOME Software'. +-#: src/gs-shell.c:1962 ++#. TRANSLATORS: failure text for the in-app notification, where the 'Software' means this app, aka 'GNOME Software'. ++#: src/gs-shell.c:1924 + msgid "Software needs to be restarted to use new plugins." + msgstr "" + "Aplikace Software musí být restartována, aby mohla používat nový zásuvný " + "modul." + + #. TRANSLATORS: need to be connected to the AC power +-#: src/gs-shell.c:1966 ++#: src/gs-shell.c:1928 + msgid "AC power is required" + msgstr "Je vyžadováno připojené napájení" + + #. TRANSLATORS: not enough juice to do this safely +-#: src/gs-shell.c:1969 ++#: src/gs-shell.c:1931 + msgid "The battery level is too low" + msgstr "Úroveň nabití baterie je příliš nízká" + +@@ -4326,48 +4389,65 @@ msgid "_Software Repositories" + msgstr "_Softwarové repozitáře" + + #: src/gs-shell.ui:12 +-msgid "_Update Preferences" +-msgstr "Předvolby akt_ualizací" ++msgid "_Preferences" ++msgstr "_Předvolby" + + #. button in the info bar +-#: src/gs-shell.ui:98 ++#: src/gs-shell.ui:109 + msgid "Examine Disk" + msgstr "Prozkoumat disk" + + #. button in the info bar +-#. TRANSLATORS: this is a link to the +-#. * control-center network panel +-#: src/gs-shell.ui:108 src/gs-updates-page.c:885 ++#: src/gs-shell.ui:119 + msgid "Network Settings" + msgstr "Nastavení sítě" + + #. button in the info bar +-#: src/gs-shell.ui:118 +-msgid "Restart Now" +-msgstr "Restartovat hned" ++#: src/gs-shell.ui:129 ++msgid "_Restart Now…" ++msgstr "_Restartovat hned…" + + #. button in the info bar +-#: src/gs-shell.ui:128 ++#: src/gs-shell.ui:140 + msgid "More Information" + msgstr "Další informace" + +-#: src/gs-shell.ui:188 src/gs-shell.ui:190 ++#: src/gs-shell.ui:200 src/gs-shell.ui:202 + msgid "Search" + msgstr "Hledat" + +-#: src/gs-shell.ui:204 src/gs-shell.ui:206 +-msgid "Primary Menu" +-msgstr "Hlavní nabídky" ++#: src/gs-shell.ui:216 src/gs-shell.ui:218 ++msgid "Main Menu" ++msgstr "Hlavní nabídka" ++ ++#: src/gs-shell.ui:245 ++msgid "Search apps" ++msgstr "Hledat aplikace" ++ ++#: src/gs-shell.ui:257 ++msgid "Metered network ‒ automatic updates paused" ++msgstr "Měřená síť – automatické aktualizace jsou pozastaveny" + +-#: src/gs-shell.ui:276 ++#: src/gs-shell.ui:258 + msgid "Find Out _More" + msgstr "Dozvědět se _více…" + ++#. Translators: A label for a button to show all available software. ++#: src/gs-shell.ui:272 ++msgid "_Explore" ++msgstr "_Procházet" ++ ++#. Translators: A label for a button to show only software which is already installed. ++#: src/gs-shell.ui:286 ++msgctxt "List of installed apps" ++msgid "_Installed" ++msgstr "Na_instalováno" ++ + #. Translators: A label for a button to show only updates which are available to install. +-#: src/gs-shell.ui:330 ++#: src/gs-shell.ui:308 + msgctxt "Header bar button for list of apps to be updated" +-msgid "Updates" +-msgstr "Aktualizace" ++msgid "_Updates" ++msgstr "_Aktualizace" + + #. Translators: This is shown in a bubble to represent a 0 byte + #. * storage size, so its context is “storage size: none”. The +@@ -4378,11 +4458,11 @@ msgid "None" + msgstr "Žádná" + + #: src/gs-storage-context-dialog.c:139 +-msgid "Application Data" ++msgid "App Data" + msgstr "Data aplikace" + + #: src/gs-storage-context-dialog.c:140 +-msgid "Data needed for the application to run" ++msgid "Data needed for the app to run" + msgstr "Data potřebná ke spuštění aplikace" + + #: src/gs-storage-context-dialog.c:145 +@@ -4390,7 +4470,7 @@ msgid "User Data" + msgstr "Uživatelská data" + + #: src/gs-storage-context-dialog.c:146 +-msgid "Data created by you in the application" ++msgid "Data created by you in the app" + msgstr "Vámi vytvořená data v aplikaci" + + #: src/gs-storage-context-dialog.c:153 +@@ -4402,7 +4482,7 @@ msgid "Temporary cached data" + msgstr "Dočasná data v mezipaměti" + + #: src/gs-storage-context-dialog.c:172 +-msgid "The application itself" ++msgid "The app itself" + msgstr "Aplikace samotná" + + #: src/gs-storage-context-dialog.c:177 +@@ -4410,7 +4490,7 @@ msgid "Required Dependencies" + msgstr "Vyžadované závislosti" + + #: src/gs-storage-context-dialog.c:178 +-msgid "Shared system components required by this application" ++msgid "Shared system components required by this app" + msgstr "Sdílené systémové komponenty vyžadované touto aplikací" + + #: src/gs-storage-context-dialog.c:188 +@@ -4426,23 +4506,22 @@ msgstr "Úložiště" + #. Translators: Please do not translate the markup or link href + #: src/gs-storage-context-dialog.ui:69 + msgid "" +-"Cached data can be cleared from the _application settings." ++"Cached data can be cleared from the _app settings." + msgstr "" + "Data uložená v mezipaměti lze vymazat v _nastavení " + "aplikace." + +-#: src/gs-summary-tile.c:118 ++#: src/gs-summary-tile.c:139 + #, c-format + msgid "%s (Installed)" + msgstr "%s (nainstalováno)" + +-#: src/gs-summary-tile.c:123 ++#: src/gs-summary-tile.c:144 + #, c-format + msgid "%s (Installing)" + msgstr "%s (instaluje se)" + +-#: src/gs-summary-tile.c:128 ++#: src/gs-summary-tile.c:149 + #, c-format + msgid "%s (Removing)" + msgstr "%s (odebírá se)" +@@ -4508,8 +4587,8 @@ msgstr "Stáhněte prosím čekající aktualizace softwaru." + #. TRANSLATORS: apps were auto-updated and restart is required + #: src/gs-update-monitor.c:355 + #, c-format +-msgid "%u Application Updated — Restart Required" +-msgid_plural "%u Applications Updated — Restart Required" ++msgid "%u App Updated — Restart Required" ++msgid_plural "%u Apps Updated — Restart Required" + msgstr[0] "Byla aktualizována %u aplikace — vyžaduje restart" + msgstr[1] "Byly aktualizovány %u aplikace — vyžaduje restart" + msgstr[2] "Bylo aktualizováno %u aplikací — vyžaduje restart" +@@ -4517,13 +4596,13 @@ msgstr[2] "Bylo aktualizováno %u aplikací — vyžaduje restart" + #. TRANSLATORS: apps were auto-updated + #: src/gs-update-monitor.c:361 + #, c-format +-msgid "%u Application Updated" +-msgid_plural "%u Applications Updated" ++msgid "%u App Updated" ++msgid_plural "%u Apps Updated" + msgstr[0] "Byla aktualizována %u aplikace" + msgstr[1] "Byly aktualizovány %u aplikace" + msgstr[2] "Bylo aktualizováno %u aplikací" + +-#. TRANSLATORS: %1 is an application name, e.g. Firefox ++#. TRANSLATORS: %1 is an app name, e.g. Firefox + #: src/gs-update-monitor.c:372 + #, c-format + msgid "%s has been updated." +@@ -4531,81 +4610,81 @@ msgstr "Aplikace %s byla aktualizována." + + #. TRANSLATORS: the app needs restarting + #: src/gs-update-monitor.c:375 +-msgid "Please restart the application." ++msgid "Please restart the app." + msgstr "Restartujte ji prosím." + +-#. TRANSLATORS: %1 and %2 are both application names, e.g. Firefox ++#. TRANSLATORS: %1 and %2 are both app names, e.g. Firefox + #: src/gs-update-monitor.c:383 + #, c-format + msgid "%s and %s have been updated." + msgstr "Aplikace %s a %s byly aktualizovány." + +-#. TRANSLATORS: at least one application needs restarting ++#. TRANSLATORS: at least one app needs restarting + #: src/gs-update-monitor.c:389 src/gs-update-monitor.c:408 + #, c-format +-msgid "%u application requires a restart." +-msgid_plural "%u applications require a restart." ++msgid "%u app requires a restart." ++msgid_plural "%u apps require a restart." + msgstr[0] "%u aplikace vyžaduje restart." + msgstr[1] "%u aplikace vyžadují restart." + msgstr[2] "%u aplikací vyžaduje restart." + +-#. TRANSLATORS: %1, %2 and %3 are all application names, e.g. Firefox ++#. TRANSLATORS: %1, %2 and %3 are all app names, e.g. Firefox + #: src/gs-update-monitor.c:401 + #, c-format + msgid "Includes %s, %s and %s." + msgstr "Včetně %s, %s a %s." + + #. TRANSLATORS: this is when the current operating system version goes end-of-life +-#: src/gs-update-monitor.c:671 src/gs-updates-page.ui:20 ++#: src/gs-update-monitor.c:696 + msgid "Operating System Updates Unavailable" + msgstr "Aktualizace operačního systému nejsou dostupné" + + #. TRANSLATORS: this is the message dialog for the distro EOL notice +-#: src/gs-update-monitor.c:673 ++#: src/gs-update-monitor.c:698 + msgid "Upgrade to continue receiving security updates." + msgstr "Povýšit, aby byly nadále přijímány bezpečnostní aktualizace." + + #. TRANSLATORS: this is a distro upgrade, the replacement would be the + #. * distro name, e.g. 'Fedora' +-#: src/gs-update-monitor.c:728 ++#: src/gs-update-monitor.c:753 + #, c-format + msgid "A new version of %s is available to install" + msgstr "K instalaci je dostupná nová verze distribuce %s" + + #. TRANSLATORS: this is a distro upgrade +-#: src/gs-update-monitor.c:732 ++#: src/gs-update-monitor.c:757 + msgid "Software Upgrade Available" + msgstr "Dostupné povýšení softwaru" + + #. TRANSLATORS: title when we offline updates have failed +-#: src/gs-update-monitor.c:1137 ++#: src/gs-update-monitor.c:1162 + msgid "Software Updates Failed" + msgstr "Aktualizace softwaru selhaly" + + #. TRANSLATORS: message when we offline updates have failed +-#: src/gs-update-monitor.c:1139 ++#: src/gs-update-monitor.c:1164 + msgid "An important operating system update failed to be installed." + msgstr "Selhala instalace důležité aktualizace operačního systému." + +-#: src/gs-update-monitor.c:1140 ++#: src/gs-update-monitor.c:1165 + msgid "Show Details" + msgstr "Zobrazit podrobnosti" + + #. TRANSLATORS: Notification title when we've done a distro upgrade +-#: src/gs-update-monitor.c:1162 ++#: src/gs-update-monitor.c:1187 + msgid "System Upgrade Complete" + msgstr "Bylo dokončeno povýšení systému" + + #. TRANSLATORS: This is the notification body when we've done a + #. * distro upgrade. First %s is the distro name and the 2nd %s + #. * is the version, e.g. "Welcome to Fedora 28!" +-#: src/gs-update-monitor.c:1167 ++#: src/gs-update-monitor.c:1192 + #, c-format + msgid "Welcome to %s %s!" + msgstr "Vítejte ve vydání %s %s!" + + #. TRANSLATORS: title when we've done offline updates +-#: src/gs-update-monitor.c:1173 ++#: src/gs-update-monitor.c:1198 + msgid "Software Update Installed" + msgid_plural "Software Updates Installed" + msgstr[0] "Aktualizace softwaru nainstalována" +@@ -4613,7 +4692,7 @@ msgstr[1] "Aktualizace softwaru nainstalovány" + msgstr[2] "Aktualizace softwaru nainstalovány" + + #. TRANSLATORS: message when we've done offline updates +-#: src/gs-update-monitor.c:1177 ++#: src/gs-update-monitor.c:1202 + msgid "An important operating system update has been installed." + msgid_plural "Important operating system updates have been installed." + msgstr[0] "Byla nainstalována důležitá aktualizace operačního systému." +@@ -4621,34 +4700,34 @@ msgstr[1] "Byly nainstalovány důležité aktualizace operačního systému." + msgstr[2] "Byly nainstalovány důležité aktualizace operačního systému." + + #. TRANSLATORS: Button to look at the updates that were installed. +-#. * Note that it has nothing to do with the application reviews, the ++#. * Note that it has nothing to do with the app reviews, the + #. * users can't express their opinions here. In some languages + #. * "Review (evaluate) something" is a different translation than + #. * "Review (browse) something." +-#: src/gs-update-monitor.c:1188 ++#: src/gs-update-monitor.c:1213 + msgctxt "updates" + msgid "Review" + msgstr "Přehled" + + #. TRANSLATORS: this is when the offline update failed +-#: src/gs-update-monitor.c:1237 ++#: src/gs-update-monitor.c:1262 + msgid "Failed To Update" + msgstr "Aktualizace selhala" + + #. TRANSLATORS: the user must have updated manually after + #. * the updates were prepared +-#: src/gs-update-monitor.c:1242 ++#: src/gs-update-monitor.c:1267 + msgid "The system was already up to date." + msgstr "Systém již byl aktuální." + + #. TRANSLATORS: the user aborted the update manually +-#: src/gs-update-monitor.c:1247 ++#: src/gs-update-monitor.c:1272 + msgid "The update was cancelled." + msgstr "Aktualizace byla zrušena." + + #. TRANSLATORS: the package manager needed to download + #. * something with no network available +-#: src/gs-update-monitor.c:1252 ++#: src/gs-update-monitor.c:1277 + msgid "" + "Internet access was required but wasn’t available. Please make sure that you " + "have internet access and try again." +@@ -4657,7 +4736,7 @@ msgstr "" + "připojení k Internetu a zkuste to znovu." + + #. TRANSLATORS: if the package is not signed correctly +-#: src/gs-update-monitor.c:1257 ++#: src/gs-update-monitor.c:1282 + msgid "" + "There were security issues with the update. Please consult your software " + "provider for more details." +@@ -4666,7 +4745,7 @@ msgstr "" + "svým poskytovatelem softwaru." + + #. TRANSLATORS: we ran out of disk space +-#: src/gs-update-monitor.c:1262 ++#: src/gs-update-monitor.c:1287 + msgid "" + "There wasn’t enough disk space. Please free up some space and try again." + msgstr "" +@@ -4674,7 +4753,7 @@ msgstr "" + "znovu." + + #. TRANSLATORS: We didn't handle the error type +-#: src/gs-update-monitor.c:1266 ++#: src/gs-update-monitor.c:1291 + msgid "" + "We’re sorry: the update failed to install. Please wait for another update " + "and try again. If the problem persists, contact your software provider." +@@ -4684,49 +4763,39 @@ msgstr "" + "poskytovatele softwaru." + + #. TRANSLATORS: This is the time when we last checked for updates +-#: src/gs-updates-page.c:248 ++#: src/gs-updates-page.c:253 + #, c-format + msgid "Last checked: %s" + msgstr "Poslední kontrola: %s" + +-#: src/gs-updates-page.c:297 +-msgid "Stop Refreshing" +-msgstr "" ++#: src/gs-updates-page.c:302 ++msgid "Stop" ++msgstr "Zastavit" + +-#: src/gs-updates-page.c:306 src/gs-updates-page.c:318 +-msgid "Refresh" +-msgstr "" ++#: src/gs-updates-page.c:311 src/gs-updates-page.c:323 ++msgid "Check for Updates" ++msgstr "Zkontrolovat aktualizace" + + #. TRANSLATORS: the first %s is the distro name, e.g. 'Fedora' + #. * and the second %s is the distro version, e.g. '25' +-#: src/gs-updates-page.c:563 ++#: src/gs-updates-page.c:568 + #, c-format +-msgid "%s %s is no longer supported." +-msgstr "Systém %s %s již není podporován." +- +-#: src/gs-updates-page.c:567 +-msgid "Your operating system is no longer supported." +-msgstr "Váš operační systém není nadále podporován." +- +-#. TRANSLATORS: EOL distros do not get important updates +-#: src/gs-updates-page.c:572 +-msgid "This means that it does not receive security updates." +-msgstr "" +-"Znamená to, že pro něj již nadále nejsou poskytovány bezpečnostní opravy." ++msgid "%s %s has stopped receiving critical software updates" ++msgstr "Distribuce %s %s přestala dostávat kritické aktualizace softwaru" + +-#. TRANSLATORS: upgrade refers to a major update, e.g. Fedora 25 to 26 +-#: src/gs-updates-page.c:576 +-msgid "It is recommended that you upgrade to a more recent version." +-msgstr "Doporučuje se povýšit na nejnovější verzi." ++#. TRANSLATORS: This message is meant to tell users that they need to upgrade ++#. * or else their distro will not get important updates. ++#: src/gs-updates-page.c:574 ++msgid "Your operating system has stopped receiving critical software updates" ++msgstr "Váš operační systém přestal dostávat kritické aktualizace softwaru" + + #. TRANSLATORS: this is to explain that downloading updates may cost money +-#: src/gs-updates-page.c:853 ++#: src/gs-updates-page.c:843 + msgid "Charges May Apply" + msgstr "Možné zpoplatnění" + +-#. TRANSLATORS: we need network +-#. * to do the updates check +-#: src/gs-updates-page.c:857 ++#. TRANSLATORS: we need network to do the updates check ++#: src/gs-updates-page.c:845 + msgid "" + "Checking for updates while using mobile broadband could cause you to incur " + "charges." +@@ -4734,28 +4803,31 @@ msgstr "" + "Kontrola aktualizací přes mobilní připojení může být zpoplatněna vaším " + "operátorem." + +-#. TRANSLATORS: this is a link to the +-#. * control-center network panel +-#: src/gs-updates-page.c:861 ++#. TRANSLATORS: this is a link to the control-center network panel ++#: src/gs-updates-page.c:849 + msgid "Check _Anyway" + msgstr "_Přesto zkontrolovat" + + #. TRANSLATORS: can't do updates check +-#: src/gs-updates-page.c:877 ++#: src/gs-updates-page.c:860 + msgid "No Network" + msgstr "Žádné připojení k síti" + +-#. TRANSLATORS: we need network +-#. * to do the updates check +-#: src/gs-updates-page.c:881 ++#. TRANSLATORS: we need network to do the updates check ++#: src/gs-updates-page.c:862 + msgid "Internet access is required to check for updates." + msgstr "Přístup k internetu je nezbytný pro kontrolu aktualizací." + +-#: src/gs-updates-page.c:1254 ++#. TRANSLATORS: this is a link to the control-center network panel ++#: src/gs-updates-page.c:866 ++msgid "Network _Settings" ++msgstr "Nastavení _sítě" ++ ++#: src/gs-updates-page.c:1235 + msgid "Check for updates" + msgstr "Zkontrolovat aktualizace" + +-#: src/gs-updates-page.c:1290 ++#: src/gs-updates-page.c:1271 + msgctxt "Apps to be updated" + msgid "Updates" + msgstr "Aktualizace" +@@ -4765,25 +4837,25 @@ msgid "Updates page" + msgstr "Stránka s aktualizacemi" + + #. TRANSLATORS: the updates panel is starting up. +-#: src/gs-updates-page.ui:82 ++#: src/gs-updates-page.ui:58 + msgid "Loading Updates…" + msgstr "Načítají se aktualizace…" + + #. TRANSLATORS: the updates panel is starting up. +-#: src/gs-updates-page.ui:95 ++#: src/gs-updates-page.ui:71 + msgid "This could take a while." + msgstr "Může to chvilku trvat." + + #. TRANSLATORS: This means all software (plural) installed on this system is up to date. +-#: src/gs-updates-page.ui:203 ++#: src/gs-updates-page.ui:179 + msgid "Up to Date" + msgstr "Aktuální" + +-#: src/gs-updates-page.ui:242 ++#: src/gs-updates-page.ui:218 + msgid "Use Mobile Data?" + msgstr "Použít mobilní data?" + +-#: src/gs-updates-page.ui:243 ++#: src/gs-updates-page.ui:219 + msgid "" + "Checking for updates when using mobile broadband could cause you to incur " + "charges." +@@ -4791,68 +4863,68 @@ msgstr "" + "Kontrola aktualizací při používání mobilního širokopásmového připojení vám " + "může způsobit poplatky." + +-#: src/gs-updates-page.ui:246 ++#: src/gs-updates-page.ui:222 + msgid "_Check Anyway" + msgstr "_Přesto zkontrolovat" + +-#: src/gs-updates-page.ui:262 ++#: src/gs-updates-page.ui:238 + msgid "No Connection" + msgstr "Žádné připojení" + +-#: src/gs-updates-page.ui:263 ++#: src/gs-updates-page.ui:239 + msgid "Go online to check for updates." + msgstr "Kvůli kontrole aktualizací se musíte připojit k síti." + +-#: src/gs-updates-page.ui:266 ++#: src/gs-updates-page.ui:242 + msgid "_Network Settings" + msgstr "_Nastavení sítě" + +-#: src/gs-updates-page.ui:295 ++#: src/gs-updates-page.ui:275 + msgid "Error" + msgstr "Chyba" + +-#: src/gs-updates-page.ui:296 ++#: src/gs-updates-page.ui:276 + msgid "Updates are automatically managed." + msgstr "Aktualizace jsou spravovány automaticky." + + #. TRANSLATORS: This is the button for installing all + #. * offline updates +-#: src/gs-updates-section.c:312 +-msgid "Restart & Update" +-msgstr "Restartovat a aktualizovat" ++#: src/gs-updates-section.c:340 ++msgid "_Restart & Update…" ++msgstr "_Restartovat a aktualizovat…" + + #. TRANSLATORS: This is the button for upgrading all +-#. * online-updatable applications +-#: src/gs-updates-section.c:318 +-msgid "Update All" +-msgstr "Aktualizovat vše" ++#. * online-updatable apps ++#: src/gs-updates-section.c:346 ++msgid "U_pdate All" ++msgstr "_Aktualizovat vše" + + #. TRANSLATORS: This is the header for system firmware that + #. * requires a reboot to apply +-#: src/gs-updates-section.c:450 ++#: src/gs-updates-section.c:474 + msgid "Integrated Firmware" + msgstr "Integrovaný Firmware" + + #. TRANSLATORS: This is the header for offline OS and offline + #. * app updates that require a reboot to apply +-#: src/gs-updates-section.c:455 ++#: src/gs-updates-section.c:479 + msgid "Requires Restart" + msgstr "Vyžaduje restart" + + #. TRANSLATORS: This is the header for online runtime and + #. * app updates, typically flatpaks or snaps +-#: src/gs-updates-section.c:460 +-msgid "Application Updates" ++#: src/gs-updates-section.c:484 ++msgid "App Updates" + msgstr "Aktualizace aplikací" + + #. TRANSLATORS: This is the header for device firmware that can + #. * be installed online +-#: src/gs-updates-section.c:465 ++#: src/gs-updates-section.c:489 + msgid "Device Firmware" + msgstr "Firmware zařízení" + + #: src/gs-updates-section.ui:33 src/gs-upgrade-banner.ui:72 +-#: plugins/packagekit/gs-packagekit-task.c:155 ++#: plugins/packagekit/gs-packagekit-task.c:154 + msgid "_Download" + msgstr "S_táhnout" + +@@ -4899,8 +4971,8 @@ msgid "A major upgrade, with new features and added polish." + msgstr "Povýšení na novou verzi s novými funkcemi a vylepšeními." + + #: src/gs-upgrade-banner.ui:187 +-msgid "_Restart & Upgrade" +-msgstr "_Restartovat a aktualizovat" ++msgid "_Restart & Upgrade…" ++msgstr "_Restartovat a aktualizovat…" + + #: src/gs-upgrade-banner.ui:201 + msgid "Remember to back up data and files before upgrading." +@@ -4910,7 +4982,7 @@ msgstr "Nezapomeňte zazálohovat si před povýšením svá data a soubory." + msgid "Add, remove or update software on this computer" + msgstr "Přidat, odebrat nebo aktualizovat software v tomto počítači" + +-#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! ++#. Translators: Search terms to find this app. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! + #: src/org.gnome.Software.desktop.in:12 + msgid "" + "Updates;Upgrade;Sources;Repositories;Preferences;Install;Uninstall;Program;" +@@ -4922,14 +4994,14 @@ msgstr "" + #. TRANSLATORS: this is a group of updates that are not + #. * packages and are not shown in the main list + #: plugins/core/gs-plugin-generic-updates.c:67 +-#: plugins/rpm-ostree/gs-plugin-rpm-ostree.c:2975 ++#: plugins/rpm-ostree/gs-plugin-rpm-ostree.c:3049 + msgid "System Updates" + msgstr "Aktualizace systému" + + #. TRANSLATORS: this is a longer description of the + #. * "System Updates" string + #: plugins/core/gs-plugin-generic-updates.c:72 +-#: plugins/rpm-ostree/gs-plugin-rpm-ostree.c:2980 ++#: plugins/rpm-ostree/gs-plugin-rpm-ostree.c:3054 + msgid "" + "General system updates, such as security or bug fixes, and performance " + "improvements." +@@ -4943,21 +5015,19 @@ msgid "Downloading featured images…" + msgstr "Stahují se obrázky k významným aplikacím…" + + #. Translators: The '%s' is replaced with the OS name, like "Endless OS" +-#: plugins/eos-updater/gs-plugin-eos-updater.c:637 ++#: plugins/eos-updater/gs-plugin-eos-updater.c:684 + #, c-format + msgid "%s update with new features and fixes." + msgstr "Aktualizace %s s novými funkcemi a opravami." + +-#: plugins/eos-updater/gs-plugin-eos-updater.c:970 ++#: plugins/eos-updater/gs-plugin-eos-updater.c:1267 + msgid "EOS update service could not fetch and apply the update." + msgstr "Aktualizační služba EOS nemohla stáhnout a nasadit aktualizaci." + + #: plugins/epiphany/gs-plugin-epiphany.c:499 + #: plugins/epiphany/gs-plugin-epiphany.c:503 +-#, fuzzy +-#| msgid "Web Applications" + msgid "Web App" +-msgstr "Webové aplikace" ++msgstr "Webová aplikace" + + #: plugins/epiphany/org.gnome.Software.Plugin.Epiphany.metainfo.xml.in:6 + msgid "Web Apps Support" +@@ -4985,139 +5055,139 @@ msgid "Flatpak Support" + msgstr "Podpora pro Flatpak" + + #: plugins/flatpak/org.gnome.Software.Plugin.Flatpak.metainfo.xml.in:7 +-msgid "Flatpak is a framework for desktop applications on Linux" ++msgid "Flatpak is a framework for desktop apps on Linux" + msgstr "Flatpak je systém pro provozování aplikací na Linuxu" + + #. Reference: https://docs.flatpak.org/en/latest/flatpak-command-reference.html#idm45858571325264 +-#: plugins/flatpak/gs-flatpak.c:313 ++#: plugins/flatpak/gs-flatpak.c:318 + #, c-format + msgid "System folder %s" + msgstr "Systémová složka %s" + +-#: plugins/flatpak/gs-flatpak.c:314 plugins/flatpak/gs-flatpak.c:315 ++#: plugins/flatpak/gs-flatpak.c:319 plugins/flatpak/gs-flatpak.c:320 + #, c-format + msgid "Home subfolder %s" + msgstr "Podsložka %s v domovské složce" + +-#: plugins/flatpak/gs-flatpak.c:316 ++#: plugins/flatpak/gs-flatpak.c:321 + msgid "Host system folders" + msgstr "Složky hostitelského systému" + +-#: plugins/flatpak/gs-flatpak.c:317 ++#: plugins/flatpak/gs-flatpak.c:322 + msgid "Host system configuration from /etc" + msgstr "Konfigurace hostitelského systému z /etc" + +-#: plugins/flatpak/gs-flatpak.c:318 ++#: plugins/flatpak/gs-flatpak.c:323 + msgid "Desktop folder" + msgstr "Složka plochy" + +-#: plugins/flatpak/gs-flatpak.c:318 ++#: plugins/flatpak/gs-flatpak.c:323 + #, c-format + msgid "Desktop subfolder %s" + msgstr "Podsložka %s ve složce plochy" + +-#: plugins/flatpak/gs-flatpak.c:319 ++#: plugins/flatpak/gs-flatpak.c:324 + msgid "Documents folder" + msgstr "Složka dokumentů" + +-#: plugins/flatpak/gs-flatpak.c:319 ++#: plugins/flatpak/gs-flatpak.c:324 + #, c-format + msgid "Documents subfolder %s" + msgstr "Podsložka %s ve složce dokumentů" + +-#: plugins/flatpak/gs-flatpak.c:320 ++#: plugins/flatpak/gs-flatpak.c:325 + msgid "Music folder" + msgstr "Složka hudby" + +-#: plugins/flatpak/gs-flatpak.c:320 ++#: plugins/flatpak/gs-flatpak.c:325 + #, c-format + msgid "Music subfolder %s" + msgstr "Podsložka %s ve složce hudby" + +-#: plugins/flatpak/gs-flatpak.c:321 ++#: plugins/flatpak/gs-flatpak.c:326 + msgid "Pictures folder" + msgstr "Složka obrázků" + +-#: plugins/flatpak/gs-flatpak.c:321 ++#: plugins/flatpak/gs-flatpak.c:326 + #, c-format + msgid "Pictures subfolder %s" + msgstr "Podsložka %s ve složce obrázků" + +-#: plugins/flatpak/gs-flatpak.c:322 ++#: plugins/flatpak/gs-flatpak.c:327 + msgid "Public Share folder" + msgstr "Složka veřejně sdílených" + +-#: plugins/flatpak/gs-flatpak.c:322 ++#: plugins/flatpak/gs-flatpak.c:327 + #, c-format + msgid "Public Share subfolder %s" + msgstr "Podsložka %s ve složce veřejně sdílených" + +-#: plugins/flatpak/gs-flatpak.c:323 ++#: plugins/flatpak/gs-flatpak.c:328 + msgid "Videos folder" + msgstr "Složka videí" + +-#: plugins/flatpak/gs-flatpak.c:323 ++#: plugins/flatpak/gs-flatpak.c:328 + #, c-format + msgid "Videos subfolder %s" + msgstr "Podsložka %s ve složce videí" + +-#: plugins/flatpak/gs-flatpak.c:324 ++#: plugins/flatpak/gs-flatpak.c:329 + msgid "Templates folder" + msgstr "Složka šablon" + +-#: plugins/flatpak/gs-flatpak.c:324 ++#: plugins/flatpak/gs-flatpak.c:329 + #, c-format + msgid "Templates subfolder %s" + msgstr "Podsložka %s ve složce šablon" + +-#: plugins/flatpak/gs-flatpak.c:325 ++#: plugins/flatpak/gs-flatpak.c:330 + msgid "User cache folder" + msgstr "Složka uživatelské mezipaměti" + +-#: plugins/flatpak/gs-flatpak.c:325 ++#: plugins/flatpak/gs-flatpak.c:330 + #, c-format + msgid "User cache subfolder %s" + msgstr "Podsložka %s ve složce uživatelské mezipaměti" + +-#: plugins/flatpak/gs-flatpak.c:326 ++#: plugins/flatpak/gs-flatpak.c:331 + msgid "User configuration folder" + msgstr "Složka uživatelské konfigurace" + +-#: plugins/flatpak/gs-flatpak.c:326 ++#: plugins/flatpak/gs-flatpak.c:331 + #, c-format + msgid "User configuration subfolder %s" + msgstr "Podsložka %s ve složce uživatelské konfigurace" + +-#: plugins/flatpak/gs-flatpak.c:327 ++#: plugins/flatpak/gs-flatpak.c:332 + msgid "User data folder" + msgstr "Složka uživatelských dat" + +-#: plugins/flatpak/gs-flatpak.c:327 ++#: plugins/flatpak/gs-flatpak.c:332 + #, c-format + msgid "User data subfolder %s" + msgstr "Podsložka %s ve složce uživatelských dat" + +-#: plugins/flatpak/gs-flatpak.c:328 ++#: plugins/flatpak/gs-flatpak.c:333 + msgid "User runtime folder" + msgstr "Uživatelská složka pro běh aplikací" + +-#: plugins/flatpak/gs-flatpak.c:328 ++#: plugins/flatpak/gs-flatpak.c:333 + #, c-format + msgid "User runtime subfolder %s" + msgstr "Podsložka %s v uživatelské složce pro běh aplikací" + +-#: plugins/flatpak/gs-flatpak.c:386 ++#: plugins/flatpak/gs-flatpak.c:391 + #, c-format + msgid "Filesystem access to %s" + msgstr "Přístup k souborovému systému v %s" + + #. TRANSLATORS: status text when downloading new metadata +-#: plugins/flatpak/gs-flatpak.c:1403 ++#: plugins/flatpak/gs-flatpak.c:1408 + #, c-format + msgid "Getting flatpak metadata for %s…" + msgstr "Získávají se metadata Flatpak pro %s…" + +-#: plugins/flatpak/gs-flatpak.c:3580 ++#: plugins/flatpak/gs-flatpak.c:3589 + #, c-format + msgid "Failed to refine addon ‘%s’: %s" + msgstr "Selhalo vylepšení doplňku „%s“: %s" +@@ -5130,17 +5200,17 @@ msgstr "Uživatelská instalace" + msgid "System Installation" + msgstr "Systémová instalace" + +-#: plugins/flatpak/gs-plugin-flatpak.c:1038 ++#: plugins/flatpak/gs-plugin-flatpak.c:1320 + #, c-format + msgid "Failed to add to install for addon ‘%s’: %s" + msgstr "Selhalo přídání doplňku „%s“ k nainstalování: %s" + +-#: plugins/flatpak/gs-plugin-flatpak.c:1052 ++#: plugins/flatpak/gs-plugin-flatpak.c:1334 + #, c-format + msgid "Failed to add to uninstall for addon ‘%s’: %s" + msgstr "Selhalo přidání doplňku „%s“ k odinstalování: %s" + +-#: plugins/flatpak/gs-plugin-flatpak.c:1318 ++#: plugins/flatpak/gs-plugin-flatpak.c:1601 + #, c-format + msgid "" + "Remote “%s” doesn't allow install of “%s”, possibly due to its filter. " +@@ -5152,87 +5222,85 @@ msgstr "" + #. TRANSLATORS: as in laptop battery power + #: plugins/fwupd/gs-fwupd-app.c:66 + msgid "System power is too low to perform the update" +-msgstr "" ++msgstr "Systém nemá dostatek energie, aby provedl aktualizaci" + + #. TRANSLATORS: as in laptop battery power + #: plugins/fwupd/gs-fwupd-app.c:70 + #, c-format + msgid "System power is too low to perform the update (%u%%, requires %u%%)" + msgstr "" ++"Systém nemá dostatek energie, aby provedl aktualizaci (%u%%, vyžaduje %u%%)" + + #. TRANSLATORS: for example, a Bluetooth mouse that is in powersave mode + #: plugins/fwupd/gs-fwupd-app.c:76 + msgid "Device is unreachable, or out of wireless range" +-msgstr "" ++msgstr "Zařízení je nedostupné nebo mimo dosah bezdrátové sítě" + + #. TRANSLATORS: for example the batteries *inside* the Bluetooth mouse + #: plugins/fwupd/gs-fwupd-app.c:82 +-#, fuzzy, c-format +-#| msgid "The battery level is too low" ++#, c-format + msgid "Device battery power is too low" +-msgstr "Úroveň nabití baterie je příliš nízká" ++msgstr "Úroveň nabití baterie zařízení je příliš nízká" + + #. TRANSLATORS: for example the batteries *inside* the Bluetooth mouse + #: plugins/fwupd/gs-fwupd-app.c:85 + #, c-format + msgid "Device battery power is too low (%u%%, requires %u%%)" +-msgstr "" ++msgstr "Úroveň nabití baterie zařízení je příliš nízká (%u%%, vyžaduje %u%%)" + + #. TRANSLATORS: usually this is when we're waiting for a reboot + #: plugins/fwupd/gs-fwupd-app.c:91 + msgid "Device is waiting for the update to be applied" +-msgstr "" ++msgstr "Zařízení čeká na aplikování aktualizace" + + #. TRANSLATORS: as in, wired mains power for a laptop + #: plugins/fwupd/gs-fwupd-app.c:95 + msgid "Device requires AC power to be connected" +-msgstr "" ++msgstr "Zařízení vyžaduje připojené napájení za sítě" + + #. TRANSLATORS: lid means "laptop top cover" + #: plugins/fwupd/gs-fwupd-app.c:99 +-#, fuzzy +-#| msgid "Device cannot be used during update." + msgid "Device cannot be used while the lid is closed" +-msgstr "Zařízení nelze během aktualizace používat." ++msgstr "Zařízení nelze používat, pokud je víko notebooku zavřené" + + #. TRANSLATORS: a specific part of hardware, + #. * the first %s is the device name, e.g. 'Unifying Receiver` +-#: plugins/fwupd/gs-fwupd-app.c:218 ++#: plugins/fwupd/gs-fwupd-app.c:219 + #, c-format + msgid "%s Device Update" + msgstr "Aktualizace zařízení %s" + + #. TRANSLATORS: the entire system, e.g. all internal devices, + #. * the first %s is the device name, e.g. 'ThinkPad P50` +-#: plugins/fwupd/gs-fwupd-app.c:223 ++#: plugins/fwupd/gs-fwupd-app.c:224 + #, c-format + msgid "%s System Update" + msgstr "Aktualizace systému pro %s" + + #. TRANSLATORS: the EC is typically the keyboard controller chip, + #. * the first %s is the device name, e.g. 'ThinkPad P50` +-#: plugins/fwupd/gs-fwupd-app.c:228 ++#: plugins/fwupd/gs-fwupd-app.c:229 + #, c-format + msgid "%s Embedded Controller Update" + msgstr "Aktualizace vestavěného řadiče pro %s" + + #. TRANSLATORS: ME stands for Management Engine, the Intel AMT thing, + #. * the first %s is the device name, e.g. 'ThinkPad P50` +-#: plugins/fwupd/gs-fwupd-app.c:233 ++#: plugins/fwupd/gs-fwupd-app.c:234 + #, c-format + msgid "%s ME Update" + msgstr "Aktualizace ME pro %s" + + #. TRANSLATORS: ME stands for Management Engine (with Intel AMT), + #. * where the first %s is the device name, e.g. 'ThinkPad P50` +-#: plugins/fwupd/gs-fwupd-app.c:238 ++#: plugins/fwupd/gs-fwupd-app.c:239 + #, c-format + msgid "%s Corporate ME Update" + msgstr "Aktualizace ME pro firmy pro %s" + + #. TRANSLATORS: ME stands for Management Engine, where + #. * the first %s is the device name, e.g. 'ThinkPad P50` +-#: plugins/fwupd/gs-fwupd-app.c:243 ++#: plugins/fwupd/gs-fwupd-app.c:244 + #, c-format + msgid "%s Consumer ME Update" + msgstr "Aktualizace ME pro běžné spotřebitele pro %s" +@@ -5240,7 +5308,7 @@ msgstr "Aktualizace ME pro běžné spotřebitele pro %s" + #. TRANSLATORS: the controller is a device that has other devices + #. * plugged into it, for example ThunderBolt, FireWire or USB, + #. * the first %s is the device name, e.g. 'Intel ThunderBolt` +-#: plugins/fwupd/gs-fwupd-app.c:249 ++#: plugins/fwupd/gs-fwupd-app.c:250 + #, c-format + msgid "%s Controller Update" + msgstr "Aktualizace řadiče pro %s" +@@ -5248,97 +5316,137 @@ msgstr "Aktualizace řadiče pro %s" + #. TRANSLATORS: the Thunderbolt controller is a device that + #. * has other high speed Thunderbolt devices plugged into it; + #. * the first %s is the system name, e.g. 'ThinkPad P50` +-#: plugins/fwupd/gs-fwupd-app.c:255 ++#: plugins/fwupd/gs-fwupd-app.c:256 + #, c-format + msgid "%s Thunderbolt Controller Update" + msgstr "Aktualizace řadiče Thunderbolt pro %s" + + #. TRANSLATORS: the CPU microcode is firmware loaded onto the CPU + #. * at system bootup +-#: plugins/fwupd/gs-fwupd-app.c:260 ++#: plugins/fwupd/gs-fwupd-app.c:261 + #, c-format + msgid "%s CPU Microcode Update" + msgstr "Aktualizace mikrokódu CPU pro %s" + + #. TRANSLATORS: configuration refers to hardware state, + #. * e.g. a security database or a default power value +-#: plugins/fwupd/gs-fwupd-app.c:265 ++#: plugins/fwupd/gs-fwupd-app.c:266 + #, c-format + msgid "%s Configuration Update" + msgstr "Aktualizace nastavení pro %s" + + #. TRANSLATORS: battery refers to the system power source +-#: plugins/fwupd/gs-fwupd-app.c:269 ++#: plugins/fwupd/gs-fwupd-app.c:270 + #, c-format + msgid "%s Battery Update" + msgstr "Aktualizace baterie pro %s" + + #. TRANSLATORS: camera can refer to the laptop internal + #. * camera in the bezel or external USB webcam +-#: plugins/fwupd/gs-fwupd-app.c:274 ++#: plugins/fwupd/gs-fwupd-app.c:275 + #, c-format + msgid "%s Camera Update" + msgstr "Aktualizace kamery pro %s" + + #. TRANSLATORS: TPM refers to a Trusted Platform Module +-#: plugins/fwupd/gs-fwupd-app.c:278 ++#: plugins/fwupd/gs-fwupd-app.c:279 + #, c-format + msgid "%s TPM Update" + msgstr "Aktualizace TPM pro %s" + + #. TRANSLATORS: TouchPad refers to a flat input device +-#: plugins/fwupd/gs-fwupd-app.c:282 ++#: plugins/fwupd/gs-fwupd-app.c:283 + #, c-format + msgid "%s Touchpad Update" + msgstr "Aktualizace touchpadu pro %s" + + #. TRANSLATORS: Mouse refers to a handheld input device +-#: plugins/fwupd/gs-fwupd-app.c:286 ++#: plugins/fwupd/gs-fwupd-app.c:287 + #, c-format + msgid "%s Mouse Update" + msgstr "Aktualizace myši pro %s" + + #. TRANSLATORS: Keyboard refers to an input device for typing +-#: plugins/fwupd/gs-fwupd-app.c:290 ++#: plugins/fwupd/gs-fwupd-app.c:291 + #, c-format + msgid "%s Keyboard Update" + msgstr "Aktualizace klávesnice pro %s" + + #. TRANSLATORS: Storage Controller is typically a RAID or SAS adapter +-#: plugins/fwupd/gs-fwupd-app.c:294 ++#: plugins/fwupd/gs-fwupd-app.c:295 + #, c-format + msgid "%s Storage Controller Update" + msgstr "Aktualizace řadiče disků pro %s" + + #. TRANSLATORS: Network Interface refers to the physical + #. * PCI card, not the logical wired connection +-#: plugins/fwupd/gs-fwupd-app.c:299 ++#: plugins/fwupd/gs-fwupd-app.c:300 + #, c-format + msgid "%s Network Interface Update" + msgstr "Aktualizace síťové karty pro %s" + + #. TRANSLATORS: Video Display refers to the laptop internal display or + #. * external monitor +-#: plugins/fwupd/gs-fwupd-app.c:304 ++#: plugins/fwupd/gs-fwupd-app.c:305 + #, c-format + msgid "%s Display Update" + msgstr "Aktualizace displeje pro %s" + + #. TRANSLATORS: BMC refers to baseboard management controller which + #. * is the device that updates all the other firmware on the system +-#: plugins/fwupd/gs-fwupd-app.c:309 ++#: plugins/fwupd/gs-fwupd-app.c:310 + #, c-format + msgid "%s BMC Update" + msgstr "Aktualizace BMC pro %s" + + #. TRANSLATORS: Receiver refers to a radio device, e.g. a tiny Bluetooth + #. * device that stays in the USB port so the wireless peripheral works +-#: plugins/fwupd/gs-fwupd-app.c:314 ++#: plugins/fwupd/gs-fwupd-app.c:315 + #, c-format + msgid "%s USB Receiver Update" + msgstr "Aktualizace přijímače USB pro %s" + +-#: plugins/fwupd/gs-plugin-fwupd.c:1244 ++#. TRANSLATORS: drive refers to a storage device, e.g. SATA disk ++#: plugins/fwupd/gs-fwupd-app.c:319 ++#, c-format ++msgid "%s Drive Update" ++msgstr "Aktualizace disku pro %s" ++ ++#. TRANSLATORS: flash refers to solid state storage, e.g. UFS or eMMC ++#: plugins/fwupd/gs-fwupd-app.c:323 ++#, c-format ++msgid "%s Flash Drive Update" ++msgstr "Aktualizace flash disku pro %s" ++ ++#. TRANSLATORS: SSD refers to a Solid State Drive, e.g. non-rotating ++#. * SATA or NVMe disk ++#: plugins/fwupd/gs-fwupd-app.c:328 ++#, c-format ++msgid "%s SSD Update" ++msgstr "Aktualizace SSD pro %s" ++ ++#. TRANSLATORS: GPU refers to a Graphics Processing Unit, e.g. ++#. * the "video card" ++#: plugins/fwupd/gs-fwupd-app.c:333 ++#, c-format ++msgid "%s GPU Update" ++msgstr "Aktualizace grafické karty pro %s" ++ ++#. TRANSLATORS: Dock refers to the port replicator hardware laptops are ++#. * cradled in, or lowered onto ++#: plugins/fwupd/gs-fwupd-app.c:338 ++#, c-format ++msgid "%s Dock Update" ++msgstr "Aktualizace dokovacího zařízení pro %s" ++ ++#. TRANSLATORS: Dock refers to the port replicator device connected ++#. * by plugging in a USB cable -- which may or may not also provide power ++#: plugins/fwupd/gs-fwupd-app.c:343 ++#, c-format ++msgid "%s USB Dock Update" ++msgstr "Aktualizace USB dokovacího zařízení pro %s" ++ ++#: plugins/fwupd/gs-plugin-fwupd.c:1763 + msgid "Firmware" + msgstr "Firmware" + +@@ -5350,11 +5458,11 @@ msgstr "Podpora aktualizací firmwaru" + msgid "Provides support for firmware upgrades" + msgstr "Poskytuje podporu pro povyšování verzí firmwaru" + +-#: plugins/packagekit/gs-packagekit-task.c:148 ++#: plugins/packagekit/gs-packagekit-task.c:147 + msgid "Install Unsigned Software?" + msgstr "Nainstalovat nepodepsaný software?" + +-#: plugins/packagekit/gs-packagekit-task.c:149 ++#: plugins/packagekit/gs-packagekit-task.c:148 + msgid "" + "Software that is to be installed is not signed. It will not be possible to " + "verify the origin of updates to this software, or whether updates have been " +@@ -5363,11 +5471,11 @@ msgstr "" + "Software, který se chystáte nainstalovat, není podepsaný. Nebude tak možné " + "ověřit původ jeho aktualizací, nebo zda aktualizace nebyly zmanipulovány." + +-#: plugins/packagekit/gs-packagekit-task.c:153 ++#: plugins/packagekit/gs-packagekit-task.c:152 + msgid "Download Unsigned Software?" + msgstr "Stáhnout nepodepsaný software?" + +-#: plugins/packagekit/gs-packagekit-task.c:154 ++#: plugins/packagekit/gs-packagekit-task.c:153 + msgid "" + "Unsigned updates are available. Without a signature, it is not possible to " + "verify the origin of the update, or whether it has been tampered with." +@@ -5375,11 +5483,11 @@ msgstr "" + "Jsou k dispozici nepodepsané aktualizace. Bez podpisu není možné ověřit " + "původ aktualizace, nebo zda nebyla zmanipulována." + +-#: plugins/packagekit/gs-packagekit-task.c:158 ++#: plugins/packagekit/gs-packagekit-task.c:157 + msgid "Update Unsigned Software?" + msgstr "Aktualizovat nepodepsaný software?" + +-#: plugins/packagekit/gs-packagekit-task.c:159 ++#: plugins/packagekit/gs-packagekit-task.c:158 + msgid "" + "Unsigned updates are available. Without a signature, it is not possible to " + "verify the origin of the update, or whether it has been tampered with. " +@@ -5391,11 +5499,11 @@ msgstr "" + "zakázány, dokud nebudou nepodepsané aktualizace buďto odstraněny nebo " + "nahrazeny jinými." + +-#: plugins/packagekit/gs-plugin-packagekit.c:367 ++#: plugins/packagekit/gs-plugin-packagekit.c:416 + msgid "Packages" + msgstr "Balíčky" + +-#: plugins/rpm-ostree/gs-plugin-rpm-ostree.c:2696 ++#: plugins/rpm-ostree/gs-plugin-rpm-ostree.c:2764 + msgid "Operating System (OSTree)" + msgstr "Operační systém (OSTree)" + +@@ -5412,6 +5520,76 @@ msgstr "Podpora pro Snap" + msgid "A snap is a universal Linux package" + msgstr "Snap je univerzální linuxový balíček" + ++#~ msgid "Selected add-ons will be installed with the app." ++#~ msgstr "Vybrané doplňky budou nainstalovány spolu s aplikací." ++ ++#~ msgid "The last timestamp when the system was online and got any updates" ++#~ msgstr "" ++#~ "Datum a čas, kdy byl systém naposledy on-line a dostal nějaké aktualizace" ++ ++#~ msgid "_User" ++#~ msgstr "_Uživatel" ++ ++#~ msgid "" ++#~ "This software is not available in your language and will appear in US " ++#~ "English." ++#~ msgstr "" ++#~ "Tento software není dostupný ve vašem jazyce a zobrazí se v americké " ++#~ "angličtině." ++ ++#~ msgid "Applications" ++#~ msgstr "Aplikace" ++ ++#~ msgid "Web Applications" ++#~ msgstr "Webové aplikace" ++ ++#~ msgid "Post Review" ++#~ msgstr "Příspěvek do recenzí" ++ ++#~ msgid "_Post" ++#~ msgstr "_Odeslat" ++ ++#~ msgid "Rating" ++#~ msgstr "Hodnocení" ++ ++#~ msgid "" ++#~ "Give a short summary of your review, for example: “Great app, would " ++#~ "recommend”." ++#~ msgstr "" ++#~ "Uveďte krátké shrnutí své recenze, například: „Skvělá aplikace, " ++#~ "doporučuji“." ++ ++#~ msgctxt "app review" ++#~ msgid "Review" ++#~ msgstr "Recenze" ++ ++#~ msgid "What do you think of the app? Try to give reasons for your views." ++#~ msgstr "Co si o aplikaci myslíte? Snažte se uvést důvody svého hodnocení." ++ ++#~ msgid "No screenshot provided" ++#~ msgstr "Nemá snímek obrazovky" ++ ++#~ msgid "Primary Menu" ++#~ msgstr "Hlavní nabídky" ++ ++#~ msgctxt "Header bar button for list of apps to be updated" ++#~ msgid "Updates" ++#~ msgstr "Aktualizace" ++ ++#, c-format ++#~ msgid "%s %s is no longer supported." ++#~ msgstr "Systém %s %s již není podporován." ++ ++#~ msgid "This means that it does not receive security updates." ++#~ msgstr "" ++#~ "Znamená to, že pro něj již nadále nejsou poskytovány bezpečnostní opravy." ++ ++#~ msgid "It is recommended that you upgrade to a more recent version." ++#~ msgstr "Doporučuje se povýšit na nejnovější verzi." ++ ++#~ msgid "Application Updates" ++#~ msgstr "Aktualizace aplikací" ++ + #~ msgid "_Continue" + #~ msgstr "_Pokračovat" + diff --git a/gnome-software.spec b/gnome-software.spec index d525c64..746ce38 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -20,7 +20,7 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 44~rc +Version: 44.0 Release: 1%{?dist} Summary: A software center for GNOME @@ -29,6 +29,7 @@ URL: https://wiki.gnome.org/Apps/Software Source0: https://download.gnome.org/sources/gnome-software/44/%{name}-%{tarball_version}.tar.xz Patch01: 0001-crash-with-broken-theme.patch +Patch02: 0002-update-czech-translation.patch BuildRequires: docbook-style-xsl BuildRequires: desktop-file-utils @@ -228,6 +229,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Mar 17 2023 Milan Crha - 44.0-1 +- Update to 44.0 + * Fri Mar 03 2023 Milan Crha - 44~rc-1 - Update to 44.rc diff --git a/sources b/sources index 0ad486a..91637d7 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-44.rc.tar.xz) = 15d40987a001af58dd0a671c8aa7399a1397a21bcd62ff5850e5dde4cee67cb64d53408492d8da0990cee301bf535b5c1954257d8dcbb0f49ba74ee1347ec843 +SHA512 (gnome-software-44.0.tar.xz) = 592a88fd3488d7d9cd573eff99e8ec503169b52354d672263d7e514846c666c56f87fcbdb31fb8c497ed048808ec223646c247326af76a7e4a361084fd1b180e From 5babfff9d73355c6239465c7beac70fa499727a4 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 24 Mar 2023 07:17:17 +0100 Subject: [PATCH 036/116] Resolves: #2181367 (Prefer Fedora Flatpaks before RPM before other sources for apps) --- gnome-software.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gnome-software.spec b/gnome-software.spec index 746ce38..ddb80ca 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -21,7 +21,7 @@ Name: gnome-software Version: 44.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -152,6 +152,7 @@ official-repos = [ 'rhel-%{?rhel}' ] %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' ] required-repos = [ 'fedora', 'updates' ] +packaging-format-preference = [ 'flatpak:fedora', 'rpm' ] %endif FOE @@ -229,6 +230,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Mar 24 2023 Milan Crha - 44.0-2 +- Resolves: #2181367 (Prefer Fedora Flatpaks before RPM before other sources for apps) + * Fri Mar 17 2023 Milan Crha - 44.0-1 - Update to 44.0 From ba20db05e79a803486c744d7886b834bd4564d80 Mon Sep 17 00:00:00 2001 From: Yaakov Selkowitz Date: Sun, 26 Mar 2023 12:30:05 -0400 Subject: [PATCH 037/116] Fix libsoup runtime dependency This was switched to libsoup3 in 44~alpha but the runtime dependency was not switched to match. With the switch, there is no particular version constraint, so just rely on the dynamic link dependency. --- gnome-software.spec | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index ddb80ca..42a59ce 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -5,7 +5,6 @@ %global gtk4_version 4.9.2 %global json_glib_version 1.2.0 %global libadwaita_version 1.3.alpha -%global libsoup_version 2.52.0 %global libxmlb_version 0.1.7 %global packagekit_version 1.1.1 @@ -21,7 +20,7 @@ Name: gnome-software Version: 44.0 -Release: 2%{?dist} +Release: 3%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -77,7 +76,6 @@ Requires: json-glib%{?_isa} >= %{json_glib_version} Requires: iso-codes # librsvg2 is needed for gdk-pixbuf svg loader Requires: librsvg2%{?_isa} -Requires: libsoup%{?_isa} >= %{libsoup_version} Requires: libxmlb%{?_isa} >= %{libxmlb_version} Recommends: PackageKit%{?_isa} >= %{packagekit_version} @@ -230,6 +228,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Sun Mar 26 2023 Yaakov Selkowitz - 44.0-3 +- Fix libsoup runtime dependency + * Fri Mar 24 2023 Milan Crha - 44.0-2 - Resolves: #2181367 (Prefer Fedora Flatpaks before RPM before other sources for apps) From 248c8dbdc8defa97548be91e1abca25df0f644da Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 27 Mar 2023 08:46:48 +0200 Subject: [PATCH 038/116] Added 'flatpak:fedora-testing' into packaging-format-preference --- gnome-software.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gnome-software.spec b/gnome-software.spec index 42a59ce..79fd305 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -150,7 +150,7 @@ official-repos = [ 'rhel-%{?rhel}' ] %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' ] required-repos = [ 'fedora', 'updates' ] -packaging-format-preference = [ 'flatpak:fedora', 'rpm' ] +packaging-format-preference = [ 'flatpak:fedora-testing', 'flatpak:fedora', 'rpm' ] %endif FOE From 487ab393e18ebb579e3ae21643ed57cb560b6669 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 21 Apr 2023 08:55:05 +0200 Subject: [PATCH 039/116] Update to 44.1 --- 0002-update-czech-translation.patch | 4889 --------------------------- gnome-software.spec | 8 +- sources | 2 +- 3 files changed, 6 insertions(+), 4893 deletions(-) delete mode 100644 0002-update-czech-translation.patch diff --git a/0002-update-czech-translation.patch b/0002-update-czech-translation.patch deleted file mode 100644 index 86b6304..0000000 --- a/0002-update-czech-translation.patch +++ /dev/null @@ -1,4889 +0,0 @@ -diff --git a/po/cs.po b/po/cs.po -index 3301fcaf4..b532ac8a9 100644 ---- a/po/cs.po -+++ b/po/cs.po -@@ -4,22 +4,23 @@ - # - # Petr Kovar , 2015. - # Marek Černocký , 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022. --# Vojtěch Perník , 2021-2022. -+# Vojtěch Perník , 2021-2023. -+# Daniel Rusek , 2023. - # - msgid "" - msgstr "" - "Project-Id-Version: gnome-software\n" - "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-software/issues\n" --"POT-Creation-Date: 2022-11-10 08:39+0000\n" --"PO-Revision-Date: 2022-08-28 11:45+0200\n" --"Last-Translator: Vojtěch Perník \n" -+"POT-Creation-Date: 2023-03-16 13:07+0000\n" -+"PO-Revision-Date: 2023-03-16 12:54+0100\n" -+"Last-Translator: Daniel Rusek \n" - "Language-Team: Czech \n" - "Language: cs\n" - "MIME-Version: 1.0\n" - "Content-Type: text/plain; charset=UTF-8\n" - "Content-Transfer-Encoding: 8bit\n" - "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" --"X-Generator: Poedit 3.1.1\n" -+"X-Generator: Poedit 3.2.2\n" - "X-Project-Style: gnome\n" - - #: data/metainfo/org.gnome.Software.metainfo.xml.in:7 src/gs-shell.ui:21 -@@ -33,18 +34,18 @@ msgstr "Instalujte a aktualizujte aplikace" - - #: data/metainfo/org.gnome.Software.metainfo.xml.in:10 - msgid "" --"Software allows you to find and install new applications and system " --"extensions and remove existing installed applications." -+"Software allows you to find and install new apps and system extensions and " -+"remove existing installed apps." - msgstr "" - "Aplikace Software umožňuje vyhledávat a instalovat aplikace a systémová " - "rozšíření a odebírat stávající nainstalované aplikace." - - #: data/metainfo/org.gnome.Software.metainfo.xml.in:14 - msgid "" --"Software showcases featured and popular applications with useful " --"descriptions and multiple screenshots per application. Applications can be " --"found either through browsing the list of categories or by searching. It " --"also allows you to update your system using an offline update." -+"Software showcases featured and popular apps with useful descriptions and " -+"multiple screenshots per app. Apps can be found either through browsing the " -+"list of categories or by searching. It also allows you to update your system " -+"using an offline update." - msgstr "" - "Aplikace Software vám představí významné a oblíbené aplikace pomocí " - "srozumitelného popisu a několika snímků obrazovky. Aplikace můžete najít buď " -@@ -73,7 +74,7 @@ msgstr "Panel s aktualizacemi" - msgid "The update details" - msgstr "Podrobnosti o aktualizaci" - --#: data/metainfo/org.gnome.Software.metainfo.xml.in:2076 -+#: data/metainfo/org.gnome.Software.metainfo.xml.in:2222 - #: src/gs-application.c:264 - msgid "The GNOME Project" - msgstr "Projekt GNOME" -@@ -195,17 +196,12 @@ msgid "The last update timestamp" - msgstr "Datum a čas poslední aktualizace" - - #: data/org.gnome.software.gschema.xml:67 --msgid "The last timestamp when the system was online and got any updates" --msgstr "" --"Datum a čas, kdy byl systém naposledy on-line a dostal nějaké aktualizace" -- --#: data/org.gnome.software.gschema.xml:71 - msgid "The age in seconds to verify the upstream screenshot is still valid" - msgstr "" - "Doba v sekundách, po které se má ověřit, jestli je snímek obrazovky z " - "hlavního zdroje stále platný" - --#: data/org.gnome.software.gschema.xml:72 -+#: data/org.gnome.software.gschema.xml:68 - msgid "" - "Choosing a larger value will mean less round-trips to the remote server but " - "updates to the screenshots may take longer to show to the user. A value of 0 " -@@ -216,75 +212,75 @@ msgstr "" - "znamená, že se kontroly na serveru nemají provádět vůbec, pokud je již " - "snímek v mezipaměti." - --#: data/org.gnome.software.gschema.xml:81 -+#: data/org.gnome.software.gschema.xml:77 - msgid "The server to use for application reviews" - msgstr "Server, který se má používat pro recenze aktualizací" - --#: data/org.gnome.software.gschema.xml:85 -+#: data/org.gnome.software.gschema.xml:81 - msgid "The minimum karma score for reviews" - msgstr "Minimální karma pro recenze" - --#: data/org.gnome.software.gschema.xml:86 -+#: data/org.gnome.software.gschema.xml:82 - msgid "Reviews with karma less than this number will not be shown." - msgstr "Recenze s karmou nižší než toto číslo nebudou zobrazovány." - --#: data/org.gnome.software.gschema.xml:90 -+#: data/org.gnome.software.gschema.xml:86 - msgid "A list of official repositories that should not be considered 3rd party" - msgstr "" - "Seznam oficiálních repozitářů, které by neměly být považovány za třetí stranu" - --#: data/org.gnome.software.gschema.xml:94 -+#: data/org.gnome.software.gschema.xml:90 - msgid "A list of required repositories that cannot be disabled or removed" - msgstr "" - "Seznam vyžadovaných repozitářů, které nemohou být zakázány nebo odebrány" - --#: data/org.gnome.software.gschema.xml:98 -+#: data/org.gnome.software.gschema.xml:94 - msgid "A list of official repositories that should be considered free software" - msgstr "" - "Seznam oficiálních repozitářů, které by měly být považovány za svobodný " - "software" - --#: data/org.gnome.software.gschema.xml:102 -+#: data/org.gnome.software.gschema.xml:98 - msgid "" - "The licence URL to use when an application should be considered free software" - msgstr "" - "Adresa URL licence, která se má použít, když má aplikace považována za " - "svobodný software" - --#: data/org.gnome.software.gschema.xml:106 -+#: data/org.gnome.software.gschema.xml:102 - msgid "Install bundled applications for all users on the system where possible" - msgstr "" - "Kde je to možné, instalovat všem uživatelům v systému přibalené aplikace" - --#: data/org.gnome.software.gschema.xml:110 -+#: data/org.gnome.software.gschema.xml:106 - msgid "Allow access to the Software Repositories dialog" - msgstr "Umožnit přístup k dialogovému oknu s repozitáři softwaru" - --#: data/org.gnome.software.gschema.xml:114 -+#: data/org.gnome.software.gschema.xml:110 - msgid "Offer upgrades for pre-releases" - msgstr "Nabízet povýšení na předběžná vydání" - --#: data/org.gnome.software.gschema.xml:118 -+#: data/org.gnome.software.gschema.xml:114 - msgid "Show some UI elements informing the user that an app is non-free" - msgstr "" - "Zobrazovat v rozhraní prvky, které informují uživatele, že aplikace není " - "svobodná" - --#: data/org.gnome.software.gschema.xml:122 -+#: data/org.gnome.software.gschema.xml:118 - msgid "Show the installed size for apps in the list of installed applications" - msgstr "" - "Zobrazovat velikost instalace pro aplikace v seznamu nainstalovaných aplikací" - - #. Translators: Replace the link with a version in your language, e.g. 'https://de.wikipedia.org/wiki/Proprietäre_Software'. Remember to include ''. --#: data/org.gnome.software.gschema.xml:126 -+#: data/org.gnome.software.gschema.xml:122 - msgid "'https://en.wikipedia.org/wiki/Proprietary_software'" - msgstr "'https://cs.wikipedia.org/wiki/Propriet%C3%A1rn%C3%AD_software'" - --#: data/org.gnome.software.gschema.xml:127 -+#: data/org.gnome.software.gschema.xml:123 - msgid "The URI that explains nonfree and proprietary software" - msgstr "Adresa URI, která vysvětluje nesvobodný a komerční software" - --#: data/org.gnome.software.gschema.xml:131 -+#: data/org.gnome.software.gschema.xml:127 - msgid "" - "A list of URLs pointing to appstream files that will be downloaded into an " - "swcatalog folder" -@@ -292,7 +288,7 @@ msgstr "" - "Seznam adres URL ukazujících na soubory appstream, které byly stažené do " - "složky swcatalog" - --#: data/org.gnome.software.gschema.xml:135 -+#: data/org.gnome.software.gschema.xml:131 - msgid "" - "Install the AppStream files to a system-wide location for all users. If " - "false, files are installed in non-standard $XDG_DATA_HOME/swcatalog/xml " -@@ -302,13 +298,7 @@ msgstr "" - "uživatele. Pokud je vypnuto, budou soubory instalovány do nestandardní " - "složky $XDG_DATA_HOME/swcatalog/xmls" - --#: data/org.gnome.software.gschema.xml:139 --#, fuzzy --#| msgid "" --#| "Priority order of packaging formats to prefer, with more important " --#| "formats listed first. An empty array means the default order. Omitted " --#| "formats are assumed to be listed last. Example packaging formats are: " --#| "deb, flatpak, rpm, snap." -+#: data/org.gnome.software.gschema.xml:135 - msgid "" - "Priority order of packaging formats to prefer, with more important formats " - "listed first. An empty array means the default order. Omitted formats are " -@@ -319,9 +309,24 @@ msgstr "" - "Prioritní pořadí formátů balíčků, kterým dáváte přednost, přičemž " - "důležitější formáty jsou uvedeny na prvním místě. Prázdné pole znamená " - "výchozí pořadí. Předpokládá se, že vynechané formáty budou uvedeny jako " --"poslední. Příklady balíčkovacích formátů: deb, flatpak, rpm, snap." -+"poslední. Příklady balíčkovacích formátů: deb, flatpak, rpm, snap. Formáty " -+"mohou být nepovinně specifikovány s názvem původu odděleného dvojtečkou, " -+"například „flatpak:flathub“." -+ -+#: data/org.gnome.software.gschema.xml:139 -+msgid "The timestamp of the last attempt to remove unused Flatpak runtimes" -+msgstr "" -+"Datum a čas posledního pokusu odebrat nepoužívaná běhová prostředí Flatpak" -+ -+#: data/org.gnome.software.gschema.xml:143 -+msgid "" -+"Set to 'true' to show only freely licensed apps and hide any proprietary " -+"apps." -+msgstr "" -+"Nastavte na „true“, chcete-li zobrazit pouze aplikace s otevřenou licencí a " -+"skrýt všechny proprietární aplikace." - --#: data/org.gnome.software.gschema.xml:146 -+#: data/org.gnome.software.gschema.xml:150 - msgid "A string storing the gnome-online-account id used to login" - msgstr "Řetězec uchovávající ID gnome-online-account pro přihlášení" - -@@ -710,7 +715,7 @@ msgstr "%s • %s" - - #. Translators: The app is considered suitable to be run by all ages of people. - #. * This is displayed in a context tile, so the string should be short. --#: src/gs-age-rating-context-dialog.c:936 -+#: src/gs-age-rating-context-dialog.c:935 - msgctxt "Age rating" - msgid "All" - msgstr "Vše" -@@ -719,44 +724,44 @@ msgstr "Vše" - #. * app’s context tile if the size is unknown. It should be short - #. * (at most a couple of characters wide). - #. Translators: This is shown in a bubble if the storage --#. * size of an application is not known. The bubble is small, -+#. * size of an app is not known. The bubble is small, - #. * so the string should be as short as possible. --#: src/gs-age-rating-context-dialog.c:949 src/gs-app-context-bar.c:206 -+#: src/gs-age-rating-context-dialog.c:948 src/gs-app-context-bar.c:206 - #: src/gs-storage-context-dialog.c:89 - msgid "?" - msgstr "?" - - #. Translators: This is a dialogue title which indicates that an app is suitable - #. * for all ages. The placeholder is the app name. --#: src/gs-age-rating-context-dialog.c:1023 -+#: src/gs-age-rating-context-dialog.c:1020 - #, c-format - msgid "%s is suitable for everyone" - msgstr "Aplikace %s je vhodná pro každého" - - #. Translators: This is a dialogue title which indicates that an app is suitable - #. * for children up to around age 3. The placeholder is the app name. --#: src/gs-age-rating-context-dialog.c:1027 -+#: src/gs-age-rating-context-dialog.c:1024 - #, c-format - msgid "%s is suitable for toddlers" - msgstr "Aplikace %s je vhodná pro batolata" - - #. Translators: This is a dialogue title which indicates that an app is suitable - #. * for children up to around age 5. The placeholder is the app name. --#: src/gs-age-rating-context-dialog.c:1031 -+#: src/gs-age-rating-context-dialog.c:1028 - #, c-format - msgid "%s is suitable for young children" - msgstr "Aplikace %s je vhodná pro malé děti" - - #. Translators: This is a dialogue title which indicates that an app is suitable - #. * for people up to around age 18. The placeholder is the app name. --#: src/gs-age-rating-context-dialog.c:1039 -+#: src/gs-age-rating-context-dialog.c:1036 - #, c-format - msgid "%s is suitable for teenagers" - msgstr "Aplikace %s je vhodná pro dospívající mládež" - - #. Translators: This is a dialogue title which indicates that an app is suitable - #. * for people aged up to and over 18. The placeholder is the app name. --#: src/gs-age-rating-context-dialog.c:1043 -+#: src/gs-age-rating-context-dialog.c:1040 - #, c-format - msgid "%s is suitable for adults" - msgstr "Aplikace %s je vhodná pro dospělé" -@@ -764,14 +769,14 @@ msgstr "Aplikace %s je vhodná pro dospělé" - #. Translators: This is a dialogue title which indicates that an app is suitable - #. * for a specified age group. The first placeholder is the app name, the second - #. * is the age group. --#: src/gs-age-rating-context-dialog.c:1048 -+#: src/gs-age-rating-context-dialog.c:1045 - #, c-format - msgid "%s is suitable for %s" - msgstr "Aplikace %s je vhodná pro %s" - - #. Translators: This is the title of the dialog which contains information about the suitability of an app for different ages. - #. this one’s not a placeholder --#: src/gs-age-rating-context-dialog.ui:5 src/gs-app-context-bar.ui:211 -+#: src/gs-age-rating-context-dialog.ui:5 src/gs-app-context-bar.ui:217 - msgid "Age Rating" - msgstr "Vhodné od věku" - -@@ -781,7 +786,7 @@ msgstr "Vhodné od věku" - msgid "How to contribute missing information" - msgstr "Jak přidat chybějící informace" - --#: lib/gs-app.c:6178 -+#: lib/gs-app.c:6256 - msgid "Local file" - msgstr "Místní soubor" - -@@ -790,44 +795,51 @@ msgstr "Místní soubor" - #. Example string: "Local file (RPM)" - #. Translators: The first placeholder is an app runtime - #. * name, the second is its version number. --#: lib/gs-app.c:6197 src/gs-safety-context-dialog.c:439 -+#: lib/gs-app.c:6275 src/gs-safety-context-dialog.c:443 - #, c-format - msgid "%s (%s)" - msgstr "%s (%s)" - --#: lib/gs-app.c:6274 -+#: lib/gs-app.c:6352 - msgid "Package" - msgstr "Balíček" - --#: src/gs-app-addon-row.c:97 src/gs-app-row.c:460 -+#: src/gs-app-addon-row.c:95 src/gs-app-row.c:452 - msgid "Pending" - msgstr "Čeká na zpracování" - --#: src/gs-app-addon-row.c:101 src/gs-app-row.c:464 src/gs-details-page.c:369 -+#: src/gs-app-addon-row.c:99 src/gs-app-row.c:456 src/gs-details-page.c:379 - msgid "Pending install" - msgstr "Čeká na instalaci" - --#: src/gs-app-addon-row.c:105 src/gs-app-row.c:468 src/gs-details-page.c:376 -+#: src/gs-app-addon-row.c:103 src/gs-app-row.c:460 src/gs-details-page.c:386 - msgid "Pending remove" - msgstr "Čeká na odebrání" - --#: src/gs-app-addon-row.c:111 src/gs-app-row.ui:197 src/gs-app-tile.ui:50 --#: src/gs-feature-tile.c:535 --msgctxt "Single app" --msgid "Installed" --msgstr "Nainstalováno" -- - #. TRANSLATORS: this is a button next to the search results that --#. * shows the status of an application being installed --#: src/gs-app-addon-row.c:115 src/gs-app-row.c:208 src/gs-details-page.c:362 -+#. * shows the status of an app being installed -+#: src/gs-app-addon-row.c:107 src/gs-app-row.c:207 src/gs-details-page.c:372 - msgid "Installing" - msgstr "Instaluje se" - --#: src/gs-app-addon-row.c:119 -+#: src/gs-app-addon-row.c:111 - msgid "Removing" - msgstr "Odebírá se" - --#: src/gs-app-addon-row.ui:64 src/gs-details-page.c:1015 -+#. TRANSLATORS: button text -+#. TRANSLATORS: button text in the header when an app -+#. * can be installed -+#. TRANSLATORS: button text in the header when firmware -+#. * can be live-installed -+#. TRANSLATORS: update the fw -+#: src/gs-app-addon-row.ui:66 src/gs-common.c:303 src/gs-details-page.c:924 -+#: src/gs-details-page.c:950 src/gs-details-page.ui:209 src/gs-page.c:412 -+#: plugins/packagekit/gs-packagekit-task.c:149 -+msgid "_Install" -+msgstr "_Instalovat" -+ -+#. TRANSLATORS: this is button text to remove the app -+#: src/gs-app-addon-row.ui:73 src/gs-page.c:551 - msgid "_Uninstall" - msgstr "_Odinstalovat" - -@@ -855,116 +867,120 @@ msgstr "Služby sezení" - msgid "Can access D-Bus services on the session bus" - msgstr "Může přistupovat k službám D-Bus na sběrnici sezení" - --#: src/gs-app-details-page.c:71 -+#: src/gs-app-details-page.c:71 src/gs-app-details-page.c:72 - msgid "Devices" - msgstr "Zařízení" - - #: src/gs-app-details-page.c:71 -+msgid "Can access arbitrary devices such as webcams" -+msgstr "Může přistupovat k libovolným zařízením, například webovým kamerám" -+ -+#: src/gs-app-details-page.c:72 - msgid "Can access system device files" - msgstr "Může přistupovat k souborům na systémovém zařízení" - --#: src/gs-app-details-page.c:72 src/gs-app-details-page.c:73 -+#: src/gs-app-details-page.c:73 src/gs-app-details-page.c:74 - msgid "Home folder" - msgstr "Domovská složka" - --#: src/gs-app-details-page.c:72 src/gs-app-details-page.c:74 --#: src/gs-app-details-page.c:77 src/gs-app-details-page.c:150 -+#: src/gs-app-details-page.c:73 src/gs-app-details-page.c:75 -+#: src/gs-app-details-page.c:78 src/gs-app-details-page.c:151 - msgid "Can view, edit and create files" - msgstr "Může zobrazovat, upravovat a vytvářet soubory" - --#: src/gs-app-details-page.c:73 src/gs-app-details-page.c:75 --#: src/gs-app-details-page.c:78 src/gs-app-details-page.c:145 -+#: src/gs-app-details-page.c:74 src/gs-app-details-page.c:76 -+#: src/gs-app-details-page.c:79 src/gs-app-details-page.c:146 - msgid "Can view files" - msgstr "Může zobrazovat soubory" - --#: src/gs-app-details-page.c:74 src/gs-app-details-page.c:75 -+#: src/gs-app-details-page.c:75 src/gs-app-details-page.c:76 - msgid "File system" - msgstr "Souborový systém" - - #. The GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_OTHER is used only as a flag, with actual files being part of the read/full lists --#: src/gs-app-details-page.c:77 src/gs-app-details-page.c:78 -+#: src/gs-app-details-page.c:78 src/gs-app-details-page.c:79 - msgid "Downloads folder" - msgstr "Složka se staženými soubory" - --#: src/gs-app-details-page.c:79 -+#: src/gs-app-details-page.c:80 - msgid "Settings" - msgstr "Nastavení" - --#: src/gs-app-details-page.c:79 -+#: src/gs-app-details-page.c:80 - msgid "Can view and change any settings" - msgstr "Může zobrazovat a měnit libovolná nastavení" - --#: src/gs-app-details-page.c:80 -+#: src/gs-app-details-page.c:81 - msgid "Legacy display system" - msgstr "Zastaralý zobrazovací systém" - --#: src/gs-app-details-page.c:80 -+#: src/gs-app-details-page.c:81 - msgid "Uses an old, insecure display system" - msgstr "Používá starý, ne zcela bezpečný, zobrazovací systém" - --#: src/gs-app-details-page.c:81 -+#: src/gs-app-details-page.c:82 - msgid "Sandbox escape" - msgstr "Opuštění izolovaného prostředí" - --#: src/gs-app-details-page.c:81 -+#: src/gs-app-details-page.c:82 - msgid "Can escape the sandbox and circumvent any other restrictions" - msgstr "Může opustit izolované prostředí a obejít další omezení" - - #. FIXME support app == NULL - #. set window title --#: src/gs-app-details-page.c:166 -+#: src/gs-app-details-page.c:167 - msgid "Update Details" - msgstr "Podrobnosti o aktualizaci" - - #. TRANSLATORS: this is where the packager did not write - #. * a description for the update --#: src/gs-app-details-page.c:174 -+#: src/gs-app-details-page.c:175 - msgid "No update description available." - msgstr "Není k dispozici žádný popis aktualizace." - - #: src/gs-app-details-page.ui:25 src/gs-os-update-page.ui:25 --#: src/gs-shell.ui:369 src/gs-shell.ui:460 -+#: src/gs-shell.ui:348 src/gs-shell.ui:439 - msgid "Go back" - msgstr "Přejít zpět" - --#: src/gs-app-details-page.ui:48 src/gs-app-row.c:523 -+#: src/gs-app-details-page.ui:48 src/gs-app-row.c:515 - msgid "Requires additional permissions" - msgstr "Vyžaduje dodatečná oprávnění" - - #. Translators: Header of the section with other users' opinions about the app. --#: src/gs-app-reviews-dialog.ui:6 src/gs-details-page.ui:867 -+#: src/gs-app-reviews-dialog.ui:6 src/gs-details-page.ui:930 - msgid "Reviews" - msgstr "Recenze" - - #: src/gs-app-reviews-dialog.ui:25 --msgid "No reviews were found for this application." -+msgid "No reviews were found for this app." - msgstr "Pro tuto aplikaci nebyly nalezeny žádné recenze." - - #: src/gs-app-reviews-dialog.ui:27 - msgid "No Reviews" - msgstr "Bez recenzí" - --#: src/gs-app-version-history-dialog.ui:6 src/gs-details-page.ui:545 -+#: src/gs-app-version-history-dialog.ui:6 src/gs-details-page.ui:529 - msgid "Version History" - msgstr "Historie verzí" - --#: src/gs-app-version-history-row.c:71 -+#: src/gs-app-version-history-row.c:133 - #, c-format - msgid "New in Version %s" - msgstr "Novinky ve verzi %s" - --#: src/gs-app-version-history-row.c:78 -+#: src/gs-app-version-history-row.c:140 - #, c-format - msgid "Version %s" - msgstr "Verze %s" - --#: src/gs-app-version-history-row.c:80 -+#: src/gs-app-version-history-row.c:142 - msgid "No details for this release" - msgstr "K tomuto vydání nejsou k dispozici žádné podrobnosti." - - #. TRANSLATORS: This is the date string with: day number, month name, year. - #. i.e. "25 May 2012" --#: src/gs-app-version-history-row.c:94 src/gs-review-row.c:63 -+#: src/gs-app-version-history-row.c:156 src/gs-review-row.c:67 - msgid "%e %B %Y" - msgstr "%e. %B %Y" - -@@ -1040,8 +1056,8 @@ msgid "Installs any pending updates in the background" - msgstr "Nainstalovat na pozadí případné čekající aktualizace" - - #: src/gs-application.c:147 --msgid "Show update preferences" --msgstr "Zobrazit předvolby aktualizací" -+msgid "Show preferences" -+msgstr "Zobrazit předvolby" - - #: src/gs-application.c:149 - msgid "Quit the running instance" -@@ -1056,8 +1072,8 @@ msgid "Show version number" - msgstr "Zobrazit číslo verze" - - #: src/gs-application.c:271 src/gs-application.c:279 --msgid "Copyright © 2016–2022 GNOME Software contributors" --msgstr "Copyright © 2016 – 2022 přispěvatelé Softwaru GNOME" -+msgid "Copyright © 2016–2023 GNOME Software contributors" -+msgstr "Copyright © 2016 – 2023 přispěvatelé Softwaru GNOME" - - #: src/gs-application.c:273 src/gs-application.c:282 - msgid "translator-credits" -@@ -1067,7 +1083,7 @@ msgstr "" - - #. TRANSLATORS: this is the title of the about window - #. TRANSLATORS: this is the menu item that opens the about window --#: src/gs-application.c:287 src/gs-shell.c:2163 -+#: src/gs-application.c:287 src/gs-shell.c:2127 - msgid "About Software" - msgstr "O aplikaci Software" - -@@ -1077,11 +1093,11 @@ msgid "A nice way to manage the software on your system." - msgstr "Elegantní způsob správy softwaru ve vašem počítači." - - #. TRANSLATORS: we tried to show an app that did not exist --#: src/gs-application.c:478 -+#: src/gs-application.c:507 - msgid "Sorry! There are no details for that application." - msgstr "Omlouváme se, ale pro tuto aplikaci nejsou k dispozici detaily." - --#. Translators: The disk usage of an application when installed. -+#. Translators: The disk usage of an app when installed. - #. * This is displayed in a context tile, so the string should be short. - #: src/gs-app-context-bar.c:162 src/gs-storage-context-dialog.c:133 - msgid "Installed Size" -@@ -1106,7 +1122,7 @@ msgstr "Obsahuje %s mezipaměti" - msgid "Cache and data usage unknown" - msgstr "Využití mezipaměti a dat není známo" - --#. Translators: The download size of an application. -+#. Translators: The download size of an app. - #. * This is displayed in a context tile, so the string should be short. - #: src/gs-app-context-bar.c:187 src/gs-storage-context-dialog.c:165 - msgid "Download Size" -@@ -1136,117 +1152,123 @@ msgstr "Velikost je neznámá" - - #. Translators: This indicates an app requires no permissions to run. - #. * It’s used in a context tile, so should be short. --#: src/gs-app-context-bar.c:282 -+#: src/gs-app-context-bar.c:281 - msgid "No permissions" - msgstr "Žádná oprávnění" - - #. Translators: This indicates an app uses the network. - #. * It’s used in a context tile, so should be short. --#: src/gs-app-context-bar.c:293 -+#: src/gs-app-context-bar.c:292 - msgid "Has network access" - msgstr "Má přístup k síti" - - #. Translators: This indicates an app uses D-Bus system services. - #. * It’s used in a context tile, so should be short. --#: src/gs-app-context-bar.c:300 -+#: src/gs-app-context-bar.c:299 - msgid "Uses system services" - msgstr "Využívá služby systému" - - #. Translators: This indicates an app uses D-Bus session services. - #. * It’s used in a context tile, so should be short. --#: src/gs-app-context-bar.c:307 -+#: src/gs-app-context-bar.c:306 - msgid "Uses session services" - msgstr "Využívá služby sezení" - - #. Translators: This indicates an app can access arbitrary hardware devices. - #. * It’s used in a context tile, so should be short. --#: src/gs-app-context-bar.c:314 -+#: src/gs-app-context-bar.c:313 - msgid "Can access hardware devices" - msgstr "Může přistupovat k hardwarovým zařízením" - -+#. Translators: This indicates an app can access system devices such as /dev/shm. -+#. * It’s used in a context tile, so should be short. -+#: src/gs-app-context-bar.c:320 -+msgid "Can access system devices" -+msgstr "Může přistupovat k systémovým zařízením" -+ - #. Translators: This indicates an app can read/write to the user’s home or the entire filesystem. - #. * It’s used in a context tile, so should be short. --#: src/gs-app-context-bar.c:326 -+#: src/gs-app-context-bar.c:332 - msgid "Can read/write all your data" - msgstr "Může číst/zapisovat všechna vaše data" - - #. Translators: This indicates an app can read (but not write) from the user’s home or the entire filesystem. - #. * It’s used in a context tile, so should be short. --#: src/gs-app-context-bar.c:338 -+#: src/gs-app-context-bar.c:344 - msgid "Can read all your data" - msgstr "Může číst všechna vaše data" - - #. Translators: This indicates an app can read/write to the user’s Downloads directory. - #. * It’s used in a context tile, so should be short. --#: src/gs-app-context-bar.c:345 -+#: src/gs-app-context-bar.c:351 - msgid "Can read/write your downloads" - msgstr "Může zapisovat do všech vašich dat" - - #. Translators: This indicates an app can read (but not write) from the user’s Downloads directory. - #. * It’s used in a context tile, so should be short. --#: src/gs-app-context-bar.c:352 -+#: src/gs-app-context-bar.c:358 - msgid "Can read your downloads" - msgstr "Může číst vaše stažené soubory" - - #. Translators: This indicates an app can access data in the system unknown to the Software. - #. * It’s used in a context tile, so should be short. --#: src/gs-app-context-bar.c:359 -+#: src/gs-app-context-bar.c:365 - msgid "Can access arbitrary files" - msgstr "Může přistupovat k libovolným souborům" - - #. Translators: This indicates an app can access or change user settings. - #. * It’s used in a context tile, so should be short. --#: src/gs-app-context-bar.c:366 src/gs-safety-context-dialog.c:227 -+#: src/gs-app-context-bar.c:372 src/gs-safety-context-dialog.c:234 - msgid "Can access and change user settings" - msgstr "Může zobrazovat a měnit uživatelská nastavení" - - #. Translators: This indicates an app uses the X11 windowing system. - #. * It’s used in a context tile, so should be short. --#: src/gs-app-context-bar.c:373 src/gs-safety-context-dialog.c:211 -+#: src/gs-app-context-bar.c:379 src/gs-safety-context-dialog.c:218 - msgid "Uses a legacy windowing system" - msgstr "Používá starý zobrazovací systém" - - #. Translators: This indicates an app can escape its sandbox. - #. * It’s used in a context tile, so should be short. --#: src/gs-app-context-bar.c:380 src/gs-safety-context-dialog.c:219 -+#: src/gs-app-context-bar.c:386 src/gs-safety-context-dialog.c:226 - msgid "Can acquire arbitrary permissions" - msgstr "Může získat libovolná oprávnění" - --#. Translators: This indicates that an application has been packaged -+#. Translators: This indicates that an app has been packaged - #. * by the user’s distribution and is safe. - #. * It’s used in a context tile, so should be short. --#: src/gs-app-context-bar.c:406 src/gs-safety-context-dialog.c:146 -+#: src/gs-app-context-bar.c:412 src/gs-safety-context-dialog.c:145 - msgid "Reviewed by your distribution" - msgstr "Zkontrolováno vaší distribucí" - --#. Translators: This indicates that an application has been packaged -+#. Translators: This indicates that an app has been packaged - #. * by someone other than the user’s distribution, so might not be safe. - #. * It’s used in a context tile, so should be short. --#: src/gs-app-context-bar.c:413 src/gs-safety-context-dialog.c:143 -+#: src/gs-app-context-bar.c:419 src/gs-safety-context-dialog.c:142 - msgid "Provided by a third party" - msgstr "Poskytováno třetí stranou" - - #. Translators: This indicates an app is not licensed under a free software license. - #. * It’s used in a context tile, so should be short. --#: src/gs-app-context-bar.c:425 -+#: src/gs-app-context-bar.c:431 - msgid "Proprietary code" - msgstr "Uzavřený kód" - - #. Translators: This indicates an app’s source code is freely available, so can be audited for security. - #. * It’s used in a context tile, so should be short. --#: src/gs-app-context-bar.c:431 -+#: src/gs-app-context-bar.c:437 - msgid "Auditable code" - msgstr "Otevřený kód" - - #. Translators: This indicates an app was written and released by a developer who has been verified. - #. * It’s used in a context tile, so should be short. --#: src/gs-app-context-bar.c:438 -+#: src/gs-app-context-bar.c:444 - msgid "Software developer is verified" - msgstr "Vývojář softwaru je ověřený" - - #. Translators: This indicates an app or its runtime reached its end of life. - #. * It’s used in a context tile, so should be short. --#: src/gs-app-context-bar.c:447 -+#: src/gs-app-context-bar.c:453 - msgid "Software no longer supported" - msgstr "Software není nadále podporován" - -@@ -1264,180 +1286,180 @@ msgstr "Software není nadále podporován" - #. * If concatenating strings as a list using a separator like this is not - #. * possible in your language, please file an issue against gnome-software: - #. * https://gitlab.gnome.org/GNOME/gnome-software/-/issues/new --#: src/gs-app-context-bar.c:459 src/gs-app-context-bar.c:730 -+#: src/gs-app-context-bar.c:465 src/gs-app-context-bar.c:731 - msgid "; " - msgstr "; " - - #. Translators: The app is considered safe to install and run. - #. * This is displayed in a context tile, so the string should be short. --#: src/gs-app-context-bar.c:467 -+#: src/gs-app-context-bar.c:473 - msgid "Safe" - msgstr "Bezpečné" - - #. Translators: The app is considered potentially unsafe to install and run. - #. * This is displayed in a context tile, so the string should be short. --#: src/gs-app-context-bar.c:474 -+#: src/gs-app-context-bar.c:480 - msgid "Potentially Unsafe" - msgstr "Potenciálně nebezpečné" - - #. Translators: The app is considered unsafe to install and run. - #. * This is displayed in a context tile, so the string should be short. --#: src/gs-app-context-bar.c:481 -+#: src/gs-app-context-bar.c:487 - msgid "Unsafe" - msgstr "Nebezpečné" - --#: src/gs-app-context-bar.c:560 src/gs-app-context-bar.c:592 --#: src/gs-hardware-support-context-dialog.c:603 -+#: src/gs-app-context-bar.c:563 src/gs-app-context-bar.c:595 -+#: src/gs-hardware-support-context-dialog.c:602 - msgid "Mobile Only" - msgstr "Jen pro mobilní zařízení" - --#: src/gs-app-context-bar.c:561 -+#: src/gs-app-context-bar.c:564 - msgid "Only works on a small screen" - msgstr "Funguje pouze na malé obrazovce" - --#: src/gs-app-context-bar.c:566 src/gs-app-context-bar.c:599 --#: src/gs-app-context-bar.c:606 src/gs-app-context-bar.c:656 --#: src/gs-app-context-bar.c:661 src/gs-hardware-support-context-dialog.c:583 -+#: src/gs-app-context-bar.c:569 src/gs-app-context-bar.c:602 -+#: src/gs-app-context-bar.c:609 src/gs-app-context-bar.c:659 -+#: src/gs-app-context-bar.c:664 src/gs-hardware-support-context-dialog.c:582 - msgid "Desktop Only" - msgstr "Pouze pro PC" - --#: src/gs-app-context-bar.c:567 -+#: src/gs-app-context-bar.c:570 - msgid "Only works on a large screen" - msgstr "Funguje pouze na velké obrazovce" - --#: src/gs-app-context-bar.c:571 src/gs-hardware-support-context-dialog.c:621 -+#: src/gs-app-context-bar.c:574 src/gs-hardware-support-context-dialog.c:620 - msgid "Screen Size Mismatch" - msgstr "Nesoulad velikosti obrazovky" - --#: src/gs-app-context-bar.c:572 src/gs-hardware-support-context-dialog.c:622 -+#: src/gs-app-context-bar.c:575 src/gs-hardware-support-context-dialog.c:621 - msgid "Doesn’t support your current screen size" - msgstr "Nepodporuje vaši současnou velikost obrazovky" - --#: src/gs-app-context-bar.c:593 src/gs-hardware-support-context-dialog.c:674 --#: src/gs-hardware-support-context-dialog.c:680 -+#: src/gs-app-context-bar.c:596 src/gs-hardware-support-context-dialog.c:673 -+#: src/gs-hardware-support-context-dialog.c:679 - msgid "Requires a touchscreen" - msgstr "Vyžaduje dotykovou obrazovku" - --#: src/gs-app-context-bar.c:600 src/gs-hardware-support-context-dialog.c:634 --#: src/gs-hardware-support-context-dialog.c:640 -+#: src/gs-app-context-bar.c:603 src/gs-hardware-support-context-dialog.c:633 -+#: src/gs-hardware-support-context-dialog.c:639 - msgid "Requires a keyboard" - msgstr "Vyžaduje klávesnici" - --#: src/gs-app-context-bar.c:607 -+#: src/gs-app-context-bar.c:610 - msgid "Requires a mouse" - msgstr "Vyžaduje myš" - --#: src/gs-app-context-bar.c:618 -+#: src/gs-app-context-bar.c:621 - msgid "Gamepad Needed" - msgstr "Vyžaduje herní ovladač" - --#: src/gs-app-context-bar.c:619 -+#: src/gs-app-context-bar.c:622 - msgid "Requires a gamepad to play" - msgstr "Ke hraní vyžaduje herní ovladač" - - #. Translators: This is used in a context tile to indicate that - #. * an app works on phones, tablets *and* desktops. It should be - #. * short and in title case. --#: src/gs-app-context-bar.c:643 -+#: src/gs-app-context-bar.c:646 - msgid "Adaptive" - msgstr "Adaptivní" - --#: src/gs-app-context-bar.c:644 -+#: src/gs-app-context-bar.c:647 - msgid "Works on phones, tablets and desktops" - msgstr "Funguje na telefonech, tabletech a PC" - --#: src/gs-app-context-bar.c:657 -+#: src/gs-app-context-bar.c:660 - msgid "Probably requires a keyboard or mouse" - msgstr "Pravděpodobně vyžaduje klávesnici nebo myš" - --#: src/gs-app-context-bar.c:662 -+#: src/gs-app-context-bar.c:665 - msgid "Works on desktops and laptops" - msgstr "Funguje na PC a laptopech" - - #. Translators: This indicates that the content rating for an - #. * app says it can be used by all ages of people, as it contains - #. * no objectionable content. --#: src/gs-app-context-bar.c:705 -+#: src/gs-app-context-bar.c:706 - msgid "Contains no age-inappropriate content" - msgstr "Neobsahuje žádný věkově nevhodný obsah" - --#: src/gs-app-context-bar.c:753 -+#: src/gs-app-context-bar.c:754 - msgid "No age rating information available" - msgstr "Informace o věkové kategorii nejsou k dispozici" - - #. TRANSLATORS: this is a button next to the search results that --#. * allows the application to be easily installed --#: src/gs-app-row.c:155 -+#. * allows the app to be easily installed -+#: src/gs-app-row.c:154 - msgid "Visit Website" - msgstr "Navštívit webové stránky" - - #. TRANSLATORS: this is a button next to the search results that --#. * allows the application to be easily installed. -+#. * allows the app to be easily installed. - #. * The ellipsis indicates that further steps are required --#: src/gs-app-row.c:161 -+#: src/gs-app-row.c:160 - msgid "Install…" - msgstr "Instalovat…" - - #. TRANSLATORS: this is a button next to the search results that --#. * allows to cancel a queued install of the application --#: src/gs-app-row.c:169 src/gs-updates-section.ui:62 -+#. * allows to cancel a queued install of the app -+#: src/gs-app-row.c:168 src/gs-updates-section.ui:63 - msgid "Cancel" - msgstr "Zrušit" - - #. TRANSLATORS: this is a button next to the search results that --#. * allows the application to be easily installed --#. TRANSLATORS: button text --#. TRANSLATORS: update the fw --#: src/gs-app-row.c:177 src/gs-common.c:307 src/gs-page.c:374 -+#. * allows the app to be easily installed -+#: src/gs-app-row.c:176 - msgid "Install" - msgstr "Instalovat" - - #. TRANSLATORS: this is a button in the updates panel - #. * that allows the app to be easily updated live --#: src/gs-app-row.c:185 -+#: src/gs-app-row.c:184 - msgid "Update" - msgstr "Aktualizovat" - - #. TRANSLATORS: this is a button next to the search results that --#. * allows the application to be easily removed --#. TRANSLATORS: button text in the header when an application can be erased --#. TRANSLATORS: this is button text to remove the application --#: src/gs-app-row.c:191 src/gs-app-row.c:201 src/gs-details-page.ui:280 --#: src/gs-details-page.ui:290 src/gs-page.c:549 --msgid "Uninstall" --msgstr "Odinstalovat" -+#. * allows the app to be easily removed -+#: src/gs-app-row.c:190 src/gs-app-row.c:200 -+msgid "Uninstall…" -+msgstr "Odinstalovat…" - - #. TRANSLATORS: this is a button next to the search results that --#. * shows the status of an application being erased --#: src/gs-app-row.c:215 -+#. * shows the status of an app being erased -+#: src/gs-app-row.c:214 - msgid "Uninstalling" - msgstr "Odinstalovává se" - - #. TRANSLATORS: during the update the device - #. * will restart into a special update-only mode --#: src/gs-app-row.c:330 -+#: src/gs-app-row.c:327 - msgid "Device cannot be used during update." - msgstr "Zařízení nelze během aktualizace používat." - - #. TRANSLATORS: this refers to where the app came from --#: src/gs-app-row.c:340 src/gs-shell-search-provider.c:264 -+#: src/gs-app-row.c:337 src/gs-shell-search-provider.c:268 - #, c-format - msgid "Source: %s" - msgstr "Zdroj: %s" - - #. Translators: A message to indicate that an app has been renamed. The placeholder is the old human-readable name. --#: src/gs-app-row.c:530 -+#: src/gs-app-row.c:522 - #, c-format - msgid "Renamed from %s" - msgstr "Přejmenováno z %s" - --#. Translators: The placeholder is an application name -+#: src/gs-app-row.ui:197 src/gs-app-tile.ui:50 src/gs-feature-tile.c:543 -+msgctxt "Single app" -+msgid "Installed" -+msgstr "Nainstalováno" -+ -+#. Translators: The placeholder is an app name - #: src/gs-app-translation-dialog.c:67 - #, c-format - msgid "Help Translate %s" - msgstr "Pomozte přeložit %s" - --#. Translators: The placeholder is an application name -+#. Translators: The placeholder is an app name - #: src/gs-app-translation-dialog.c:70 - #, c-format - msgid "" -@@ -1451,7 +1473,7 @@ msgstr "" - "dobrovolníků.\n" - "\n" - "To znamená, že i když ještě není k dispozici ve vašem jazyce, můžete se " --"zapojit a pomoci s jeho překladem." -+"zapojit a pomoci s jejím překladem." - - #: src/gs-app-translation-dialog.ui:5 - msgid "Translations" -@@ -1467,29 +1489,35 @@ msgstr "_Stránka překladu" - msgid "Login required remote %s (realm %s)" - msgstr "Vyžadováno přihlášení vzdáleným %s (sféra %s)" - --#: src/gs-basic-auth-dialog.ui:13 -+#: src/gs-basic-auth-dialog.ui:6 - msgid "Login Required" - msgstr "Vyžadováno přihlášení" - --#: src/gs-basic-auth-dialog.ui:21 src/gs-common.c:721 --#: src/gs-details-page.ui:306 src/gs-removal-dialog.ui:28 --#: src/gs-review-dialog.ui:18 -+#. TRANSLATORS: button text -+#: src/gs-basic-auth-dialog.ui:12 src/gs-common.c:296 src/gs-common.c:697 -+#: src/gs-details-page.ui:297 src/gs-page.c:410 src/gs-page.c:549 -+#: src/gs-removal-dialog.ui:28 src/gs-repos-dialog.c:171 -+#: src/gs-repos-dialog.c:249 src/gs-review-dialog.ui:18 src/gs-review-row.c:237 -+#: src/gs-updates-page.c:847 src/gs-updates-page.c:864 - msgid "_Cancel" - msgstr "_Zrušit" - --#: src/gs-basic-auth-dialog.ui:35 -+#: src/gs-basic-auth-dialog.ui:24 - msgid "_Login" - msgstr "Přih_lásit" - --#: src/gs-basic-auth-dialog.ui:88 --msgid "_User" --msgstr "_Uživatel" -+#. Translators: Placeholder text for a login entry. -+#. Translators: It's an origin scope, 'User' or 'System' installation -+#: src/gs-basic-auth-dialog.ui:60 src/gs-origin-popover-row.ui:138 -+msgid "User" -+msgstr "Uživatel" - --#: src/gs-basic-auth-dialog.ui:107 --msgid "_Password" --msgstr "_Heslo" -+#. Translators: Placeholder text for a login entry. -+#: src/gs-basic-auth-dialog.ui:73 -+msgid "Password" -+msgstr "Heslo" - --#. TRANSLATORS: this is where all applications that don't -+#. TRANSLATORS: this is where all apps that don't - #. * fit in other groups are put - #: lib/gs-category.c:209 - msgid "Other" -@@ -1509,13 +1537,13 @@ msgstr "Významné" - - #. Heading for featured apps on a category page - #. Translators: This is a heading for software which has been featured ('picked') by the distribution. --#: src/gs-category-page.ui:41 src/gs-overview-page.ui:106 -+#: src/gs-category-page.ui:41 src/gs-overview-page.ui:69 - msgid "Editor’s Choice" - msgstr "Výběr od distribuce" - - #. Heading for recently updated apps on a category page - #. Translators: This is a heading for software which has been recently released upstream. --#: src/gs-category-page.ui:69 src/gs-overview-page.ui:129 -+#: src/gs-category-page.ui:69 src/gs-overview-page.ui:92 - msgid "New & Updated" - msgstr "Nové a aktualizované" - -@@ -1530,14 +1558,14 @@ msgid "Other Software" - msgstr "Ostatní" - - #. TRANSLATORS: the user isn't reading the question --#: lib/gs-cmd.c:194 -+#: lib/gs-cmd.c:195 - #, c-format - msgid "Please enter a number from 1 to %u: " - msgstr "Zadejte prosím číslo od 1 do %u: " - - #. TRANSLATORS: asking the user to choose an app from a list --#: lib/gs-cmd.c:266 --msgid "Choose an application:" -+#: lib/gs-cmd.c:283 -+msgid "Choose an app:" - msgstr "Vyberte aplikaci:" - - #: lib/gs-desktop-data.c:16 -@@ -1910,7 +1938,7 @@ msgstr "Jazykové balíčky" - msgid "Localization" - msgstr "Lokalizace" - --#. TRANSLATORS: this is the summary of a notification that an application -+#. TRANSLATORS: this is the summary of a notification that an app - #. * has been successfully installed - #. TRANSLATORS: this is the summary of a notification that a component - #. * has been successfully installed -@@ -1919,16 +1947,16 @@ msgstr "Lokalizace" - msgid "%s is now installed" - msgstr "Aplikace %s je nyní nainstalována" - --#. TRANSLATORS: an application has been installed, but -+#. TRANSLATORS: an app has been installed, but - #. * needs a reboot to complete the installation - #: src/gs-common.c:73 src/gs-common.c:96 - msgid "A restart is required for the changes to take effect." - msgstr "Aby se změny projevily, je zapotřebí provést restart." - --#. TRANSLATORS: this is the body of a notification that an application -+#. TRANSLATORS: this is the body of a notification that an app - #. * has been successfully installed - #: src/gs-common.c:77 --msgid "Application is ready to be used." -+msgid "App is ready to be used." - msgstr "Aplikace je připravená k použití." - - #. TRANSLATORS: this is the summary of a notification that OS updates -@@ -1944,7 +1972,7 @@ msgid "Recently installed updates are available to review" - msgstr "Nedávno nainstalované aktualizace jsou k dispozici pro recenze" - - #. TRANSLATORS: button text --#: src/gs-common.c:107 src/gs-common.c:884 -+#: src/gs-common.c:107 src/gs-common.c:860 - msgid "Restart" - msgstr "Restartovat" - -@@ -1953,97 +1981,98 @@ msgid "Launch" - msgstr "Spustit" - - #. TRANSLATORS: window title --#: src/gs-common.c:234 --#, fuzzy --#| msgid "Install Unsigned Software?" -+#: src/gs-common.c:230 - msgid "Install Software?" --msgstr "Nainstalovat nepodepsaný software?" -+msgstr "Nainstalovat software?" - - #. TRANSLATORS: window title --#: src/gs-common.c:236 -+#: src/gs-common.c:232 - msgid "Install Third-Party Software?" - msgstr "Instalovat software třetí strany?" - - #. TRANSLATORS: window title --#: src/gs-common.c:241 --#, fuzzy --#| msgid "Enable Third-Party Software Repository?" -+#: src/gs-common.c:236 - msgid "Enable Software Repository?" --msgstr "Povolit repozitář softwaru třetí strany?" -+msgstr "Povolit repozitář softwaru?" - - #. TRANSLATORS: window title --#: src/gs-common.c:243 src/gs-repos-dialog.c:168 -+#: src/gs-common.c:238 src/gs-repos-dialog.c:168 - msgid "Enable Third-Party Software Repository?" - msgstr "Povolit repozitář softwaru třetí strany?" - - #. TRANSLATORS: the replacements are as follows: --#. * 1. Application name, e.g. "Firefox" -+#. * 1. App name, e.g. "Firefox" - #. * 2. Software repository name, e.g. fedora-optional - #. --#: src/gs-common.c:261 -+#: src/gs-common.c:250 - #, c-format - msgid "" - "%s is not free and open source software, and is provided by “%s”." - msgstr "" --"%s není svobodný a otevřený software a poskytuje jej „%s“." -+"%s není svobodný a otevřený software a poskytuje jej „%s“." - - #. TRANSLATORS: the replacements are as follows: --#. * 1. Application name, e.g. "Firefox" -+#. * 1. App name, e.g. "Firefox" - #. * 2. Software repository name, e.g. fedora-optional --#: src/gs-common.c:271 -+#: src/gs-common.c:260 - #, c-format - msgid "%s is provided by “%s”." - msgstr "%s poskytuje „%s“." - --#: src/gs-common.c:280 -+#: src/gs-common.c:269 - msgid "This software repository must be enabled to continue installation." - msgstr "" - "Aby bylo možné pokračovat v instalaci, je nutné povolit tento repozitář " - "softwaru." - - #. TRANSLATORS: Laws are geographical, urgh... --#: src/gs-common.c:290 -+#: src/gs-common.c:279 - #, c-format - msgid "It may be illegal to install or use %s in some countries." - msgstr "" - "V některých zemích nemusí být instalace a používání softwaru %s legální." - - #. TRANSLATORS: Laws are geographical, urgh... --#: src/gs-common.c:296 -+#: src/gs-common.c:285 - msgid "It may be illegal to install or use this codec in some countries." - msgstr "" - "V některých zemích nemusí být instalace a používání tohoto kodeku legální." - - #. TRANSLATORS: this is button text to not ask about non-free content again --#: src/gs-common.c:303 --msgid "Don’t Warn Again" --msgstr "Příště nevarovat" -+#: src/gs-common.c:299 -+msgid "Don’t _Warn Again" -+msgstr "Příště _nevarovat" - - #. TRANSLATORS: button text --#: src/gs-common.c:312 --msgid "Enable and Install" --msgstr "Povolit a nainstalovat" -+#: src/gs-common.c:308 -+msgid "Enable and _Install" -+msgstr "Povolit a na_instalovat" - - #. TRANSLATORS: these are show_detailed_error messages from the - #. * package manager no mortal is supposed to understand, - #. * but google might know what they mean --#: src/gs-common.c:514 -+#: src/gs-common.c:511 - msgid "Detailed errors from the package manager follow:" - msgstr "Dále jsou uvedeny podrobnosti o chybě získané od správy balíčků:" - --#: src/gs-common.c:530 src/gs-safety-context-dialog.ui:72 -+#: src/gs-common.c:518 src/gs-safety-context-dialog.ui:72 - msgid "Details" - msgstr "Podrobnosti" - -+#. TRANSLATORS: button text -+#: src/gs-common.c:567 -+msgid "_Close" -+msgstr "_Zavřít" -+ - #. Translators: an accept button label, in a Cancel/Accept dialog --#: src/gs-common.c:709 -+#: src/gs-common.c:689 - msgid "_Accept" - msgstr "_Přijmout" - - #. TRANSLATORS: we've just live-updated some apps --#: src/gs-common.c:859 -+#: src/gs-common.c:835 - msgid "An update has been installed" - msgid_plural "Updates have been installed" - msgstr[0] "Aktualizace byla nainstalována" -@@ -2051,15 +2080,15 @@ msgstr[1] "Aktualizace byly nainstalovány" - msgstr[2] "Aktualizace byly nainstalovány" - - #. TRANSLATORS: we've just removed some apps --#: src/gs-common.c:869 --msgid "An application has been removed" --msgid_plural "Applications have been removed" -+#: src/gs-common.c:845 -+msgid "An app has been removed" -+msgid_plural "Apps have been removed" - msgstr[0] "Aplikace byla odebrána" - msgstr[1] "Aplikace byly odebrány" - msgstr[2] "Aplikace byly odebrány" - - #. TRANSLATORS: the new apps will not be run until we restart --#: src/gs-common.c:875 -+#: src/gs-common.c:851 - msgid "A restart is required for it to take effect." - msgid_plural "A restart is required for them to take effect." - msgstr[0] "Aby se projevila, je zapotřebí provést restart." -@@ -2067,16 +2096,16 @@ msgstr[1] "Aby se projevily, je zapotřebí provést restart." - msgstr[2] "Aby se projevily, je zapotřebí provést restart." - - #. TRANSLATORS: button text --#: src/gs-common.c:882 -+#: src/gs-common.c:858 - msgid "Not Now" - msgstr "Nyní ne" - - #. TRANSLATORS: something happened less than 5 minutes ago --#: src/gs-common.c:978 -+#: src/gs-common.c:954 - msgid "Just now" - msgstr "právě teď" - --#: src/gs-common.c:980 -+#: src/gs-common.c:956 - #, c-format - msgid "%d minute ago" - msgid_plural "%d minutes ago" -@@ -2084,7 +2113,7 @@ msgstr[0] "před %d minutou" - msgstr[1] "před %d minutami" - msgstr[2] "před %d minutami" - --#: src/gs-common.c:984 -+#: src/gs-common.c:960 - #, c-format - msgid "%d hour ago" - msgid_plural "%d hours ago" -@@ -2092,7 +2121,7 @@ msgstr[0] "před %d hodinou" - msgstr[1] "před %d hodinami" - msgstr[2] "před %d hodinami" - --#: src/gs-common.c:988 -+#: src/gs-common.c:964 - #, c-format - msgid "%d day ago" - msgid_plural "%d days ago" -@@ -2100,7 +2129,7 @@ msgstr[0] "před %d dnem" - msgstr[1] "před %d dny" - msgstr[2] "před %d dny" - --#: src/gs-common.c:992 -+#: src/gs-common.c:968 - #, c-format - msgid "%d week ago" - msgid_plural "%d weeks ago" -@@ -2108,7 +2137,7 @@ msgstr[0] "před %d týdnem" - msgstr[1] "před %d týdny" - msgstr[2] "před %d týdny" - --#: src/gs-common.c:996 -+#: src/gs-common.c:972 - #, c-format - msgid "%d month ago" - msgid_plural "%d months ago" -@@ -2116,7 +2145,7 @@ msgstr[0] "před %d měsícem" - msgstr[1] "před %d měsíci" - msgstr[2] "před %d měsíci" - --#: src/gs-common.c:1000 -+#: src/gs-common.c:976 - #, c-format - msgid "%d year ago" - msgid_plural "%d years ago" -@@ -2128,7 +2157,7 @@ msgstr[2] "před %d lety" - #. * the unit is drawn with a smaller font. If you need to flip the order, then you can use "%2$s %1$s". - #. * Make sure you'll preserve the no break space between the values. - #. * Example result: "13.0 MB" --#: src/gs-common.c:1364 -+#: src/gs-common.c:1340 - #, c-format - msgctxt "format-size" - msgid "%s %s" -@@ -2136,7 +2165,7 @@ msgstr "%s %s" - - #. TRANSLATORS: this is a what we use in notifications if the app's name is unknown - #: src/gs-dbus-helper.c:291 --msgid "An application" -+msgid "An app" - msgstr "Nějaká aplikace" - - #. TRANSLATORS: this is a notification displayed when an app needs additional MIME types. -@@ -2199,58 +2228,49 @@ msgstr "Požadavek na dodatečné balíčky" - msgid "Find in Software" - msgstr "Najít v aplikaci Software" - --#: src/gs-description-box.c:67 src/gs-description-box.c:269 -+#: src/gs-description-box.c:87 src/gs-description-box.c:335 - msgid "_Show More" - msgstr "Zobrazit _více" - --#: src/gs-description-box.c:67 -+#: src/gs-description-box.c:87 - msgid "_Show Less" - msgstr "Zobrazit _méně" - --#: src/gs-details-page.c:357 -+#: src/gs-details-page.c:367 - msgid "Removing…" - msgstr "Odebírá se…" - --#: src/gs-details-page.c:367 -+#: src/gs-details-page.c:377 - msgid "Requires restart to finish install" - msgstr "Vyžaduje restart k dokončení instalace" - --#: src/gs-details-page.c:374 -+#: src/gs-details-page.c:384 - msgid "Requires restart to finish remove" - msgstr "Vyžaduje restart k dokončení odebírání" - - #. TRANSLATORS: This is a label on top of the app's progress - #. * bar to inform the user that the app should be installed soon --#: src/gs-details-page.c:391 -+#: src/gs-details-page.c:401 - msgid "Pending installation…" - msgstr "Probíhá instalace…" - - #. TRANSLATORS: This is a label on top of the app's progress - #. * bar to inform the user that the app should be updated soon --#: src/gs-details-page.c:398 -+#: src/gs-details-page.c:407 - msgid "Pending update…" - msgstr "Probíhá aktualizace…" - - #. Translators: This string is shown when preparing to download and install an app. --#: src/gs-details-page.c:414 -+#: src/gs-details-page.c:421 - msgid "Preparing…" - msgstr "Připravuje se…" - - #. Translators: This string is shown when uninstalling an app. --#: src/gs-details-page.c:417 -+#: src/gs-details-page.c:424 - msgid "Uninstalling…" - msgstr "Odinstalovává se…" - --#. TRANSLATORS: button text in the header when an application --#. * can be installed --#. TRANSLATORS: button text in the header when firmware --#. * can be live-installed --#: src/gs-details-page.c:908 src/gs-details-page.c:934 --#: src/gs-details-page.ui:229 plugins/packagekit/gs-packagekit-task.c:150 --msgid "_Install" --msgstr "_Instalovat" -- --#: src/gs-details-page.c:924 -+#: src/gs-details-page.c:940 - msgid "_Restart" - msgstr "_Restartovat" - -@@ -2258,22 +2278,40 @@ msgstr "_Restartovat" - #. * be installed. - #. * The ellipsis indicates that further steps are required, - #. * e.g. enabling software repositories or the like --#: src/gs-details-page.c:948 -+#: src/gs-details-page.c:964 - msgid "_Install…" - msgstr "_Instalovat…" - -+#: src/gs-details-page.c:1031 -+msgid "_Uninstall…" -+msgstr "_Odinstalovat…" -+ -+#. Translators: %s is the user-visible app name -+#: src/gs-details-page.c:1175 -+#, c-format -+msgid "%s will appear in US English" -+msgstr "Aplikace %s se zobrazí v americké angličtině" -+ -+#: src/gs-details-page.c:1181 -+msgid "This app will appear in US English" -+msgstr "Tato aplikace se zobrazí v americké angličtině" -+ -+#: src/gs-details-page.c:1196 src/gs-details-page.ui:59 -+msgid "Help _Translate" -+msgstr "_Pomoci přeložit" -+ - #. Translators: the '%s' is replaced with a developer name or a project group --#: src/gs-details-page.c:1237 -+#: src/gs-details-page.c:1260 - #, c-format - msgid "Other Apps by %s" - msgstr "Co dalšího nabízí %s" - - #. TRANSLATORS: we need a remote server to process --#: src/gs-details-page.c:1620 -+#: src/gs-details-page.c:1637 - msgid "You need internet access to write a review" - msgstr "Abyste mohli napsat recenzi, musíte být připojeni k Internetu" - --#: src/gs-details-page.c:1790 src/gs-details-page.c:1806 -+#: src/gs-details-page.c:1822 src/gs-details-page.c:1838 - #, c-format - msgid "Unable to find “%s”" - msgstr "Nelze najít „%s“" -@@ -2283,74 +2321,61 @@ msgid "Details page" - msgstr "Stránka s podrobnostmi" - - #: src/gs-details-page.ui:39 --msgid "Loading application details…" -+msgid "Loading app details…" - msgstr "Načítají se podrobnosti o aplikaci…" - --#: src/gs-details-page.ui:77 --msgid "" --"This software is not available in your language and will appear in US " --"English." --msgstr "" --"Tento software není dostupný ve vašem jazyce a zobrazí se v americké " --"angličtině." -- --#: src/gs-details-page.ui:83 --msgid "Help _Translate" --msgstr "_Pomoci přeložit" -- --#. TRANSLATORS: A label for a button to execute the selected application. --#: src/gs-details-page.ui:246 -+#. TRANSLATORS: A label for a button to execute the selected app. -+#: src/gs-details-page.ui:226 - msgid "_Open" - msgstr "_Otevřít" - --#: src/gs-details-page.ui:262 plugins/packagekit/gs-packagekit-task.c:160 -+#: src/gs-details-page.ui:242 plugins/packagekit/gs-packagekit-task.c:159 - msgid "_Update" - msgstr "_Aktualizovat" - --#: src/gs-details-page.ui:331 -+#. TRANSLATORS: button text in the header when an app can be erased -+#: src/gs-details-page.ui:260 src/gs-details-page.ui:270 -+msgid "Uninstall" -+msgstr "Odinstalovat" -+ -+#: src/gs-details-page.ui:322 - msgid "Downloading" - msgstr "Stahuje se" - --#: src/gs-details-page.ui:468 src/gs-installed-page.ui:135 -+#: src/gs-details-page.ui:459 src/gs-installed-page.ui:135 - msgid "Add-ons" - msgstr "Doplňky" - --#: src/gs-details-page.ui:479 --msgid "Selected add-ons will be installed with the application." --msgstr "Vybrané doplňky budou nainstalovány spolu s aplikací." -- --#: src/gs-details-page.ui:579 --msgid "" --"This application can only be used when there is an active internet " --"connection." -+#: src/gs-details-page.ui:563 -+msgid "This app can only be used when there is an active internet connection." - msgstr "" - "Tuto aplikaci je možné používat, jen když je funkční připojení k Internetu." - --#: src/gs-details-page.ui:599 -+#: src/gs-details-page.ui:586 - msgid "Software Repository Included" - msgstr "Součástí je repozitář softwaru" - --#: src/gs-details-page.ui:600 -+#: src/gs-details-page.ui:596 - msgid "" --"This application includes a software repository which provides updates, as " --"well as access to other software." -+"This app includes a software repository which provides updates, as well as " -+"access to other software." - msgstr "" - "Součástí této aplikace je repozitář softwaru, který poskytuje aktualizace a " - "přístup k dalšímu softwaru." - --#: src/gs-details-page.ui:617 -+#: src/gs-details-page.ui:624 - msgid "No Software Repository Included" - msgstr "Součástí není žádný repozitář softwaru" - --#: src/gs-details-page.ui:618 -+#: src/gs-details-page.ui:634 - msgid "" --"This application does not include a software repository. It will not be " --"updated with new versions." -+"This app does not include a software repository. It will not be updated with " -+"new versions." - msgstr "" - "Součástí této aplikace není žádný repozitář softwaru. Nebude tak průběžně " - "aktualizována na novější verze." - --#: src/gs-details-page.ui:636 -+#: src/gs-details-page.ui:662 - msgid "" - "This software is already provided by your distribution and should not be " - "replaced." -@@ -2358,11 +2383,11 @@ msgstr "" - "Tento software již poskytuje vaše distribuce a neměli byste jej nahrazovat." - - #. Translators: a repository file used for installing software has been discovered. --#: src/gs-details-page.ui:653 -+#: src/gs-details-page.ui:693 - msgid "Software Repository Identified" - msgstr "Rozpoznán repozitář softwaru" - --#: src/gs-details-page.ui:654 -+#: src/gs-details-page.ui:703 - msgid "" - "Adding this software repository will give you access to additional software " - "and upgrades." -@@ -2370,15 +2395,15 @@ msgstr "" - "Přídáním tohoto repozitáře softwaru získáte přístup k dalšímu softwaru a " - "aktualizacím." - --#: src/gs-details-page.ui:655 -+#: src/gs-details-page.ui:710 - msgid "Only use software repositories that you trust." - msgstr "Používejte pouze repozitáře softwaru, kterým věříte." - --#: src/gs-details-page.ui:720 -+#: src/gs-details-page.ui:783 - msgid "No Metadata" - msgstr "Žádná metadata" - --#: src/gs-details-page.ui:729 -+#: src/gs-details-page.ui:792 - msgid "" - "This software doesn’t provide any links to a website, code repository or " - "issue tracker." -@@ -2386,33 +2411,33 @@ msgstr "" - "Tento software neposkytuje žádné odkazy na webové stránky, repozitáře kódu " - "ani nástroj pro sledování problémů." - --#: src/gs-details-page.ui:757 -+#: src/gs-details-page.ui:820 - msgid "Project _Website" - msgstr "_Webové stránky projektu" - --#: src/gs-details-page.ui:774 -+#: src/gs-details-page.ui:837 - msgid "_Donate" - msgstr "Věnovat _dar" - --#: src/gs-details-page.ui:791 -+#: src/gs-details-page.ui:854 - msgid "Contribute _Translations" - msgstr "_Přispět k překladu" - --#: src/gs-details-page.ui:808 -+#: src/gs-details-page.ui:871 - msgid "_Report an Issue" - msgstr "_Nahlásit chybu" - --#: src/gs-details-page.ui:825 -+#: src/gs-details-page.ui:888 - msgid "_Help" - msgstr "_Nápověda" - - #. Translators: Button opening a dialog where the users can write and publish their opinions about the apps. --#: src/gs-details-page.ui:919 --msgid "_Write Review" -+#: src/gs-details-page.ui:982 -+msgid "Write R_eview" - msgstr "Nap_sat recenzi" - - #. Translators: Button opening a dialog showing all reviews for an app. --#: src/gs-details-page.ui:956 -+#: src/gs-details-page.ui:1019 - msgid "All Reviews" - msgstr "Všechny recenze" - -@@ -2431,7 +2456,7 @@ msgstr " a " - msgid ", " - msgstr ", " - --#. TRANSLATORS: Application window title for fonts installation. -+#. TRANSLATORS: App window title for fonts installation. - #. %s will be replaced by name of the script we're searching for. - #: src/gs-extras-page.c:171 - #, c-format -@@ -2441,7 +2466,7 @@ msgstr[0] "Dostupné fonty pro písmo %s" - msgstr[1] "Dostupné fonty pro písma %s" - msgstr[2] "Dostupné fonty pro písma %s" - --#. TRANSLATORS: Application window title for codec installation. -+#. TRANSLATORS: App window title for codec installation. - #. %s will be replaced by actual codec name(s) - #: src/gs-extras-page.c:179 - #, c-format -@@ -2470,11 +2495,11 @@ msgstr "%s nebyl nalezen" - msgid "on the website" - msgstr "na webových stránkách" - --#. TRANSLATORS: this is when we know about an application or -+#. TRANSLATORS: this is when we know about an app or - #. * addon, but it can't be listed for some reason - #: src/gs-extras-page.c:354 - #, c-format --msgid "No applications are available that provide the file %s." -+msgid "No apps are available that provide the file %s." - msgstr "Nejsou k dispozici žádné aplikace, které by poskytovaly soubor %s." - - #. TRANSLATORS: first %s is the codec name, and second %s is a -@@ -2482,20 +2507,20 @@ msgstr "Nejsou k dispozici žádné aplikace, které by poskytovaly soubor %s." - #: src/gs-extras-page.c:358 src/gs-extras-page.c:369 src/gs-extras-page.c:380 - #, c-format - msgid "" --"Information about %s, as well as options for how to get missing applications " --"might be found %s." -+"Information about %s, as well as options for how to get missing apps might " -+"be found %s." - msgstr "" - "Informace o formátu %s, včetně toho, jak získat chybějící aplikace, najdete " - "%s." - --#. TRANSLATORS: this is when we know about an application or -+#. TRANSLATORS: this is when we know about an app or - #. * addon, but it can't be listed for some reason - #: src/gs-extras-page.c:365 src/gs-extras-page.c:387 - #, c-format --msgid "No applications are available for %s support." -+msgid "No apps are available for %s support." - msgstr "Pro podporu %s nejsou k dispozici žádné aplikace." - --#. TRANSLATORS: this is when we know about an application or -+#. TRANSLATORS: this is when we know about an app or - #. * addon, but it can't be listed for some reason - #: src/gs-extras-page.c:376 - #, c-format -@@ -2507,13 +2532,13 @@ msgstr "%s není k dispozici." - #: src/gs-extras-page.c:391 - #, c-format - msgid "" --"Information about %s, as well as options for how to get an application that " --"can support this format might be found %s." -+"Information about %s, as well as options for how to get an app that can " -+"support this format might be found %s." - msgstr "" --"Informace o formátu %s, včetně toho, jak získat aplikaci, který umí tento " --"tento formát podporovat, najdete %s." -+"Informace o formátu %s, včetně toho, jak získat aplikaci, který tento tento " -+"formát podporuje, najdete %s." - --#. TRANSLATORS: this is when we know about an application or -+#. TRANSLATORS: this is when we know about an app or - #. * addon, but it can't be listed for some reason - #: src/gs-extras-page.c:398 - #, c-format -@@ -2530,7 +2555,7 @@ msgid "" - msgstr "" - "Informace o písmu %s, včetně toho, jak získat dodatečná písma, najdete %s." - --#. TRANSLATORS: this is when we know about an application or -+#. TRANSLATORS: this is when we know about an app or - #. * addon, but it can't be listed for some reason - #: src/gs-extras-page.c:409 - #, c-format -@@ -2548,7 +2573,7 @@ msgstr "" - "Informace o kodeku %s, včetně toho, jak získat kodek, který umí tento formát " - "přehrát, najdete %s." - --#. TRANSLATORS: this is when we know about an application or -+#. TRANSLATORS: this is when we know about an app or - #. * addon, but it can't be listed for some reason - #: src/gs-extras-page.c:420 - #, c-format -@@ -2566,7 +2591,7 @@ msgstr "" - "Informace o kodeku %s, včetně toho, jak získat dodatečné prostředky Plasma, " - "najdete %s." - --#. TRANSLATORS: this is when we know about an application or -+#. TRANSLATORS: this is when we know about an app or - #. * addon, but it can't be listed for some reason - #: src/gs-extras-page.c:431 - #, c-format -@@ -2590,7 +2615,7 @@ msgid "the documentation" - msgstr "dokumentace" - - #. TRANSLATORS: no codecs were found. The first %s will be replaced by actual codec name(s), --#. the second %s is the application name, which requested the codecs, the third %s is a link titled "the documentation" -+#. the second %s is the app name, which requested the codecs, the third %s is a link titled "the documentation" - #: src/gs-extras-page.c:487 - #, c-format - msgid "" -@@ -2631,12 +2656,12 @@ msgstr[2] "" - msgid "Failed to find any search results: %s" - msgstr "Selhalo získání jakýchkoliv výsledků hledání: %s" - --#: src/gs-extras-page.c:874 -+#: src/gs-extras-page.c:878 - #, c-format - msgid "%s file format" - msgstr "formát souboru %s" - --#: src/gs-extras-page.c:1254 -+#: src/gs-extras-page.c:1258 - msgid "Unable to Find Requested Software" - msgstr "Nelze najít požadovaný software" - -@@ -2656,206 +2681,206 @@ msgstr "Další" - msgid "Featured Apps List" - msgstr "Seznam významných aplikací" - --#: src/gs-hardware-support-context-dialog.c:577 --#: src/gs-hardware-support-context-dialog.c:586 -+#: src/gs-hardware-support-context-dialog.c:576 -+#: src/gs-hardware-support-context-dialog.c:585 - msgid "Desktop Support" - msgstr "Podpora pro PC" - --#: src/gs-hardware-support-context-dialog.c:578 --#: src/gs-hardware-support-context-dialog.c:587 -+#: src/gs-hardware-support-context-dialog.c:577 -+#: src/gs-hardware-support-context-dialog.c:586 - msgid "Supports being used on a large screen" - msgstr "Podporuje použití na velké obrazovce" - --#: src/gs-hardware-support-context-dialog.c:580 -+#: src/gs-hardware-support-context-dialog.c:579 - msgid "Desktop Support Unknown" - msgstr "Neznámá podpora pro PC" - --#: src/gs-hardware-support-context-dialog.c:581 -+#: src/gs-hardware-support-context-dialog.c:580 - msgid "Not enough information to know if large screens are supported" - msgstr "" - "Není dostatek informací, abychom věděli, zda jsou podporovány velké obrazovky" - --#: src/gs-hardware-support-context-dialog.c:584 -+#: src/gs-hardware-support-context-dialog.c:583 - msgid "Requires a large screen" - msgstr "Vyžaduje velkou obrazovku" - --#: src/gs-hardware-support-context-dialog.c:589 -+#: src/gs-hardware-support-context-dialog.c:588 - msgid "Desktop Not Supported" - msgstr "Nepodporuje stolní počítače" - --#: src/gs-hardware-support-context-dialog.c:590 -+#: src/gs-hardware-support-context-dialog.c:589 - msgid "Cannot be used on a large screen" - msgstr "Nelze použít na velké obrazovce" - --#: src/gs-hardware-support-context-dialog.c:597 --#: src/gs-hardware-support-context-dialog.c:606 -+#: src/gs-hardware-support-context-dialog.c:596 -+#: src/gs-hardware-support-context-dialog.c:605 - msgid "Mobile Support" - msgstr "Podpora pro mobilní zařízení" - --#: src/gs-hardware-support-context-dialog.c:598 --#: src/gs-hardware-support-context-dialog.c:607 -+#: src/gs-hardware-support-context-dialog.c:597 -+#: src/gs-hardware-support-context-dialog.c:606 - msgid "Supports being used on a small screen" - msgstr "Podporuje použití na malé obrazovce" - --#: src/gs-hardware-support-context-dialog.c:600 -+#: src/gs-hardware-support-context-dialog.c:599 - msgid "Mobile Support Unknown" - msgstr "Neznámá podpora pro mobilní zařízení" - --#: src/gs-hardware-support-context-dialog.c:601 -+#: src/gs-hardware-support-context-dialog.c:600 - msgid "Not enough information to know if small screens are supported" - msgstr "" - "Není dostatek informací, abychom věděli, zda jsou podporovány malé obrazovky" - --#: src/gs-hardware-support-context-dialog.c:604 -+#: src/gs-hardware-support-context-dialog.c:603 - msgid "Requires a small screen" - msgstr "Vyžaduje malou obrazovku" - --#: src/gs-hardware-support-context-dialog.c:609 -+#: src/gs-hardware-support-context-dialog.c:608 - msgid "Mobile Not Supported" - msgstr "Nepodporuje mobily" - --#: src/gs-hardware-support-context-dialog.c:610 -+#: src/gs-hardware-support-context-dialog.c:609 - msgid "Cannot be used on a small screen" - msgstr "Nelze použít na malé obrazovce" - --#: src/gs-hardware-support-context-dialog.c:633 --#: src/gs-hardware-support-context-dialog.c:642 -+#: src/gs-hardware-support-context-dialog.c:632 -+#: src/gs-hardware-support-context-dialog.c:641 - msgid "Keyboard Support" - msgstr "Podpora klávesnice" - --#: src/gs-hardware-support-context-dialog.c:636 -+#: src/gs-hardware-support-context-dialog.c:635 - msgid "Keyboard Support Unknown" - msgstr "Neznámá podpora klávesnice" - --#: src/gs-hardware-support-context-dialog.c:637 -+#: src/gs-hardware-support-context-dialog.c:636 - msgid "Not enough information to know if keyboards are supported" - msgstr "" - "Není dostatek informací, abychom věděli, zda jsou podporovány klávesnice" - --#: src/gs-hardware-support-context-dialog.c:639 -+#: src/gs-hardware-support-context-dialog.c:638 - msgid "Keyboard Required" - msgstr "Vyžaduje klávesnici" - --#: src/gs-hardware-support-context-dialog.c:643 -+#: src/gs-hardware-support-context-dialog.c:642 - msgid "Supports keyboards" - msgstr "Podporuje klávesnice" - --#: src/gs-hardware-support-context-dialog.c:645 -+#: src/gs-hardware-support-context-dialog.c:644 - msgid "Keyboard Not Supported" - msgstr "Nepodporuje klávesnici" - --#: src/gs-hardware-support-context-dialog.c:646 -+#: src/gs-hardware-support-context-dialog.c:645 - msgid "Cannot be used with a keyboard" - msgstr "Nelze použít s klávesnicí" - --#: src/gs-hardware-support-context-dialog.c:653 --#: src/gs-hardware-support-context-dialog.c:662 -+#: src/gs-hardware-support-context-dialog.c:652 -+#: src/gs-hardware-support-context-dialog.c:661 - msgid "Mouse Support" - msgstr "Podpora myši" - --#: src/gs-hardware-support-context-dialog.c:654 --#: src/gs-hardware-support-context-dialog.c:660 -+#: src/gs-hardware-support-context-dialog.c:653 -+#: src/gs-hardware-support-context-dialog.c:659 - msgid "Requires a mouse or pointing device" - msgstr "Vyžaduje myš nebo ukazovátko" - --#: src/gs-hardware-support-context-dialog.c:656 -+#: src/gs-hardware-support-context-dialog.c:655 - msgid "Mouse Support Unknown" - msgstr "Neznámá podpora myši" - --#: src/gs-hardware-support-context-dialog.c:657 -+#: src/gs-hardware-support-context-dialog.c:656 - msgid "" - "Not enough information to know if mice or pointing devices are supported" - msgstr "" - "Není dostatek informací, abychom věděli, zda jsou podporovány myši nebo " - "ukazovátka" - --#: src/gs-hardware-support-context-dialog.c:659 -+#: src/gs-hardware-support-context-dialog.c:658 - msgid "Mouse Required" - msgstr "Vyžaduje myš" - --#: src/gs-hardware-support-context-dialog.c:663 -+#: src/gs-hardware-support-context-dialog.c:662 - msgid "Supports mice and pointing devices" - msgstr "Podporuje myši a ukazovátka" - --#: src/gs-hardware-support-context-dialog.c:665 -+#: src/gs-hardware-support-context-dialog.c:664 - msgid "Mouse Not Supported" - msgstr "Nepodporuje myš" - --#: src/gs-hardware-support-context-dialog.c:666 -+#: src/gs-hardware-support-context-dialog.c:665 - msgid "Cannot be used with a mouse or pointing device" - msgstr "Nelze použít s myší nebo ukazovátkem" - --#: src/gs-hardware-support-context-dialog.c:673 --#: src/gs-hardware-support-context-dialog.c:682 -+#: src/gs-hardware-support-context-dialog.c:672 -+#: src/gs-hardware-support-context-dialog.c:681 - msgid "Touchscreen Support" - msgstr "Podpora dotykové obrazovky" - --#: src/gs-hardware-support-context-dialog.c:676 -+#: src/gs-hardware-support-context-dialog.c:675 - msgid "Touchscreen Support Unknown" - msgstr "Neznámá podpora dotykové obrazovky" - --#: src/gs-hardware-support-context-dialog.c:677 -+#: src/gs-hardware-support-context-dialog.c:676 - msgid "Not enough information to know if touchscreens are supported" - msgstr "" - "Není dostatek informací, abychom věděli, zda jsou podporovány dotykové " - "obrazovky" - --#: src/gs-hardware-support-context-dialog.c:679 -+#: src/gs-hardware-support-context-dialog.c:678 - msgid "Touchscreen Required" - msgstr "Vyžaduje dotykovou obrazovku" - --#: src/gs-hardware-support-context-dialog.c:683 -+#: src/gs-hardware-support-context-dialog.c:682 - msgid "Supports touchscreens" - msgstr "Podporuje dotykové obrazovky" - --#: src/gs-hardware-support-context-dialog.c:685 -+#: src/gs-hardware-support-context-dialog.c:684 - msgid "Touchscreen Not Supported" - msgstr "Nepodporuje dotykovou obrazovku" - --#: src/gs-hardware-support-context-dialog.c:686 -+#: src/gs-hardware-support-context-dialog.c:685 - msgid "Cannot be used with a touchscreen" - msgstr "Nelze použít s dotykovou obrazovkou" - --#: src/gs-hardware-support-context-dialog.c:699 -+#: src/gs-hardware-support-context-dialog.c:698 - msgid "Gamepad Required" - msgstr "Vyžadován herní ovladač" - --#: src/gs-hardware-support-context-dialog.c:700 -+#: src/gs-hardware-support-context-dialog.c:699 - msgid "Requires a gamepad" - msgstr "Vyžaduje herní ovladač" - --#: src/gs-hardware-support-context-dialog.c:702 -+#: src/gs-hardware-support-context-dialog.c:701 - msgid "Gamepad Support" - msgstr "Podpora herního ovladače" - --#: src/gs-hardware-support-context-dialog.c:703 -+#: src/gs-hardware-support-context-dialog.c:702 - msgid "Supports gamepads" - msgstr "Podporuje herní ovladače" - - #. Translators: It’s unknown whether this app is supported on - #. * the current hardware. The placeholder is the app name. --#: src/gs-hardware-support-context-dialog.c:712 -+#: src/gs-hardware-support-context-dialog.c:711 - #, c-format - msgid "%s probably works on this device" - msgstr "Aplikace %s na tomto zařízení pravděpodobně funguje" - - #. Translators: The app will work on the current hardware. - #. * The placeholder is the app name. --#: src/gs-hardware-support-context-dialog.c:719 -+#: src/gs-hardware-support-context-dialog.c:718 - #, c-format - msgid "%s works on this device" - msgstr "Aplikace %s na tomto zařízení funguje" - - #. Translators: The app may not work fully on the current hardware. - #. * The placeholder is the app name. --#: src/gs-hardware-support-context-dialog.c:726 -+#: src/gs-hardware-support-context-dialog.c:725 - #, c-format - msgid "%s will not work properly on this device" - msgstr "Aplikace %s na tomto zařízení nebude fungovat správně" - - #. Translators: The app will not work properly on the current hardware. - #. * The placeholder is the app name. --#: src/gs-hardware-support-context-dialog.c:733 -+#: src/gs-hardware-support-context-dialog.c:732 - #, c-format - msgid "%s will not work on this device" - msgstr "Aplikace %s na tomto zařízení nebude fungovat" -@@ -2866,8 +2891,7 @@ msgid "Hardware Support" - msgstr "Podpora hardwaru" - - #. Translators: This is in the context of a list of apps which are installed on the system. --#. Translators: A label for a button to show only software which is already installed. --#: src/gs-installed-page.c:813 src/gs-shell.ui:309 -+#: src/gs-installed-page.c:813 - msgctxt "List of installed apps" - msgid "Installed" - msgstr "Nainstalováno" -@@ -2883,27 +2907,27 @@ msgstr "S probíhající změnou" - #. origin_ui on a remote is the repo dialogue section name, - #. * not the remote title - #: src/gs-installed-page.ui:75 plugins/flatpak/gs-flatpak-utils.c:107 --msgid "Applications" -+msgid "Apps" - msgstr "Aplikace" - - #: src/gs-installed-page.ui:95 --msgid "Web Applications" -+msgid "Web Apps" - msgstr "Webové aplikace" - - #: src/gs-installed-page.ui:115 --msgid "System Applications" -+msgid "System Apps" - msgstr "Systémové aplikace" - --#: src/gs-license-tile.c:96 -+#: src/gs-license-tile.c:97 - msgid "Community Built" - msgstr "Vybudováno komunitou" - --#: src/gs-license-tile.c:107 src/gs-license-tile.ui:98 -+#: src/gs-license-tile.c:108 src/gs-license-tile.ui:98 - msgid "_Get Involved" - msgstr "_Zapojit se" - - #. Translators: The first placeholder here is a link to information about the license, and the second placeholder here is the name of a software license. --#: src/gs-license-tile.c:114 -+#: src/gs-license-tile.c:115 - #, c-format - msgid "" - "This software is developed in the open by a community of volunteers, and " -@@ -2917,7 +2941,7 @@ msgstr "" - "Můžete přispět a pomoci jej ještě vylepšit." - - #. Translators: The placeholder here is the name of a software license. --#: src/gs-license-tile.c:121 -+#: src/gs-license-tile.c:122 - #, c-format - msgid "" - "This software is developed in the open by a community of volunteers, and " -@@ -2930,15 +2954,15 @@ msgstr "" - "\n" - "Můžete přispět a pomoci jej ještě vylepšit." - --#: src/gs-license-tile.c:127 -+#: src/gs-license-tile.c:128 - msgid "Proprietary" - msgstr "Uzavřený software" - --#: src/gs-license-tile.c:133 -+#: src/gs-license-tile.c:134 - msgid "_Learn More" - msgstr "Zjistit _více" - --#: src/gs-license-tile.c:135 -+#: src/gs-license-tile.c:136 - msgid "" - "This software is not developed in the open, so only its developers know how " - "it works. It may be insecure in ways that are hard to detect, and it may " -@@ -2965,7 +2989,7 @@ msgstr "Načítá se stránka" - msgid "Starting up…" - msgstr "Spouští se…" - --#: src/gs-metered-data-dialog.ui:5 src/gs-shell.ui:258 -+#: src/gs-metered-data-dialog.ui:5 - msgid "Automatic Updates Paused" - msgstr "Automatické aktualizace jsou pozastaveny" - -@@ -3012,62 +3036,72 @@ msgstr "Neznámý zdroj" - msgid "Beta" - msgstr "Beta" - --#. Translators: It's an origin scope, 'User' or 'System' installation --#: src/gs-origin-popover-row.ui:138 --msgid "User" --msgstr "Uživatel" -- - #. TRANSLATORS: This is the header for package additions during - #. * a system update --#: src/gs-os-update-page.c:250 -+#: src/gs-os-update-page.c:249 - msgid "Additions" - msgstr "Přidávání" - - #. TRANSLATORS: This is the header for package removals during - #. * a system update --#: src/gs-os-update-page.c:254 -+#: src/gs-os-update-page.c:253 - msgid "Removals" - msgstr "Odstraňování" - - #. TRANSLATORS: This is the header for package updates during - #. * a system update --#: src/gs-os-update-page.c:258 -+#: src/gs-os-update-page.c:257 - msgctxt "Packages to be updated during a system upgrade" - msgid "Updates" - msgstr "Aktualizace" - - #. TRANSLATORS: This is the header for package downgrades during - #. * a system update --#: src/gs-os-update-page.c:262 -+#: src/gs-os-update-page.c:261 - msgid "Downgrades" - msgstr "Ponižování" - --#. Translators: This is a clickable link on the third party repositories info bar. It's -+#. Translators: This is a clickable link on the third party repositories message dialog. It's - #. part of a constructed sentence: "Provides access to additional software from [selected external sources]. - #. Some proprietary software is included." --#: src/gs-overview-page.c:876 -+#: src/gs-overview-page.c:475 - msgid "selected external sources" - msgstr "vybraných externích zdrojů" - --#. Translators: This is the third party repositories info bar. The %s is replaced with "selected external sources" link. --#: src/gs-overview-page.c:878 -+#. Translators: This is the third party repositories message dialog. -+#. The %s is replaced with "selected external sources" link. -+#. Repositories Preferences is an item from Software's main menu. -+#: src/gs-overview-page.c:479 - #, c-format - msgid "" - "Provides access to additional software from %s. Some proprietary software is " --"included." -+"included.\n" -+"\n" -+"You can enable those repositories later in Software Repositories preferences." - msgstr "" - "Poskytuje přístup k dalšímu softwaru z %s. Součástí je i některý uzavřený " --"software." -+"software.\n" -+"\n" -+"Tyto repozitáře můžete později povolit v předvolbách Softwarových repozitářů." -+ -+#. TRANSLATORS: Heading asking whether to turn third party software repositories on of off. -+#: src/gs-overview-page.c:485 -+msgid "Enable Third Party Software Repositories?" -+msgstr "Povolit repozitáře softwaru třetích stran?" -+ -+#. TRANSLATORS: button to keep the third party software repositories off -+#: src/gs-overview-page.c:490 -+msgid "_Ignore" -+msgstr "_Ignorovat" - - #. TRANSLATORS: button to turn on third party software repositories - #. TRANSLATORS: button to accept the agreement --#: src/gs-overview-page.c:887 src/gs-repos-dialog.c:173 --msgid "Enable" --msgstr "Povolit" -+#: src/gs-overview-page.c:492 src/gs-repos-dialog.c:173 -+msgid "_Enable" -+msgstr "_Povolit" - - #. Translators: This is the title of the main page of the UI. --#. Translators: A label for a button to show all available software. --#: src/gs-overview-page.c:946 src/gs-shell.ui:296 -+#: src/gs-overview-page.c:985 - msgid "Explore" - msgstr "Procházet" - -@@ -3075,61 +3109,62 @@ msgstr "Procházet" - msgid "Overview page" - msgstr "Stránka s přehledem" - --#: src/gs-overview-page.ui:35 --msgid "Enable Third Party Software Repositories?" --msgstr "Povolit repozitáře softwaru třetích stran?" -- - #. Translators: This is a heading for a list of categories. --#: src/gs-overview-page.ui:180 -+#: src/gs-overview-page.ui:143 - msgid "Other Categories" - msgstr "Ostatní kategorie" - --#: src/gs-overview-page.ui:221 --msgid "No Application Data Found" -+#: src/gs-overview-page.ui:184 -+msgid "No App Data Found" - msgstr "O aplikaci nebyly nalezeny žádné informace" - --#: lib/gs-plugin-loader.c:2836 -+#: lib/gs-plugin-loader.c:2771 - msgctxt "Distribution name" - msgid "Unknown" - msgstr "neznámá" - --#: src/gs-page.c:274 -+#. TRANSLATORS: button text -+#: src/gs-page.c:92 -+msgid "_OK" -+msgstr "_Budiž" -+ -+#: src/gs-page.c:271 - msgid "User declined installation" - msgstr "Uživatel odmítl instalaci" - - #. TRANSLATORS: this is a prompt message, and --#. * '%s' is an application summary, e.g. 'GNOME Clocks' --#: src/gs-page.c:365 -+#. * '%s' is an app summary, e.g. 'GNOME Clocks' -+#: src/gs-page.c:404 - #, c-format - msgid "Prepare %s" - msgstr "Příprava aplikace %s" - - #. TRANSLATORS: this is a prompt message, and '%s' is an - #. * repository name, e.g. 'GNOME Nightly' --#: src/gs-page.c:518 -+#: src/gs-page.c:523 - #, c-format - msgid "Are you sure you want to remove the %s repository?" - msgstr "Opravdu chcete odebrat repozitář %s?" - - #. TRANSLATORS: longer dialog text --#: src/gs-page.c:522 -+#: src/gs-page.c:527 - #, c-format - msgid "" --"All applications from %s will be uninstalled, and you will have to re-" --"install the repository to use them again." -+"All apps from %s will be uninstalled, and you will have to re-install the " -+"repository to use them again." - msgstr "" --"Všechny aplikace pocházející ze repozitáře %s budou odinstalovány. Abyste je " -+"Všechny aplikace pocházející z repozitáře %s budou odinstalovány. Abyste je " - "mohli znovu použít, budete muset repozitář znovu nainstalovat." - - #. TRANSLATORS: this is a prompt message, and '%s' is an --#. * application summary, e.g. 'GNOME Clocks' --#: src/gs-page.c:530 -+#. * app summary, e.g. 'GNOME Clocks' -+#: src/gs-page.c:535 - #, c-format - msgid "Are you sure you want to uninstall %s?" - msgstr "Opravdu chcete odinstalovat %s?" - - #. TRANSLATORS: longer dialog text --#: src/gs-page.c:533 -+#: src/gs-page.c:538 - #, c-format - msgid "" - "%s will be uninstalled, and you will have to install it to use it again." -@@ -3138,8 +3173,8 @@ msgstr "" - "muset provést novou instalaci." - - #: src/gs-prefs-dialog.ui:5 --msgid "Update Preferences" --msgstr "Předvolby aktualizací" -+msgid "Preferences" -+msgstr "Předvolby" - - #: src/gs-prefs-dialog.ui:16 - msgid "" -@@ -3150,65 +3185,69 @@ msgstr "" - "automaticky stahovány na mobilních nebo měřených připojeních." - - #: src/gs-prefs-dialog.ui:19 --msgid "Automatic Updates" --msgstr "Automatické aktualizace" -+msgid "Automatic _Updates" -+msgstr "Automatické _aktualizace" - - #: src/gs-prefs-dialog.ui:20 - msgid "" --"Downloads and installs software updates in the background, when possible." -+"Downloads and installs software updates in the background, when possible" - msgstr "Stahuje a instaluje aktualizace softwaru na pozadí, pokud je to možné." - --#: src/gs-prefs-dialog.ui:32 --msgid "Automatic Update Notifications" --msgstr "Oznamovat automatické aktualizace" -- - #: src/gs-prefs-dialog.ui:33 --msgid "Show notifications when updates have been automatically installed." -+msgid "Automatic Update _Notifications" -+msgstr "_Oznamovat automatické aktualizace" -+ -+#: src/gs-prefs-dialog.ui:34 -+msgid "Show notifications when updates have been automatically installed" - msgstr "Zobrazovat oznámení, když jsou automaticky nainstalovány aplikace." - -+#: src/gs-prefs-dialog.ui:47 -+msgid "Show Only _Free Apps" -+msgstr "Zobrazit _pouze svobodné aplikace" -+ -+#: src/gs-prefs-dialog.ui:48 -+msgid "Show only freely licensed apps and hide any proprietary apps" -+msgstr "" -+"Zobrazit pouze aplikace se svobodnou licencí a skrýt všechny proprietární " -+"aplikace." -+ - #. TRANSLATORS: This is a text displayed during a distro upgrade. %s - #. will be replaced by the name and version of distro, e.g. 'Fedora 23'. - #: src/gs-removal-dialog.c:96 --#, fuzzy, c-format --#| msgid "" --#| "Some of the currently installed software is not compatible with %s. If " --#| "you continue, the following will be automatically removed during the " --#| "upgrade:" -+#, c-format - msgid "" - "Installed software is incompatible with %s, and will be automatically " - "removed during upgrade." - msgstr "" - "Některý z právě instalovaného softwaru není kompatibilní s distribucí %s. " --"Pokud budete pokračovat, následujíc se během povýšení odstraní:" -+"Pokud budete pokračovat, během povýšení se odstraní." - - #: src/gs-removal-dialog.ui:7 - msgid "Incompatible Software" - msgstr "Nekompatibilní software" - - #: src/gs-removal-dialog.ui:37 --#, fuzzy --#| msgid "_Restart & Upgrade" - msgid "_Upgrade" --msgstr "_Restartovat a aktualizovat" -+msgstr "_Aktualizovat" - - #. TRANSLATORS: The '%s' is replaced with a repository name, like "Fedora Modular - x86_64" --#: src/gs-repos-dialog.c:239 -+#: src/gs-repos-dialog.c:241 - #, c-format - msgid "" - "Software that has been installed from “%s” will cease to receive updates." - msgstr "" - "Software, který byl nainstalován z „%s“, přestane dostávat aktualizace." - --#: src/gs-repos-dialog.c:248 -+#: src/gs-repos-dialog.c:246 - msgid "Disable Repository?" - msgstr "Zakázat repozitář?" - --#: src/gs-repos-dialog.c:248 -+#: src/gs-repos-dialog.c:246 - msgid "Remove Repository?" - msgstr "Odebrat repozitář?" - - #. TRANSLATORS: this is button text to disable a repo --#: src/gs-repos-dialog.c:254 -+#: src/gs-repos-dialog.c:253 - msgid "_Disable" - msgstr "_Zakázat" - -@@ -3217,41 +3256,41 @@ msgstr "_Zakázat" - msgid "_Remove" - msgstr "_Odebrat" - --#: src/gs-repos-dialog.c:508 -+#: src/gs-repos-dialog.c:507 - msgid "Enable New Repositories" - msgstr "Povolit nové repozitáře" - --#: src/gs-repos-dialog.c:509 -+#: src/gs-repos-dialog.c:508 - msgid "Turn on new repositories when they are added." - msgstr "Zapnout nové repozitáře při jejich přidání." - - #. TRANSLATORS: this is the clickable - #. * link on the third party repositories info bar --#: src/gs-repos-dialog.c:518 -+#: src/gs-repos-dialog.c:517 - msgid "more information" - msgstr "více informací" - - #. TRANSLATORS: this is the third party repositories info bar. The '%s' is replaced - #. with a link consisting a text "more information", which constructs a sentence: - #. "Additional repositories from selected third parties - more information." --#: src/gs-repos-dialog.c:523 -+#: src/gs-repos-dialog.c:522 - #, c-format - msgid "Additional repositories from selected third parties — %s." - msgstr "Další repozitáře od vybraných třetích stran — %s." - --#: src/gs-repos-dialog.c:528 -+#: src/gs-repos-dialog.c:527 - msgid "Fedora Third Party Repositories" - msgstr "Repozitáře třetích stran Fedory" - - #. TRANSLATORS: this is the fallback text we use if we can't - #. figure out the name of the operating system --#: src/gs-repos-dialog.c:670 -+#: src/gs-repos-dialog.c:669 - msgid "the operating system" - msgstr "operačního systému" - - #. TRANSLATORS: This is the description text displayed in the Software Repositories dialog. - #. %s gets replaced by the name of the actual distro, e.g. Fedora. --#: src/gs-repos-dialog.c:728 -+#: src/gs-repos-dialog.c:727 - #, c-format - msgid "These repositories supplement the default software provided by %s." - msgstr "" -@@ -3259,7 +3298,7 @@ msgstr "" - "%s." - - #. button in the info bar --#: src/gs-repos-dialog.ui:8 src/gs-shell.ui:88 -+#: src/gs-repos-dialog.ui:8 src/gs-shell.ui:99 - msgid "Software Repositories" - msgstr "Softwarové repozitáře" - -@@ -3267,19 +3306,21 @@ msgstr "Softwarové repozitáře" - msgid "No Repositories" - msgstr "Žádné repozitáře" - --#. TRANSLATORS: This string is used to construct the 'X applications --#. installed' sentence, describing a software repository. --#: src/gs-repo-row.c:160 -+#. TRANSLATORS: This string states how many apps have been -+#. * installed from a particular repo, and is displayed on a row -+#. * describing that repo. The placeholder is the number of apps. -+#: src/gs-repo-row.c:161 - #, c-format --msgid "%u application installed" --msgid_plural "%u applications installed" -+msgid "%u app installed" -+msgid_plural "%u apps installed" - msgstr[0] "Nainstalována %u aplikace" - msgstr[1] "Nainstalovány %u aplikace" - msgstr[2] "Nainstalováno %u aplikací" - --#. TRANSLATORS: This string is used to construct the 'X add-ons --#. installed' sentence, describing a software repository. --#: src/gs-repo-row.c:167 -+#. TRANSLATORS: This string states how many add-ons have been -+#. * installed from a particular repo, and is displayed on a row -+#. * describing that repo. The placeholder is the number of add-ons. -+#: src/gs-repo-row.c:169 - #, c-format - msgid "%u add-on installed" - msgid_plural "%u add-ons installed" -@@ -3287,21 +3328,27 @@ msgstr[0] "Nainstalován %u doplněk" - msgstr[1] "Nainstalovány %u doplňky" - msgstr[2] "Nainstalováno %u doplňků" - --#. TRANSLATORS: This string is used to construct the 'X applications --#. and y add-ons installed' sentence, describing a software repository. --#. The correct form here depends on the number of applications. --#: src/gs-repo-row.c:175 -+#. TRANSLATORS: This string is used to construct the 'X apps -+#. and Y add-ons installed' sentence, stating how many things have been -+#. * installed from a particular repo. It’s displayed on a row describing -+#. * that repo. The placeholder is the number of apps, and the translated -+#. * string will be substituted in for the first placeholder in the -+#. * string “%s and %s installed”. -+#: src/gs-repo-row.c:180 - #, c-format --msgid "%u application" --msgid_plural "%u applications" -+msgid "%u app" -+msgid_plural "%u apps" - msgstr[0] "%u aplikace" - msgstr[1] "%u aplikace" - msgstr[2] "%u aplikací" - --#. TRANSLATORS: This string is used to construct the 'X applications --#. and y add-ons installed' sentence, describing a software repository. --#. The correct form here depends on the number of add-ons. --#: src/gs-repo-row.c:181 -+#. TRANSLATORS: This string is used to construct the 'X apps -+#. and Y add-ons installed' sentence, stating how many things have been -+#. * installed from a particular repo. It’s displayed on a row describing -+#. * that repo. The placeholder is the number of add-ons, and the translated -+#. * string will be substituted in for the second placeholder in the -+#. * string “%s and %s installed”. -+#: src/gs-repo-row.c:189 - #, c-format - msgid "%u add-on" - msgid_plural "%u add-ons" -@@ -3309,11 +3356,20 @@ msgstr[0] "%u doplněk" - msgstr[1] "%u doplňky" - msgstr[2] "%u doplňků" - --#. TRANSLATORS: This string is used to construct the 'X applications --#. and y add-ons installed' sentence, describing a software repository. --#. The correct form here depends on the total number of --#. applications and add-ons. --#: src/gs-repo-row.c:188 -+#. TRANSLATORS: This string is used to construct the 'X apps -+#. and Y add-ons installed' sentence, stating how many things have been -+#. * installed from a particular repo. It’s displayed on a row describing -+#. * that repo. The first placeholder is the translated string “%u app” or -+#. * “%u apps”. The second placeholder is the translated string “%u add-on” -+#. * or “%u add-ons”. -+#. * -+#. * The choice of plural form for this string is determined by the total -+#. * number of apps plus add-ons. For example, -+#. * - “1 app and 2 add-ons installed” - uses count 3 -+#. * - “2 apps and 1 add-on installed” - uses count 3 -+#. * - “4 apps and 5 add-ons installed” - uses count 9 -+#. -+#: src/gs-repo-row.c:205 - #, c-format - msgid "%s and %s installed" - msgid_plural "%s and %s installed" -@@ -3321,120 +3377,117 @@ msgstr[0] "%s a %s" - msgstr[1] "%s a %s" - msgstr[2] "%s a %s" - --#. Translators: The first '%s' is replaced with a text like '10 applications installed', -+#. Translators: The first '%s' is replaced with a text like '10 apps installed', - #. the second '%s' is replaced with installation kind, like in case of Flatpak 'User Installation'. --#: src/gs-repo-row.c:243 -+#: src/gs-repo-row.c:260 - #, c-format - msgctxt "repo-row" - msgid "%s • %s" - msgstr "%s • %s" - --#: src/gs-repo-row.c:314 --#, fuzzy --#| msgid "_Remove" -+#: src/gs-repo-row.c:331 - msgid "Remove" --msgstr "_Odebrat" -+msgstr "Odebrat" - - #. TRANSLATORS: lighthearted star rating description; --#. * A really bad application -+#. * A really bad app - #: src/gs-review-dialog.c:78 - msgid "Hate it" - msgstr "Nenávidím ji" - - #. TRANSLATORS: lighthearted star rating description; --#. * Not a great application -+#. * Not a great app - #: src/gs-review-dialog.c:82 - msgid "Don’t like it" - msgstr "Nemám ji rád" - - #. TRANSLATORS: lighthearted star rating description; --#. * A fairly-good application -+#. * A fairly-good app - #: src/gs-review-dialog.c:86 - msgid "It’s OK" - msgstr "Běžná aplikace" - - #. TRANSLATORS: lighthearted star rating description; --#. * A good application -+#. * A good app - #: src/gs-review-dialog.c:90 - msgid "Like it" - msgstr "Mám ji rád" - - #. TRANSLATORS: lighthearted star rating description; --#. * A really awesome application -+#. * A really awesome app - #: src/gs-review-dialog.c:94 - msgid "Love it" - msgstr "Zbožňuji ji" - -+#. TRANSLATORS: lighthearted star rating description; -+#. * No star has been clicked yet -+#: src/gs-review-dialog.c:98 -+msgid "Select a Star to Leave a Rating" -+msgstr "Chcete-li zanechat hodnocení, vyberte hvězdičku" -+ - #. TRANSLATORS: the review can't just be copied and pasted --#: src/gs-review-dialog.c:118 -+#: src/gs-review-dialog.c:119 - msgid "Please take more time writing the review" - msgstr "Věnujte prosím trochu času napsaní recenze" - - #. TRANSLATORS: the review is not acceptable --#: src/gs-review-dialog.c:122 -+#: src/gs-review-dialog.c:123 - msgid "Please choose a star rating" - msgstr "Ohodnoťte prosím hvězdičkami" - - #. TRANSLATORS: the review is not acceptable --#: src/gs-review-dialog.c:126 -+#: src/gs-review-dialog.c:127 - msgid "The summary is too short" - msgstr "Celkové hodnocení je příliš krátké" - - #. TRANSLATORS: the review is not acceptable --#: src/gs-review-dialog.c:130 -+#: src/gs-review-dialog.c:131 - msgid "The summary is too long" - msgstr "Celkové hodnocení je příliš dlouhé" - - #. TRANSLATORS: the review is not acceptable --#: src/gs-review-dialog.c:134 -+#: src/gs-review-dialog.c:135 - msgid "The description is too short" - msgstr "Recenze je příliš krátká" - - #. TRANSLATORS: the review is not acceptable --#: src/gs-review-dialog.c:138 -+#: src/gs-review-dialog.c:139 - msgid "The description is too long" - msgstr "Recenze je příliš dlouhá" - - #. Translators: Title of the dialog box where the users can write and publish their opinions about the apps. - #: src/gs-review-dialog.ui:10 --msgid "Post Review" --msgstr "Příspěvek do recenzí" -+msgid "Write a Review" -+msgstr "Napsat recenzi" - - #. Translators: A button to publish the user's opinion about the app. - #: src/gs-review-dialog.ui:26 --msgid "_Post" -+msgid "_Send" - msgstr "_Odeslat" - --#: src/gs-review-dialog.ui:56 --msgid "Rating" --msgstr "Hodnocení" -- --#: src/gs-review-dialog.ui:88 --msgid "Summary" --msgstr "Celkový dojem" -- --#: src/gs-review-dialog.ui:97 -+#: src/gs-review-dialog.ui:71 - msgid "" --"Give a short summary of your review, for example: “Great app, would " --"recommend”." -+"What did you like about this app? Leaving your feedback along with your " -+"reasons for leaving a review is helpful for others." - msgstr "" --"Uveďte krátké shrnutí své recenze, například: „Skvělá aplikace, doporučuji“." -+"Co se vám na této aplikaci líbilo? Zanechání zpětné vazby společně s důvody " -+"pro zanechání recenze je pro ostatní užitečné." -+ -+#: src/gs-review-dialog.ui:84 -+msgid "Review Summary" -+msgstr "Celkový dojem" - - #. Translators: This is where the users enter their opinions about the apps. --#: src/gs-review-dialog.ui:119 -+#: src/gs-review-dialog.ui:116 - msgctxt "app review" --msgid "Review" --msgstr "Recenze" -+msgid "Write a short review" -+msgstr "Napište krátkou recenzi" - --#: src/gs-review-dialog.ui:128 --msgid "What do you think of the app? Try to give reasons for your views." --msgstr "Co si o aplikaci myslíte? Snažte se uvést důvody svého hodnocení." -- --#: src/gs-review-dialog.ui:156 -+#: src/gs-review-dialog.ui:160 - msgid "" --"Find what data is sent in our privacy policy. The full name attached to your account will be shown " --"publicly." -+"Find what data is sent in our privacy policy. The full name attached to your account will be " -+"shown publicly." - msgstr "" - "Najděte si v našich zásadách " - "soukromí, jaká data jsou odesílána. Celé jméno přiřazené k vašemu účtu " -@@ -3448,24 +3501,24 @@ msgstr[0] "celkem %u recenze" - msgstr[1] "celkem %u recenze" - msgstr[2] "celkem %u recenzí" - --#: src/gs-review-histogram.ui:93 -+#: src/gs-review-histogram.ui:88 - msgid "out of 5 stars" - msgstr "z 5 hvězdiček" - - #. TRANSLATORS: this is when a user doesn't specify a name --#: src/gs-review-row.c:56 -+#: src/gs-review-row.c:60 - msgctxt "Reviewer name" - msgid "Unknown" - msgstr "anonym" - - #. TRANSLATORS: we explain what the action is going to do --#: src/gs-review-row.c:220 -+#: src/gs-review-row.c:222 - msgid "You can report reviews for abusive, rude, or discriminatory behavior." - msgstr "" - "Můžete nahlásit recenze, které jsou urážlivé, sprosté nebo diskriminační." - - #. TRANSLATORS: we ask the user if they really want to do this --#: src/gs-review-row.c:225 -+#: src/gs-review-row.c:227 - msgid "" - "Once reported, a review will be hidden until it has been checked by an " - "administrator." -@@ -3474,15 +3527,15 @@ msgstr "Po nahlášení bude recenze skryta, dokud ji nezkontroluje správce." - #. TRANSLATORS: window title when - #. * reporting a user-submitted review - #. * for moderation --#: src/gs-review-row.c:239 -+#: src/gs-review-row.c:235 - msgid "Report Review?" - msgstr "Nahlásit recenzi?" - - #. TRANSLATORS: button text when - #. * sending a review for moderation --#: src/gs-review-row.c:243 --msgid "Report" --msgstr "Nahlásit" -+#: src/gs-review-row.c:240 -+msgid "_Report" -+msgstr "_Nahlásit" - - #. Translators: Users can express their opinions about other users' opinions about the apps. - #: src/gs-review-row.ui:84 -@@ -3510,175 +3563,184 @@ msgstr "Nahlásit…" - msgid "Remove…" - msgstr "Odebrat…" - --#: src/gs-safety-context-dialog.c:144 --msgid "Check that you trust the vendor, as the application isn’t sandboxed" -+#: src/gs-safety-context-dialog.c:143 -+msgid "Check that you trust the vendor, as the app isn’t sandboxed" - msgstr "" - "Zkontrolujte si, že důvěřujete dodavateli, protože aplikace není v " --"izolovaném prostředí." -+"izolovaném prostředí" - --#: src/gs-safety-context-dialog.c:147 -+#: src/gs-safety-context-dialog.c:146 - msgid "" --"Application isn’t sandboxed but the distribution has checked that it is not " --"malicious" -+"App isn’t sandboxed but the distribution has checked that it is not malicious" - msgstr "" - "Aplikace není v izolovaném prostředí, ale je prověřená v distribuci, že " --"neobsahuje škodlivý kód." -+"neobsahuje škodlivý kód" - - #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. --#: src/gs-safety-context-dialog.c:160 -+#: src/gs-safety-context-dialog.c:159 - msgid "No Permissions" - msgstr "Žádná oprávnění" - --#: src/gs-safety-context-dialog.c:161 -+#: src/gs-safety-context-dialog.c:160 - msgid "App is fully sandboxed" - msgstr "Aplikace je v plně izolovaném prostředí" - - #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. --#: src/gs-safety-context-dialog.c:172 -+#: src/gs-safety-context-dialog.c:171 - msgid "Network Access" - msgstr "Přístup k síti" - --#: src/gs-safety-context-dialog.c:173 -+#: src/gs-safety-context-dialog.c:172 - msgid "Can access the internet" - msgstr "Může přistupovat k internetu" - - #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. --#: src/gs-safety-context-dialog.c:176 -+#: src/gs-safety-context-dialog.c:175 - msgid "No Network Access" - msgstr "Žádný přístup k síti" - --#: src/gs-safety-context-dialog.c:177 -+#: src/gs-safety-context-dialog.c:176 - msgid "Cannot access the internet" - msgstr "Nemůže přistupovat k internetu" - - #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. --#: src/gs-safety-context-dialog.c:183 -+#: src/gs-safety-context-dialog.c:182 - msgid "Uses System Services" - msgstr "Využívá služby systému" - --#: src/gs-safety-context-dialog.c:184 -+#: src/gs-safety-context-dialog.c:183 - msgid "Can request data from system services" - msgstr "Může si vyžádat data ze služeb systému" - - #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. --#: src/gs-safety-context-dialog.c:191 -+#: src/gs-safety-context-dialog.c:190 - msgid "Uses Session Services" - msgstr "Využívá služby sezení" - --#: src/gs-safety-context-dialog.c:192 -+#: src/gs-safety-context-dialog.c:191 - msgid "Can request data from session services" - msgstr "Může si vyžádat data ze služeb sezení" - - #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. --#: src/gs-safety-context-dialog.c:199 --msgid "Device Access" --msgstr "Přístup k zařízení" -+#: src/gs-safety-context-dialog.c:198 -+msgid "User Device Access" -+msgstr "Přístup k uživatelským zařízením" - --#: src/gs-safety-context-dialog.c:200 -+#: src/gs-safety-context-dialog.c:199 - msgid "Can access devices such as webcams or gaming controllers" - msgstr "Může přistupovat k zařízením jako jsou webkamery nebo herní ovladače" - - #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. --#: src/gs-safety-context-dialog.c:203 --msgid "No Device Access" --msgstr "Žádný přístup k zařízení" -+#: src/gs-safety-context-dialog.c:202 -+msgid "No User Device Access" -+msgstr "Žádný přístup k uživatelským zařízením" - --#: src/gs-safety-context-dialog.c:204 -+#: src/gs-safety-context-dialog.c:203 - msgid "Cannot access devices such as webcams or gaming controllers" - msgstr "Nemůže přistupovat k zařízením jako jsou webkamery nebo herní ovladače" - - #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. -+#: src/gs-safety-context-dialog.c:209 -+msgid "System Device Access" -+msgstr "Přístup k systémovým zařízením" -+ - #: src/gs-safety-context-dialog.c:210 -+msgid "Can access system devices which require elevated permissions" -+msgstr "" -+"Může přistupovat k systémovým zařízením, která vyžadují zvýšená oprávnění" -+ -+#. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. -+#: src/gs-safety-context-dialog.c:217 - msgid "Legacy Windowing System" - msgstr "Zastaralý zobrazovací systém" - - #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. --#: src/gs-safety-context-dialog.c:218 -+#: src/gs-safety-context-dialog.c:225 - msgid "Arbitrary Permissions" - msgstr "Libovolná oprávnění" - - #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. --#: src/gs-safety-context-dialog.c:226 -+#: src/gs-safety-context-dialog.c:233 - msgid "User Settings" - msgstr "Uživatelská nastavení" - - #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. --#: src/gs-safety-context-dialog.c:238 -+#: src/gs-safety-context-dialog.c:245 - msgid "Full File System Read/Write Access" - msgstr "Plný přístup k souborovému systému pro čtení/zápis" - --#: src/gs-safety-context-dialog.c:239 -+#: src/gs-safety-context-dialog.c:246 - msgid "Can read and write all data on the file system" - msgstr "Může číst a zapisovat všechna data v souborovém systému" - - #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. --#: src/gs-safety-context-dialog.c:247 -+#: src/gs-safety-context-dialog.c:254 - msgid "Home Folder Read/Write Access" - msgstr "Přístup k domovské složce pro čtení/zápis" - --#: src/gs-safety-context-dialog.c:248 -+#: src/gs-safety-context-dialog.c:255 - msgid "Can read and write all data in your home directory" - msgstr "Může číst a zapisovat všechna data ve vaší domovské složce" - - #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. --#: src/gs-safety-context-dialog.c:256 -+#: src/gs-safety-context-dialog.c:263 - msgid "Full File System Read Access" - msgstr "Plný přístup k souborovému systému pro čtení" - --#: src/gs-safety-context-dialog.c:257 -+#: src/gs-safety-context-dialog.c:264 - msgid "Can read all data on the file system" - msgstr "Může číst všechna data v souborovém systému" - - #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. --#: src/gs-safety-context-dialog.c:266 -+#: src/gs-safety-context-dialog.c:273 - msgid "Home Folder Read Access" - msgstr "Přístup k domovské složce pro čtení" - --#: src/gs-safety-context-dialog.c:267 -+#: src/gs-safety-context-dialog.c:274 - msgid "Can read all data in your home directory" - msgstr "Může číst všechna data ve vaší domovské složce" - - #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. --#: src/gs-safety-context-dialog.c:276 -+#: src/gs-safety-context-dialog.c:283 - msgid "Download Folder Read/Write Access" - msgstr "Přístup ke složce se staženými soubory pro čtení/zápis" - --#: src/gs-safety-context-dialog.c:277 -+#: src/gs-safety-context-dialog.c:284 - msgid "Can read and write all data in your downloads directory" - msgstr "Může číst a zapisovat všechna data ve vaší složce se staženými soubory" - - #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. --#: src/gs-safety-context-dialog.c:288 -+#: src/gs-safety-context-dialog.c:295 - msgid "Download Folder Read Access" - msgstr "Přístup ke složce se staženými soubory pro čtení" - --#: src/gs-safety-context-dialog.c:289 -+#: src/gs-safety-context-dialog.c:296 - msgid "Can read all data in your downloads directory" - msgstr "Může číst všechna data ve vaší složce se staženými soubory" - --#: src/gs-safety-context-dialog.c:299 -+#: src/gs-safety-context-dialog.c:306 - msgid "Can read and write all data in the directory" - msgstr "Může číst a zapisovat všechna data ve složce" - --#: src/gs-safety-context-dialog.c:310 -+#: src/gs-safety-context-dialog.c:317 - msgid "Can read all data in the directory" - msgstr "Může číst všechna data ve složce" - - #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. --#: src/gs-safety-context-dialog.c:326 -+#: src/gs-safety-context-dialog.c:333 - msgid "No File System Access" - msgstr "Žádný přístup k souborovému systému" - --#: src/gs-safety-context-dialog.c:327 -+#: src/gs-safety-context-dialog.c:334 - msgid "Cannot access the file system at all" - msgstr "Vůbec nemůže přistupovat k souborovému systému" - - #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. --#: src/gs-safety-context-dialog.c:341 -+#: src/gs-safety-context-dialog.c:348 - msgid "Proprietary Code" - msgstr "uzavřená" - --#: src/gs-safety-context-dialog.c:342 -+#: src/gs-safety-context-dialog.c:349 - msgid "" - "The source code is not public, so it cannot be independently audited and " - "might be unsafe" -@@ -3687,11 +3749,11 @@ msgstr "" - "nebezpečný." - - #. Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. --#: src/gs-safety-context-dialog.c:345 -+#: src/gs-safety-context-dialog.c:352 - msgid "Auditable Code" - msgstr "otevřený kód" - --#: src/gs-safety-context-dialog.c:346 -+#: src/gs-safety-context-dialog.c:353 - msgid "" - "The source code is public and can be independently audited, which makes the " - "app more likely to be safe" -@@ -3701,21 +3763,21 @@ msgstr "" - - #. Translators: This indicates an app was written and released by a developer who has been verified. - #. * It’s used in a context tile, so should be short. --#: src/gs-safety-context-dialog.c:354 -+#: src/gs-safety-context-dialog.c:361 - msgid "App developer is verified" - msgstr "Vývojář aplikace je ověřený" - --#: src/gs-safety-context-dialog.c:355 -+#: src/gs-safety-context-dialog.c:362 - msgid "The developer of this app has been verified to be who they say they are" - msgstr "Bylo ověřeno, že vývojář této aplikace je tím, za koho se vydává" - - #. Translators: This indicates an app uses an outdated SDK. - #. * It’s used in a context tile, so should be short. --#: src/gs-safety-context-dialog.c:366 -+#: src/gs-safety-context-dialog.c:373 - msgid "Insecure Dependencies" - msgstr "Bezpečnostní rizika v závislostech" - --#: src/gs-safety-context-dialog.c:367 -+#: src/gs-safety-context-dialog.c:374 - msgid "" - "Software or its dependencies are no longer supported and may be insecure" - msgstr "" -@@ -3724,21 +3786,21 @@ msgstr "" - - #. Translators: The app is considered safe to install and run. - #. * The placeholder is the app name. --#: src/gs-safety-context-dialog.c:376 -+#: src/gs-safety-context-dialog.c:383 - #, c-format - msgid "%s is safe" - msgstr "Aplikace %s je bezpečná" - - #. Translators: The app is considered potentially unsafe to install and run. - #. * The placeholder is the app name. --#: src/gs-safety-context-dialog.c:383 -+#: src/gs-safety-context-dialog.c:390 - #, c-format - msgid "%s is potentially unsafe" - msgstr "Aplikace %s je potenciálně nebezpečná" - - #. Translators: The app is considered unsafe to install and run. - #. * The placeholder is the app name. --#: src/gs-safety-context-dialog.c:390 -+#: src/gs-safety-context-dialog.c:397 - #, c-format - msgid "%s is unsafe" - msgstr "Aplikace %s je nebezpečná" -@@ -3775,42 +3837,43 @@ msgstr "Předchozí snímek obrazovky" - msgid "Next Screenshot" - msgstr "Následující snímek obrazovky" - --#: src/gs-screenshot-carousel.ui:127 --msgid "No screenshot provided" --msgstr "Nemá snímek obrazovky" -+#. Translators: Shortened form of “no screenshots available” when showing an app’s details. -+#: src/gs-screenshot-carousel.ui:130 -+msgid "No Screenshots" -+msgstr "Žádné snímky obrazovky" - - #. TRANSLATORS: this is when we try to download a screenshot and - #. * we get back 404 --#: src/gs-screenshot-image.c:362 src/gs-screenshot-image.c:419 --#: src/gs-screenshot-image.c:623 -+#: src/gs-screenshot-image.c:359 src/gs-screenshot-image.c:416 -+#: src/gs-screenshot-image.c:620 - msgid "Screenshot not found" - msgstr "Snímek nebyl nalezen" - - #. TRANSLATORS: possibly image file corrupt or not an image --#: src/gs-screenshot-image.c:438 -+#: src/gs-screenshot-image.c:435 - msgid "Failed to load image" - msgstr "Selhalo načtení obrázku" - - #. TRANSLATORS: this is when we request a screenshot size that - #. * the generator did not create or the parser did not add --#: src/gs-screenshot-image.c:651 -+#: src/gs-screenshot-image.c:648 - msgid "Screenshot size not found" - msgstr "Velikost snímku nebyla nalezena" - - #. TRANSLATORS: this is when we try create the cache directory - #. * but we were out of space or permission was denied --#: src/gs-screenshot-image.c:733 -+#: src/gs-screenshot-image.c:730 - msgid "Could not create cache" - msgstr "Nelze vytvoři mezipaměť" - - #. TRANSLATORS: this is when we try to download a screenshot - #. * that was not a valid URL --#: src/gs-screenshot-image.c:747 -+#: src/gs-screenshot-image.c:744 - msgid "Screenshot not valid" - msgstr "Snímek není platný" - - #. TRANSLATORS: this is when networking is not available --#: src/gs-screenshot-image.c:797 -+#: src/gs-screenshot-image.c:794 - msgid "Screenshot not available" - msgstr "Snímek není k dispozici" - -@@ -3820,7 +3883,7 @@ msgstr "Snímek" - - #. TRANSLATORS: this is when there are too many search results - #. * to show in in the search page --#: src/gs-search-page.c:180 -+#: src/gs-search-page.c:179 - #, c-format - msgid "%u more match" - msgid_plural "%u more matches" -@@ -3837,7 +3900,7 @@ msgid "Search for Apps" - msgstr "Hledat aplikace" - - #: src/gs-search-page.ui:46 --msgid "No Application Found" -+msgid "No App Found" - msgstr "Žádná aplikace nebyla nalezena" - - #. TRANSLATORS: this is part of the in-app notification, -@@ -3848,33 +3911,33 @@ msgstr "Žádná aplikace nebyla nalezena" - #. TRANSLATORS: this is part of the in-app notification, - #. * where the %s is a multi-word localised app name - #. * e.g. 'Getting things GNOME!" --#: src/gs-shell.c:1209 src/gs-shell.c:1214 src/gs-shell.c:1229 --#: src/gs-shell.c:1233 -+#: src/gs-shell.c:1170 src/gs-shell.c:1175 src/gs-shell.c:1190 -+#: src/gs-shell.c:1194 - #, c-format - msgid "“%s”" - msgstr "„%s“" - - #. TRANSLATORS: failure text for the in-app notification, - #. * where the %s is the source (e.g. "alt.fedoraproject.org") --#: src/gs-shell.c:1285 -+#: src/gs-shell.c:1246 - #, c-format - msgid "Unable to download firmware updates from %s" - msgstr "Nelze stáhnout aktualizace firmwaru z %s" - - #. TRANSLATORS: failure text for the in-app notification, - #. * where the %s is the source (e.g. "alt.fedoraproject.org") --#: src/gs-shell.c:1291 -+#: src/gs-shell.c:1252 - #, c-format - msgid "Unable to download updates from %s" - msgstr "Nelze stáhnout aktualizace z %s" - - #. TRANSLATORS: failure text for the in-app notification --#: src/gs-shell.c:1298 src/gs-shell.c:1338 -+#: src/gs-shell.c:1259 src/gs-shell.c:1300 - msgid "Unable to download updates" - msgstr "Nelze stáhnout aktualizace" - - #. TRANSLATORS: failure text for the in-app notification --#: src/gs-shell.c:1303 -+#: src/gs-shell.c:1264 - msgid "" - "Unable to download updates: internet access was required but wasn’t available" - msgstr "" -@@ -3883,124 +3946,124 @@ msgstr "" - - #. TRANSLATORS: failure text for the in-app notification, - #. * where the %s is the source (e.g. "alt.fedoraproject.org") --#: src/gs-shell.c:1311 -+#: src/gs-shell.c:1272 - #, c-format - msgid "Unable to download updates from %s: not enough disk space" - msgstr "Nelze stáhnout aktualizace z %s: není dostatek místa na disku" - - #. TRANSLATORS: failure text for the in-app notification --#: src/gs-shell.c:1316 -+#: src/gs-shell.c:1277 - msgid "Unable to download updates: not enough disk space" - msgstr "Nelze stáhnout aktualizace: není dostatek místa na disku" - - #. TRANSLATORS: failure text for the in-app notification --#: src/gs-shell.c:1322 -+#: src/gs-shell.c:1283 - msgid "Unable to download updates: authentication was required" - msgstr "Nelze stáhnout aktualizace: je vyžadováno ověření" - - #. TRANSLATORS: failure text for the in-app notification --#: src/gs-shell.c:1326 -+#: src/gs-shell.c:1287 - msgid "Unable to download updates: authentication was invalid" - msgstr "Nelze stáhnout aktualizace: ověření nebylo platné" - - #. TRANSLATORS: failure text for the in-app notification --#: src/gs-shell.c:1330 -+#: src/gs-shell.c:1291 - msgid "" - "Unable to download updates: you do not have permission to install software" - msgstr "Nelze stáhnout aktualizace: nemáte oprávnění instalovat software" - - #. TRANSLATORS: failure text for the in-app notification --#: src/gs-shell.c:1341 -+#: src/gs-shell.c:1303 - msgid "Unable to get list of updates" - msgstr "Nelze získat seznam aktualizací" - - #. TRANSLATORS: failure text for the in-app notification, --#. * where the first %s is the application name (e.g. "GIMP") and -+#. * where the first %s is the app name (e.g. "GIMP") and - #. * the second %s is the origin, e.g. "Fedora Project [fedoraproject.org]" --#: src/gs-shell.c:1377 -+#: src/gs-shell.c:1339 - #, c-format - msgid "Unable to install %s as download failed from %s" - msgstr "Nelze nainstalovat balíček %s, protože selhalo jeho stažení z %s" - - #. TRANSLATORS: failure text for the in-app notification, --#. * where the %s is the application name (e.g. "GIMP") --#: src/gs-shell.c:1383 -+#. * where the %s is the app name (e.g. "GIMP") -+#: src/gs-shell.c:1345 - #, c-format - msgid "Unable to install %s as download failed" - msgstr "Nelze nainstalovat balíček %s, protože selhalo stažení" - - #. TRANSLATORS: failure text for the in-app notification, --#. * where the first %s is the application name (e.g. "GIMP") -+#. * where the first %s is the app name (e.g. "GIMP") - #. * and the second %s is the name of the runtime, e.g. - #. * "GNOME SDK [flatpak.gnome.org]" --#: src/gs-shell.c:1395 -+#: src/gs-shell.c:1357 - #, c-format - msgid "Unable to install %s as runtime %s not available" - msgstr "" - "Nelze nainstalovat balíček %s, protože není k dispozici běhové prostředí %s" - - #. TRANSLATORS: failure text for the in-app notification, --#. * where the %s is the application name (e.g. "GIMP") --#: src/gs-shell.c:1401 -+#. * where the %s is the app name (e.g. "GIMP") -+#: src/gs-shell.c:1363 - #, c-format - msgid "Unable to install %s as not supported" - msgstr "Nelze nainstalovat balíček %s, protože není podporovaný" - - #. TRANSLATORS: failure text for the in-app notification --#: src/gs-shell.c:1407 -+#: src/gs-shell.c:1369 - msgid "Unable to install: internet access was required but wasn’t available" - msgstr "" - "Nelze nainstalovat: přístup k internetu je nezbytný, ale není k dispozici" - - #. TRANSLATORS: failure text for the in-app notification --#: src/gs-shell.c:1412 --msgid "Unable to install: the application has an invalid format" -+#: src/gs-shell.c:1374 -+msgid "Unable to install: the app has an invalid format" - msgstr "Nelze nainstalovat: aplikace má neplatný formát" - - #. TRANSLATORS: failure text for the in-app notification, --#. * where the %s is the application name (e.g. "GIMP") --#: src/gs-shell.c:1416 -+#. * where the %s is the app name (e.g. "GIMP") -+#: src/gs-shell.c:1378 - #, c-format - msgid "Unable to install %s: not enough disk space" - msgstr "Nelze nainstalovat balíček %s: není dostatek místa na disku" - - #. TRANSLATORS: failure text for the in-app notification --#: src/gs-shell.c:1422 -+#: src/gs-shell.c:1384 - #, c-format - msgid "Unable to install %s: authentication was required" - msgstr "Nelze nainstalovat balíček %s: je vyžadováno ověření" - - #. TRANSLATORS: failure text for the in-app notification, --#. * where the %s is the application name (e.g. "GIMP") --#: src/gs-shell.c:1428 -+#. * where the %s is the app name (e.g. "GIMP") -+#: src/gs-shell.c:1390 - #, c-format - msgid "Unable to install %s: authentication was invalid" - msgstr "Nelze nainstalovat balíček %s: ověření nebylo platné" - - #. TRANSLATORS: failure text for the in-app notification, --#. * where the %s is the application name (e.g. "GIMP") --#: src/gs-shell.c:1434 -+#. * where the %s is the app name (e.g. "GIMP") -+#: src/gs-shell.c:1396 - #, c-format - msgid "Unable to install %s: you do not have permission to install software" - msgstr "Nelze nainstalovat balíček %s: nemáte oprávnění k instalaci softwaru" - - #. TRANSLATORS: failure text for the in-app notification, --#. * where the %s is the application name (e.g. "Dell XPS 13") --#: src/gs-shell.c:1441 -+#. * where the %s is the app name (e.g. "Dell XPS 13") -+#: src/gs-shell.c:1403 - #, c-format - msgid "Unable to install %s: AC power is required" - msgstr "Nelze nainstalovat balíček %s: je vyžadováno připojené napájení" - - #. TRANSLATORS: failure text for the in-app notification, --#. * where the %s is the application name (e.g. "Dell XPS 13") --#: src/gs-shell.c:1447 -+#. * where the %s is the app name (e.g. "Dell XPS 13") -+#: src/gs-shell.c:1409 - #, c-format - msgid "Unable to install %s: The battery level is too low" - msgstr "Nelze nainstalovat balíček %s: úroveň nabití baterie je příliš nízká" - - #. TRANSLATORS: failure text for the in-app notification, --#. * where the %s is the application name (e.g. "GIMP") --#: src/gs-shell.c:1456 -+#. * where the %s is the app name (e.g. "GIMP") -+#: src/gs-shell.c:1418 - #, c-format - msgid "Unable to install %s" - msgstr "Nelze nainstalovat balíček %s" -@@ -4009,14 +4072,14 @@ msgstr "Nelze nainstalovat balíček %s" - #. * where the first %s is the app name (e.g. "GIMP") and - #. * the second %s is the origin, e.g. "Fedora" or - #. * "Fedora Project [fedoraproject.org]" --#: src/gs-shell.c:1495 -+#: src/gs-shell.c:1457 - #, c-format - msgid "Unable to update %s from %s as download failed" - msgstr "Nelze aktualizovat balíček %s z %s, protože selhalo stažení" - - #. TRANSLATORS: failure text for the in-app notification, --#. * where the %s is the application name (e.g. "GIMP") --#: src/gs-shell.c:1502 -+#. * where the %s is the app name (e.g. "GIMP") -+#: src/gs-shell.c:1464 - #, c-format - msgid "Unable to update %s as download failed" - msgstr "Nelze aktualizovat balíček %s, protože selhalo stažení" -@@ -4024,71 +4087,71 @@ msgstr "Nelze aktualizovat balíček %s, protože selhalo stažení" - #. TRANSLATORS: failure text for the in-app notification, - #. * where the %s is the origin, e.g. "Fedora" or - #. * "Fedora Project [fedoraproject.org]" --#: src/gs-shell.c:1509 -+#: src/gs-shell.c:1471 - #, c-format - msgid "Unable to install updates from %s as download failed" - msgstr "Nelze nainstalovat aktualizace z %s, protože selhalo stažení" - - #. TRANSLATORS: failure text for the in-app notification --#: src/gs-shell.c:1513 -+#: src/gs-shell.c:1475 - #, c-format - msgid "Unable to install updates as download failed" - msgstr "Nelze nainstalovat aktualizace, protože selhalo stažení" - - #. TRANSLATORS: failure text for the in-app notification --#: src/gs-shell.c:1518 -+#: src/gs-shell.c:1480 - msgid "Unable to update: internet access was required but wasn’t available" - msgstr "" - "Nelze aktualizovat: přístup k internetu je nezbytný, ale není k dispozici" - - #. TRANSLATORS: failure text for the in-app notification, --#. * where the %s is the application name (e.g. "GIMP") --#: src/gs-shell.c:1527 -+#. * where the %s is the app name (e.g. "GIMP") -+#: src/gs-shell.c:1489 - #, c-format - msgid "Unable to update %s: not enough disk space" - msgstr "Nelze aktualizovat balíček %s: nedostatek místa na disku" - - #. TRANSLATORS: failure text for the in-app notification --#: src/gs-shell.c:1532 -+#: src/gs-shell.c:1494 - #, c-format - msgid "Unable to install updates: not enough disk space" - msgstr "Nelze nainstalovat aktualizace: nedostatek místa na disku" - - #. TRANSLATORS: failure text for the in-app notification, --#. * where the %s is the application name (e.g. "GIMP") --#: src/gs-shell.c:1541 -+#. * where the %s is the app name (e.g. "GIMP") -+#: src/gs-shell.c:1503 - #, c-format - msgid "Unable to update %s: authentication was required" - msgstr "Nelze aktualizovat balíček %s: je vyžadováno ověření" - - #. TRANSLATORS: failure text for the in-app notification --#: src/gs-shell.c:1546 -+#: src/gs-shell.c:1508 - #, c-format - msgid "Unable to install updates: authentication was required" - msgstr "Nelze nainstalovat aktualizace: je vyžadováno ověření" - - #. TRANSLATORS: failure text for the in-app notification, --#. * where the %s is the application name (e.g. "GIMP") --#: src/gs-shell.c:1554 -+#. * where the %s is the app name (e.g. "GIMP") -+#: src/gs-shell.c:1516 - #, c-format - msgid "Unable to update %s: authentication was invalid" - msgstr "Nelze aktualizovat balíček %s: ověření bylo neplatné" - - #. TRANSLATORS: failure text for the in-app notification --#: src/gs-shell.c:1559 -+#: src/gs-shell.c:1521 - #, c-format - msgid "Unable to install updates: authentication was invalid" - msgstr "Nelze nainstalovat aktualizace: ověření bylo neplatné" - - #. TRANSLATORS: failure text for the in-app notification, --#. * where the %s is the application name (e.g. "GIMP") --#: src/gs-shell.c:1567 -+#. * where the %s is the app name (e.g. "GIMP") -+#: src/gs-shell.c:1529 - #, c-format - msgid "Unable to update %s: you do not have permission to update software" - msgstr "Nelze aktualizovat balíček %s: nemáte oprávnění k aktualizaci softwaru" - - #. TRANSLATORS: failure text for the in-app notification --#: src/gs-shell.c:1573 -+#: src/gs-shell.c:1535 - #, c-format - msgid "" - "Unable to install updates: you do not have permission to update software" -@@ -4096,44 +4159,44 @@ msgstr "" - "Nelze nainstalovat aktualizace: nemáte oprávnění k aktualizaci softwaru" - - #. TRANSLATORS: failure text for the in-app notification, --#. * where the %s is the application name (e.g. "Dell XPS 13") --#: src/gs-shell.c:1582 -+#. * where the %s is the app name (e.g. "Dell XPS 13") -+#: src/gs-shell.c:1544 - #, c-format - msgid "Unable to update %s: AC power is required" - msgstr "" - "Nelze aktualizovat balíček %s: je vyžadováno napájení z elektrické sítě" - - #. TRANSLATORS: failure text for the in-app notification, --#. * where the %s is the application name (e.g. "Dell XPS 13") --#: src/gs-shell.c:1588 -+#. * where the %s is the app name (e.g. "Dell XPS 13") -+#: src/gs-shell.c:1550 - #, c-format - msgid "Unable to install updates: AC power is required" - msgstr "" - "Nelze nainstalovat aktualizace: je vyžadováno napájení z elektrické sítě" - - #. TRANSLATORS: failure text for the in-app notification, --#. * where the %s is the application name (e.g. "Dell XPS 13") --#: src/gs-shell.c:1596 -+#. * where the %s is the app name (e.g. "Dell XPS 13") -+#: src/gs-shell.c:1558 - #, c-format - msgid "Unable to update %s: The battery level is too low" - msgstr "Nelze aktualizovat balíček %s: úroveň nabití baterie je příliš nízká" - - #. TRANSLATORS: failure text for the in-app notification, --#. * where the %s is the application name (e.g. "Dell XPS 13") --#: src/gs-shell.c:1602 -+#. * where the %s is the app name (e.g. "Dell XPS 13") -+#: src/gs-shell.c:1564 - #, c-format - msgid "Unable to install updates: The battery level is too low" - msgstr "Nelze nainstalovat aktualizace: úroveň nabití baterie je příliš nízká" - - #. TRANSLATORS: failure text for the in-app notification, --#. * where the %s is the application name (e.g. "GIMP") --#: src/gs-shell.c:1613 -+#. * where the %s is the app name (e.g. "GIMP") -+#: src/gs-shell.c:1575 - #, c-format - msgid "Unable to update %s" - msgstr "Nelze aktualizovat balíček %s" - - #. TRANSLATORS: failure text for the in-app notification --#: src/gs-shell.c:1616 -+#: src/gs-shell.c:1578 - #, c-format - msgid "Unable to install updates" - msgstr "Nelze nainstalovat aktualizace" -@@ -4141,21 +4204,21 @@ msgstr "Nelze nainstalovat aktualizace" - #. TRANSLATORS: failure text for the in-app notification, - #. * where the first %s is the distro name (e.g. "Fedora 25") and - #. * the second %s is the origin, e.g. "Fedora Project [fedoraproject.org]" --#: src/gs-shell.c:1652 -+#: src/gs-shell.c:1614 - #, c-format - msgid "Unable to upgrade to %s from %s" - msgstr "Nelze povýšit na %s z %s" - - #. TRANSLATORS: failure text for the in-app notification, - #. * where the %s is the app name (e.g. "GIMP") --#: src/gs-shell.c:1657 -+#: src/gs-shell.c:1619 - #, c-format - msgid "Unable to upgrade to %s as download failed" - msgstr "Nelze povýšit na %s, protože selhalo stažení" - - #. TRANSLATORS: failure text for the in-app notification, - #. * where the %s is the distro name (e.g. "Fedora 25") --#: src/gs-shell.c:1665 -+#: src/gs-shell.c:1627 - #, c-format - msgid "" - "Unable to upgrade to %s: internet access was required but wasn’t available" -@@ -4165,159 +4228,159 @@ msgstr "" - - #. TRANSLATORS: failure text for the in-app notification, - #. * where the %s is the distro name (e.g. "Fedora 25") --#: src/gs-shell.c:1673 -+#: src/gs-shell.c:1635 - #, c-format - msgid "Unable to upgrade to %s: not enough disk space" - msgstr "Nelze povýšit na %s: není dostatek místa na disku" - - #. TRANSLATORS: failure text for the in-app notification, - #. * where the %s is the distro name (e.g. "Fedora 25") --#: src/gs-shell.c:1680 -+#: src/gs-shell.c:1642 - #, c-format - msgid "Unable to upgrade to %s: authentication was required" - msgstr "Nelze povýšit na %s: je vyžadováno ověření" - - #. TRANSLATORS: failure text for the in-app notification, - #. * where the %s is the distro name (e.g. "Fedora 25") --#: src/gs-shell.c:1686 -+#: src/gs-shell.c:1648 - #, c-format - msgid "Unable to upgrade to %s: authentication was invalid" - msgstr "Nelze povýšit na %s: ověření nebylo platné" - - #. TRANSLATORS: failure text for the in-app notification, - #. * where the %s is the distro name (e.g. "Fedora 25") --#: src/gs-shell.c:1692 -+#: src/gs-shell.c:1654 - #, c-format - msgid "Unable to upgrade to %s: you do not have permission to upgrade" - msgstr "Nelze povýšit na %s: nemáte oprávnění k povyšování" - - #. TRANSLATORS: failure text for the in-app notification, - #. * where the %s is the distro name (e.g. "Fedora 25") --#: src/gs-shell.c:1698 -+#: src/gs-shell.c:1660 - #, c-format - msgid "Unable to upgrade to %s: AC power is required" - msgstr "Nelze povýšit na %s: je vyžadováno připojené napájení" - - #. TRANSLATORS: failure text for the in-app notification, - #. * where the %s is the distro name (e.g. "Fedora 25") --#: src/gs-shell.c:1704 -+#: src/gs-shell.c:1666 - #, c-format - msgid "Unable to upgrade to %s: The battery level is too low" - msgstr "Nelze povýšit na %s: úroveň nabití baterie je příliš nízká" - - #. TRANSLATORS: failure text for the in-app notification, - #. * where the %s is the distro name (e.g. "Fedora 25") --#: src/gs-shell.c:1713 -+#: src/gs-shell.c:1675 - #, c-format - msgid "Unable to upgrade to %s" - msgstr "Nelze povýšit na %s" - - #. TRANSLATORS: failure text for the in-app notification, --#. * where the %s is the application name (e.g. "GIMP") --#: src/gs-shell.c:1744 -+#. * where the %s is the app name (e.g. "GIMP") -+#: src/gs-shell.c:1706 - #, c-format - msgid "Unable to remove %s: authentication was required" - msgstr "Nelze odstranit balíček %s: je vyžadováno ověření" - - #. TRANSLATORS: failure text for the in-app notification, --#. * where the %s is the application name (e.g. "GIMP") --#: src/gs-shell.c:1749 -+#. * where the %s is the app name (e.g. "GIMP") -+#: src/gs-shell.c:1711 - #, c-format - msgid "Unable to remove %s: authentication was invalid" - msgstr "Nelze odstranit balíček %s: ověření nebylo platné" - - #. TRANSLATORS: failure text for the in-app notification, --#. * where the %s is the application name (e.g. "GIMP") --#: src/gs-shell.c:1754 -+#. * where the %s is the app name (e.g. "GIMP") -+#: src/gs-shell.c:1716 - #, c-format - msgid "Unable to remove %s: you do not have permission to remove software" - msgstr "Nelze odstranit balíček %s: nemáte oprávnění k odstranění softwaru" - - #. TRANSLATORS: failure text for the in-app notification, --#. * where the %s is the application name (e.g. "GIMP") --#: src/gs-shell.c:1760 -+#. * where the %s is the app name (e.g. "GIMP") -+#: src/gs-shell.c:1722 - #, c-format - msgid "Unable to remove %s: AC power is required" - msgstr "Nelze odstranit balíček %s: je vyžadováno připojené napájení" - - #. TRANSLATORS: failure text for the in-app notification, --#. * where the %s is the application name (e.g. "GIMP") --#: src/gs-shell.c:1766 -+#. * where the %s is the app name (e.g. "GIMP") -+#: src/gs-shell.c:1728 - #, c-format - msgid "Unable to remove %s: The battery level is too low" - msgstr "Nelze odstranit balíček %s: úroveň nabití baterie je příliš nízká" - - #. TRANSLATORS: failure text for the in-app notification, --#. * where the %s is the application name (e.g. "GIMP") --#: src/gs-shell.c:1778 -+#. * where the %s is the app name (e.g. "GIMP") -+#: src/gs-shell.c:1740 - #, c-format - msgid "Unable to remove %s" - msgstr "Nelze odstranit balíček %s" - - #. TRANSLATORS: failure text for the in-app notification, --#. * where the first %s is the application name (e.g. "GIMP") -+#. * where the first %s is the app name (e.g. "GIMP") - #. * and the second %s is the name of the runtime, e.g. - #. * "GNOME SDK [flatpak.gnome.org]" --#: src/gs-shell.c:1813 -+#: src/gs-shell.c:1775 - #, c-format - msgid "Unable to launch %s: %s is not installed" - msgstr "Nelze spustit aplikaci %s: balíček %s není nainstalovaný" - - #. TRANSLATORS: we failed to get a proper error code --#: src/gs-shell.c:1821 src/gs-shell.c:1837 src/gs-shell.c:1879 --#: src/gs-shell.c:1921 src/gs-shell.c:1978 -+#: src/gs-shell.c:1783 src/gs-shell.c:1799 src/gs-shell.c:1841 -+#: src/gs-shell.c:1883 src/gs-shell.c:1940 - msgid "Sorry, something went wrong" - msgstr "Litujeme, ale něco se stalo špatně" - - #. TRANSLATORS: failure text for the in-app notification --#: src/gs-shell.c:1826 src/gs-shell.c:1868 src/gs-shell.c:1910 --#: src/gs-shell.c:1957 -+#: src/gs-shell.c:1788 src/gs-shell.c:1830 src/gs-shell.c:1872 -+#: src/gs-shell.c:1919 - msgid "Not enough disk space — free up some space and try again" - msgstr "" - "Nebyl dostatek místa na disku – uvolněte nějaké místo a pak to zkuste znovu" - - #. TRANSLATORS: failure text for the in-app notification --#: src/gs-shell.c:1862 -+#: src/gs-shell.c:1824 - msgid "Failed to install file: not supported" - msgstr "Selhala instalace souboru: není podporován" - - #. TRANSLATORS: failure text for the in-app notification --#: src/gs-shell.c:1865 -+#: src/gs-shell.c:1827 - msgid "Failed to install file: authentication failed" - msgstr "Selhala instalace souboru: selhalo ověření" - - #. TRANSLATORS: failure text for the in-app notification --#: src/gs-shell.c:1904 -+#: src/gs-shell.c:1866 - msgid "Failed to install: not supported" - msgstr "Selhala instalace: není podporováno" - - #. TRANSLATORS: failure text for the in-app notification --#: src/gs-shell.c:1907 -+#: src/gs-shell.c:1869 - msgid "Failed to install: authentication failed" - msgstr "Selhala instalace: selhalo ověření" - - #. TRANSLATORS: failure text for the in-app notification, - #. * the %s is the origin, e.g. "Fedora" or - #. * "Fedora Project [fedoraproject.org]" --#: src/gs-shell.c:1952 -+#: src/gs-shell.c:1914 - #, c-format - msgid "Unable to contact %s" - msgstr "Nelze kontaktovat %s" - --#. TRANSLATORS: failure text for the in-app notification, where the 'Software' means this application, aka 'GNOME Software'. --#: src/gs-shell.c:1962 -+#. TRANSLATORS: failure text for the in-app notification, where the 'Software' means this app, aka 'GNOME Software'. -+#: src/gs-shell.c:1924 - msgid "Software needs to be restarted to use new plugins." - msgstr "" - "Aplikace Software musí být restartována, aby mohla používat nový zásuvný " - "modul." - - #. TRANSLATORS: need to be connected to the AC power --#: src/gs-shell.c:1966 -+#: src/gs-shell.c:1928 - msgid "AC power is required" - msgstr "Je vyžadováno připojené napájení" - - #. TRANSLATORS: not enough juice to do this safely --#: src/gs-shell.c:1969 -+#: src/gs-shell.c:1931 - msgid "The battery level is too low" - msgstr "Úroveň nabití baterie je příliš nízká" - -@@ -4326,48 +4389,65 @@ msgid "_Software Repositories" - msgstr "_Softwarové repozitáře" - - #: src/gs-shell.ui:12 --msgid "_Update Preferences" --msgstr "Předvolby akt_ualizací" -+msgid "_Preferences" -+msgstr "_Předvolby" - - #. button in the info bar --#: src/gs-shell.ui:98 -+#: src/gs-shell.ui:109 - msgid "Examine Disk" - msgstr "Prozkoumat disk" - - #. button in the info bar --#. TRANSLATORS: this is a link to the --#. * control-center network panel --#: src/gs-shell.ui:108 src/gs-updates-page.c:885 -+#: src/gs-shell.ui:119 - msgid "Network Settings" - msgstr "Nastavení sítě" - - #. button in the info bar --#: src/gs-shell.ui:118 --msgid "Restart Now" --msgstr "Restartovat hned" -+#: src/gs-shell.ui:129 -+msgid "_Restart Now…" -+msgstr "_Restartovat hned…" - - #. button in the info bar --#: src/gs-shell.ui:128 -+#: src/gs-shell.ui:140 - msgid "More Information" - msgstr "Další informace" - --#: src/gs-shell.ui:188 src/gs-shell.ui:190 -+#: src/gs-shell.ui:200 src/gs-shell.ui:202 - msgid "Search" - msgstr "Hledat" - --#: src/gs-shell.ui:204 src/gs-shell.ui:206 --msgid "Primary Menu" --msgstr "Hlavní nabídky" -+#: src/gs-shell.ui:216 src/gs-shell.ui:218 -+msgid "Main Menu" -+msgstr "Hlavní nabídka" -+ -+#: src/gs-shell.ui:245 -+msgid "Search apps" -+msgstr "Hledat aplikace" -+ -+#: src/gs-shell.ui:257 -+msgid "Metered network ‒ automatic updates paused" -+msgstr "Měřená síť – automatické aktualizace jsou pozastaveny" - --#: src/gs-shell.ui:276 -+#: src/gs-shell.ui:258 - msgid "Find Out _More" - msgstr "Dozvědět se _více…" - -+#. Translators: A label for a button to show all available software. -+#: src/gs-shell.ui:272 -+msgid "_Explore" -+msgstr "_Procházet" -+ -+#. Translators: A label for a button to show only software which is already installed. -+#: src/gs-shell.ui:286 -+msgctxt "List of installed apps" -+msgid "_Installed" -+msgstr "Na_instalováno" -+ - #. Translators: A label for a button to show only updates which are available to install. --#: src/gs-shell.ui:330 -+#: src/gs-shell.ui:308 - msgctxt "Header bar button for list of apps to be updated" --msgid "Updates" --msgstr "Aktualizace" -+msgid "_Updates" -+msgstr "_Aktualizace" - - #. Translators: This is shown in a bubble to represent a 0 byte - #. * storage size, so its context is “storage size: none”. The -@@ -4378,11 +4458,11 @@ msgid "None" - msgstr "Žádná" - - #: src/gs-storage-context-dialog.c:139 --msgid "Application Data" -+msgid "App Data" - msgstr "Data aplikace" - - #: src/gs-storage-context-dialog.c:140 --msgid "Data needed for the application to run" -+msgid "Data needed for the app to run" - msgstr "Data potřebná ke spuštění aplikace" - - #: src/gs-storage-context-dialog.c:145 -@@ -4390,7 +4470,7 @@ msgid "User Data" - msgstr "Uživatelská data" - - #: src/gs-storage-context-dialog.c:146 --msgid "Data created by you in the application" -+msgid "Data created by you in the app" - msgstr "Vámi vytvořená data v aplikaci" - - #: src/gs-storage-context-dialog.c:153 -@@ -4402,7 +4482,7 @@ msgid "Temporary cached data" - msgstr "Dočasná data v mezipaměti" - - #: src/gs-storage-context-dialog.c:172 --msgid "The application itself" -+msgid "The app itself" - msgstr "Aplikace samotná" - - #: src/gs-storage-context-dialog.c:177 -@@ -4410,7 +4490,7 @@ msgid "Required Dependencies" - msgstr "Vyžadované závislosti" - - #: src/gs-storage-context-dialog.c:178 --msgid "Shared system components required by this application" -+msgid "Shared system components required by this app" - msgstr "Sdílené systémové komponenty vyžadované touto aplikací" - - #: src/gs-storage-context-dialog.c:188 -@@ -4426,23 +4506,22 @@ msgstr "Úložiště" - #. Translators: Please do not translate the markup or link href - #: src/gs-storage-context-dialog.ui:69 - msgid "" --"Cached data can be cleared from the _application settings." -+"Cached data can be cleared from the _app settings." - msgstr "" - "Data uložená v mezipaměti lze vymazat v _nastavení " - "aplikace." - --#: src/gs-summary-tile.c:118 -+#: src/gs-summary-tile.c:139 - #, c-format - msgid "%s (Installed)" - msgstr "%s (nainstalováno)" - --#: src/gs-summary-tile.c:123 -+#: src/gs-summary-tile.c:144 - #, c-format - msgid "%s (Installing)" - msgstr "%s (instaluje se)" - --#: src/gs-summary-tile.c:128 -+#: src/gs-summary-tile.c:149 - #, c-format - msgid "%s (Removing)" - msgstr "%s (odebírá se)" -@@ -4508,8 +4587,8 @@ msgstr "Stáhněte prosím čekající aktualizace softwaru." - #. TRANSLATORS: apps were auto-updated and restart is required - #: src/gs-update-monitor.c:355 - #, c-format --msgid "%u Application Updated — Restart Required" --msgid_plural "%u Applications Updated — Restart Required" -+msgid "%u App Updated — Restart Required" -+msgid_plural "%u Apps Updated — Restart Required" - msgstr[0] "Byla aktualizována %u aplikace — vyžaduje restart" - msgstr[1] "Byly aktualizovány %u aplikace — vyžaduje restart" - msgstr[2] "Bylo aktualizováno %u aplikací — vyžaduje restart" -@@ -4517,13 +4596,13 @@ msgstr[2] "Bylo aktualizováno %u aplikací — vyžaduje restart" - #. TRANSLATORS: apps were auto-updated - #: src/gs-update-monitor.c:361 - #, c-format --msgid "%u Application Updated" --msgid_plural "%u Applications Updated" -+msgid "%u App Updated" -+msgid_plural "%u Apps Updated" - msgstr[0] "Byla aktualizována %u aplikace" - msgstr[1] "Byly aktualizovány %u aplikace" - msgstr[2] "Bylo aktualizováno %u aplikací" - --#. TRANSLATORS: %1 is an application name, e.g. Firefox -+#. TRANSLATORS: %1 is an app name, e.g. Firefox - #: src/gs-update-monitor.c:372 - #, c-format - msgid "%s has been updated." -@@ -4531,81 +4610,81 @@ msgstr "Aplikace %s byla aktualizována." - - #. TRANSLATORS: the app needs restarting - #: src/gs-update-monitor.c:375 --msgid "Please restart the application." -+msgid "Please restart the app." - msgstr "Restartujte ji prosím." - --#. TRANSLATORS: %1 and %2 are both application names, e.g. Firefox -+#. TRANSLATORS: %1 and %2 are both app names, e.g. Firefox - #: src/gs-update-monitor.c:383 - #, c-format - msgid "%s and %s have been updated." - msgstr "Aplikace %s a %s byly aktualizovány." - --#. TRANSLATORS: at least one application needs restarting -+#. TRANSLATORS: at least one app needs restarting - #: src/gs-update-monitor.c:389 src/gs-update-monitor.c:408 - #, c-format --msgid "%u application requires a restart." --msgid_plural "%u applications require a restart." -+msgid "%u app requires a restart." -+msgid_plural "%u apps require a restart." - msgstr[0] "%u aplikace vyžaduje restart." - msgstr[1] "%u aplikace vyžadují restart." - msgstr[2] "%u aplikací vyžaduje restart." - --#. TRANSLATORS: %1, %2 and %3 are all application names, e.g. Firefox -+#. TRANSLATORS: %1, %2 and %3 are all app names, e.g. Firefox - #: src/gs-update-monitor.c:401 - #, c-format - msgid "Includes %s, %s and %s." - msgstr "Včetně %s, %s a %s." - - #. TRANSLATORS: this is when the current operating system version goes end-of-life --#: src/gs-update-monitor.c:671 src/gs-updates-page.ui:20 -+#: src/gs-update-monitor.c:696 - msgid "Operating System Updates Unavailable" - msgstr "Aktualizace operačního systému nejsou dostupné" - - #. TRANSLATORS: this is the message dialog for the distro EOL notice --#: src/gs-update-monitor.c:673 -+#: src/gs-update-monitor.c:698 - msgid "Upgrade to continue receiving security updates." - msgstr "Povýšit, aby byly nadále přijímány bezpečnostní aktualizace." - - #. TRANSLATORS: this is a distro upgrade, the replacement would be the - #. * distro name, e.g. 'Fedora' --#: src/gs-update-monitor.c:728 -+#: src/gs-update-monitor.c:753 - #, c-format - msgid "A new version of %s is available to install" - msgstr "K instalaci je dostupná nová verze distribuce %s" - - #. TRANSLATORS: this is a distro upgrade --#: src/gs-update-monitor.c:732 -+#: src/gs-update-monitor.c:757 - msgid "Software Upgrade Available" - msgstr "Dostupné povýšení softwaru" - - #. TRANSLATORS: title when we offline updates have failed --#: src/gs-update-monitor.c:1137 -+#: src/gs-update-monitor.c:1162 - msgid "Software Updates Failed" - msgstr "Aktualizace softwaru selhaly" - - #. TRANSLATORS: message when we offline updates have failed --#: src/gs-update-monitor.c:1139 -+#: src/gs-update-monitor.c:1164 - msgid "An important operating system update failed to be installed." - msgstr "Selhala instalace důležité aktualizace operačního systému." - --#: src/gs-update-monitor.c:1140 -+#: src/gs-update-monitor.c:1165 - msgid "Show Details" - msgstr "Zobrazit podrobnosti" - - #. TRANSLATORS: Notification title when we've done a distro upgrade --#: src/gs-update-monitor.c:1162 -+#: src/gs-update-monitor.c:1187 - msgid "System Upgrade Complete" - msgstr "Bylo dokončeno povýšení systému" - - #. TRANSLATORS: This is the notification body when we've done a - #. * distro upgrade. First %s is the distro name and the 2nd %s - #. * is the version, e.g. "Welcome to Fedora 28!" --#: src/gs-update-monitor.c:1167 -+#: src/gs-update-monitor.c:1192 - #, c-format - msgid "Welcome to %s %s!" - msgstr "Vítejte ve vydání %s %s!" - - #. TRANSLATORS: title when we've done offline updates --#: src/gs-update-monitor.c:1173 -+#: src/gs-update-monitor.c:1198 - msgid "Software Update Installed" - msgid_plural "Software Updates Installed" - msgstr[0] "Aktualizace softwaru nainstalována" -@@ -4613,7 +4692,7 @@ msgstr[1] "Aktualizace softwaru nainstalovány" - msgstr[2] "Aktualizace softwaru nainstalovány" - - #. TRANSLATORS: message when we've done offline updates --#: src/gs-update-monitor.c:1177 -+#: src/gs-update-monitor.c:1202 - msgid "An important operating system update has been installed." - msgid_plural "Important operating system updates have been installed." - msgstr[0] "Byla nainstalována důležitá aktualizace operačního systému." -@@ -4621,34 +4700,34 @@ msgstr[1] "Byly nainstalovány důležité aktualizace operačního systému." - msgstr[2] "Byly nainstalovány důležité aktualizace operačního systému." - - #. TRANSLATORS: Button to look at the updates that were installed. --#. * Note that it has nothing to do with the application reviews, the -+#. * Note that it has nothing to do with the app reviews, the - #. * users can't express their opinions here. In some languages - #. * "Review (evaluate) something" is a different translation than - #. * "Review (browse) something." --#: src/gs-update-monitor.c:1188 -+#: src/gs-update-monitor.c:1213 - msgctxt "updates" - msgid "Review" - msgstr "Přehled" - - #. TRANSLATORS: this is when the offline update failed --#: src/gs-update-monitor.c:1237 -+#: src/gs-update-monitor.c:1262 - msgid "Failed To Update" - msgstr "Aktualizace selhala" - - #. TRANSLATORS: the user must have updated manually after - #. * the updates were prepared --#: src/gs-update-monitor.c:1242 -+#: src/gs-update-monitor.c:1267 - msgid "The system was already up to date." - msgstr "Systém již byl aktuální." - - #. TRANSLATORS: the user aborted the update manually --#: src/gs-update-monitor.c:1247 -+#: src/gs-update-monitor.c:1272 - msgid "The update was cancelled." - msgstr "Aktualizace byla zrušena." - - #. TRANSLATORS: the package manager needed to download - #. * something with no network available --#: src/gs-update-monitor.c:1252 -+#: src/gs-update-monitor.c:1277 - msgid "" - "Internet access was required but wasn’t available. Please make sure that you " - "have internet access and try again." -@@ -4657,7 +4736,7 @@ msgstr "" - "připojení k Internetu a zkuste to znovu." - - #. TRANSLATORS: if the package is not signed correctly --#: src/gs-update-monitor.c:1257 -+#: src/gs-update-monitor.c:1282 - msgid "" - "There were security issues with the update. Please consult your software " - "provider for more details." -@@ -4666,7 +4745,7 @@ msgstr "" - "svým poskytovatelem softwaru." - - #. TRANSLATORS: we ran out of disk space --#: src/gs-update-monitor.c:1262 -+#: src/gs-update-monitor.c:1287 - msgid "" - "There wasn’t enough disk space. Please free up some space and try again." - msgstr "" -@@ -4674,7 +4753,7 @@ msgstr "" - "znovu." - - #. TRANSLATORS: We didn't handle the error type --#: src/gs-update-monitor.c:1266 -+#: src/gs-update-monitor.c:1291 - msgid "" - "We’re sorry: the update failed to install. Please wait for another update " - "and try again. If the problem persists, contact your software provider." -@@ -4684,49 +4763,39 @@ msgstr "" - "poskytovatele softwaru." - - #. TRANSLATORS: This is the time when we last checked for updates --#: src/gs-updates-page.c:248 -+#: src/gs-updates-page.c:253 - #, c-format - msgid "Last checked: %s" - msgstr "Poslední kontrola: %s" - --#: src/gs-updates-page.c:297 --msgid "Stop Refreshing" --msgstr "" -+#: src/gs-updates-page.c:302 -+msgid "Stop" -+msgstr "Zastavit" - --#: src/gs-updates-page.c:306 src/gs-updates-page.c:318 --msgid "Refresh" --msgstr "" -+#: src/gs-updates-page.c:311 src/gs-updates-page.c:323 -+msgid "Check for Updates" -+msgstr "Zkontrolovat aktualizace" - - #. TRANSLATORS: the first %s is the distro name, e.g. 'Fedora' - #. * and the second %s is the distro version, e.g. '25' --#: src/gs-updates-page.c:563 -+#: src/gs-updates-page.c:568 - #, c-format --msgid "%s %s is no longer supported." --msgstr "Systém %s %s již není podporován." -- --#: src/gs-updates-page.c:567 --msgid "Your operating system is no longer supported." --msgstr "Váš operační systém není nadále podporován." -- --#. TRANSLATORS: EOL distros do not get important updates --#: src/gs-updates-page.c:572 --msgid "This means that it does not receive security updates." --msgstr "" --"Znamená to, že pro něj již nadále nejsou poskytovány bezpečnostní opravy." -+msgid "%s %s has stopped receiving critical software updates" -+msgstr "Distribuce %s %s přestala dostávat kritické aktualizace softwaru" - --#. TRANSLATORS: upgrade refers to a major update, e.g. Fedora 25 to 26 --#: src/gs-updates-page.c:576 --msgid "It is recommended that you upgrade to a more recent version." --msgstr "Doporučuje se povýšit na nejnovější verzi." -+#. TRANSLATORS: This message is meant to tell users that they need to upgrade -+#. * or else their distro will not get important updates. -+#: src/gs-updates-page.c:574 -+msgid "Your operating system has stopped receiving critical software updates" -+msgstr "Váš operační systém přestal dostávat kritické aktualizace softwaru" - - #. TRANSLATORS: this is to explain that downloading updates may cost money --#: src/gs-updates-page.c:853 -+#: src/gs-updates-page.c:843 - msgid "Charges May Apply" - msgstr "Možné zpoplatnění" - --#. TRANSLATORS: we need network --#. * to do the updates check --#: src/gs-updates-page.c:857 -+#. TRANSLATORS: we need network to do the updates check -+#: src/gs-updates-page.c:845 - msgid "" - "Checking for updates while using mobile broadband could cause you to incur " - "charges." -@@ -4734,28 +4803,31 @@ msgstr "" - "Kontrola aktualizací přes mobilní připojení může být zpoplatněna vaším " - "operátorem." - --#. TRANSLATORS: this is a link to the --#. * control-center network panel --#: src/gs-updates-page.c:861 -+#. TRANSLATORS: this is a link to the control-center network panel -+#: src/gs-updates-page.c:849 - msgid "Check _Anyway" - msgstr "_Přesto zkontrolovat" - - #. TRANSLATORS: can't do updates check --#: src/gs-updates-page.c:877 -+#: src/gs-updates-page.c:860 - msgid "No Network" - msgstr "Žádné připojení k síti" - --#. TRANSLATORS: we need network --#. * to do the updates check --#: src/gs-updates-page.c:881 -+#. TRANSLATORS: we need network to do the updates check -+#: src/gs-updates-page.c:862 - msgid "Internet access is required to check for updates." - msgstr "Přístup k internetu je nezbytný pro kontrolu aktualizací." - --#: src/gs-updates-page.c:1254 -+#. TRANSLATORS: this is a link to the control-center network panel -+#: src/gs-updates-page.c:866 -+msgid "Network _Settings" -+msgstr "Nastavení _sítě" -+ -+#: src/gs-updates-page.c:1235 - msgid "Check for updates" - msgstr "Zkontrolovat aktualizace" - --#: src/gs-updates-page.c:1290 -+#: src/gs-updates-page.c:1271 - msgctxt "Apps to be updated" - msgid "Updates" - msgstr "Aktualizace" -@@ -4765,25 +4837,25 @@ msgid "Updates page" - msgstr "Stránka s aktualizacemi" - - #. TRANSLATORS: the updates panel is starting up. --#: src/gs-updates-page.ui:82 -+#: src/gs-updates-page.ui:58 - msgid "Loading Updates…" - msgstr "Načítají se aktualizace…" - - #. TRANSLATORS: the updates panel is starting up. --#: src/gs-updates-page.ui:95 -+#: src/gs-updates-page.ui:71 - msgid "This could take a while." - msgstr "Může to chvilku trvat." - - #. TRANSLATORS: This means all software (plural) installed on this system is up to date. --#: src/gs-updates-page.ui:203 -+#: src/gs-updates-page.ui:179 - msgid "Up to Date" - msgstr "Aktuální" - --#: src/gs-updates-page.ui:242 -+#: src/gs-updates-page.ui:218 - msgid "Use Mobile Data?" - msgstr "Použít mobilní data?" - --#: src/gs-updates-page.ui:243 -+#: src/gs-updates-page.ui:219 - msgid "" - "Checking for updates when using mobile broadband could cause you to incur " - "charges." -@@ -4791,68 +4863,68 @@ msgstr "" - "Kontrola aktualizací při používání mobilního širokopásmového připojení vám " - "může způsobit poplatky." - --#: src/gs-updates-page.ui:246 -+#: src/gs-updates-page.ui:222 - msgid "_Check Anyway" - msgstr "_Přesto zkontrolovat" - --#: src/gs-updates-page.ui:262 -+#: src/gs-updates-page.ui:238 - msgid "No Connection" - msgstr "Žádné připojení" - --#: src/gs-updates-page.ui:263 -+#: src/gs-updates-page.ui:239 - msgid "Go online to check for updates." - msgstr "Kvůli kontrole aktualizací se musíte připojit k síti." - --#: src/gs-updates-page.ui:266 -+#: src/gs-updates-page.ui:242 - msgid "_Network Settings" - msgstr "_Nastavení sítě" - --#: src/gs-updates-page.ui:295 -+#: src/gs-updates-page.ui:275 - msgid "Error" - msgstr "Chyba" - --#: src/gs-updates-page.ui:296 -+#: src/gs-updates-page.ui:276 - msgid "Updates are automatically managed." - msgstr "Aktualizace jsou spravovány automaticky." - - #. TRANSLATORS: This is the button for installing all - #. * offline updates --#: src/gs-updates-section.c:312 --msgid "Restart & Update" --msgstr "Restartovat a aktualizovat" -+#: src/gs-updates-section.c:340 -+msgid "_Restart & Update…" -+msgstr "_Restartovat a aktualizovat…" - - #. TRANSLATORS: This is the button for upgrading all --#. * online-updatable applications --#: src/gs-updates-section.c:318 --msgid "Update All" --msgstr "Aktualizovat vše" -+#. * online-updatable apps -+#: src/gs-updates-section.c:346 -+msgid "U_pdate All" -+msgstr "_Aktualizovat vše" - - #. TRANSLATORS: This is the header for system firmware that - #. * requires a reboot to apply --#: src/gs-updates-section.c:450 -+#: src/gs-updates-section.c:474 - msgid "Integrated Firmware" - msgstr "Integrovaný Firmware" - - #. TRANSLATORS: This is the header for offline OS and offline - #. * app updates that require a reboot to apply --#: src/gs-updates-section.c:455 -+#: src/gs-updates-section.c:479 - msgid "Requires Restart" - msgstr "Vyžaduje restart" - - #. TRANSLATORS: This is the header for online runtime and - #. * app updates, typically flatpaks or snaps --#: src/gs-updates-section.c:460 --msgid "Application Updates" -+#: src/gs-updates-section.c:484 -+msgid "App Updates" - msgstr "Aktualizace aplikací" - - #. TRANSLATORS: This is the header for device firmware that can - #. * be installed online --#: src/gs-updates-section.c:465 -+#: src/gs-updates-section.c:489 - msgid "Device Firmware" - msgstr "Firmware zařízení" - - #: src/gs-updates-section.ui:33 src/gs-upgrade-banner.ui:72 --#: plugins/packagekit/gs-packagekit-task.c:155 -+#: plugins/packagekit/gs-packagekit-task.c:154 - msgid "_Download" - msgstr "S_táhnout" - -@@ -4899,8 +4971,8 @@ msgid "A major upgrade, with new features and added polish." - msgstr "Povýšení na novou verzi s novými funkcemi a vylepšeními." - - #: src/gs-upgrade-banner.ui:187 --msgid "_Restart & Upgrade" --msgstr "_Restartovat a aktualizovat" -+msgid "_Restart & Upgrade…" -+msgstr "_Restartovat a aktualizovat…" - - #: src/gs-upgrade-banner.ui:201 - msgid "Remember to back up data and files before upgrading." -@@ -4910,7 +4982,7 @@ msgstr "Nezapomeňte zazálohovat si před povýšením svá data a soubory." - msgid "Add, remove or update software on this computer" - msgstr "Přidat, odebrat nebo aktualizovat software v tomto počítači" - --#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! -+#. Translators: Search terms to find this app. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! - #: src/org.gnome.Software.desktop.in:12 - msgid "" - "Updates;Upgrade;Sources;Repositories;Preferences;Install;Uninstall;Program;" -@@ -4922,14 +4994,14 @@ msgstr "" - #. TRANSLATORS: this is a group of updates that are not - #. * packages and are not shown in the main list - #: plugins/core/gs-plugin-generic-updates.c:67 --#: plugins/rpm-ostree/gs-plugin-rpm-ostree.c:2975 -+#: plugins/rpm-ostree/gs-plugin-rpm-ostree.c:3049 - msgid "System Updates" - msgstr "Aktualizace systému" - - #. TRANSLATORS: this is a longer description of the - #. * "System Updates" string - #: plugins/core/gs-plugin-generic-updates.c:72 --#: plugins/rpm-ostree/gs-plugin-rpm-ostree.c:2980 -+#: plugins/rpm-ostree/gs-plugin-rpm-ostree.c:3054 - msgid "" - "General system updates, such as security or bug fixes, and performance " - "improvements." -@@ -4943,21 +5015,19 @@ msgid "Downloading featured images…" - msgstr "Stahují se obrázky k významným aplikacím…" - - #. Translators: The '%s' is replaced with the OS name, like "Endless OS" --#: plugins/eos-updater/gs-plugin-eos-updater.c:637 -+#: plugins/eos-updater/gs-plugin-eos-updater.c:684 - #, c-format - msgid "%s update with new features and fixes." - msgstr "Aktualizace %s s novými funkcemi a opravami." - --#: plugins/eos-updater/gs-plugin-eos-updater.c:970 -+#: plugins/eos-updater/gs-plugin-eos-updater.c:1267 - msgid "EOS update service could not fetch and apply the update." - msgstr "Aktualizační služba EOS nemohla stáhnout a nasadit aktualizaci." - - #: plugins/epiphany/gs-plugin-epiphany.c:499 - #: plugins/epiphany/gs-plugin-epiphany.c:503 --#, fuzzy --#| msgid "Web Applications" - msgid "Web App" --msgstr "Webové aplikace" -+msgstr "Webová aplikace" - - #: plugins/epiphany/org.gnome.Software.Plugin.Epiphany.metainfo.xml.in:6 - msgid "Web Apps Support" -@@ -4985,139 +5055,139 @@ msgid "Flatpak Support" - msgstr "Podpora pro Flatpak" - - #: plugins/flatpak/org.gnome.Software.Plugin.Flatpak.metainfo.xml.in:7 --msgid "Flatpak is a framework for desktop applications on Linux" -+msgid "Flatpak is a framework for desktop apps on Linux" - msgstr "Flatpak je systém pro provozování aplikací na Linuxu" - - #. Reference: https://docs.flatpak.org/en/latest/flatpak-command-reference.html#idm45858571325264 --#: plugins/flatpak/gs-flatpak.c:313 -+#: plugins/flatpak/gs-flatpak.c:318 - #, c-format - msgid "System folder %s" - msgstr "Systémová složka %s" - --#: plugins/flatpak/gs-flatpak.c:314 plugins/flatpak/gs-flatpak.c:315 -+#: plugins/flatpak/gs-flatpak.c:319 plugins/flatpak/gs-flatpak.c:320 - #, c-format - msgid "Home subfolder %s" - msgstr "Podsložka %s v domovské složce" - --#: plugins/flatpak/gs-flatpak.c:316 -+#: plugins/flatpak/gs-flatpak.c:321 - msgid "Host system folders" - msgstr "Složky hostitelského systému" - --#: plugins/flatpak/gs-flatpak.c:317 -+#: plugins/flatpak/gs-flatpak.c:322 - msgid "Host system configuration from /etc" - msgstr "Konfigurace hostitelského systému z /etc" - --#: plugins/flatpak/gs-flatpak.c:318 -+#: plugins/flatpak/gs-flatpak.c:323 - msgid "Desktop folder" - msgstr "Složka plochy" - --#: plugins/flatpak/gs-flatpak.c:318 -+#: plugins/flatpak/gs-flatpak.c:323 - #, c-format - msgid "Desktop subfolder %s" - msgstr "Podsložka %s ve složce plochy" - --#: plugins/flatpak/gs-flatpak.c:319 -+#: plugins/flatpak/gs-flatpak.c:324 - msgid "Documents folder" - msgstr "Složka dokumentů" - --#: plugins/flatpak/gs-flatpak.c:319 -+#: plugins/flatpak/gs-flatpak.c:324 - #, c-format - msgid "Documents subfolder %s" - msgstr "Podsložka %s ve složce dokumentů" - --#: plugins/flatpak/gs-flatpak.c:320 -+#: plugins/flatpak/gs-flatpak.c:325 - msgid "Music folder" - msgstr "Složka hudby" - --#: plugins/flatpak/gs-flatpak.c:320 -+#: plugins/flatpak/gs-flatpak.c:325 - #, c-format - msgid "Music subfolder %s" - msgstr "Podsložka %s ve složce hudby" - --#: plugins/flatpak/gs-flatpak.c:321 -+#: plugins/flatpak/gs-flatpak.c:326 - msgid "Pictures folder" - msgstr "Složka obrázků" - --#: plugins/flatpak/gs-flatpak.c:321 -+#: plugins/flatpak/gs-flatpak.c:326 - #, c-format - msgid "Pictures subfolder %s" - msgstr "Podsložka %s ve složce obrázků" - --#: plugins/flatpak/gs-flatpak.c:322 -+#: plugins/flatpak/gs-flatpak.c:327 - msgid "Public Share folder" - msgstr "Složka veřejně sdílených" - --#: plugins/flatpak/gs-flatpak.c:322 -+#: plugins/flatpak/gs-flatpak.c:327 - #, c-format - msgid "Public Share subfolder %s" - msgstr "Podsložka %s ve složce veřejně sdílených" - --#: plugins/flatpak/gs-flatpak.c:323 -+#: plugins/flatpak/gs-flatpak.c:328 - msgid "Videos folder" - msgstr "Složka videí" - --#: plugins/flatpak/gs-flatpak.c:323 -+#: plugins/flatpak/gs-flatpak.c:328 - #, c-format - msgid "Videos subfolder %s" - msgstr "Podsložka %s ve složce videí" - --#: plugins/flatpak/gs-flatpak.c:324 -+#: plugins/flatpak/gs-flatpak.c:329 - msgid "Templates folder" - msgstr "Složka šablon" - --#: plugins/flatpak/gs-flatpak.c:324 -+#: plugins/flatpak/gs-flatpak.c:329 - #, c-format - msgid "Templates subfolder %s" - msgstr "Podsložka %s ve složce šablon" - --#: plugins/flatpak/gs-flatpak.c:325 -+#: plugins/flatpak/gs-flatpak.c:330 - msgid "User cache folder" - msgstr "Složka uživatelské mezipaměti" - --#: plugins/flatpak/gs-flatpak.c:325 -+#: plugins/flatpak/gs-flatpak.c:330 - #, c-format - msgid "User cache subfolder %s" - msgstr "Podsložka %s ve složce uživatelské mezipaměti" - --#: plugins/flatpak/gs-flatpak.c:326 -+#: plugins/flatpak/gs-flatpak.c:331 - msgid "User configuration folder" - msgstr "Složka uživatelské konfigurace" - --#: plugins/flatpak/gs-flatpak.c:326 -+#: plugins/flatpak/gs-flatpak.c:331 - #, c-format - msgid "User configuration subfolder %s" - msgstr "Podsložka %s ve složce uživatelské konfigurace" - --#: plugins/flatpak/gs-flatpak.c:327 -+#: plugins/flatpak/gs-flatpak.c:332 - msgid "User data folder" - msgstr "Složka uživatelských dat" - --#: plugins/flatpak/gs-flatpak.c:327 -+#: plugins/flatpak/gs-flatpak.c:332 - #, c-format - msgid "User data subfolder %s" - msgstr "Podsložka %s ve složce uživatelských dat" - --#: plugins/flatpak/gs-flatpak.c:328 -+#: plugins/flatpak/gs-flatpak.c:333 - msgid "User runtime folder" - msgstr "Uživatelská složka pro běh aplikací" - --#: plugins/flatpak/gs-flatpak.c:328 -+#: plugins/flatpak/gs-flatpak.c:333 - #, c-format - msgid "User runtime subfolder %s" - msgstr "Podsložka %s v uživatelské složce pro běh aplikací" - --#: plugins/flatpak/gs-flatpak.c:386 -+#: plugins/flatpak/gs-flatpak.c:391 - #, c-format - msgid "Filesystem access to %s" - msgstr "Přístup k souborovému systému v %s" - - #. TRANSLATORS: status text when downloading new metadata --#: plugins/flatpak/gs-flatpak.c:1403 -+#: plugins/flatpak/gs-flatpak.c:1408 - #, c-format - msgid "Getting flatpak metadata for %s…" - msgstr "Získávají se metadata Flatpak pro %s…" - --#: plugins/flatpak/gs-flatpak.c:3580 -+#: plugins/flatpak/gs-flatpak.c:3589 - #, c-format - msgid "Failed to refine addon ‘%s’: %s" - msgstr "Selhalo vylepšení doplňku „%s“: %s" -@@ -5130,17 +5200,17 @@ msgstr "Uživatelská instalace" - msgid "System Installation" - msgstr "Systémová instalace" - --#: plugins/flatpak/gs-plugin-flatpak.c:1038 -+#: plugins/flatpak/gs-plugin-flatpak.c:1320 - #, c-format - msgid "Failed to add to install for addon ‘%s’: %s" - msgstr "Selhalo přídání doplňku „%s“ k nainstalování: %s" - --#: plugins/flatpak/gs-plugin-flatpak.c:1052 -+#: plugins/flatpak/gs-plugin-flatpak.c:1334 - #, c-format - msgid "Failed to add to uninstall for addon ‘%s’: %s" - msgstr "Selhalo přidání doplňku „%s“ k odinstalování: %s" - --#: plugins/flatpak/gs-plugin-flatpak.c:1318 -+#: plugins/flatpak/gs-plugin-flatpak.c:1601 - #, c-format - msgid "" - "Remote “%s” doesn't allow install of “%s”, possibly due to its filter. " -@@ -5152,87 +5222,85 @@ msgstr "" - #. TRANSLATORS: as in laptop battery power - #: plugins/fwupd/gs-fwupd-app.c:66 - msgid "System power is too low to perform the update" --msgstr "" -+msgstr "Systém nemá dostatek energie, aby provedl aktualizaci" - - #. TRANSLATORS: as in laptop battery power - #: plugins/fwupd/gs-fwupd-app.c:70 - #, c-format - msgid "System power is too low to perform the update (%u%%, requires %u%%)" - msgstr "" -+"Systém nemá dostatek energie, aby provedl aktualizaci (%u%%, vyžaduje %u%%)" - - #. TRANSLATORS: for example, a Bluetooth mouse that is in powersave mode - #: plugins/fwupd/gs-fwupd-app.c:76 - msgid "Device is unreachable, or out of wireless range" --msgstr "" -+msgstr "Zařízení je nedostupné nebo mimo dosah bezdrátové sítě" - - #. TRANSLATORS: for example the batteries *inside* the Bluetooth mouse - #: plugins/fwupd/gs-fwupd-app.c:82 --#, fuzzy, c-format --#| msgid "The battery level is too low" -+#, c-format - msgid "Device battery power is too low" --msgstr "Úroveň nabití baterie je příliš nízká" -+msgstr "Úroveň nabití baterie zařízení je příliš nízká" - - #. TRANSLATORS: for example the batteries *inside* the Bluetooth mouse - #: plugins/fwupd/gs-fwupd-app.c:85 - #, c-format - msgid "Device battery power is too low (%u%%, requires %u%%)" --msgstr "" -+msgstr "Úroveň nabití baterie zařízení je příliš nízká (%u%%, vyžaduje %u%%)" - - #. TRANSLATORS: usually this is when we're waiting for a reboot - #: plugins/fwupd/gs-fwupd-app.c:91 - msgid "Device is waiting for the update to be applied" --msgstr "" -+msgstr "Zařízení čeká na aplikování aktualizace" - - #. TRANSLATORS: as in, wired mains power for a laptop - #: plugins/fwupd/gs-fwupd-app.c:95 - msgid "Device requires AC power to be connected" --msgstr "" -+msgstr "Zařízení vyžaduje připojené napájení za sítě" - - #. TRANSLATORS: lid means "laptop top cover" - #: plugins/fwupd/gs-fwupd-app.c:99 --#, fuzzy --#| msgid "Device cannot be used during update." - msgid "Device cannot be used while the lid is closed" --msgstr "Zařízení nelze během aktualizace používat." -+msgstr "Zařízení nelze používat, pokud je víko notebooku zavřené" - - #. TRANSLATORS: a specific part of hardware, - #. * the first %s is the device name, e.g. 'Unifying Receiver` --#: plugins/fwupd/gs-fwupd-app.c:218 -+#: plugins/fwupd/gs-fwupd-app.c:219 - #, c-format - msgid "%s Device Update" - msgstr "Aktualizace zařízení %s" - - #. TRANSLATORS: the entire system, e.g. all internal devices, - #. * the first %s is the device name, e.g. 'ThinkPad P50` --#: plugins/fwupd/gs-fwupd-app.c:223 -+#: plugins/fwupd/gs-fwupd-app.c:224 - #, c-format - msgid "%s System Update" - msgstr "Aktualizace systému pro %s" - - #. TRANSLATORS: the EC is typically the keyboard controller chip, - #. * the first %s is the device name, e.g. 'ThinkPad P50` --#: plugins/fwupd/gs-fwupd-app.c:228 -+#: plugins/fwupd/gs-fwupd-app.c:229 - #, c-format - msgid "%s Embedded Controller Update" - msgstr "Aktualizace vestavěného řadiče pro %s" - - #. TRANSLATORS: ME stands for Management Engine, the Intel AMT thing, - #. * the first %s is the device name, e.g. 'ThinkPad P50` --#: plugins/fwupd/gs-fwupd-app.c:233 -+#: plugins/fwupd/gs-fwupd-app.c:234 - #, c-format - msgid "%s ME Update" - msgstr "Aktualizace ME pro %s" - - #. TRANSLATORS: ME stands for Management Engine (with Intel AMT), - #. * where the first %s is the device name, e.g. 'ThinkPad P50` --#: plugins/fwupd/gs-fwupd-app.c:238 -+#: plugins/fwupd/gs-fwupd-app.c:239 - #, c-format - msgid "%s Corporate ME Update" - msgstr "Aktualizace ME pro firmy pro %s" - - #. TRANSLATORS: ME stands for Management Engine, where - #. * the first %s is the device name, e.g. 'ThinkPad P50` --#: plugins/fwupd/gs-fwupd-app.c:243 -+#: plugins/fwupd/gs-fwupd-app.c:244 - #, c-format - msgid "%s Consumer ME Update" - msgstr "Aktualizace ME pro běžné spotřebitele pro %s" -@@ -5240,7 +5308,7 @@ msgstr "Aktualizace ME pro běžné spotřebitele pro %s" - #. TRANSLATORS: the controller is a device that has other devices - #. * plugged into it, for example ThunderBolt, FireWire or USB, - #. * the first %s is the device name, e.g. 'Intel ThunderBolt` --#: plugins/fwupd/gs-fwupd-app.c:249 -+#: plugins/fwupd/gs-fwupd-app.c:250 - #, c-format - msgid "%s Controller Update" - msgstr "Aktualizace řadiče pro %s" -@@ -5248,97 +5316,137 @@ msgstr "Aktualizace řadiče pro %s" - #. TRANSLATORS: the Thunderbolt controller is a device that - #. * has other high speed Thunderbolt devices plugged into it; - #. * the first %s is the system name, e.g. 'ThinkPad P50` --#: plugins/fwupd/gs-fwupd-app.c:255 -+#: plugins/fwupd/gs-fwupd-app.c:256 - #, c-format - msgid "%s Thunderbolt Controller Update" - msgstr "Aktualizace řadiče Thunderbolt pro %s" - - #. TRANSLATORS: the CPU microcode is firmware loaded onto the CPU - #. * at system bootup --#: plugins/fwupd/gs-fwupd-app.c:260 -+#: plugins/fwupd/gs-fwupd-app.c:261 - #, c-format - msgid "%s CPU Microcode Update" - msgstr "Aktualizace mikrokódu CPU pro %s" - - #. TRANSLATORS: configuration refers to hardware state, - #. * e.g. a security database or a default power value --#: plugins/fwupd/gs-fwupd-app.c:265 -+#: plugins/fwupd/gs-fwupd-app.c:266 - #, c-format - msgid "%s Configuration Update" - msgstr "Aktualizace nastavení pro %s" - - #. TRANSLATORS: battery refers to the system power source --#: plugins/fwupd/gs-fwupd-app.c:269 -+#: plugins/fwupd/gs-fwupd-app.c:270 - #, c-format - msgid "%s Battery Update" - msgstr "Aktualizace baterie pro %s" - - #. TRANSLATORS: camera can refer to the laptop internal - #. * camera in the bezel or external USB webcam --#: plugins/fwupd/gs-fwupd-app.c:274 -+#: plugins/fwupd/gs-fwupd-app.c:275 - #, c-format - msgid "%s Camera Update" - msgstr "Aktualizace kamery pro %s" - - #. TRANSLATORS: TPM refers to a Trusted Platform Module --#: plugins/fwupd/gs-fwupd-app.c:278 -+#: plugins/fwupd/gs-fwupd-app.c:279 - #, c-format - msgid "%s TPM Update" - msgstr "Aktualizace TPM pro %s" - - #. TRANSLATORS: TouchPad refers to a flat input device --#: plugins/fwupd/gs-fwupd-app.c:282 -+#: plugins/fwupd/gs-fwupd-app.c:283 - #, c-format - msgid "%s Touchpad Update" - msgstr "Aktualizace touchpadu pro %s" - - #. TRANSLATORS: Mouse refers to a handheld input device --#: plugins/fwupd/gs-fwupd-app.c:286 -+#: plugins/fwupd/gs-fwupd-app.c:287 - #, c-format - msgid "%s Mouse Update" - msgstr "Aktualizace myši pro %s" - - #. TRANSLATORS: Keyboard refers to an input device for typing --#: plugins/fwupd/gs-fwupd-app.c:290 -+#: plugins/fwupd/gs-fwupd-app.c:291 - #, c-format - msgid "%s Keyboard Update" - msgstr "Aktualizace klávesnice pro %s" - - #. TRANSLATORS: Storage Controller is typically a RAID or SAS adapter --#: plugins/fwupd/gs-fwupd-app.c:294 -+#: plugins/fwupd/gs-fwupd-app.c:295 - #, c-format - msgid "%s Storage Controller Update" - msgstr "Aktualizace řadiče disků pro %s" - - #. TRANSLATORS: Network Interface refers to the physical - #. * PCI card, not the logical wired connection --#: plugins/fwupd/gs-fwupd-app.c:299 -+#: plugins/fwupd/gs-fwupd-app.c:300 - #, c-format - msgid "%s Network Interface Update" - msgstr "Aktualizace síťové karty pro %s" - - #. TRANSLATORS: Video Display refers to the laptop internal display or - #. * external monitor --#: plugins/fwupd/gs-fwupd-app.c:304 -+#: plugins/fwupd/gs-fwupd-app.c:305 - #, c-format - msgid "%s Display Update" - msgstr "Aktualizace displeje pro %s" - - #. TRANSLATORS: BMC refers to baseboard management controller which - #. * is the device that updates all the other firmware on the system --#: plugins/fwupd/gs-fwupd-app.c:309 -+#: plugins/fwupd/gs-fwupd-app.c:310 - #, c-format - msgid "%s BMC Update" - msgstr "Aktualizace BMC pro %s" - - #. TRANSLATORS: Receiver refers to a radio device, e.g. a tiny Bluetooth - #. * device that stays in the USB port so the wireless peripheral works --#: plugins/fwupd/gs-fwupd-app.c:314 -+#: plugins/fwupd/gs-fwupd-app.c:315 - #, c-format - msgid "%s USB Receiver Update" - msgstr "Aktualizace přijímače USB pro %s" - --#: plugins/fwupd/gs-plugin-fwupd.c:1244 -+#. TRANSLATORS: drive refers to a storage device, e.g. SATA disk -+#: plugins/fwupd/gs-fwupd-app.c:319 -+#, c-format -+msgid "%s Drive Update" -+msgstr "Aktualizace disku pro %s" -+ -+#. TRANSLATORS: flash refers to solid state storage, e.g. UFS or eMMC -+#: plugins/fwupd/gs-fwupd-app.c:323 -+#, c-format -+msgid "%s Flash Drive Update" -+msgstr "Aktualizace flash disku pro %s" -+ -+#. TRANSLATORS: SSD refers to a Solid State Drive, e.g. non-rotating -+#. * SATA or NVMe disk -+#: plugins/fwupd/gs-fwupd-app.c:328 -+#, c-format -+msgid "%s SSD Update" -+msgstr "Aktualizace SSD pro %s" -+ -+#. TRANSLATORS: GPU refers to a Graphics Processing Unit, e.g. -+#. * the "video card" -+#: plugins/fwupd/gs-fwupd-app.c:333 -+#, c-format -+msgid "%s GPU Update" -+msgstr "Aktualizace grafické karty pro %s" -+ -+#. TRANSLATORS: Dock refers to the port replicator hardware laptops are -+#. * cradled in, or lowered onto -+#: plugins/fwupd/gs-fwupd-app.c:338 -+#, c-format -+msgid "%s Dock Update" -+msgstr "Aktualizace dokovacího zařízení pro %s" -+ -+#. TRANSLATORS: Dock refers to the port replicator device connected -+#. * by plugging in a USB cable -- which may or may not also provide power -+#: plugins/fwupd/gs-fwupd-app.c:343 -+#, c-format -+msgid "%s USB Dock Update" -+msgstr "Aktualizace USB dokovacího zařízení pro %s" -+ -+#: plugins/fwupd/gs-plugin-fwupd.c:1763 - msgid "Firmware" - msgstr "Firmware" - -@@ -5350,11 +5458,11 @@ msgstr "Podpora aktualizací firmwaru" - msgid "Provides support for firmware upgrades" - msgstr "Poskytuje podporu pro povyšování verzí firmwaru" - --#: plugins/packagekit/gs-packagekit-task.c:148 -+#: plugins/packagekit/gs-packagekit-task.c:147 - msgid "Install Unsigned Software?" - msgstr "Nainstalovat nepodepsaný software?" - --#: plugins/packagekit/gs-packagekit-task.c:149 -+#: plugins/packagekit/gs-packagekit-task.c:148 - msgid "" - "Software that is to be installed is not signed. It will not be possible to " - "verify the origin of updates to this software, or whether updates have been " -@@ -5363,11 +5471,11 @@ msgstr "" - "Software, který se chystáte nainstalovat, není podepsaný. Nebude tak možné " - "ověřit původ jeho aktualizací, nebo zda aktualizace nebyly zmanipulovány." - --#: plugins/packagekit/gs-packagekit-task.c:153 -+#: plugins/packagekit/gs-packagekit-task.c:152 - msgid "Download Unsigned Software?" - msgstr "Stáhnout nepodepsaný software?" - --#: plugins/packagekit/gs-packagekit-task.c:154 -+#: plugins/packagekit/gs-packagekit-task.c:153 - msgid "" - "Unsigned updates are available. Without a signature, it is not possible to " - "verify the origin of the update, or whether it has been tampered with." -@@ -5375,11 +5483,11 @@ msgstr "" - "Jsou k dispozici nepodepsané aktualizace. Bez podpisu není možné ověřit " - "původ aktualizace, nebo zda nebyla zmanipulována." - --#: plugins/packagekit/gs-packagekit-task.c:158 -+#: plugins/packagekit/gs-packagekit-task.c:157 - msgid "Update Unsigned Software?" - msgstr "Aktualizovat nepodepsaný software?" - --#: plugins/packagekit/gs-packagekit-task.c:159 -+#: plugins/packagekit/gs-packagekit-task.c:158 - msgid "" - "Unsigned updates are available. Without a signature, it is not possible to " - "verify the origin of the update, or whether it has been tampered with. " -@@ -5391,11 +5499,11 @@ msgstr "" - "zakázány, dokud nebudou nepodepsané aktualizace buďto odstraněny nebo " - "nahrazeny jinými." - --#: plugins/packagekit/gs-plugin-packagekit.c:367 -+#: plugins/packagekit/gs-plugin-packagekit.c:416 - msgid "Packages" - msgstr "Balíčky" - --#: plugins/rpm-ostree/gs-plugin-rpm-ostree.c:2696 -+#: plugins/rpm-ostree/gs-plugin-rpm-ostree.c:2764 - msgid "Operating System (OSTree)" - msgstr "Operační systém (OSTree)" - -@@ -5412,6 +5520,76 @@ msgstr "Podpora pro Snap" - msgid "A snap is a universal Linux package" - msgstr "Snap je univerzální linuxový balíček" - -+#~ msgid "Selected add-ons will be installed with the app." -+#~ msgstr "Vybrané doplňky budou nainstalovány spolu s aplikací." -+ -+#~ msgid "The last timestamp when the system was online and got any updates" -+#~ msgstr "" -+#~ "Datum a čas, kdy byl systém naposledy on-line a dostal nějaké aktualizace" -+ -+#~ msgid "_User" -+#~ msgstr "_Uživatel" -+ -+#~ msgid "" -+#~ "This software is not available in your language and will appear in US " -+#~ "English." -+#~ msgstr "" -+#~ "Tento software není dostupný ve vašem jazyce a zobrazí se v americké " -+#~ "angličtině." -+ -+#~ msgid "Applications" -+#~ msgstr "Aplikace" -+ -+#~ msgid "Web Applications" -+#~ msgstr "Webové aplikace" -+ -+#~ msgid "Post Review" -+#~ msgstr "Příspěvek do recenzí" -+ -+#~ msgid "_Post" -+#~ msgstr "_Odeslat" -+ -+#~ msgid "Rating" -+#~ msgstr "Hodnocení" -+ -+#~ msgid "" -+#~ "Give a short summary of your review, for example: “Great app, would " -+#~ "recommend”." -+#~ msgstr "" -+#~ "Uveďte krátké shrnutí své recenze, například: „Skvělá aplikace, " -+#~ "doporučuji“." -+ -+#~ msgctxt "app review" -+#~ msgid "Review" -+#~ msgstr "Recenze" -+ -+#~ msgid "What do you think of the app? Try to give reasons for your views." -+#~ msgstr "Co si o aplikaci myslíte? Snažte se uvést důvody svého hodnocení." -+ -+#~ msgid "No screenshot provided" -+#~ msgstr "Nemá snímek obrazovky" -+ -+#~ msgid "Primary Menu" -+#~ msgstr "Hlavní nabídky" -+ -+#~ msgctxt "Header bar button for list of apps to be updated" -+#~ msgid "Updates" -+#~ msgstr "Aktualizace" -+ -+#, c-format -+#~ msgid "%s %s is no longer supported." -+#~ msgstr "Systém %s %s již není podporován." -+ -+#~ msgid "This means that it does not receive security updates." -+#~ msgstr "" -+#~ "Znamená to, že pro něj již nadále nejsou poskytovány bezpečnostní opravy." -+ -+#~ msgid "It is recommended that you upgrade to a more recent version." -+#~ msgstr "Doporučuje se povýšit na nejnovější verzi." -+ -+#~ msgid "Application Updates" -+#~ msgstr "Aktualizace aplikací" -+ - #~ msgid "_Continue" - #~ msgstr "_Pokračovat" - diff --git a/gnome-software.spec b/gnome-software.spec index 79fd305..cacfd7e 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -19,8 +19,8 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 44.0 -Release: 3%{?dist} +Version: 44.1 +Release: 1%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -28,7 +28,6 @@ URL: https://wiki.gnome.org/Apps/Software Source0: https://download.gnome.org/sources/gnome-software/44/%{name}-%{tarball_version}.tar.xz Patch01: 0001-crash-with-broken-theme.patch -Patch02: 0002-update-czech-translation.patch BuildRequires: docbook-style-xsl BuildRequires: desktop-file-utils @@ -228,6 +227,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Apr 21 2023 Milan Crha - 44.1-1 +- Update to 44.1 + * Sun Mar 26 2023 Yaakov Selkowitz - 44.0-3 - Fix libsoup runtime dependency diff --git a/sources b/sources index 91637d7..116347a 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-44.0.tar.xz) = 592a88fd3488d7d9cd573eff99e8ec503169b52354d672263d7e514846c666c56f87fcbdb31fb8c497ed048808ec223646c247326af76a7e4a361084fd1b180e +SHA512 (gnome-software-44.1.tar.xz) = 4f6d50d8308b3d2694a67f35db0c716f8631380282c7586243499449dd86d11ebfa08a18ccd083839b93bcf7e1b16075433cb427642c2c7b59033e721bb32c9b From 2ea292e8f33e1169991bb919204a078a771e6785 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 19 May 2023 12:57:20 +0200 Subject: [PATCH 040/116] Rebuild for RPM --- gnome-software.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gnome-software.spec b/gnome-software.spec index cacfd7e..16a0b71 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -20,7 +20,7 @@ Name: gnome-software Version: 44.1 -Release: 1%{?dist} +Release: 2%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -227,6 +227,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri May 19 2023 Milan Crha - 44.1-2 +- Rebuild for RPM + * Fri Apr 21 2023 Milan Crha - 44.1-1 - Update to 44.1 From d32b18a85c4d999cd1a06b0929a190c6b5410a55 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 26 May 2023 07:55:44 +0200 Subject: [PATCH 041/116] Update to 44.2 --- gnome-software.spec | 7 +++++-- sources | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index 16a0b71..5d2b837 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -19,8 +19,8 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 44.1 -Release: 2%{?dist} +Version: 44.2 +Release: 1%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -227,6 +227,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri May 26 2023 Milan Crha - 44.2-1 +- Update to 44.2 + * Fri May 19 2023 Milan Crha - 44.1-2 - Rebuild for RPM diff --git a/sources b/sources index 116347a..d99906e 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-44.1.tar.xz) = 4f6d50d8308b3d2694a67f35db0c716f8631380282c7586243499449dd86d11ebfa08a18ccd083839b93bcf7e1b16075433cb427642c2c7b59033e721bb32c9b +SHA512 (gnome-software-44.2.tar.xz) = 0f053d1d92285239d7edd62a5dcc5c8ce9e991103e3987808ef82406e2dc665a13e0cd14b043d66dfd420459a6aa7c83e7db2fd6a16a8f3b41a6e93498820251 From 6c9157f9066ec9e2c985ff8cfdff9a4297489c00 Mon Sep 17 00:00:00 2001 From: Tomas Popela Date: Thu, 22 Jun 2023 15:39:56 +0200 Subject: [PATCH 042/116] Disable parental control (through malcontent) and rpm-ostree support in RHEL Also move the webapp conditional to a newer syntax to be consistent. --- gnome-software.spec | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index 5d2b837..63029d7 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -9,7 +9,11 @@ %global packagekit_version 1.1.1 # Disable WebApps for RHEL builds -%{!?with_webapps: %global with_webapps !0%{?rhel}} +%bcond webapps %[!0%{?rhel}] +# Disable parental control for RHEL builds +%bcond malcontent %[!0%{?rhel}] +# Disable rpm-ostree support for RHEL builds +%bcond rpmostree %[!0%{?rhel}] # this is not a library version %define gs_plugin_version 20 @@ -20,7 +24,7 @@ Name: gnome-software Version: 44.2 -Release: 1%{?dist} +Release: 2%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -50,18 +54,22 @@ BuildRequires: pkgconfig(json-glib-1.0) >= %{json_glib_version} BuildRequires: pkgconfig(libadwaita-1) >= %{libadwaita_version} BuildRequires: pkgconfig(libdnf) BuildRequires: pkgconfig(libsoup-3.0) +%if %{with malcontent} BuildRequires: pkgconfig(malcontent-0) +%endif BuildRequires: pkgconfig(ostree-1) BuildRequires: pkgconfig(packagekit-glib2) >= %{packagekit_version} BuildRequires: pkgconfig(polkit-gobject-1) BuildRequires: pkgconfig(rpm) +%if %{with rpmostree} BuildRequires: pkgconfig(rpm-ostree-1) +%endif BuildRequires: pkgconfig(sysprof-capture-4) BuildRequires: pkgconfig(xmlb) >= %{libxmlb_version} Requires: appstream-data Requires: appstream%{?_isa} >= %{appstream_version} -%if %{with_webapps} +%if %{with webapps} Requires: epiphany-runtime%{?_isa} %endif Requires: flatpak%{?_isa} >= %{flatpak_version} @@ -94,6 +102,7 @@ Requires: %{name}%{?_isa} = %{version}-%{release} These development files are for building gnome-software plugins outside the source tree. Most users do not need this subpackage installed. +%if %{with rpmostree} %package rpm-ostree Summary: rpm-ostree backend for gnome-software Requires: %{name}%{?_isa} = %{version}-%{release} @@ -105,6 +114,7 @@ gnome-software is an application that makes it easy to add, remove and update software in the GNOME desktop. This package includes the rpm-ostree backend. +%endif %prep %autosetup -p1 -S gendiff -n %{name}-%{tarball_version} @@ -113,13 +123,21 @@ This package includes the rpm-ostree backend. %meson \ -Dsoup2=false \ -Dsnap=false \ +%if %{with malcontent} -Dmalcontent=true \ +%else + -Dmalcontent=false \ +%endif -Dgudev=true \ -Dpackagekit=true \ -Dpackagekit_autoremove=true \ -Dexternal_appstream=false \ +%if %{with rpmostree} -Drpm_ostree=true \ -%if %{with_webapps} +%else + -Drpm_ostree=false \ +%endif +%if %{with webapps} -Dwebapps=true \ -Dhardcoded_foss_webapps=true \ -Dhardcoded_proprietary_webapps=false \ @@ -171,7 +189,7 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/icons/hicolor/symbolic/apps/org.gnome.Software-symbolic.svg %{_datadir}/icons/hicolor/scalable/actions/app-remove-symbolic.svg %{_datadir}/metainfo/org.gnome.Software.metainfo.xml -%if %{with_webapps} +%if %{with webapps} %{_datadir}/metainfo/org.gnome.Software.Plugin.Epiphany.metainfo.xml %endif %{_datadir}/metainfo/org.gnome.Software.Plugin.Flatpak.metainfo.xml @@ -180,7 +198,7 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_libdir}/gnome-software/libgnomesoftware.so.%{gs_plugin_version} %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_appstream.so %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_dummy.so -%if %{with_webapps} +%if %{with webapps} %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_epiphany.so %endif %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_fedora-langpacks.so @@ -190,7 +208,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_generic-updates.so %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_hardcoded-blocklist.so %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_icons.so +%if %{with malcontent} %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_malcontent.so +%endif %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_modalias.so %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_os-release.so %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_packagekit.so @@ -201,7 +221,7 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_sysconfdir}/xdg/autostart/org.gnome.Software.desktop %dir %{_datadir}/swcatalog %dir %{_datadir}/swcatalog/xml -%if %{with_webapps} +%if %{with webapps} %{_datadir}/swcatalog/xml/gnome-pwa-list-foss.xml %endif %{_datadir}/swcatalog/xml/org.gnome.Software.Curated.xml @@ -214,8 +234,10 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_libexecdir}/gnome-software-cmd %{_libexecdir}/gnome-software-restarter +%if %{with rpmostree} %files rpm-ostree %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_rpm-ostree.so +%endif %files devel %{_libdir}/pkgconfig/gnome-software.pc @@ -227,6 +249,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Thu Jun 22 2023 Tomas Popela - 44.2-2 +- Disable parental control (though malcontent) and rpm-ostree support in RHEL + * Fri May 26 2023 Milan Crha - 44.2-1 - Update to 44.2 From 91d71073bb7e8304db78a891eb9656be17d46c1e Mon Sep 17 00:00:00 2001 From: Tomas Popela Date: Thu, 22 Jun 2023 19:13:10 +0200 Subject: [PATCH 043/116] Fix a changelog typo Spotten by mcrha. --- gnome-software.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gnome-software.spec b/gnome-software.spec index 63029d7..ffc39b7 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -250,7 +250,7 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %changelog * Thu Jun 22 2023 Tomas Popela - 44.2-2 -- Disable parental control (though malcontent) and rpm-ostree support in RHEL +- Disable parental control (through malcontent) and rpm-ostree support in RHEL * Fri May 26 2023 Milan Crha - 44.2-1 - Update to 44.2 From 5e095d670f3401790923845e3491083c2e185c3c Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 30 Jun 2023 11:35:00 +0200 Subject: [PATCH 044/116] Update to 45.alpha --- 0001-crash-with-broken-theme.patch | 33 ------------------------------ gnome-software.spec | 11 +++++----- sources | 2 +- 3 files changed, 7 insertions(+), 39 deletions(-) delete mode 100644 0001-crash-with-broken-theme.patch diff --git a/0001-crash-with-broken-theme.patch b/0001-crash-with-broken-theme.patch deleted file mode 100644 index d41a916..0000000 --- a/0001-crash-with-broken-theme.patch +++ /dev/null @@ -1,33 +0,0 @@ -diff -up gnome-software-devel/src/gs-feature-tile.c.1 gnome-software-devel/src/gs-feature-tile.c ---- gnome-software-devel/src/gs-feature-tile.c.1 2023-01-02 17:08:54.157641969 +0100 -+++ gnome-software-devel/src/gs-feature-tile.c 2023-01-02 17:09:36.881632780 +0100 -@@ -397,9 +397,6 @@ gs_feature_tile_refresh (GsAppTile *self - if (key_colors != tile->key_colors_cache) { - g_autoptr(GArray) colors = NULL; - GdkRGBA fg_rgba; --#if !GTK_CHECK_VERSION(4, 9, 2) -- gboolean fg_rgba_valid; --#endif - GsHSBC fg_hsbc; - const GsHSBC *chosen_hsbc; - GsHSBC chosen_hsbc_modified; -@@ -424,8 +421,17 @@ gs_feature_tile_refresh (GsAppTile *self - gtk_widget_get_color (GTK_WIDGET (self), &fg_rgba); - #else - context = gtk_widget_get_style_context (GTK_WIDGET (self)); -- 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; -+ } - #endif - - gtk_rgb_to_hsv (fg_rgba.red, fg_rgba.green, fg_rgba.blue, diff --git a/gnome-software.spec b/gnome-software.spec index ffc39b7..9c5b953 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -23,15 +23,13 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 44.2 -Release: 2%{?dist} +Version: 45~alpha +Release: 1%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later URL: https://wiki.gnome.org/Apps/Software -Source0: https://download.gnome.org/sources/gnome-software/44/%{name}-%{tarball_version}.tar.xz - -Patch01: 0001-crash-with-broken-theme.patch +Source0: https://download.gnome.org/sources/gnome-software/45/%{name}-%{tarball_version}.tar.xz BuildRequires: docbook-style-xsl BuildRequires: desktop-file-utils @@ -249,6 +247,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Jun 30 2023 Milan Crha - 45~alpha-1 +- Update to 45.alpha + * Thu Jun 22 2023 Tomas Popela - 44.2-2 - Disable parental control (through malcontent) and rpm-ostree support in RHEL diff --git a/sources b/sources index d99906e..1c19108 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-44.2.tar.xz) = 0f053d1d92285239d7edd62a5dcc5c8ce9e991103e3987808ef82406e2dc665a13e0cd14b043d66dfd420459a6aa7c83e7db2fd6a16a8f3b41a6e93498820251 +SHA512 (gnome-software-45.alpha.tar.xz) = 1a2c5e6eec249fdeb726b6cdd58c47ccbdefd6c9bc7278c6d30f1350cc62d3e1231e12b5b2cd9acee8deff269346171d427fd389194f04ca641825bd32ddaa2a From ee6f7c739f170417e24e4b5061d2d5046e35318a Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 19 Jul 2023 23:48:37 +0000 Subject: [PATCH 045/116] Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- gnome-software.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gnome-software.spec b/gnome-software.spec index 9c5b953..32a220f 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -24,7 +24,7 @@ Name: gnome-software Version: 45~alpha -Release: 1%{?dist} +Release: 2%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -247,6 +247,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Wed Jul 19 2023 Fedora Release Engineering - 45~alpha-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + * Fri Jun 30 2023 Milan Crha - 45~alpha-1 - Update to 45.alpha From cc29af56c44eb46f76ac4cc84a414f5f836679a8 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 31 Jul 2023 07:21:50 +0200 Subject: [PATCH 046/116] Update to 45.beta --- gnome-software.spec | 19 +++++++++++-------- sources | 2 +- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index 32a220f..125988a 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -1,12 +1,12 @@ %global appstream_version 0.14.0 -%global flatpak_version 1.5.1 -%global fwupd_version 1.3.3 -%global glib2_version 2.61.1 -%global gtk4_version 4.9.2 -%global json_glib_version 1.2.0 +%global flatpak_version 1.9.1 +%global fwupd_version 1.5.6 +%global glib2_version 2.70.0 +%global gtk4_version 4.10.0 +%global json_glib_version 1.6.0 %global libadwaita_version 1.3.alpha %global libxmlb_version 0.1.7 -%global packagekit_version 1.1.1 +%global packagekit_version 1.2.5 # Disable WebApps for RHEL builds %bcond webapps %[!0%{?rhel}] @@ -23,8 +23,8 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 45~alpha -Release: 2%{?dist} +Version: 45~beta +Release: 1%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -247,6 +247,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Mon Jul 31 2023 Milan Crha - 45~beta-1 +- Update to 45.beta + * Wed Jul 19 2023 Fedora Release Engineering - 45~alpha-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild diff --git a/sources b/sources index 1c19108..68087d0 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-45.alpha.tar.xz) = 1a2c5e6eec249fdeb726b6cdd58c47ccbdefd6c9bc7278c6d30f1350cc62d3e1231e12b5b2cd9acee8deff269346171d427fd389194f04ca641825bd32ddaa2a +SHA512 (gnome-software-45.beta.tar.xz) = d4218b56478c9e7e83adf4fb8daec8d0730f5ce16cca0a0c59962894a0abb2d21c356a55f232d266aaaa4f15b21c21bc5904cc1f7b6db4d94db8889019fea092 From b660d8025771ee3cf51b9c5bd3c36821733361d1 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 31 Jul 2023 09:44:56 +0200 Subject: [PATCH 047/116] Remove reference to a dropped plugin (it's builtin now) --- gnome-software.spec | 1 - 1 file changed, 1 deletion(-) diff --git a/gnome-software.spec b/gnome-software.spec index 125988a..02e4cd3 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -215,7 +215,6 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_provenance-license.so %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_provenance.so %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_repos.so -%{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_rewrite-resource.so %{_sysconfdir}/xdg/autostart/org.gnome.Software.desktop %dir %{_datadir}/swcatalog %dir %{_datadir}/swcatalog/xml From 10938fed7958653661cb060ff2305ee0b20f0e0d Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 1 Sep 2023 09:40:08 +0200 Subject: [PATCH 048/116] Update to 45.rc --- gnome-software.spec | 5 ++++- sources | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index 02e4cd3..b0df077 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -23,7 +23,7 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 45~beta +Version: 45~rc Release: 1%{?dist} Summary: A software center for GNOME @@ -246,6 +246,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Sep 01 2023 Milan Crha - 45~rc-1 +- Update to 45.rc + * Mon Jul 31 2023 Milan Crha - 45~beta-1 - Update to 45.beta diff --git a/sources b/sources index 68087d0..b167261 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-45.beta.tar.xz) = d4218b56478c9e7e83adf4fb8daec8d0730f5ce16cca0a0c59962894a0abb2d21c356a55f232d266aaaa4f15b21c21bc5904cc1f7b6db4d94db8889019fea092 +SHA512 (gnome-software-45.rc.tar.xz) = 674c89619419cb7622bed3ce1453c31460d51ba6716db3d8bfc79829ca619e24d1f9c954f2fe72d96156e2e6dbaaf151faa29c97425b0cac132ec3e49871fb79 From aa509767b4eb49df0a86e39f81a3b1434c552a9a Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 15 Sep 2023 09:41:21 +0200 Subject: [PATCH 049/116] Update to 45.0 --- gnome-software.spec | 5 ++++- sources | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index b0df077..4da8d43 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -23,7 +23,7 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 45~rc +Version: 45.0 Release: 1%{?dist} Summary: A software center for GNOME @@ -246,6 +246,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Sep 15 2023 Milan Crha - 45.0-1 +- Update to 45.0 + * Fri Sep 01 2023 Milan Crha - 45~rc-1 - Update to 45.rc diff --git a/sources b/sources index b167261..acbec40 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-45.rc.tar.xz) = 674c89619419cb7622bed3ce1453c31460d51ba6716db3d8bfc79829ca619e24d1f9c954f2fe72d96156e2e6dbaaf151faa29c97425b0cac132ec3e49871fb79 +SHA512 (gnome-software-45.0.tar.xz) = 3a7fab748c6d826e07e4bf86462cfecd9494bfaca2383222f7053be97830ab603cb0dc83d4d5693c2ddac1cc72897783922a05f5aae2ad07d6b7f5ccd5a4eefb From 1b93572ab692ac08e2f09af7d3aa42f6f6fbb3bf Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 20 Oct 2023 08:48:21 +0200 Subject: [PATCH 050/116] Update to 45.1 --- gnome-software.spec | 5 ++++- sources | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index 4da8d43..21730b3 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -23,7 +23,7 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 45.0 +Version: 45.1 Release: 1%{?dist} Summary: A software center for GNOME @@ -246,6 +246,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Oct 20 2023 Milan Crha - 45.1-1 +- Update to 45.1 + * Fri Sep 15 2023 Milan Crha - 45.0-1 - Update to 45.0 diff --git a/sources b/sources index acbec40..c15ccca 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-45.0.tar.xz) = 3a7fab748c6d826e07e4bf86462cfecd9494bfaca2383222f7053be97830ab603cb0dc83d4d5693c2ddac1cc72897783922a05f5aae2ad07d6b7f5ccd5a4eefb +SHA512 (gnome-software-45.1.tar.xz) = 5fdf5e6a34ab9acf938bc4ade41b916ad38ad3b4a7f604b2cba9dfaa38f17299001bef8fde9165f6a035fcc7fef3ebd451bd29ff126c0b9d5a7104e448729434 From 5ed67eade63e02401506d540c6063c8fc668ee9b Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Tue, 7 Nov 2023 08:25:58 +0100 Subject: [PATCH 051/116] Add patch to build with appstream 1.0 --- 0001-port-to-appstream1.patch | 494 ++++++++++++++++++++++++++++++++++ gnome-software.spec | 8 +- 2 files changed, 501 insertions(+), 1 deletion(-) create mode 100644 0001-port-to-appstream1.patch diff --git a/0001-port-to-appstream1.patch b/0001-port-to-appstream1.patch new file mode 100644 index 0000000..c166088 --- /dev/null +++ b/0001-port-to-appstream1.patch @@ -0,0 +1,494 @@ +From e6f7e28bdd50a63586ba6a82b936d54db19a311b Mon Sep 17 00:00:00 2001 +From: Matthias Klumpp +Date: Sun, 8 Oct 2023 20:22:44 +0200 +Subject: [PATCH] Adjust to build with AppStream 1.0 as well as 0.16.x + +--- + lib/gs-app.c | 4 ++ + lib/gs-appstream.c | 58 ++++++++++++++++++++---- + lib/gs-utils.c | 8 ++-- + meson.build | 22 +-------- + plugins/core/gs-plugin-appstream.c | 8 ---- + plugins/fwupd/gs-fwupd-app.c | 8 ++++ + plugins/fwupd/gs-plugin-fwupd.c | 4 ++ + src/gs-hardware-support-context-dialog.c | 6 +++ + src/gs-repos-dialog.c | 4 ++ + src/gs-screenshot-carousel.c | 4 +- + src/gs-screenshot-image.c | 41 +++++++++++++---- + src/gs-screenshot-image.h | 7 +++ + subprojects/appstream.wrap | 2 +- + 13 files changed, 120 insertions(+), 56 deletions(-) + +diff --git a/lib/gs-app.c b/lib/gs-app.c +index 048a061225..e2694057cd 100644 +--- a/lib/gs-app.c ++++ b/lib/gs-app.c +@@ -609,7 +609,11 @@ gs_app_to_string_append (GsApp *app, GString *str) + AsScreenshot *ss = g_ptr_array_index (priv->screenshots, i); + g_autofree gchar *key = NULL; + tmp = as_screenshot_get_caption (ss); ++#if AS_CHECK_VERSION(1, 0, 0) ++ im = as_screenshot_get_image (ss, 0, 0, 1); ++#else + im = as_screenshot_get_image (ss, 0, 0); ++#endif + if (im == NULL) + continue; + key = g_strdup_printf ("screenshot-%02u", i); +diff --git a/lib/gs-appstream.c b/lib/gs-appstream.c +index deca176dcf..2cc2427a19 100644 +--- a/lib/gs-appstream.c ++++ b/lib/gs-appstream.c +@@ -1011,8 +1011,11 @@ gs_appstream_refine_app_relation (GsApp *app, + as_relation_set_item_kind (relation, AS_RELATION_ITEM_KIND_CONTROL); + as_relation_set_value_control_kind (relation, as_control_kind_from_string (xb_node_get_text (child))); + } else if (g_str_equal (item_kind, "display_length")) { +- AsDisplayLengthKind display_length_kind; + const gchar *compare; ++ const gchar *side; ++#if !AS_CHECK_VERSION(1, 0, 0) ++ AsDisplayLengthKind display_length_kind; ++#endif + + /* https://www.freedesktop.org/software/appstream/docs/chap-Metadata.html#tag-relations-display_length */ + as_relation_set_item_kind (relation, AS_RELATION_ITEM_KIND_DISPLAY_LENGTH); +@@ -1020,15 +1023,21 @@ gs_appstream_refine_app_relation (GsApp *app, + compare = xb_node_get_attr (child, "compare"); + as_relation_set_compare (relation, (compare != NULL) ? as_relation_compare_from_string (compare) : AS_RELATION_COMPARE_GE); + ++#if AS_CHECK_VERSION(1, 0, 0) ++ side = xb_node_get_attr (child, "side"); ++ as_relation_set_display_side_kind (relation, (side != NULL) ? as_display_side_kind_from_string (side) : AS_DISPLAY_SIDE_KIND_SHORTEST); ++ as_relation_set_value_px (relation, xb_node_get_text_as_uint (child)); ++#else + display_length_kind = as_display_length_kind_from_string (xb_node_get_text (child)); + if (display_length_kind != AS_DISPLAY_LENGTH_KIND_UNKNOWN) { + /* Ignore the `side` attribute */ + as_relation_set_value_display_length_kind (relation, display_length_kind); + } else { +- const gchar *side = xb_node_get_attr (child, "side"); ++ side = xb_node_get_attr (child, "side"); + as_relation_set_display_side_kind (relation, (side != NULL) ? as_display_side_kind_from_string (side) : AS_DISPLAY_SIDE_KIND_SHORTEST); + as_relation_set_value_px (relation, xb_node_get_text_as_uint (child)); + } ++#endif + } else { + g_debug ("Relation type ‘%s’ not currently supported for %s; ignoring", + item_kind, gs_app_get_id (app)); +@@ -1472,7 +1481,7 @@ gs_appstream_refine_app (GsPlugin *plugin, + } + + typedef struct { +- AsSearchTokenMatch match_value; ++ guint16 match_value; + XbQuery *query; + } GsAppstreamSearchHelper; + +@@ -1522,7 +1531,7 @@ gs_appstream_silo_search_component (GPtrArray *array, XbNode *component, const g + } + + typedef struct { +- AsSearchTokenMatch match_value; ++ guint16 match_value; + const gchar *xpath; + } Query; + +@@ -1585,7 +1594,11 @@ gs_appstream_do_search (GsPlugin *plugin, + * Drop the ID token from it as it’s the highest + * numeric value but isn’t visible to the user in the + * UI, which leads to confusing results ordering. */ ++#if AS_CHECK_VERSION(1, 0, 0) ++ gs_app_set_match_value (app, match_value & (~as_utils_get_tag_search_weight ("id"))); ++#else + gs_app_set_match_value (app, match_value & (~AS_SEARCH_TOKEN_MATCH_ID)); ++#endif + gs_app_list_add (list, app); + + if (gs_app_get_kind (app) == AS_COMPONENT_KIND_ADDON) { +@@ -1624,18 +1637,32 @@ gs_appstream_search (GsPlugin *plugin, + GCancellable *cancellable, + GError **error) + { ++#if AS_CHECK_VERSION(1, 0, 0) ++ guint16 pkgname_weight = as_utils_get_tag_search_weight ("pkgname"); ++ guint16 name_weight = as_utils_get_tag_search_weight ("name"); ++ guint16 id_weight = as_utils_get_tag_search_weight ("id"); + const Query queries[] = { +- #ifdef HAVE_AS_SEARCH_TOKEN_MATCH_MEDIATYPE +- { AS_SEARCH_TOKEN_MATCH_MEDIATYPE, "mimetypes/mimetype[text()~=stem(?)]" }, +- #else +- { AS_SEARCH_TOKEN_MATCH_MIMETYPE, "mimetypes/mimetype[text()~=stem(?)]" }, +- #endif ++ { as_utils_get_tag_search_weight ("mediatype"), "provides/mediatype[text()~=stem(?)]" }, + /* Search once with a tokenize-and-casefold operator (`~=`) to support casefolded + * full-text search, then again using substring matching (`contains()`), to + * support prefix matching. Only do the prefix matches on a few fields, and at a + * lower priority, otherwise things will get confusing. +- * ++ * + * See https://gitlab.gnome.org/GNOME/gnome-software/-/issues/2277 */ ++ { pkgname_weight, "pkgname[text()~=stem(?)]" }, ++ { pkgname_weight / 2, "pkgname[contains(text(),stem(?))]" }, ++ { as_utils_get_tag_search_weight ("summary"), "summary[text()~=stem(?)]" }, ++ { name_weight, "name[text()~=stem(?)]" }, ++ { name_weight / 2, "name[contains(text(),stem(?))]" }, ++ { as_utils_get_tag_search_weight ("keyword"), "keywords/keyword[text()~=stem(?)]" }, ++ { id_weight, "id[text()~=stem(?)]" }, ++ { id_weight, "launchable[text()~=stem(?)]" }, ++ { as_utils_get_tag_search_weight ("origin"), "../components[@origin~=stem(?)]" }, ++ { 0, NULL } ++ }; ++#else ++ const Query queries[] = { ++ { AS_SEARCH_TOKEN_MATCH_MEDIATYPE, "mimetypes/mimetype[text()~=stem(?)]" }, + { AS_SEARCH_TOKEN_MATCH_PKGNAME, "pkgname[text()~=stem(?)]" }, + { AS_SEARCH_TOKEN_MATCH_PKGNAME / 2, "pkgname[contains(text(),stem(?))]" }, + { AS_SEARCH_TOKEN_MATCH_SUMMARY, "summary[text()~=stem(?)]" }, +@@ -1647,6 +1674,7 @@ gs_appstream_search (GsPlugin *plugin, + { AS_SEARCH_TOKEN_MATCH_ORIGIN, "../components[@origin~=stem(?)]" }, + { AS_SEARCH_TOKEN_MATCH_NONE, NULL } + }; ++#endif + + return gs_appstream_do_search (plugin, silo, values, queries, list, cancellable, error); + } +@@ -1659,11 +1687,21 @@ gs_appstream_search_developer_apps (GsPlugin *plugin, + GCancellable *cancellable, + GError **error) + { ++#if AS_CHECK_VERSION(1, 0, 0) ++ const Query queries[] = { ++ { as_utils_get_tag_search_weight ("pkgname"), "developer/name[text()~=stem(?)]" }, ++ { as_utils_get_tag_search_weight ("summary"), "project_group[text()~=stem(?)]" }, ++ /* for legacy support */ ++ { as_utils_get_tag_search_weight ("pkgname"), "developer_name[text()~=stem(?)]" }, ++ { 0, NULL } ++ }; ++#else + const Query queries[] = { + { AS_SEARCH_TOKEN_MATCH_PKGNAME, "developer_name[text()~=stem(?)]" }, + { AS_SEARCH_TOKEN_MATCH_SUMMARY, "project_group[text()~=stem(?)]" }, + { AS_SEARCH_TOKEN_MATCH_NONE, NULL } + }; ++#endif + + return gs_appstream_do_search (plugin, silo, values, queries, list, cancellable, error); + } +diff --git a/lib/gs-utils.c b/lib/gs-utils.c +index cf9073025f..19e6ebd046 100644 +--- a/lib/gs-utils.c ++++ b/lib/gs-utils.c +@@ -1694,9 +1694,9 @@ gs_utils_gstring_replace (GString *str, + const gchar *find, + const gchar *replace) + { +- #ifdef HAVE_AS_GSTRING_REPLACE_WITH_FOUR_ARGS ++#if AS_CHECK_VERSION(1, 0, 0) + as_gstring_replace (str, find, replace, 0); +- #else +- as_gstring_replace (str, find, replace); +- #endif ++#else ++ as_gstring_replace2 (str, find, replace, 0); ++#endif + } +diff --git a/meson.build b/meson.build +index 09c39df180..ad105869e5 100644 +--- a/meson.build ++++ b/meson.build +@@ -113,7 +113,7 @@ add_project_arguments('-D_GNU_SOURCE', language : 'c') + conf.set('HAVE_LINUX_UNISTD_H', cc.has_header('linux/unistd.h')) + + appstream = dependency('appstream', +- version : '>= 0.14.0', ++ version : '>= 0.16.2', + fallback : ['appstream', 'appstream_dep'], + default_options : [ + 'docs=false', +@@ -121,26 +121,6 @@ appstream = dependency('appstream', + 'install-docs=false' + ] + ) +-if appstream.type_name() == 'internal' +-else +- if meson.get_compiler('c').has_header_symbol('appstream.h', 'AS_SEARCH_TOKEN_MATCH_MEDIATYPE', dependencies: appstream) +- conf.set('HAVE_AS_SEARCH_TOKEN_MATCH_MEDIATYPE', '1') +- endif +- if meson.get_compiler('c').has_header_symbol('appstream.h', 'AS_FORMAT_STYLE_CATALOG', dependencies: appstream) +- conf.set('HAVE_AS_FORMAT_STYLE_CATALOG', '1') +- endif +- if meson.get_compiler('c').has_function('as_metadata_components_to_catalog', prefix: '#include ', dependencies: appstream) +- conf.set('HAVE_AS_METADATA_COMPONENTS_TO_CATALOG', '1') +- endif +- if meson.get_compiler('c').links('''#include +- int main (void) +- { +- as_gstring_replace (NULL, "a", "b", 0); +- return 0; +- }''', name: 'as_gstring_replace() has four arguments', dependencies: appstream) +- conf.set('HAVE_AS_GSTRING_REPLACE_WITH_FOUR_ARGS', '1') +- endif +-endif + + gdk_pixbuf = dependency('gdk-pixbuf-2.0', version : '>= 2.32.0') + libxmlb = dependency('xmlb', version : '>= 0.1.7', fallback : ['libxmlb', 'libxmlb_dep']) +diff --git a/plugins/core/gs-plugin-appstream.c b/plugins/core/gs-plugin-appstream.c +index cf9f3022b1..ef3226a591 100644 +--- a/plugins/core/gs-plugin-appstream.c ++++ b/plugins/core/gs-plugin-appstream.c +@@ -414,11 +414,7 @@ gs_plugin_appstream_load_dep11_cb (XbBuilderSource *self, + if (bytes == NULL) + return NULL; + +- #ifdef HAVE_AS_FORMAT_STYLE_CATALOG + as_metadata_set_format_style (mdata, AS_FORMAT_STYLE_CATALOG); +- #else +- as_metadata_set_format_style (mdata, AS_FORMAT_STYLE_COLLECTION); +- #endif + as_metadata_parse_bytes (mdata, + bytes, + AS_FORMAT_KIND_YAML, +@@ -428,11 +424,7 @@ gs_plugin_appstream_load_dep11_cb (XbBuilderSource *self, + return NULL; + } + +- #ifdef HAVE_AS_METADATA_COMPONENTS_TO_CATALOG + xml = as_metadata_components_to_catalog (mdata, AS_FORMAT_KIND_XML, &tmp_error); +- #else +- xml = as_metadata_components_to_collection (mdata, AS_FORMAT_KIND_XML, &tmp_error); +- #endif + if (xml == NULL) { + // This API currently returns NULL if there is nothing to serialize, so we + // have to test if this is an error or not. +diff --git a/plugins/fwupd/gs-fwupd-app.c b/plugins/fwupd/gs-fwupd-app.c +index 6dcda6ee92..5d3254da59 100644 +--- a/plugins/fwupd/gs-fwupd-app.c ++++ b/plugins/fwupd/gs-fwupd-app.c +@@ -164,7 +164,11 @@ gs_fwupd_app_set_from_device (GsApp *app, + gs_app_set_install_date (app, fwupd_device_get_created (dev)); + if (fwupd_device_get_description (dev) != NULL) { + g_autofree gchar *tmp = NULL; ++#if AS_CHECK_VERSION(1, 0, 0) ++ tmp = as_markup_convert (fwupd_device_get_description (dev), AS_MARKUP_KIND_TEXT, NULL); ++#else + tmp = as_markup_convert_simple (fwupd_device_get_description (dev), NULL); ++#endif + if (tmp != NULL) + gs_app_set_description (app, GS_APP_QUALITY_NORMAL, tmp); + } +@@ -402,7 +406,11 @@ gs_fwupd_app_set_from_release (GsApp *app, FwupdRelease *rel) + } + if (fwupd_release_get_description (rel) != NULL) { + g_autofree gchar *tmp = NULL; ++#if AS_CHECK_VERSION(1, 0, 0) ++ tmp = as_markup_convert (fwupd_release_get_description (rel), AS_MARKUP_KIND_TEXT, NULL); ++#else + tmp = as_markup_convert_simple (fwupd_release_get_description (rel), NULL); ++#endif + if (tmp != NULL) + gs_app_set_update_details_text (app, tmp); + } +diff --git a/plugins/fwupd/gs-plugin-fwupd.c b/plugins/fwupd/gs-plugin-fwupd.c +index e931b2b6db..0747d6e250 100644 +--- a/plugins/fwupd/gs-plugin-fwupd.c ++++ b/plugins/fwupd/gs-plugin-fwupd.c +@@ -726,7 +726,11 @@ gs_plugin_add_updates (GsPlugin *plugin, + g_autofree gchar *desc = NULL; + if (fwupd_release_get_description (rel) == NULL) + continue; ++#if AS_CHECK_VERSION(1, 0, 0) ++ desc = as_markup_convert (fwupd_release_get_description (rel), AS_MARKUP_KIND_TEXT, NULL); ++#else + desc = as_markup_convert_simple (fwupd_release_get_description (rel), NULL); ++#endif + if (desc == NULL) + continue; + g_string_append_printf (update_desc, +diff --git a/src/gs-hardware-support-context-dialog.c b/src/gs-hardware-support-context-dialog.c +index 0e48c8c266..14653401de 100644 +--- a/src/gs-hardware-support-context-dialog.c ++++ b/src/gs-hardware-support-context-dialog.c +@@ -461,6 +461,7 @@ gs_hardware_support_context_dialog_get_display_support (GdkMonitor *monitor, + AsRelationCompare comparator = as_relation_get_compare (relation); + Range current_display_comparand, relation_comparand; + ++#if !AS_CHECK_VERSION(1, 0, 0) + /* From https://www.freedesktop.org/software/appstream/docs/chap-Metadata.html#tag-requires-recommends-display_length */ + Range display_lengths[] = { + [AS_DISPLAY_LENGTH_KIND_XSMALL] = { 0, 360 }, +@@ -469,6 +470,7 @@ gs_hardware_support_context_dialog_get_display_support (GdkMonitor *monitor, + [AS_DISPLAY_LENGTH_KIND_LARGE] = { 1024, 3840 }, + [AS_DISPLAY_LENGTH_KIND_XLARGE] = { 3840, G_MAXUINT }, + }; ++#endif + + any_display_relations_set = TRUE; + +@@ -485,11 +487,14 @@ gs_hardware_support_context_dialog_get_display_support (GdkMonitor *monitor, + case AS_DISPLAY_SIDE_KIND_LAST: + default: + current_display_comparand.min = current_display_comparand.max = MAX (current_screen_size.width, current_screen_size.height); ++#if !AS_CHECK_VERSION(1, 0, 0) + relation_comparand.min = display_lengths[as_relation_get_value_display_length_kind (relation)].min; + relation_comparand.max = display_lengths[as_relation_get_value_display_length_kind (relation)].max; ++#endif + break; + } + ++#if !AS_CHECK_VERSION(1, 0, 0) + if (evaluate_display_comparison (display_lengths[AS_DISPLAY_LENGTH_KIND_SMALL], comparator, relation_comparand)) { + *mobile_relation_kind_out = max_relation_kind (*mobile_relation_kind_out, as_relation_get_kind (relation)); + *mobile_match_out = TRUE; +@@ -499,6 +504,7 @@ gs_hardware_support_context_dialog_get_display_support (GdkMonitor *monitor, + *desktop_relation_kind_out = max_relation_kind (*desktop_relation_kind_out, as_relation_get_kind (relation)); + *desktop_match_out = TRUE; + } ++#endif + + if (evaluate_display_comparison (current_display_comparand, comparator, relation_comparand)) { + *current_relation_kind_out = max_relation_kind (*current_relation_kind_out, as_relation_get_kind (relation)); +diff --git a/src/gs-repos-dialog.c b/src/gs-repos-dialog.c +index c41c4944a1..7dac0416d9 100644 +--- a/src/gs-repos-dialog.c ++++ b/src/gs-repos-dialog.c +@@ -154,7 +154,11 @@ enable_repo (GsReposDialog *dialog, + g_autoptr(GError) error = NULL; + + /* convert from AppStream markup */ ++#if AS_CHECK_VERSION(1, 0, 0) ++ message = as_markup_convert (gs_app_get_agreement (repo), AS_MARKUP_KIND_TEXT, &error); ++#else + message = as_markup_convert_simple (gs_app_get_agreement (repo), &error); ++#endif + if (message == NULL) { + /* failed, so just try and show the original markup */ + message = g_strdup (gs_app_get_agreement (repo)); +diff --git a/src/gs-screenshot-carousel.c b/src/gs-screenshot-carousel.c +index 04bbf86a1e..d269af6605 100644 +--- a/src/gs-screenshot-carousel.c ++++ b/src/gs-screenshot-carousel.c +@@ -141,8 +141,8 @@ gs_screenshot_carousel_load_screenshots (GsScreenshotCarousel *self, GsApp *app, + gtk_widget_set_can_focus (gtk_widget_get_first_child (ssimg), FALSE); + gs_screenshot_image_set_screenshot (GS_SCREENSHOT_IMAGE (ssimg), ss); + gs_screenshot_image_set_size (GS_SCREENSHOT_IMAGE (ssimg), +- AS_IMAGE_NORMAL_WIDTH, +- AS_IMAGE_NORMAL_HEIGHT); ++ GS_IMAGE_NORMAL_WIDTH, ++ GS_IMAGE_NORMAL_HEIGHT); + gtk_widget_add_css_class (ssimg, "screenshot-image-main"); + gs_screenshot_image_load_async (GS_SCREENSHOT_IMAGE (ssimg), cancellable); + +diff --git a/src/gs-screenshot-image.c b/src/gs-screenshot-image.c +index c313a2589f..b24083b387 100644 +--- a/src/gs-screenshot-image.c ++++ b/src/gs-screenshot-image.c +@@ -284,13 +284,13 @@ gs_screenshot_image_save_downloaded_img (GsScreenshotImage *ssimg, + if (images->len > 1) + return TRUE; + +- if (width == AS_IMAGE_THUMBNAIL_WIDTH && +- height == AS_IMAGE_THUMBNAIL_HEIGHT) { +- width = AS_IMAGE_NORMAL_WIDTH; +- height = AS_IMAGE_NORMAL_HEIGHT; ++ if (width == GS_IMAGE_THUMBNAIL_WIDTH && ++ height == GS_IMAGE_THUMBNAIL_HEIGHT) { ++ width = GS_IMAGE_NORMAL_WIDTH; ++ height = GS_IMAGE_NORMAL_HEIGHT; + } else { +- width = AS_IMAGE_THUMBNAIL_WIDTH; +- height = AS_IMAGE_THUMBNAIL_HEIGHT; ++ width = GS_IMAGE_THUMBNAIL_WIDTH; ++ height = GS_IMAGE_THUMBNAIL_HEIGHT; + } + + width *= ssimg->scale; +@@ -582,16 +582,30 @@ gs_screenshot_image_get_url (GsScreenshotImage *ssimg) + } else if (as_screenshot_get_media_kind (ssimg->screenshot) == AS_SCREENSHOT_MEDIA_KIND_IMAGE) { + AsImage *im; + ++#if AS_CHECK_VERSION(1, 0, 0) ++ im = as_screenshot_get_image (ssimg->screenshot, ++ ssimg->width, ++ ssimg->height, ++ ssimg->scale); ++#else + im = as_screenshot_get_image (ssimg->screenshot, + ssimg->width * ssimg->scale, + ssimg->height * ssimg->scale); ++#endif + + /* if we've failed to load a HiDPI image, fallback to LoDPI */ + if (im == NULL && ssimg->scale > 1) { + ssimg->scale = 1; ++#if AS_CHECK_VERSION(1, 0, 0) ++ im = as_screenshot_get_image (ssimg->screenshot, ++ ssimg->width, ++ ssimg->height, ++ 1); ++#else + im = as_screenshot_get_image (ssimg->screenshot, + ssimg->width, + ssimg->height); ++#endif + } + + if (im) +@@ -698,15 +712,22 @@ gs_screenshot_image_load_async (GsScreenshotImage *ssimg, + * smaller version of it straight away */ + if (!ssimg->showing_image && + as_screenshot_get_media_kind (ssimg->screenshot) == AS_SCREENSHOT_MEDIA_KIND_IMAGE && +- ssimg->width > AS_IMAGE_THUMBNAIL_WIDTH && +- ssimg->height > AS_IMAGE_THUMBNAIL_HEIGHT) { ++ ssimg->width > GS_IMAGE_THUMBNAIL_WIDTH && ++ ssimg->height > GS_IMAGE_THUMBNAIL_HEIGHT) { + const gchar *url_thumb; + g_autofree gchar *basename_thumb = NULL; + g_autofree gchar *cache_kind_thumb = NULL; + AsImage *im; ++#if AS_CHECK_VERSION(1, 0, 0) + im = as_screenshot_get_image (ssimg->screenshot, +- AS_IMAGE_THUMBNAIL_WIDTH * ssimg->scale, +- AS_IMAGE_THUMBNAIL_HEIGHT * ssimg->scale); ++ GS_IMAGE_THUMBNAIL_WIDTH, ++ GS_IMAGE_THUMBNAIL_HEIGHT, ++ ssimg->scale); ++#else ++ im = as_screenshot_get_image (ssimg->screenshot, ++ GS_IMAGE_THUMBNAIL_WIDTH * ssimg->scale, ++ GS_IMAGE_THUMBNAIL_HEIGHT * ssimg->scale); ++#endif + url_thumb = as_image_get_url (im); + basename_thumb = gs_screenshot_get_cachefn_for_url (url_thumb); + cache_kind_thumb = g_build_filename ("screenshots", "112x63", NULL); +diff --git a/src/gs-screenshot-image.h b/src/gs-screenshot-image.h +index 1f6cf81ce6..6e45f5d20a 100644 +--- a/src/gs-screenshot-image.h ++++ b/src/gs-screenshot-image.h +@@ -21,6 +21,13 @@ G_BEGIN_DECLS + + G_DECLARE_FINAL_TYPE (GsScreenshotImage, gs_screenshot_image, GS, SCREENSHOT_IMAGE, GtkWidget) + ++#define GS_IMAGE_LARGE_HEIGHT 423 ++#define GS_IMAGE_LARGE_WIDTH 752 ++#define GS_IMAGE_NORMAL_HEIGHT 351 ++#define GS_IMAGE_NORMAL_WIDTH 624 ++#define GS_IMAGE_THUMBNAIL_HEIGHT 63 ++#define GS_IMAGE_THUMBNAIL_WIDTH 112 ++ + GtkWidget *gs_screenshot_image_new (SoupSession *session); + + AsScreenshot *gs_screenshot_image_get_screenshot (GsScreenshotImage *ssimg); +diff --git a/subprojects/appstream.wrap b/subprojects/appstream.wrap +index 6f0beb0cbc..5763a32c64 100644 +--- a/subprojects/appstream.wrap ++++ b/subprojects/appstream.wrap +@@ -1,5 +1,5 @@ + [wrap-git] + directory = appstream + url = https://github.com/ximion/appstream.git +-revision = v0.14.1 ++revision = v0.16.3 + depth = 1 +-- +GitLab + diff --git a/gnome-software.spec b/gnome-software.spec index 21730b3..af54a93 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -24,13 +24,16 @@ Name: gnome-software Version: 45.1 -Release: 1%{?dist} +Release: 2%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later URL: https://wiki.gnome.org/Apps/Software Source0: https://download.gnome.org/sources/gnome-software/45/%{name}-%{tarball_version}.tar.xz +# https://gitlab.gnome.org/GNOME/gnome-software/-/merge_requests/1810 +Patch: 0001-port-to-appstream1.patch + BuildRequires: docbook-style-xsl BuildRequires: desktop-file-utils BuildRequires: gcc @@ -246,6 +249,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Tue Nov 07 2023 Milan Crha - 45.1-2 +- Add patch to build with appstream 1.0 + * Fri Oct 20 2023 Milan Crha - 45.1-1 - Update to 45.1 From fa61d9aee481d4275775b33d9a0e3e4b0cf428c1 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Tue, 7 Nov 2023 09:10:58 +0100 Subject: [PATCH 052/116] Require appstream version 1.0.0 --- gnome-software.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gnome-software.spec b/gnome-software.spec index af54a93..be9cb1b 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -1,4 +1,4 @@ -%global appstream_version 0.14.0 +%global appstream_version 1.0.0 %global flatpak_version 1.9.1 %global fwupd_version 1.5.6 %global glib2_version 2.70.0 From 34ee6fc989eff65e296e1b230ead120069d140fd Mon Sep 17 00:00:00 2001 From: Neal Gompa Date: Tue, 7 Nov 2023 13:06:54 -0500 Subject: [PATCH 053/116] Fix appstream_version macro for prerelease appstream 1.0 package --- gnome-software.spec | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index be9cb1b..7af1f2a 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -1,4 +1,4 @@ -%global appstream_version 1.0.0 +%global appstream_version 1.0.0~ %global flatpak_version 1.9.1 %global fwupd_version 1.5.6 %global glib2_version 2.70.0 @@ -24,7 +24,7 @@ Name: gnome-software Version: 45.1 -Release: 2%{?dist} +Release: 3%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -249,6 +249,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Tue Nov 07 2023 Neal Gompa - 45.1-3 +- Fix appstream_version macro for prerelease appstream 1.0 package + * Tue Nov 07 2023 Milan Crha - 45.1-2 - Add patch to build with appstream 1.0 From a3f0848b35859cbb0305243afb2c68b54d2500aa Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 1 Dec 2023 10:20:36 +0100 Subject: [PATCH 054/116] Update to 45.2 --- 0001-port-to-appstream1.patch | 13 +++++++++++++ gnome-software.spec | 7 +++++-- sources | 2 +- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/0001-port-to-appstream1.patch b/0001-port-to-appstream1.patch index c166088..f121d70 100644 --- a/0001-port-to-appstream1.patch +++ b/0001-port-to-appstream1.patch @@ -489,6 +489,19 @@ index 6f0beb0cbc..5763a32c64 100644 -revision = v0.14.1 +revision = v0.16.3 depth = 1 +diff --git a/lib/gs-appstream.c b/lib/gs-appstream.c +index 6504d6f25..4fd7f5334 100644 +--- a/lib/gs-appstream.c ++++ b/lib/gs-appstream.c +@@ -587,8 +587,6 @@ gs_appstream_refine_add_provides (GsApp *app, XbNode *component, GError **error) + kind = AS_PROVIDED_KIND_FIRMWARE_RUNTIME; + else if (g_strcmp0 (fw_type, "flashed") == 0) + kind = AS_PROVIDED_KIND_FIRMWARE_FLASHED; +- } else if (g_strcmp0 (element_name, "python2") == 0) { +- kind = AS_PROVIDED_KIND_PYTHON_2; + } else if (g_strcmp0 (element_name, "python3") == 0) { + kind = AS_PROVIDED_KIND_PYTHON; + } else if (g_strcmp0 (element_name, "dbus") == 0) { -- GitLab diff --git a/gnome-software.spec b/gnome-software.spec index 7af1f2a..9c7b8db 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -23,8 +23,8 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 45.1 -Release: 3%{?dist} +Version: 45.2 +Release: 1%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -249,6 +249,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Dec 01 2023 Milan Crha - 45.2-1 +- Update to 45.2 + * Tue Nov 07 2023 Neal Gompa - 45.1-3 - Fix appstream_version macro for prerelease appstream 1.0 package diff --git a/sources b/sources index c15ccca..fe4c93b 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-45.1.tar.xz) = 5fdf5e6a34ab9acf938bc4ade41b916ad38ad3b4a7f604b2cba9dfaa38f17299001bef8fde9165f6a035fcc7fef3ebd451bd29ff126c0b9d5a7104e448729434 +SHA512 (gnome-software-45.2.tar.xz) = ea271146683d199b27ffaaab98a13c25f8f794da3c6cc6b0daeb37f3f4c92d8644926dc592d309ea32dcb131d33e6c77d1c6fa36ac10cf6b23cd7adc73e898cb From 3140f37d2d3b64c2889d143bcb9e6bee142981a4 Mon Sep 17 00:00:00 2001 From: Troy Dawson Date: Tue, 19 Dec 2023 09:38:23 -0800 Subject: [PATCH 055/116] ostree and flatpak not on i686 for RHEL 10 Signed-off-by: Troy Dawson --- gnome-software.spec | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gnome-software.spec b/gnome-software.spec index 9c7b8db..40678e5 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -34,6 +34,12 @@ Source0: https://download.gnome.org/sources/gnome-software/45/%{name}-%{tarbal # https://gitlab.gnome.org/GNOME/gnome-software/-/merge_requests/1810 Patch: 0001-port-to-appstream1.patch +# ostree and flatpak not on i686 for RHEL 10 +# https://github.com/containers/composefs/pull/229#issuecomment-1838735764 +%if 0%{?rhel} >= 10 +ExcludeArch: %{ix86} +%endif + BuildRequires: docbook-style-xsl BuildRequires: desktop-file-utils BuildRequires: gcc From ef76ba99411e0057ac5ccfd88df8307a1beff187 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 5 Jan 2024 10:28:23 +0100 Subject: [PATCH 056/116] Update to 46.alpha --- 0001-port-to-appstream1.patch | 507 ---------------------------------- gnome-software.spec | 10 +- sources | 2 +- 3 files changed, 6 insertions(+), 513 deletions(-) delete mode 100644 0001-port-to-appstream1.patch diff --git a/0001-port-to-appstream1.patch b/0001-port-to-appstream1.patch deleted file mode 100644 index f121d70..0000000 --- a/0001-port-to-appstream1.patch +++ /dev/null @@ -1,507 +0,0 @@ -From e6f7e28bdd50a63586ba6a82b936d54db19a311b Mon Sep 17 00:00:00 2001 -From: Matthias Klumpp -Date: Sun, 8 Oct 2023 20:22:44 +0200 -Subject: [PATCH] Adjust to build with AppStream 1.0 as well as 0.16.x - ---- - lib/gs-app.c | 4 ++ - lib/gs-appstream.c | 58 ++++++++++++++++++++---- - lib/gs-utils.c | 8 ++-- - meson.build | 22 +-------- - plugins/core/gs-plugin-appstream.c | 8 ---- - plugins/fwupd/gs-fwupd-app.c | 8 ++++ - plugins/fwupd/gs-plugin-fwupd.c | 4 ++ - src/gs-hardware-support-context-dialog.c | 6 +++ - src/gs-repos-dialog.c | 4 ++ - src/gs-screenshot-carousel.c | 4 +- - src/gs-screenshot-image.c | 41 +++++++++++++---- - src/gs-screenshot-image.h | 7 +++ - subprojects/appstream.wrap | 2 +- - 13 files changed, 120 insertions(+), 56 deletions(-) - -diff --git a/lib/gs-app.c b/lib/gs-app.c -index 048a061225..e2694057cd 100644 ---- a/lib/gs-app.c -+++ b/lib/gs-app.c -@@ -609,7 +609,11 @@ gs_app_to_string_append (GsApp *app, GString *str) - AsScreenshot *ss = g_ptr_array_index (priv->screenshots, i); - g_autofree gchar *key = NULL; - tmp = as_screenshot_get_caption (ss); -+#if AS_CHECK_VERSION(1, 0, 0) -+ im = as_screenshot_get_image (ss, 0, 0, 1); -+#else - im = as_screenshot_get_image (ss, 0, 0); -+#endif - if (im == NULL) - continue; - key = g_strdup_printf ("screenshot-%02u", i); -diff --git a/lib/gs-appstream.c b/lib/gs-appstream.c -index deca176dcf..2cc2427a19 100644 ---- a/lib/gs-appstream.c -+++ b/lib/gs-appstream.c -@@ -1011,8 +1011,11 @@ gs_appstream_refine_app_relation (GsApp *app, - as_relation_set_item_kind (relation, AS_RELATION_ITEM_KIND_CONTROL); - as_relation_set_value_control_kind (relation, as_control_kind_from_string (xb_node_get_text (child))); - } else if (g_str_equal (item_kind, "display_length")) { -- AsDisplayLengthKind display_length_kind; - const gchar *compare; -+ const gchar *side; -+#if !AS_CHECK_VERSION(1, 0, 0) -+ AsDisplayLengthKind display_length_kind; -+#endif - - /* https://www.freedesktop.org/software/appstream/docs/chap-Metadata.html#tag-relations-display_length */ - as_relation_set_item_kind (relation, AS_RELATION_ITEM_KIND_DISPLAY_LENGTH); -@@ -1020,15 +1023,21 @@ gs_appstream_refine_app_relation (GsApp *app, - compare = xb_node_get_attr (child, "compare"); - as_relation_set_compare (relation, (compare != NULL) ? as_relation_compare_from_string (compare) : AS_RELATION_COMPARE_GE); - -+#if AS_CHECK_VERSION(1, 0, 0) -+ side = xb_node_get_attr (child, "side"); -+ as_relation_set_display_side_kind (relation, (side != NULL) ? as_display_side_kind_from_string (side) : AS_DISPLAY_SIDE_KIND_SHORTEST); -+ as_relation_set_value_px (relation, xb_node_get_text_as_uint (child)); -+#else - display_length_kind = as_display_length_kind_from_string (xb_node_get_text (child)); - if (display_length_kind != AS_DISPLAY_LENGTH_KIND_UNKNOWN) { - /* Ignore the `side` attribute */ - as_relation_set_value_display_length_kind (relation, display_length_kind); - } else { -- const gchar *side = xb_node_get_attr (child, "side"); -+ side = xb_node_get_attr (child, "side"); - as_relation_set_display_side_kind (relation, (side != NULL) ? as_display_side_kind_from_string (side) : AS_DISPLAY_SIDE_KIND_SHORTEST); - as_relation_set_value_px (relation, xb_node_get_text_as_uint (child)); - } -+#endif - } else { - g_debug ("Relation type ‘%s’ not currently supported for %s; ignoring", - item_kind, gs_app_get_id (app)); -@@ -1472,7 +1481,7 @@ gs_appstream_refine_app (GsPlugin *plugin, - } - - typedef struct { -- AsSearchTokenMatch match_value; -+ guint16 match_value; - XbQuery *query; - } GsAppstreamSearchHelper; - -@@ -1522,7 +1531,7 @@ gs_appstream_silo_search_component (GPtrArray *array, XbNode *component, const g - } - - typedef struct { -- AsSearchTokenMatch match_value; -+ guint16 match_value; - const gchar *xpath; - } Query; - -@@ -1585,7 +1594,11 @@ gs_appstream_do_search (GsPlugin *plugin, - * Drop the ID token from it as it’s the highest - * numeric value but isn’t visible to the user in the - * UI, which leads to confusing results ordering. */ -+#if AS_CHECK_VERSION(1, 0, 0) -+ gs_app_set_match_value (app, match_value & (~as_utils_get_tag_search_weight ("id"))); -+#else - gs_app_set_match_value (app, match_value & (~AS_SEARCH_TOKEN_MATCH_ID)); -+#endif - gs_app_list_add (list, app); - - if (gs_app_get_kind (app) == AS_COMPONENT_KIND_ADDON) { -@@ -1624,18 +1637,32 @@ gs_appstream_search (GsPlugin *plugin, - GCancellable *cancellable, - GError **error) - { -+#if AS_CHECK_VERSION(1, 0, 0) -+ guint16 pkgname_weight = as_utils_get_tag_search_weight ("pkgname"); -+ guint16 name_weight = as_utils_get_tag_search_weight ("name"); -+ guint16 id_weight = as_utils_get_tag_search_weight ("id"); - const Query queries[] = { -- #ifdef HAVE_AS_SEARCH_TOKEN_MATCH_MEDIATYPE -- { AS_SEARCH_TOKEN_MATCH_MEDIATYPE, "mimetypes/mimetype[text()~=stem(?)]" }, -- #else -- { AS_SEARCH_TOKEN_MATCH_MIMETYPE, "mimetypes/mimetype[text()~=stem(?)]" }, -- #endif -+ { as_utils_get_tag_search_weight ("mediatype"), "provides/mediatype[text()~=stem(?)]" }, - /* Search once with a tokenize-and-casefold operator (`~=`) to support casefolded - * full-text search, then again using substring matching (`contains()`), to - * support prefix matching. Only do the prefix matches on a few fields, and at a - * lower priority, otherwise things will get confusing. -- * -+ * - * See https://gitlab.gnome.org/GNOME/gnome-software/-/issues/2277 */ -+ { pkgname_weight, "pkgname[text()~=stem(?)]" }, -+ { pkgname_weight / 2, "pkgname[contains(text(),stem(?))]" }, -+ { as_utils_get_tag_search_weight ("summary"), "summary[text()~=stem(?)]" }, -+ { name_weight, "name[text()~=stem(?)]" }, -+ { name_weight / 2, "name[contains(text(),stem(?))]" }, -+ { as_utils_get_tag_search_weight ("keyword"), "keywords/keyword[text()~=stem(?)]" }, -+ { id_weight, "id[text()~=stem(?)]" }, -+ { id_weight, "launchable[text()~=stem(?)]" }, -+ { as_utils_get_tag_search_weight ("origin"), "../components[@origin~=stem(?)]" }, -+ { 0, NULL } -+ }; -+#else -+ const Query queries[] = { -+ { AS_SEARCH_TOKEN_MATCH_MEDIATYPE, "mimetypes/mimetype[text()~=stem(?)]" }, - { AS_SEARCH_TOKEN_MATCH_PKGNAME, "pkgname[text()~=stem(?)]" }, - { AS_SEARCH_TOKEN_MATCH_PKGNAME / 2, "pkgname[contains(text(),stem(?))]" }, - { AS_SEARCH_TOKEN_MATCH_SUMMARY, "summary[text()~=stem(?)]" }, -@@ -1647,6 +1674,7 @@ gs_appstream_search (GsPlugin *plugin, - { AS_SEARCH_TOKEN_MATCH_ORIGIN, "../components[@origin~=stem(?)]" }, - { AS_SEARCH_TOKEN_MATCH_NONE, NULL } - }; -+#endif - - return gs_appstream_do_search (plugin, silo, values, queries, list, cancellable, error); - } -@@ -1659,11 +1687,21 @@ gs_appstream_search_developer_apps (GsPlugin *plugin, - GCancellable *cancellable, - GError **error) - { -+#if AS_CHECK_VERSION(1, 0, 0) -+ const Query queries[] = { -+ { as_utils_get_tag_search_weight ("pkgname"), "developer/name[text()~=stem(?)]" }, -+ { as_utils_get_tag_search_weight ("summary"), "project_group[text()~=stem(?)]" }, -+ /* for legacy support */ -+ { as_utils_get_tag_search_weight ("pkgname"), "developer_name[text()~=stem(?)]" }, -+ { 0, NULL } -+ }; -+#else - const Query queries[] = { - { AS_SEARCH_TOKEN_MATCH_PKGNAME, "developer_name[text()~=stem(?)]" }, - { AS_SEARCH_TOKEN_MATCH_SUMMARY, "project_group[text()~=stem(?)]" }, - { AS_SEARCH_TOKEN_MATCH_NONE, NULL } - }; -+#endif - - return gs_appstream_do_search (plugin, silo, values, queries, list, cancellable, error); - } -diff --git a/lib/gs-utils.c b/lib/gs-utils.c -index cf9073025f..19e6ebd046 100644 ---- a/lib/gs-utils.c -+++ b/lib/gs-utils.c -@@ -1694,9 +1694,9 @@ gs_utils_gstring_replace (GString *str, - const gchar *find, - const gchar *replace) - { -- #ifdef HAVE_AS_GSTRING_REPLACE_WITH_FOUR_ARGS -+#if AS_CHECK_VERSION(1, 0, 0) - as_gstring_replace (str, find, replace, 0); -- #else -- as_gstring_replace (str, find, replace); -- #endif -+#else -+ as_gstring_replace2 (str, find, replace, 0); -+#endif - } -diff --git a/meson.build b/meson.build -index 09c39df180..ad105869e5 100644 ---- a/meson.build -+++ b/meson.build -@@ -113,7 +113,7 @@ add_project_arguments('-D_GNU_SOURCE', language : 'c') - conf.set('HAVE_LINUX_UNISTD_H', cc.has_header('linux/unistd.h')) - - appstream = dependency('appstream', -- version : '>= 0.14.0', -+ version : '>= 0.16.2', - fallback : ['appstream', 'appstream_dep'], - default_options : [ - 'docs=false', -@@ -121,26 +121,6 @@ appstream = dependency('appstream', - 'install-docs=false' - ] - ) --if appstream.type_name() == 'internal' --else -- if meson.get_compiler('c').has_header_symbol('appstream.h', 'AS_SEARCH_TOKEN_MATCH_MEDIATYPE', dependencies: appstream) -- conf.set('HAVE_AS_SEARCH_TOKEN_MATCH_MEDIATYPE', '1') -- endif -- if meson.get_compiler('c').has_header_symbol('appstream.h', 'AS_FORMAT_STYLE_CATALOG', dependencies: appstream) -- conf.set('HAVE_AS_FORMAT_STYLE_CATALOG', '1') -- endif -- if meson.get_compiler('c').has_function('as_metadata_components_to_catalog', prefix: '#include ', dependencies: appstream) -- conf.set('HAVE_AS_METADATA_COMPONENTS_TO_CATALOG', '1') -- endif -- if meson.get_compiler('c').links('''#include -- int main (void) -- { -- as_gstring_replace (NULL, "a", "b", 0); -- return 0; -- }''', name: 'as_gstring_replace() has four arguments', dependencies: appstream) -- conf.set('HAVE_AS_GSTRING_REPLACE_WITH_FOUR_ARGS', '1') -- endif --endif - - gdk_pixbuf = dependency('gdk-pixbuf-2.0', version : '>= 2.32.0') - libxmlb = dependency('xmlb', version : '>= 0.1.7', fallback : ['libxmlb', 'libxmlb_dep']) -diff --git a/plugins/core/gs-plugin-appstream.c b/plugins/core/gs-plugin-appstream.c -index cf9f3022b1..ef3226a591 100644 ---- a/plugins/core/gs-plugin-appstream.c -+++ b/plugins/core/gs-plugin-appstream.c -@@ -414,11 +414,7 @@ gs_plugin_appstream_load_dep11_cb (XbBuilderSource *self, - if (bytes == NULL) - return NULL; - -- #ifdef HAVE_AS_FORMAT_STYLE_CATALOG - as_metadata_set_format_style (mdata, AS_FORMAT_STYLE_CATALOG); -- #else -- as_metadata_set_format_style (mdata, AS_FORMAT_STYLE_COLLECTION); -- #endif - as_metadata_parse_bytes (mdata, - bytes, - AS_FORMAT_KIND_YAML, -@@ -428,11 +424,7 @@ gs_plugin_appstream_load_dep11_cb (XbBuilderSource *self, - return NULL; - } - -- #ifdef HAVE_AS_METADATA_COMPONENTS_TO_CATALOG - xml = as_metadata_components_to_catalog (mdata, AS_FORMAT_KIND_XML, &tmp_error); -- #else -- xml = as_metadata_components_to_collection (mdata, AS_FORMAT_KIND_XML, &tmp_error); -- #endif - if (xml == NULL) { - // This API currently returns NULL if there is nothing to serialize, so we - // have to test if this is an error or not. -diff --git a/plugins/fwupd/gs-fwupd-app.c b/plugins/fwupd/gs-fwupd-app.c -index 6dcda6ee92..5d3254da59 100644 ---- a/plugins/fwupd/gs-fwupd-app.c -+++ b/plugins/fwupd/gs-fwupd-app.c -@@ -164,7 +164,11 @@ gs_fwupd_app_set_from_device (GsApp *app, - gs_app_set_install_date (app, fwupd_device_get_created (dev)); - if (fwupd_device_get_description (dev) != NULL) { - g_autofree gchar *tmp = NULL; -+#if AS_CHECK_VERSION(1, 0, 0) -+ tmp = as_markup_convert (fwupd_device_get_description (dev), AS_MARKUP_KIND_TEXT, NULL); -+#else - tmp = as_markup_convert_simple (fwupd_device_get_description (dev), NULL); -+#endif - if (tmp != NULL) - gs_app_set_description (app, GS_APP_QUALITY_NORMAL, tmp); - } -@@ -402,7 +406,11 @@ gs_fwupd_app_set_from_release (GsApp *app, FwupdRelease *rel) - } - if (fwupd_release_get_description (rel) != NULL) { - g_autofree gchar *tmp = NULL; -+#if AS_CHECK_VERSION(1, 0, 0) -+ tmp = as_markup_convert (fwupd_release_get_description (rel), AS_MARKUP_KIND_TEXT, NULL); -+#else - tmp = as_markup_convert_simple (fwupd_release_get_description (rel), NULL); -+#endif - if (tmp != NULL) - gs_app_set_update_details_text (app, tmp); - } -diff --git a/plugins/fwupd/gs-plugin-fwupd.c b/plugins/fwupd/gs-plugin-fwupd.c -index e931b2b6db..0747d6e250 100644 ---- a/plugins/fwupd/gs-plugin-fwupd.c -+++ b/plugins/fwupd/gs-plugin-fwupd.c -@@ -726,7 +726,11 @@ gs_plugin_add_updates (GsPlugin *plugin, - g_autofree gchar *desc = NULL; - if (fwupd_release_get_description (rel) == NULL) - continue; -+#if AS_CHECK_VERSION(1, 0, 0) -+ desc = as_markup_convert (fwupd_release_get_description (rel), AS_MARKUP_KIND_TEXT, NULL); -+#else - desc = as_markup_convert_simple (fwupd_release_get_description (rel), NULL); -+#endif - if (desc == NULL) - continue; - g_string_append_printf (update_desc, -diff --git a/src/gs-hardware-support-context-dialog.c b/src/gs-hardware-support-context-dialog.c -index 0e48c8c266..14653401de 100644 ---- a/src/gs-hardware-support-context-dialog.c -+++ b/src/gs-hardware-support-context-dialog.c -@@ -461,6 +461,7 @@ gs_hardware_support_context_dialog_get_display_support (GdkMonitor *monitor, - AsRelationCompare comparator = as_relation_get_compare (relation); - Range current_display_comparand, relation_comparand; - -+#if !AS_CHECK_VERSION(1, 0, 0) - /* From https://www.freedesktop.org/software/appstream/docs/chap-Metadata.html#tag-requires-recommends-display_length */ - Range display_lengths[] = { - [AS_DISPLAY_LENGTH_KIND_XSMALL] = { 0, 360 }, -@@ -469,6 +470,7 @@ gs_hardware_support_context_dialog_get_display_support (GdkMonitor *monitor, - [AS_DISPLAY_LENGTH_KIND_LARGE] = { 1024, 3840 }, - [AS_DISPLAY_LENGTH_KIND_XLARGE] = { 3840, G_MAXUINT }, - }; -+#endif - - any_display_relations_set = TRUE; - -@@ -485,11 +487,14 @@ gs_hardware_support_context_dialog_get_display_support (GdkMonitor *monitor, - case AS_DISPLAY_SIDE_KIND_LAST: - default: - current_display_comparand.min = current_display_comparand.max = MAX (current_screen_size.width, current_screen_size.height); -+#if !AS_CHECK_VERSION(1, 0, 0) - relation_comparand.min = display_lengths[as_relation_get_value_display_length_kind (relation)].min; - relation_comparand.max = display_lengths[as_relation_get_value_display_length_kind (relation)].max; -+#endif - break; - } - -+#if !AS_CHECK_VERSION(1, 0, 0) - if (evaluate_display_comparison (display_lengths[AS_DISPLAY_LENGTH_KIND_SMALL], comparator, relation_comparand)) { - *mobile_relation_kind_out = max_relation_kind (*mobile_relation_kind_out, as_relation_get_kind (relation)); - *mobile_match_out = TRUE; -@@ -499,6 +504,7 @@ gs_hardware_support_context_dialog_get_display_support (GdkMonitor *monitor, - *desktop_relation_kind_out = max_relation_kind (*desktop_relation_kind_out, as_relation_get_kind (relation)); - *desktop_match_out = TRUE; - } -+#endif - - if (evaluate_display_comparison (current_display_comparand, comparator, relation_comparand)) { - *current_relation_kind_out = max_relation_kind (*current_relation_kind_out, as_relation_get_kind (relation)); -diff --git a/src/gs-repos-dialog.c b/src/gs-repos-dialog.c -index c41c4944a1..7dac0416d9 100644 ---- a/src/gs-repos-dialog.c -+++ b/src/gs-repos-dialog.c -@@ -154,7 +154,11 @@ enable_repo (GsReposDialog *dialog, - g_autoptr(GError) error = NULL; - - /* convert from AppStream markup */ -+#if AS_CHECK_VERSION(1, 0, 0) -+ message = as_markup_convert (gs_app_get_agreement (repo), AS_MARKUP_KIND_TEXT, &error); -+#else - message = as_markup_convert_simple (gs_app_get_agreement (repo), &error); -+#endif - if (message == NULL) { - /* failed, so just try and show the original markup */ - message = g_strdup (gs_app_get_agreement (repo)); -diff --git a/src/gs-screenshot-carousel.c b/src/gs-screenshot-carousel.c -index 04bbf86a1e..d269af6605 100644 ---- a/src/gs-screenshot-carousel.c -+++ b/src/gs-screenshot-carousel.c -@@ -141,8 +141,8 @@ gs_screenshot_carousel_load_screenshots (GsScreenshotCarousel *self, GsApp *app, - gtk_widget_set_can_focus (gtk_widget_get_first_child (ssimg), FALSE); - gs_screenshot_image_set_screenshot (GS_SCREENSHOT_IMAGE (ssimg), ss); - gs_screenshot_image_set_size (GS_SCREENSHOT_IMAGE (ssimg), -- AS_IMAGE_NORMAL_WIDTH, -- AS_IMAGE_NORMAL_HEIGHT); -+ GS_IMAGE_NORMAL_WIDTH, -+ GS_IMAGE_NORMAL_HEIGHT); - gtk_widget_add_css_class (ssimg, "screenshot-image-main"); - gs_screenshot_image_load_async (GS_SCREENSHOT_IMAGE (ssimg), cancellable); - -diff --git a/src/gs-screenshot-image.c b/src/gs-screenshot-image.c -index c313a2589f..b24083b387 100644 ---- a/src/gs-screenshot-image.c -+++ b/src/gs-screenshot-image.c -@@ -284,13 +284,13 @@ gs_screenshot_image_save_downloaded_img (GsScreenshotImage *ssimg, - if (images->len > 1) - return TRUE; - -- if (width == AS_IMAGE_THUMBNAIL_WIDTH && -- height == AS_IMAGE_THUMBNAIL_HEIGHT) { -- width = AS_IMAGE_NORMAL_WIDTH; -- height = AS_IMAGE_NORMAL_HEIGHT; -+ if (width == GS_IMAGE_THUMBNAIL_WIDTH && -+ height == GS_IMAGE_THUMBNAIL_HEIGHT) { -+ width = GS_IMAGE_NORMAL_WIDTH; -+ height = GS_IMAGE_NORMAL_HEIGHT; - } else { -- width = AS_IMAGE_THUMBNAIL_WIDTH; -- height = AS_IMAGE_THUMBNAIL_HEIGHT; -+ width = GS_IMAGE_THUMBNAIL_WIDTH; -+ height = GS_IMAGE_THUMBNAIL_HEIGHT; - } - - width *= ssimg->scale; -@@ -582,16 +582,30 @@ gs_screenshot_image_get_url (GsScreenshotImage *ssimg) - } else if (as_screenshot_get_media_kind (ssimg->screenshot) == AS_SCREENSHOT_MEDIA_KIND_IMAGE) { - AsImage *im; - -+#if AS_CHECK_VERSION(1, 0, 0) -+ im = as_screenshot_get_image (ssimg->screenshot, -+ ssimg->width, -+ ssimg->height, -+ ssimg->scale); -+#else - im = as_screenshot_get_image (ssimg->screenshot, - ssimg->width * ssimg->scale, - ssimg->height * ssimg->scale); -+#endif - - /* if we've failed to load a HiDPI image, fallback to LoDPI */ - if (im == NULL && ssimg->scale > 1) { - ssimg->scale = 1; -+#if AS_CHECK_VERSION(1, 0, 0) -+ im = as_screenshot_get_image (ssimg->screenshot, -+ ssimg->width, -+ ssimg->height, -+ 1); -+#else - im = as_screenshot_get_image (ssimg->screenshot, - ssimg->width, - ssimg->height); -+#endif - } - - if (im) -@@ -698,15 +712,22 @@ gs_screenshot_image_load_async (GsScreenshotImage *ssimg, - * smaller version of it straight away */ - if (!ssimg->showing_image && - as_screenshot_get_media_kind (ssimg->screenshot) == AS_SCREENSHOT_MEDIA_KIND_IMAGE && -- ssimg->width > AS_IMAGE_THUMBNAIL_WIDTH && -- ssimg->height > AS_IMAGE_THUMBNAIL_HEIGHT) { -+ ssimg->width > GS_IMAGE_THUMBNAIL_WIDTH && -+ ssimg->height > GS_IMAGE_THUMBNAIL_HEIGHT) { - const gchar *url_thumb; - g_autofree gchar *basename_thumb = NULL; - g_autofree gchar *cache_kind_thumb = NULL; - AsImage *im; -+#if AS_CHECK_VERSION(1, 0, 0) - im = as_screenshot_get_image (ssimg->screenshot, -- AS_IMAGE_THUMBNAIL_WIDTH * ssimg->scale, -- AS_IMAGE_THUMBNAIL_HEIGHT * ssimg->scale); -+ GS_IMAGE_THUMBNAIL_WIDTH, -+ GS_IMAGE_THUMBNAIL_HEIGHT, -+ ssimg->scale); -+#else -+ im = as_screenshot_get_image (ssimg->screenshot, -+ GS_IMAGE_THUMBNAIL_WIDTH * ssimg->scale, -+ GS_IMAGE_THUMBNAIL_HEIGHT * ssimg->scale); -+#endif - url_thumb = as_image_get_url (im); - basename_thumb = gs_screenshot_get_cachefn_for_url (url_thumb); - cache_kind_thumb = g_build_filename ("screenshots", "112x63", NULL); -diff --git a/src/gs-screenshot-image.h b/src/gs-screenshot-image.h -index 1f6cf81ce6..6e45f5d20a 100644 ---- a/src/gs-screenshot-image.h -+++ b/src/gs-screenshot-image.h -@@ -21,6 +21,13 @@ G_BEGIN_DECLS - - G_DECLARE_FINAL_TYPE (GsScreenshotImage, gs_screenshot_image, GS, SCREENSHOT_IMAGE, GtkWidget) - -+#define GS_IMAGE_LARGE_HEIGHT 423 -+#define GS_IMAGE_LARGE_WIDTH 752 -+#define GS_IMAGE_NORMAL_HEIGHT 351 -+#define GS_IMAGE_NORMAL_WIDTH 624 -+#define GS_IMAGE_THUMBNAIL_HEIGHT 63 -+#define GS_IMAGE_THUMBNAIL_WIDTH 112 -+ - GtkWidget *gs_screenshot_image_new (SoupSession *session); - - AsScreenshot *gs_screenshot_image_get_screenshot (GsScreenshotImage *ssimg); -diff --git a/subprojects/appstream.wrap b/subprojects/appstream.wrap -index 6f0beb0cbc..5763a32c64 100644 ---- a/subprojects/appstream.wrap -+++ b/subprojects/appstream.wrap -@@ -1,5 +1,5 @@ - [wrap-git] - directory = appstream - url = https://github.com/ximion/appstream.git --revision = v0.14.1 -+revision = v0.16.3 - depth = 1 -diff --git a/lib/gs-appstream.c b/lib/gs-appstream.c -index 6504d6f25..4fd7f5334 100644 ---- a/lib/gs-appstream.c -+++ b/lib/gs-appstream.c -@@ -587,8 +587,6 @@ gs_appstream_refine_add_provides (GsApp *app, XbNode *component, GError **error) - kind = AS_PROVIDED_KIND_FIRMWARE_RUNTIME; - else if (g_strcmp0 (fw_type, "flashed") == 0) - kind = AS_PROVIDED_KIND_FIRMWARE_FLASHED; -- } else if (g_strcmp0 (element_name, "python2") == 0) { -- kind = AS_PROVIDED_KIND_PYTHON_2; - } else if (g_strcmp0 (element_name, "python3") == 0) { - kind = AS_PROVIDED_KIND_PYTHON; - } else if (g_strcmp0 (element_name, "dbus") == 0) { --- -GitLab - diff --git a/gnome-software.spec b/gnome-software.spec index 40678e5..3569a72 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -23,16 +23,13 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 45.2 +Version: 46~alpha Release: 1%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later URL: https://wiki.gnome.org/Apps/Software -Source0: https://download.gnome.org/sources/gnome-software/45/%{name}-%{tarball_version}.tar.xz - -# https://gitlab.gnome.org/GNOME/gnome-software/-/merge_requests/1810 -Patch: 0001-port-to-appstream1.patch +Source0: https://download.gnome.org/sources/gnome-software/46/%{name}-%{tarball_version}.tar.xz # ostree and flatpak not on i686 for RHEL 10 # https://github.com/containers/composefs/pull/229#issuecomment-1838735764 @@ -255,6 +252,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Jan 05 2024 Milan Crha - 46~alpha-1 +- Update to 46.alpha + * Fri Dec 01 2023 Milan Crha - 45.2-1 - Update to 45.2 diff --git a/sources b/sources index fe4c93b..50ca12a 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-45.2.tar.xz) = ea271146683d199b27ffaaab98a13c25f8f794da3c6cc6b0daeb37f3f4c92d8644926dc592d309ea32dcb131d33e6c77d1c6fa36ac10cf6b23cd7adc73e898cb +SHA512 (gnome-software-46.alpha.tar.xz) = 373ef9b103b7963dad1824888261958d60d11f9f55d1fc07634de5df6a0436388334fec1a018d83b4024e61c18a2c95b9dc942c3a592cbb9fe1274f5950b4104 From 2152c30083596475de72116b36d0dc48a5f1e81a Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 19 Jan 2024 23:07:23 +0000 Subject: [PATCH 057/116] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild --- gnome-software.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gnome-software.spec b/gnome-software.spec index 3569a72..be4564a 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -24,7 +24,7 @@ Name: gnome-software Version: 46~alpha -Release: 1%{?dist} +Release: 2%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -252,6 +252,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Jan 19 2024 Fedora Release Engineering - 46~alpha-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + * Fri Jan 05 2024 Milan Crha - 46~alpha-1 - Update to 46.alpha From 881bbc7f12f9e70d401720c2c072f1efc136a1f6 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 24 Jan 2024 15:41:25 +0000 Subject: [PATCH 058/116] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild --- gnome-software.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gnome-software.spec b/gnome-software.spec index be4564a..4e4adac 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -24,7 +24,7 @@ Name: gnome-software Version: 46~alpha -Release: 2%{?dist} +Release: 3%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -252,6 +252,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Wed Jan 24 2024 Fedora Release Engineering - 46~alpha-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + * Fri Jan 19 2024 Fedora Release Engineering - 46~alpha-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild From 0b4b0060f8e8ce015ecef7d3cd4e1ae2918cf27e Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 26 Jan 2024 11:02:25 +0100 Subject: [PATCH 059/116] Resolves: #2260294 (Split fedora-langpacks plugin into a subpackage) --- gnome-software.spec | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index 4e4adac..e6d4798 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -24,7 +24,7 @@ Name: gnome-software Version: 46~alpha -Release: 3%{?dist} +Release: 4%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -90,6 +90,7 @@ Requires: librsvg2%{?_isa} Requires: libxmlb%{?_isa} >= %{libxmlb_version} Recommends: PackageKit%{?_isa} >= %{packagekit_version} +Recommends: %{name}-fedora-langpacks Obsoletes: gnome-software-snap < 3.33.1 Obsoletes: gnome-software-editor < 3.35.1 @@ -106,6 +107,14 @@ Requires: %{name}%{?_isa} = %{version}-%{release} These development files are for building gnome-software plugins outside the source tree. Most users do not need this subpackage installed. +%package fedora-langpacks +Summary: Contains fedora-langpacks plugin +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description fedora-langpacks +The fedora-langpacks plugin ensures langpacks packages are installed +for the current locale. + %if %{with rpmostree} %package rpm-ostree Summary: rpm-ostree backend for gnome-software @@ -205,7 +214,6 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %if %{with webapps} %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_epiphany.so %endif -%{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_fedora-langpacks.so %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_fedora-pkgdb-collections.so %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_flatpak.so %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_fwupd.so @@ -237,6 +245,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_libexecdir}/gnome-software-cmd %{_libexecdir}/gnome-software-restarter +%files fedora-langpacks +%{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_fedora-langpacks.so + %if %{with rpmostree} %files rpm-ostree %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_rpm-ostree.so @@ -252,6 +263,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Jan 26 2024 Milan Crha - 46~alpha-4 +- Resolves: #2260294 (Split fedora-langpacks plugin into a subpackage) + * Wed Jan 24 2024 Fedora Release Engineering - 46~alpha-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild From e1a74cef52eda1601fdc90c6cd1d8f0b6c130c3a Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 9 Feb 2024 10:05:49 +0100 Subject: [PATCH 060/116] Update to 46.beta --- gnome-software.spec | 8 ++++++-- sources | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index e6d4798..e0755b4 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -23,8 +23,8 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 46~alpha -Release: 4%{?dist} +Version: 46~beta +Release: 1%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -197,6 +197,7 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/applications/gnome-software-local-file-fwupd.desktop %{_datadir}/applications/gnome-software-local-file-packagekit.desktop %{_datadir}/applications/org.gnome.Software.desktop +%{_datadir}/bash-completion/completions/gnome-software %{_mandir}/man1/gnome-software.1* %{_datadir}/icons/hicolor/*/apps/org.gnome.Software.svg %{_datadir}/icons/hicolor/symbolic/apps/org.gnome.Software-symbolic.svg @@ -263,6 +264,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Feb 09 2024 Milan Crha - 46~beta-1 +- Update to 46.beta + * Fri Jan 26 2024 Milan Crha - 46~alpha-4 - Resolves: #2260294 (Split fedora-langpacks plugin into a subpackage) diff --git a/sources b/sources index 50ca12a..6816df2 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-46.alpha.tar.xz) = 373ef9b103b7963dad1824888261958d60d11f9f55d1fc07634de5df6a0436388334fec1a018d83b4024e61c18a2c95b9dc942c3a592cbb9fe1274f5950b4104 +SHA512 (gnome-software-46.beta.tar.xz) = 932f6fe10ae9baf233a93abb62ad92a8fced0ce39d77c8ab1ecb3450699fc7491eaa4481968aa585a9dab011e1796a71f5b356eee0e2004ca0f8ace74aae473a From 9452c386433141e066efc9baa00b7b6d1cd9aefe Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 1 Mar 2024 11:27:02 +0100 Subject: [PATCH 061/116] Update to 46.rc --- gnome-software.spec | 5 ++++- sources | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index e0755b4..8761fb8 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -23,7 +23,7 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 46~beta +Version: 46~rc Release: 1%{?dist} Summary: A software center for GNOME @@ -264,6 +264,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Mar 01 2024 Milan Crha - 46~rc-1 +- Update to 46.rc + * Fri Feb 09 2024 Milan Crha - 46~beta-1 - Update to 46.beta diff --git a/sources b/sources index 6816df2..9471511 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-46.beta.tar.xz) = 932f6fe10ae9baf233a93abb62ad92a8fced0ce39d77c8ab1ecb3450699fc7491eaa4481968aa585a9dab011e1796a71f5b356eee0e2004ca0f8ace74aae473a +SHA512 (gnome-software-46.rc.tar.xz) = dc7122c9675722269977d7e69e3c435306be1059e4dbc7303eaa0bda6916481a8a6ca90bbe6eb01f49269045b5a472bfd56c2774ca8281eae3f38e32329d6fb3 From 9848abdaf8f1fbba33a80a2abaf92397ea66ecce Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 18 Mar 2024 10:03:43 +0100 Subject: [PATCH 062/116] Update to 46.0 --- gnome-software.spec | 5 ++++- sources | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index 8761fb8..6cd66e1 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -23,7 +23,7 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 46~rc +Version: 46.0 Release: 1%{?dist} Summary: A software center for GNOME @@ -264,6 +264,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Mon Mar 18 2024 Milan Crha - 46.0-1 +- Update to 46.0 + * Fri Mar 01 2024 Milan Crha - 46~rc-1 - Update to 46.rc diff --git a/sources b/sources index 9471511..2d68da6 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-46.rc.tar.xz) = dc7122c9675722269977d7e69e3c435306be1059e4dbc7303eaa0bda6916481a8a6ca90bbe6eb01f49269045b5a472bfd56c2774ca8281eae3f38e32329d6fb3 +SHA512 (gnome-software-46.0.tar.xz) = d221db960bb0a04c8976d20626eb1154a80b12f64f5b4af09ca837814078797e265ab978ae5cad03e3b592f0b9fc41c837d741ef288590b4992fbb4a0fab1d55 From ea6727cab2990dc27d0a9b2e950ee1de0dc7e15c Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Wed, 27 Mar 2024 09:39:17 +0100 Subject: [PATCH 063/116] Update URL to point to the new app page --- gnome-software.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gnome-software.spec b/gnome-software.spec index 6cd66e1..dad1e93 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -28,7 +28,7 @@ Release: 1%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later -URL: https://wiki.gnome.org/Apps/Software +URL: https://apps.gnome.org/Software Source0: https://download.gnome.org/sources/gnome-software/46/%{name}-%{tarball_version}.tar.xz # ostree and flatpak not on i686 for RHEL 10 From e68edf805818db2994c7be2db6aea96cab7bc8f5 Mon Sep 17 00:00:00 2001 From: Adam Williamson Date: Fri, 12 Apr 2024 10:19:53 -0700 Subject: [PATCH 064/116] Backport MR #1949 to fix upgrading --- ...lections-Incorrect-state-set-on-the-.patch | 62 +++++++++++++++++++ gnome-software.spec | 10 ++- 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 0001-fedora-pkgdb-collections-Incorrect-state-set-on-the-.patch diff --git a/0001-fedora-pkgdb-collections-Incorrect-state-set-on-the-.patch b/0001-fedora-pkgdb-collections-Incorrect-state-set-on-the-.patch new file mode 100644 index 0000000..88e0522 --- /dev/null +++ b/0001-fedora-pkgdb-collections-Incorrect-state-set-on-the-.patch @@ -0,0 +1,62 @@ +From cd0743032edccfad47d2253b87daebd01b0ee2e1 Mon Sep 17 00:00:00 2001 +From: Milan Crha +Date: Fri, 12 Apr 2024 07:57:14 +0200 +Subject: [PATCH] fedora-pkgdb-collections: Incorrect state set on the upgrade + app + +The "updatable" state means "downloaded locally, ready to be installed", which +is not the case here. The upgrade is either "available" (to be downloaded), or +"unavailable" (end of life). The other states are determined by the other plugins. + +Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/2514 +--- + .../gs-plugin-fedora-pkgdb-collections.c | 23 +++---------------- + 1 file changed, 3 insertions(+), 20 deletions(-) + +diff --git a/plugins/fedora-pkgdb-collections/gs-plugin-fedora-pkgdb-collections.c b/plugins/fedora-pkgdb-collections/gs-plugin-fedora-pkgdb-collections.c +index 2983defaa..15d3c385a 100644 +--- a/plugins/fedora-pkgdb-collections/gs-plugin-fedora-pkgdb-collections.c ++++ b/plugins/fedora-pkgdb-collections/gs-plugin-fedora-pkgdb-collections.c +@@ -393,18 +393,10 @@ _create_upgrade_from_info (GsPluginFedoraPkgdbCollections *self, + + /* create */ + app = gs_app_new (app_id); +- switch (item->status) { +- case PKGDB_ITEM_STATUS_ACTIVE: +- case PKGDB_ITEM_STATUS_DEVEL: +- gs_app_set_state (app, GS_APP_STATE_UPDATABLE); +- break; +- case PKGDB_ITEM_STATUS_EOL: ++ if (item->status == PKGDB_ITEM_STATUS_EOL) + gs_app_set_state (app, GS_APP_STATE_UNAVAILABLE); +- break; +- default: ++ else + gs_app_set_state (app, GS_APP_STATE_AVAILABLE); +- break; +- } + gs_app_set_kind (app, AS_COMPONENT_KIND_OPERATING_SYSTEM); + gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE); + gs_app_set_name (app, GS_APP_QUALITY_LOWEST, item->name); +@@ -729,17 +721,8 @@ refine_app (GsPluginFedoraPkgdbCollections *self, + return TRUE; + + /* fix the state */ +- switch (item->status) { +- case PKGDB_ITEM_STATUS_ACTIVE: +- case PKGDB_ITEM_STATUS_DEVEL: +- gs_app_set_state (app, GS_APP_STATE_UPDATABLE); +- break; +- case PKGDB_ITEM_STATUS_EOL: ++ if (item->status == PKGDB_ITEM_STATUS_EOL) + gs_app_set_state (app, GS_APP_STATE_UNAVAILABLE); +- break; +- default: +- break; +- } + + return TRUE; + } +-- +2.44.0 + diff --git a/gnome-software.spec b/gnome-software.spec index dad1e93..eeb1db9 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -24,13 +24,18 @@ Name: gnome-software Version: 46.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later URL: https://apps.gnome.org/Software Source0: https://download.gnome.org/sources/gnome-software/46/%{name}-%{tarball_version}.tar.xz +# https://gitlab.gnome.org/GNOME/gnome-software/-/issues/2514 +# https://gitlab.gnome.org/GNOME/gnome-software/-/merge_requests/1949 +# Fix incorrect upgrade state (breaks upgrade process) +Patch: 0001-fedora-pkgdb-collections-Incorrect-state-set-on-the-.patch + # ostree and flatpak not on i686 for RHEL 10 # https://github.com/containers/composefs/pull/229#issuecomment-1838735764 %if 0%{?rhel} >= 10 @@ -264,6 +269,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Apr 12 2024 Adam Williamson - 46.0-2 +- Backport MR #1949 to fix upgrading + * Mon Mar 18 2024 Milan Crha - 46.0-1 - Update to 46.0 From 869715beb209ecb3b0bd011ee889c8db9939365a Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Thu, 25 Apr 2024 10:28:27 +0200 Subject: [PATCH 065/116] Update to 46.1 --- ...lections-Incorrect-state-set-on-the-.patch | 62 ------------------- gnome-software.spec | 12 ++-- sources | 2 +- 3 files changed, 6 insertions(+), 70 deletions(-) delete mode 100644 0001-fedora-pkgdb-collections-Incorrect-state-set-on-the-.patch diff --git a/0001-fedora-pkgdb-collections-Incorrect-state-set-on-the-.patch b/0001-fedora-pkgdb-collections-Incorrect-state-set-on-the-.patch deleted file mode 100644 index 88e0522..0000000 --- a/0001-fedora-pkgdb-collections-Incorrect-state-set-on-the-.patch +++ /dev/null @@ -1,62 +0,0 @@ -From cd0743032edccfad47d2253b87daebd01b0ee2e1 Mon Sep 17 00:00:00 2001 -From: Milan Crha -Date: Fri, 12 Apr 2024 07:57:14 +0200 -Subject: [PATCH] fedora-pkgdb-collections: Incorrect state set on the upgrade - app - -The "updatable" state means "downloaded locally, ready to be installed", which -is not the case here. The upgrade is either "available" (to be downloaded), or -"unavailable" (end of life). The other states are determined by the other plugins. - -Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/2514 ---- - .../gs-plugin-fedora-pkgdb-collections.c | 23 +++---------------- - 1 file changed, 3 insertions(+), 20 deletions(-) - -diff --git a/plugins/fedora-pkgdb-collections/gs-plugin-fedora-pkgdb-collections.c b/plugins/fedora-pkgdb-collections/gs-plugin-fedora-pkgdb-collections.c -index 2983defaa..15d3c385a 100644 ---- a/plugins/fedora-pkgdb-collections/gs-plugin-fedora-pkgdb-collections.c -+++ b/plugins/fedora-pkgdb-collections/gs-plugin-fedora-pkgdb-collections.c -@@ -393,18 +393,10 @@ _create_upgrade_from_info (GsPluginFedoraPkgdbCollections *self, - - /* create */ - app = gs_app_new (app_id); -- switch (item->status) { -- case PKGDB_ITEM_STATUS_ACTIVE: -- case PKGDB_ITEM_STATUS_DEVEL: -- gs_app_set_state (app, GS_APP_STATE_UPDATABLE); -- break; -- case PKGDB_ITEM_STATUS_EOL: -+ if (item->status == PKGDB_ITEM_STATUS_EOL) - gs_app_set_state (app, GS_APP_STATE_UNAVAILABLE); -- break; -- default: -+ else - gs_app_set_state (app, GS_APP_STATE_AVAILABLE); -- break; -- } - gs_app_set_kind (app, AS_COMPONENT_KIND_OPERATING_SYSTEM); - gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE); - gs_app_set_name (app, GS_APP_QUALITY_LOWEST, item->name); -@@ -729,17 +721,8 @@ refine_app (GsPluginFedoraPkgdbCollections *self, - return TRUE; - - /* fix the state */ -- switch (item->status) { -- case PKGDB_ITEM_STATUS_ACTIVE: -- case PKGDB_ITEM_STATUS_DEVEL: -- gs_app_set_state (app, GS_APP_STATE_UPDATABLE); -- break; -- case PKGDB_ITEM_STATUS_EOL: -+ if (item->status == PKGDB_ITEM_STATUS_EOL) - gs_app_set_state (app, GS_APP_STATE_UNAVAILABLE); -- break; -- default: -- break; -- } - - return TRUE; - } --- -2.44.0 - diff --git a/gnome-software.spec b/gnome-software.spec index eeb1db9..e7b85be 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -23,19 +23,14 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 46.0 -Release: 2%{?dist} +Version: 46.1 +Release: 1%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later URL: https://apps.gnome.org/Software Source0: https://download.gnome.org/sources/gnome-software/46/%{name}-%{tarball_version}.tar.xz -# https://gitlab.gnome.org/GNOME/gnome-software/-/issues/2514 -# https://gitlab.gnome.org/GNOME/gnome-software/-/merge_requests/1949 -# Fix incorrect upgrade state (breaks upgrade process) -Patch: 0001-fedora-pkgdb-collections-Incorrect-state-set-on-the-.patch - # ostree and flatpak not on i686 for RHEL 10 # https://github.com/containers/composefs/pull/229#issuecomment-1838735764 %if 0%{?rhel} >= 10 @@ -269,6 +264,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Thu Apr 25 2024 Milan Crha - 46.1-1 +- Update to 46.1 + * Fri Apr 12 2024 Adam Williamson - 46.0-2 - Backport MR #1949 to fix upgrading diff --git a/sources b/sources index 2d68da6..c841edb 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-46.0.tar.xz) = d221db960bb0a04c8976d20626eb1154a80b12f64f5b4af09ca837814078797e265ab978ae5cad03e3b592f0b9fc41c837d741ef288590b4992fbb4a0fab1d55 +SHA512 (gnome-software-46.1.tar.xz) = 7f851faa706c347a92a10b2a70cef7310cf27fec47bb3d9fc0c832041c9d612ec1fdd029df0a60368eda447047ff9f5afffaacd77669ecefdd4d04827de539ca From 4e0c8cfc83d96fc0eed22104de63ed665ee44b04 Mon Sep 17 00:00:00 2001 From: Hristo Marinov Date: Wed, 8 May 2024 19:01:10 +0300 Subject: [PATCH 066/116] OSTree not on i686 for Fedora --- gnome-software.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index e7b85be..c092a4b 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -31,9 +31,9 @@ License: GPL-2.0-or-later URL: https://apps.gnome.org/Software Source0: https://download.gnome.org/sources/gnome-software/46/%{name}-%{tarball_version}.tar.xz -# ostree and flatpak not on i686 for RHEL 10 +# ostree and flatpak not on i686 for Fedora and RHEL 10 # https://github.com/containers/composefs/pull/229#issuecomment-1838735764 -%if 0%{?rhel} >= 10 +%if 0%{?fedora} || 0%{?rhel} >= 10 ExcludeArch: %{ix86} %endif From 4f2a027a25187f81fd7d7437673ab7d540235dac Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 24 May 2024 08:30:36 +0200 Subject: [PATCH 067/116] Update to 46.2 --- gnome-software.spec | 5 ++++- sources | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index c092a4b..6b65ab7 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -23,7 +23,7 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 46.1 +Version: 46.2 Release: 1%{?dist} Summary: A software center for GNOME @@ -264,6 +264,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri May 24 2024 Milan Crha - 46.2-1 +- Update to 46.2 + * Thu Apr 25 2024 Milan Crha - 46.1-1 - Update to 46.1 diff --git a/sources b/sources index c841edb..bc7fdbd 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-46.1.tar.xz) = 7f851faa706c347a92a10b2a70cef7310cf27fec47bb3d9fc0c832041c9d612ec1fdd029df0a60368eda447047ff9f5afffaacd77669ecefdd4d04827de539ca +SHA512 (gnome-software-46.2.tar.xz) = 4e7cccc20001ccee114508bb50e2a25968ee6fea64fb545e1174ff435cd368b2d7c928b6a182874af8e9f0c99f9f506e75c5ac9bf61b35ba0a897368ae0abc3c From 2f2f30d236e3c1906ad2e6430051e978656a6623 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 3 Jun 2024 10:27:39 +0200 Subject: [PATCH 068/116] Build fedora-langpacks subpackage only in Fedora The subpackage contains a plugin, which disables itself when the system is not Fedora, thus is does not need to be distributed elsewhere. --- gnome-software.spec | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/gnome-software.spec b/gnome-software.spec index 6b65ab7..8c9715d 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -14,6 +14,8 @@ %bcond malcontent %[!0%{?rhel}] # Disable rpm-ostree support for RHEL builds %bcond rpmostree %[!0%{?rhel}] +# Disable fedora-langpacks subpackage for RHEL builds +%bcond langpacks %[!0%{?rhel}] # this is not a library version %define gs_plugin_version 20 @@ -90,7 +92,9 @@ Requires: librsvg2%{?_isa} Requires: libxmlb%{?_isa} >= %{libxmlb_version} Recommends: PackageKit%{?_isa} >= %{packagekit_version} +%if %{with langpacks} Recommends: %{name}-fedora-langpacks +%endif Obsoletes: gnome-software-snap < 3.33.1 Obsoletes: gnome-software-editor < 3.35.1 @@ -107,6 +111,7 @@ Requires: %{name}%{?_isa} = %{version}-%{release} These development files are for building gnome-software plugins outside the source tree. Most users do not need this subpackage installed. +%if %{with langpacks} %package fedora-langpacks Summary: Contains fedora-langpacks plugin Requires: %{name}%{?_isa} = %{version}-%{release} @@ -114,6 +119,7 @@ Requires: %{name}%{?_isa} = %{version}-%{release} %description fedora-langpacks The fedora-langpacks plugin ensures langpacks packages are installed for the current locale. +%endif %if %{with rpmostree} %package rpm-ostree @@ -168,6 +174,10 @@ This package includes the rpm-ostree backend. # remove unneeded dpkg plugin rm %{buildroot}%{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_dpkg.so +%if !%{with langpacks} +rm %{buildroot}%{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_fedora-langpacks.so +%endif + # make the software center load faster desktop-file-edit %{buildroot}%{_datadir}/applications/org.gnome.Software.desktop \ --set-key=X-AppInstall-Package --set-value=%{name} @@ -246,8 +256,10 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_libexecdir}/gnome-software-cmd %{_libexecdir}/gnome-software-restarter +%if %{with langpacks} %files fedora-langpacks %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_fedora-langpacks.so +%endif %if %{with rpmostree} %files rpm-ostree From 7cca703b2070afbb3f492753c361dd8d04b5529d Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 28 Jun 2024 12:12:25 +0200 Subject: [PATCH 069/116] Update to 47.alpha --- gnome-software.spec | 26 +++++++++++++++++++------- sources | 2 +- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index 8c9715d..9360808 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -1,10 +1,10 @@ -%global appstream_version 1.0.0~ +%global appstream_version 0.14.0 %global flatpak_version 1.9.1 %global fwupd_version 1.5.6 %global glib2_version 2.70.0 -%global gtk4_version 4.10.0 +%global gtk4_version 4.14.0 %global json_glib_version 1.6.0 -%global libadwaita_version 1.3.alpha +%global libadwaita_version 1.6~alpha %global libxmlb_version 0.1.7 %global packagekit_version 1.2.5 @@ -18,20 +18,20 @@ %bcond langpacks %[!0%{?rhel}] # this is not a library version -%define gs_plugin_version 20 +%define gs_plugin_version 21 %global tarball_version %%(echo %{version} | tr '~' '.') %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 46.2 +Version: 47~alpha Release: 1%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later URL: https://apps.gnome.org/Software -Source0: https://download.gnome.org/sources/gnome-software/46/%{name}-%{tarball_version}.tar.xz +Source0: https://download.gnome.org/sources/gnome-software/47/%{name}-%{tarball_version}.tar.xz # ostree and flatpak not on i686 for Fedora and RHEL 10 # https://github.com/containers/composefs/pull/229#issuecomment-1838735764 @@ -44,6 +44,7 @@ BuildRequires: desktop-file-utils BuildRequires: gcc BuildRequires: gettext BuildRequires: gtk-doc +BuildRequires: itstool BuildRequires: libxslt BuildRequires: meson BuildRequires: pkgconfig(appstream) >= %{appstream_version} @@ -211,7 +212,15 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_mandir}/man1/gnome-software.1* %{_datadir}/icons/hicolor/*/apps/org.gnome.Software.svg %{_datadir}/icons/hicolor/symbolic/apps/org.gnome.Software-symbolic.svg -%{_datadir}/icons/hicolor/scalable/actions/app-remove-symbolic.svg +%{_datadir}/icons/hicolor/scalable/categories/system-component-addon.svg +%{_datadir}/icons/hicolor/scalable/categories/system-component-application.svg +%{_datadir}/icons/hicolor/scalable/categories/system-component-codecs.svg +%{_datadir}/icons/hicolor/scalable/categories/system-component-driver.svg +%{_datadir}/icons/hicolor/scalable/categories/system-component-firmware.svg +%{_datadir}/icons/hicolor/scalable/categories/system-component-input-sources.svg +%{_datadir}/icons/hicolor/scalable/categories/system-component-language.svg +%{_datadir}/icons/hicolor/scalable/categories/system-component-os-updates.svg +%{_datadir}/icons/hicolor/scalable/categories/system-component-runtime.svg %{_datadir}/metainfo/org.gnome.Software.metainfo.xml %if %{with webapps} %{_datadir}/metainfo/org.gnome.Software.Plugin.Epiphany.metainfo.xml @@ -276,6 +285,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Jun 28 2024 Milan Crha - 47~alpha-1 +- Update to 47.alpha + * Fri May 24 2024 Milan Crha - 46.2-1 - Update to 46.2 diff --git a/sources b/sources index bc7fdbd..544051e 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-46.2.tar.xz) = 4e7cccc20001ccee114508bb50e2a25968ee6fea64fb545e1174ff435cd368b2d7c928b6a182874af8e9f0c99f9f506e75c5ac9bf61b35ba0a897368ae0abc3c +SHA512 (gnome-software-47.alpha.tar.xz) = e1ec552a52d93c128918fd397a448ab34e182464543eb1bf694c54950c755a28157466f0f9b1482b1036f65a94bc148e6a0852d3232d5e28bf0eb6e9ae82b1c8 From 9d3ce3773bcb96faa58bffd4d45f08359f0b9948 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 18 Jul 2024 03:12:21 +0000 Subject: [PATCH 070/116] Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild --- gnome-software.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gnome-software.spec b/gnome-software.spec index 9360808..3a4d753 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -26,7 +26,7 @@ Name: gnome-software Version: 47~alpha -Release: 1%{?dist} +Release: 2%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -285,6 +285,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Thu Jul 18 2024 Fedora Release Engineering - 47~alpha-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + * Fri Jun 28 2024 Milan Crha - 47~alpha-1 - Update to 47.alpha From 5897c8b5747e95ea91b2fa9edbcd118dc3adf562 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 2 Aug 2024 09:34:24 +0200 Subject: [PATCH 071/116] Update to 47.beta --- gnome-software.spec | 19 +++++-------------- sources | 2 +- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index 3a4d753..8389288 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -14,8 +14,6 @@ %bcond malcontent %[!0%{?rhel}] # Disable rpm-ostree support for RHEL builds %bcond rpmostree %[!0%{?rhel}] -# Disable fedora-langpacks subpackage for RHEL builds -%bcond langpacks %[!0%{?rhel}] # this is not a library version %define gs_plugin_version 21 @@ -25,8 +23,8 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 47~alpha -Release: 2%{?dist} +Version: 47~beta +Release: 1%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -93,9 +91,7 @@ Requires: librsvg2%{?_isa} Requires: libxmlb%{?_isa} >= %{libxmlb_version} Recommends: PackageKit%{?_isa} >= %{packagekit_version} -%if %{with langpacks} Recommends: %{name}-fedora-langpacks -%endif Obsoletes: gnome-software-snap < 3.33.1 Obsoletes: gnome-software-editor < 3.35.1 @@ -112,7 +108,6 @@ Requires: %{name}%{?_isa} = %{version}-%{release} These development files are for building gnome-software plugins outside the source tree. Most users do not need this subpackage installed. -%if %{with langpacks} %package fedora-langpacks Summary: Contains fedora-langpacks plugin Requires: %{name}%{?_isa} = %{version}-%{release} @@ -120,7 +115,6 @@ Requires: %{name}%{?_isa} = %{version}-%{release} %description fedora-langpacks The fedora-langpacks plugin ensures langpacks packages are installed for the current locale. -%endif %if %{with rpmostree} %package rpm-ostree @@ -175,10 +169,6 @@ This package includes the rpm-ostree backend. # remove unneeded dpkg plugin rm %{buildroot}%{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_dpkg.so -%if !%{with langpacks} -rm %{buildroot}%{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_fedora-langpacks.so -%endif - # make the software center load faster desktop-file-edit %{buildroot}%{_datadir}/applications/org.gnome.Software.desktop \ --set-key=X-AppInstall-Package --set-value=%{name} @@ -265,10 +255,8 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_libexecdir}/gnome-software-cmd %{_libexecdir}/gnome-software-restarter -%if %{with langpacks} %files fedora-langpacks %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_fedora-langpacks.so -%endif %if %{with rpmostree} %files rpm-ostree @@ -285,6 +273,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Aug 02 2024 Milan Crha - 47~beta-1 +- Update to 47.beta + * Thu Jul 18 2024 Fedora Release Engineering - 47~alpha-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild diff --git a/sources b/sources index 544051e..becf8db 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-47.alpha.tar.xz) = e1ec552a52d93c128918fd397a448ab34e182464543eb1bf694c54950c755a28157466f0f9b1482b1036f65a94bc148e6a0852d3232d5e28bf0eb6e9ae82b1c8 +SHA512 (gnome-software-47.beta.tar.xz) = e9e0daa489ac302d82901f689c553a67725b18c200d4d5c4b9d9bad648db47c2d51067bf3b2200258a73a8ce5e5dfb9bc05d4c389dd5353735842a0f1c82f964 From 1016f497ea8767f1963a833695fd9705ea4afce9 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 2 Aug 2024 09:40:32 +0200 Subject: [PATCH 072/116] Build with DKMS/akmods plugin in Fedora --- gnome-software.spec | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index 8389288..37f4d6c 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -14,6 +14,8 @@ %bcond malcontent %[!0%{?rhel}] # Disable rpm-ostree support for RHEL builds %bcond rpmostree %[!0%{?rhel}] +# Disable DKMS/akmods support for RHEL builds +%bcond dkms %[!0%{?rhel}] # this is not a library version %define gs_plugin_version 21 @@ -159,6 +161,11 @@ This package includes the rpm-ostree backend. -Dwebapps=false \ -Dhardcoded_foss_webapps=false \ -Dhardcoded_proprietary_webapps=false \ +%endif +%if %{with dkms} + -Ddkms=true \ +%else + -Ddkms=false \ %endif -Dtests=false %meson_build @@ -166,8 +173,9 @@ This package includes the rpm-ostree backend. %install %meson_install -# remove unneeded dpkg plugin +# remove unneeded dpkg and dummy plugins rm %{buildroot}%{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_dpkg.so +rm %{buildroot}%{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_dummy.so # make the software center load faster desktop-file-edit %{buildroot}%{_datadir}/applications/org.gnome.Software.desktop \ @@ -220,7 +228,6 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %dir %{_libdir}/gnome-software/plugins-%{gs_plugin_version} %{_libdir}/gnome-software/libgnomesoftware.so.%{gs_plugin_version} %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_appstream.so -%{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_dummy.so %if %{with webapps} %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_epiphany.so %endif @@ -255,6 +262,12 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_libexecdir}/gnome-software-cmd %{_libexecdir}/gnome-software-restarter +%if %{with dkms} +%{_datadir}/polkit-1/actions/org.gnome.software.dkms-helper.policy +%{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_dkms.so +%{_libexecdir}/gnome-software-dkms-helper +%endif + %files fedora-langpacks %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_fedora-langpacks.so @@ -275,6 +288,7 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %changelog * Fri Aug 02 2024 Milan Crha - 47~beta-1 - Update to 47.beta +- Build with DKMS/akmods plugin in Fedora * Thu Jul 18 2024 Fedora Release Engineering - 47~alpha-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild From 2c9dde7b621515f832d57866492a3dccbe67dc48 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 30 Aug 2024 11:32:32 +0200 Subject: [PATCH 073/116] Update to 47.rc --- gnome-software.spec | 5 ++++- sources | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index 37f4d6c..d9c30f5 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -25,7 +25,7 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 47~beta +Version: 47~rc Release: 1%{?dist} Summary: A software center for GNOME @@ -286,6 +286,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Aug 30 2024 Milan Crha - 47~rc-1 +- Update to 47.rc + * Fri Aug 02 2024 Milan Crha - 47~beta-1 - Update to 47.beta - Build with DKMS/akmods plugin in Fedora diff --git a/sources b/sources index becf8db..d9246ad 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-47.beta.tar.xz) = e9e0daa489ac302d82901f689c553a67725b18c200d4d5c4b9d9bad648db47c2d51067bf3b2200258a73a8ce5e5dfb9bc05d4c389dd5353735842a0f1c82f964 +SHA512 (gnome-software-47.rc.tar.xz) = 6e86d964ce634e1a19910227fce554ed45652f047977dbcefe5d2f564273b1d6ef00a4c7f4bd84103b176efe13daf4c1f01ab0049e1dc751a22b4ff4fae5110f From 399c9361bb329921a20ca40db893c12d5f16d911 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 13 Sep 2024 09:54:36 +0200 Subject: [PATCH 074/116] Update to 47.0 --- gnome-software.spec | 8 +++++--- sources | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index d9c30f5..16e66c7 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -25,7 +25,7 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 47~rc +Version: 47.0 Release: 1%{?dist} Summary: A software center for GNOME @@ -83,6 +83,7 @@ Requires: flatpak%{?_isa} >= %{flatpak_version} Requires: flatpak-libs%{?_isa} >= %{flatpak_version} Requires: fwupd%{?_isa} >= %{fwupd_version} Requires: glib2%{?_isa} >= %{glib2_version} +Requires: gnome-app-list # gnome-menus is needed for app folder .directory entries Requires: gnome-menus%{?_isa} Requires: gsettings-desktop-schemas%{?_isa} @@ -252,8 +253,6 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %if %{with webapps} %{_datadir}/swcatalog/xml/gnome-pwa-list-foss.xml %endif -%{_datadir}/swcatalog/xml/org.gnome.Software.Curated.xml -%{_datadir}/swcatalog/xml/org.gnome.Software.Featured.xml %{_datadir}/dbus-1/services/org.freedesktop.PackageKit.service %{_datadir}/dbus-1/services/org.gnome.Software.service %{_datadir}/gnome-shell/search-providers/org.gnome.Software-search-provider.ini @@ -286,6 +285,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Sep 13 2024 Milan Crha - 47.0-1 +- Update to 47.0 + * Fri Aug 30 2024 Milan Crha - 47~rc-1 - Update to 47.rc diff --git a/sources b/sources index d9246ad..ed97419 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-47.rc.tar.xz) = 6e86d964ce634e1a19910227fce554ed45652f047977dbcefe5d2f564273b1d6ef00a4c7f4bd84103b176efe13daf4c1f01ab0049e1dc751a22b4ff4fae5110f +SHA512 (gnome-software-47.0.tar.xz) = 0aac8e2f9803fbdef9e07c798d3171eb6267090fc1ffcbe1e4888e2499a50c28ec4a817ec82205f1eeb4e3220f11920ff045b817b692c8b1f8e5edbdbd82b6b9 From c60a0c56916812752505c72b9f11e4ea9629b2de Mon Sep 17 00:00:00 2001 From: Yaakov Selkowitz Date: Mon, 16 Sep 2024 23:06:52 -0400 Subject: [PATCH 075/116] Fix ELN build With gnome-app-list split out from gnome-software, only the webapps-related data is installed into swcatalog, and therefore those directories are not created when webapps are disabled (as in RHEL). While c10s does bundle a list file and therefore creates these directories, it is too early to know what this will look like for RHEL 11. --- gnome-software.spec | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gnome-software.spec b/gnome-software.spec index 16e66c7..89b3eb2 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -83,7 +83,9 @@ Requires: flatpak%{?_isa} >= %{flatpak_version} Requires: flatpak-libs%{?_isa} >= %{flatpak_version} Requires: fwupd%{?_isa} >= %{fwupd_version} Requires: glib2%{?_isa} >= %{glib2_version} +%if !0%{?rhel} Requires: gnome-app-list +%endif # gnome-menus is needed for app folder .directory entries Requires: gnome-menus%{?_isa} Requires: gsettings-desktop-schemas%{?_isa} @@ -248,9 +250,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_provenance.so %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_repos.so %{_sysconfdir}/xdg/autostart/org.gnome.Software.desktop +%if %{with webapps} %dir %{_datadir}/swcatalog %dir %{_datadir}/swcatalog/xml -%if %{with webapps} %{_datadir}/swcatalog/xml/gnome-pwa-list-foss.xml %endif %{_datadir}/dbus-1/services/org.freedesktop.PackageKit.service From 287e223c6ea7d1f6a23c930c5728f4492c869e00 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Thu, 19 Sep 2024 13:00:50 +0200 Subject: [PATCH 076/116] Resolves: #2312882 (dkms: Fix callback user data in a reload() function) --- ...lback-user-data-in-a-reload-function.patch | 30 +++++++++++++++++++ gnome-software.spec | 7 ++++- 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 0001-dkms-Fix-callback-user-data-in-a-reload-function.patch diff --git a/0001-dkms-Fix-callback-user-data-in-a-reload-function.patch b/0001-dkms-Fix-callback-user-data-in-a-reload-function.patch new file mode 100644 index 0000000..e44003e --- /dev/null +++ b/0001-dkms-Fix-callback-user-data-in-a-reload-function.patch @@ -0,0 +1,30 @@ +From 6b29a361465fb9b70c3a4cd66615e200bef65cd6 Mon Sep 17 00:00:00 2001 +Date: Wed, 18 Sep 2024 07:16:42 +0200 +Subject: [PATCH] dkms: Fix callback user data in a reload() function + +The gs_dkms_got_secureboot_state_cb() expects a GTask as its user data, +but the gs_plugin_dkms_reload() passed a GsPlugin instead. That could +cause a crash. + +Reported downstream at: +https://bugzilla.redhat.com/show_bug.cgi?id=2312882 +--- + plugins/dkms/gs-plugin-dkms.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/plugins/dkms/gs-plugin-dkms.c b/plugins/dkms/gs-plugin-dkms.c +index f7971334f..eb423e08d 100644 +--- a/plugins/dkms/gs-plugin-dkms.c ++++ b/plugins/dkms/gs-plugin-dkms.c +@@ -83,7 +83,7 @@ gs_plugin_dkms_reload (GsPlugin *plugin) + + /* mokutil was not installed probably; the reload can be called when some + app/package had been installed, thus re-try to check Secure Boot state */ +- gs_dkms_get_secureboot_state_async (NULL, gs_dkms_got_secureboot_state_cb, g_object_ref (plugin)); ++ gs_dkms_get_secureboot_state_async (NULL, gs_dkms_got_secureboot_state_cb, g_steal_pointer (&task)); + } + } + +-- +2.45.2 + diff --git a/gnome-software.spec b/gnome-software.spec index 89b3eb2..6493449 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -26,13 +26,15 @@ Name: gnome-software Version: 47.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later URL: https://apps.gnome.org/Software Source0: https://download.gnome.org/sources/gnome-software/47/%{name}-%{tarball_version}.tar.xz +Patch: 0001-dkms-Fix-callback-user-data-in-a-reload-function.patch + # ostree and flatpak not on i686 for Fedora and RHEL 10 # https://github.com/containers/composefs/pull/229#issuecomment-1838735764 %if 0%{?fedora} || 0%{?rhel} >= 10 @@ -287,6 +289,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Thu Sep 19 2024 Milan Crha - 47.0-2 +- Resolves: #2312882 (dkms: Fix callback user data in a reload() function) + * Fri Sep 13 2024 Milan Crha - 47.0-1 - Update to 47.0 From 8459c63d07257e0d29400db904cb772033d4026b Mon Sep 17 00:00:00 2001 From: Richard Hughes Date: Fri, 4 Oct 2024 16:47:40 +0100 Subject: [PATCH 077/116] Rebuild against libfwupd.so.3 --- ...not-use-API-removed-from-fwupd-2.0.x.patch | 45 +++++++++++++++++++ gnome-software.spec | 6 ++- 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 0001-fwupd-Do-not-use-API-removed-from-fwupd-2.0.x.patch diff --git a/0001-fwupd-Do-not-use-API-removed-from-fwupd-2.0.x.patch b/0001-fwupd-Do-not-use-API-removed-from-fwupd-2.0.x.patch new file mode 100644 index 0000000..78bd0b9 --- /dev/null +++ b/0001-fwupd-Do-not-use-API-removed-from-fwupd-2.0.x.patch @@ -0,0 +1,45 @@ +From bdfe5c691a1c3302cf61da0781b290c67f88ba6b Mon Sep 17 00:00:00 2001 +From: Richard Hughes +Date: Tue, 1 Oct 2024 12:24:09 +0100 +Subject: [PATCH 14/14] fwupd: Do not use API removed from fwupd 2.0.x + +All the systemd-offline logic was unused, and so removed. +--- + plugins/fwupd/gs-fwupd-app.c | 5 ----- + plugins/fwupd/gs-plugin-fwupd.c | 4 ---- + 2 files changed, 9 deletions(-) + +diff --git a/plugins/fwupd/gs-fwupd-app.c b/plugins/fwupd/gs-fwupd-app.c +index bad97420a..e4376b265 100644 +--- a/plugins/fwupd/gs-fwupd-app.c ++++ b/plugins/fwupd/gs-fwupd-app.c +@@ -117,11 +117,6 @@ gs_fwupd_app_set_from_device (GsApp *app, + ) + gs_app_set_state (app, GS_APP_STATE_UPDATABLE_LIVE); + +- /* only can be applied in systemd-offline */ +- if (fwupd_device_has_flag (dev, FWUPD_DEVICE_FLAG_ONLY_OFFLINE)) +- gs_app_set_metadata (app, "fwupd::OnlyOffline", ""); +- +- + /* reboot required to apply update */ + if (fwupd_device_has_flag (dev, FWUPD_DEVICE_FLAG_NEEDS_REBOOT)) + gs_app_add_quirk (app, GS_APP_QUIRK_NEEDS_REBOOT); +diff --git a/plugins/fwupd/gs-plugin-fwupd.c b/plugins/fwupd/gs-plugin-fwupd.c +index fd6049055..8e3d8ab2c 100644 +--- a/plugins/fwupd/gs-plugin-fwupd.c ++++ b/plugins/fwupd/gs-plugin-fwupd.c +@@ -1430,10 +1430,6 @@ gs_plugin_fwupd_install_async (GsPluginFwupd *self, + * https://github.com/fwupd/fwupd/issues/5522. */ + g_set_object (&self->app_current, app); + +- /* only offline supported */ +- if (gs_app_get_metadata_item (app, "fwupd::OnlyOffline") != NULL) +- install_flags |= FWUPD_INSTALL_FLAG_OFFLINE; +- + gs_app_set_state (app, GS_APP_STATE_INSTALLING); + + fwupd_client_install_async (self->client, data->device_id, +-- +2.46.2 + diff --git a/gnome-software.spec b/gnome-software.spec index 6493449..06e77c9 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -26,7 +26,7 @@ Name: gnome-software Version: 47.0 -Release: 2%{?dist} +Release: 3%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -34,6 +34,7 @@ URL: https://apps.gnome.org/Software Source0: https://download.gnome.org/sources/gnome-software/47/%{name}-%{tarball_version}.tar.xz Patch: 0001-dkms-Fix-callback-user-data-in-a-reload-function.patch +Patch: 0001-fwupd-Do-not-use-API-removed-from-fwupd-2.0.x.patch # ostree and flatpak not on i686 for Fedora and RHEL 10 # https://github.com/containers/composefs/pull/229#issuecomment-1838735764 @@ -289,6 +290,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Oct 04 2024 Richard Hughes - 47.0-3 +- Rebuild against fwupd 2.0.0 + * Thu Sep 19 2024 Milan Crha - 47.0-2 - Resolves: #2312882 (dkms: Fix callback user data in a reload() function) From 8bf3c4e72093b33e50e2f733699ae1708675b1a2 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Thu, 10 Oct 2024 14:58:22 +0200 Subject: [PATCH 078/116] Update to 47.1 --- ...lback-user-data-in-a-reload-function.patch | 30 ------------- ...not-use-API-removed-from-fwupd-2.0.x.patch | 45 ------------------- gnome-software.spec | 11 +++-- sources | 2 +- 4 files changed, 6 insertions(+), 82 deletions(-) delete mode 100644 0001-dkms-Fix-callback-user-data-in-a-reload-function.patch delete mode 100644 0001-fwupd-Do-not-use-API-removed-from-fwupd-2.0.x.patch diff --git a/0001-dkms-Fix-callback-user-data-in-a-reload-function.patch b/0001-dkms-Fix-callback-user-data-in-a-reload-function.patch deleted file mode 100644 index e44003e..0000000 --- a/0001-dkms-Fix-callback-user-data-in-a-reload-function.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 6b29a361465fb9b70c3a4cd66615e200bef65cd6 Mon Sep 17 00:00:00 2001 -Date: Wed, 18 Sep 2024 07:16:42 +0200 -Subject: [PATCH] dkms: Fix callback user data in a reload() function - -The gs_dkms_got_secureboot_state_cb() expects a GTask as its user data, -but the gs_plugin_dkms_reload() passed a GsPlugin instead. That could -cause a crash. - -Reported downstream at: -https://bugzilla.redhat.com/show_bug.cgi?id=2312882 ---- - plugins/dkms/gs-plugin-dkms.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/plugins/dkms/gs-plugin-dkms.c b/plugins/dkms/gs-plugin-dkms.c -index f7971334f..eb423e08d 100644 ---- a/plugins/dkms/gs-plugin-dkms.c -+++ b/plugins/dkms/gs-plugin-dkms.c -@@ -83,7 +83,7 @@ gs_plugin_dkms_reload (GsPlugin *plugin) - - /* mokutil was not installed probably; the reload can be called when some - app/package had been installed, thus re-try to check Secure Boot state */ -- gs_dkms_get_secureboot_state_async (NULL, gs_dkms_got_secureboot_state_cb, g_object_ref (plugin)); -+ gs_dkms_get_secureboot_state_async (NULL, gs_dkms_got_secureboot_state_cb, g_steal_pointer (&task)); - } - } - --- -2.45.2 - diff --git a/0001-fwupd-Do-not-use-API-removed-from-fwupd-2.0.x.patch b/0001-fwupd-Do-not-use-API-removed-from-fwupd-2.0.x.patch deleted file mode 100644 index 78bd0b9..0000000 --- a/0001-fwupd-Do-not-use-API-removed-from-fwupd-2.0.x.patch +++ /dev/null @@ -1,45 +0,0 @@ -From bdfe5c691a1c3302cf61da0781b290c67f88ba6b Mon Sep 17 00:00:00 2001 -From: Richard Hughes -Date: Tue, 1 Oct 2024 12:24:09 +0100 -Subject: [PATCH 14/14] fwupd: Do not use API removed from fwupd 2.0.x - -All the systemd-offline logic was unused, and so removed. ---- - plugins/fwupd/gs-fwupd-app.c | 5 ----- - plugins/fwupd/gs-plugin-fwupd.c | 4 ---- - 2 files changed, 9 deletions(-) - -diff --git a/plugins/fwupd/gs-fwupd-app.c b/plugins/fwupd/gs-fwupd-app.c -index bad97420a..e4376b265 100644 ---- a/plugins/fwupd/gs-fwupd-app.c -+++ b/plugins/fwupd/gs-fwupd-app.c -@@ -117,11 +117,6 @@ gs_fwupd_app_set_from_device (GsApp *app, - ) - gs_app_set_state (app, GS_APP_STATE_UPDATABLE_LIVE); - -- /* only can be applied in systemd-offline */ -- if (fwupd_device_has_flag (dev, FWUPD_DEVICE_FLAG_ONLY_OFFLINE)) -- gs_app_set_metadata (app, "fwupd::OnlyOffline", ""); -- -- - /* reboot required to apply update */ - if (fwupd_device_has_flag (dev, FWUPD_DEVICE_FLAG_NEEDS_REBOOT)) - gs_app_add_quirk (app, GS_APP_QUIRK_NEEDS_REBOOT); -diff --git a/plugins/fwupd/gs-plugin-fwupd.c b/plugins/fwupd/gs-plugin-fwupd.c -index fd6049055..8e3d8ab2c 100644 ---- a/plugins/fwupd/gs-plugin-fwupd.c -+++ b/plugins/fwupd/gs-plugin-fwupd.c -@@ -1430,10 +1430,6 @@ gs_plugin_fwupd_install_async (GsPluginFwupd *self, - * https://github.com/fwupd/fwupd/issues/5522. */ - g_set_object (&self->app_current, app); - -- /* only offline supported */ -- if (gs_app_get_metadata_item (app, "fwupd::OnlyOffline") != NULL) -- install_flags |= FWUPD_INSTALL_FLAG_OFFLINE; -- - gs_app_set_state (app, GS_APP_STATE_INSTALLING); - - fwupd_client_install_async (self->client, data->device_id, --- -2.46.2 - diff --git a/gnome-software.spec b/gnome-software.spec index 06e77c9..849bd92 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -25,17 +25,14 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 47.0 -Release: 3%{?dist} +Version: 47.1 +Release: 1%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later URL: https://apps.gnome.org/Software Source0: https://download.gnome.org/sources/gnome-software/47/%{name}-%{tarball_version}.tar.xz -Patch: 0001-dkms-Fix-callback-user-data-in-a-reload-function.patch -Patch: 0001-fwupd-Do-not-use-API-removed-from-fwupd-2.0.x.patch - # ostree and flatpak not on i686 for Fedora and RHEL 10 # https://github.com/containers/composefs/pull/229#issuecomment-1838735764 %if 0%{?fedora} || 0%{?rhel} >= 10 @@ -143,7 +140,6 @@ This package includes the rpm-ostree backend. %build %meson \ - -Dsoup2=false \ -Dsnap=false \ %if %{with malcontent} -Dmalcontent=true \ @@ -290,6 +286,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Thu Oct 10 2024 Milan Crha - 47.1-1 +- Update to 47.1 + * Fri Oct 04 2024 Richard Hughes - 47.0-3 - Rebuild against fwupd 2.0.0 diff --git a/sources b/sources index ed97419..ee2d17f 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-47.0.tar.xz) = 0aac8e2f9803fbdef9e07c798d3171eb6267090fc1ffcbe1e4888e2499a50c28ec4a817ec82205f1eeb4e3220f11920ff045b817b692c8b1f8e5edbdbd82b6b9 +SHA512 (gnome-software-47.1.tar.xz) = 18c500ef0487f9303097f939e11d2841df87d609d05484e3d4419ce9a27f6156ec4aabeca61191724d557b5603ff7857095ed09fc065b6064d0b92286bc19748 From 79f3e3a0c8c6cde3880c1f5b6cf39c00e4c758fd Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 25 Nov 2024 14:36:36 +0100 Subject: [PATCH 079/116] Update to 47.2 --- gnome-software.spec | 7 ++++++- sources | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index 849bd92..9693dd6 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -25,7 +25,7 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 47.1 +Version: 47.2 Release: 1%{?dist} Summary: A software center for GNOME @@ -89,8 +89,10 @@ Requires: gnome-app-list # gnome-menus is needed for app folder .directory entries Requires: gnome-menus%{?_isa} Requires: gsettings-desktop-schemas%{?_isa} +Requires: gtk4 >= %{gtk4_version} Requires: json-glib%{?_isa} >= %{json_glib_version} Requires: iso-codes +Requires: libadwaita >= %{libadwaita_version} # librsvg2 is needed for gdk-pixbuf svg loader Requires: librsvg2%{?_isa} Requires: libxmlb%{?_isa} >= %{libxmlb_version} @@ -286,6 +288,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Mon Nov 25 2024 Milan Crha - 47.2-1 +- Update to 47.2 + * Thu Oct 10 2024 Milan Crha - 47.1-1 - Update to 47.1 diff --git a/sources b/sources index ee2d17f..4b9ac1c 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-47.1.tar.xz) = 18c500ef0487f9303097f939e11d2841df87d609d05484e3d4419ce9a27f6156ec4aabeca61191724d557b5603ff7857095ed09fc065b6064d0b92286bc19748 +SHA512 (gnome-software-47.2.tar.xz) = 60de4a3c3237bfdc0dbbefdeccb00c97af7332a36c6beb5610fb6a416508e8b4712fd007e395ad283a3f9cb8d3e0f3a56c134ff28b3f22953a448188a1005cb6 From 0dd97896b5b14544057ab9c8c6629bcb9bde6364 Mon Sep 17 00:00:00 2001 From: Yaakov Selkowitz Date: Thu, 5 Dec 2024 16:04:14 -0500 Subject: [PATCH 080/116] Rebuild for fwupd 2.0 The ELN build of fwupd 2.0, which included an ABI version change, was delayed until now. --- gnome-software.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gnome-software.spec b/gnome-software.spec index 9693dd6..d744445 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -26,7 +26,7 @@ Name: gnome-software Version: 47.2 -Release: 1%{?dist} +Release: 2%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -288,6 +288,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Thu Dec 05 2024 Yaakov Selkowitz - 47.2-2 +- Rebuild for fwupd 2.0 + * Mon Nov 25 2024 Milan Crha - 47.2-1 - Update to 47.2 From 6263c5e777f454dff0a865042bf767484847552e Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 9 Dec 2024 10:57:46 +0100 Subject: [PATCH 081/116] Resolves: #2272232 (Crash under gs_appstream_gather_merge_data()) --- ...under-gs_appstream_gather_merge_data.patch | 1468 +++++++++++++++++ gnome-software.spec | 7 +- 2 files changed, 1474 insertions(+), 1 deletion(-) create mode 100644 0001-crash-under-gs_appstream_gather_merge_data.patch diff --git a/0001-crash-under-gs_appstream_gather_merge_data.patch b/0001-crash-under-gs_appstream_gather_merge_data.patch new file mode 100644 index 0000000..b52cefd --- /dev/null +++ b/0001-crash-under-gs_appstream_gather_merge_data.patch @@ -0,0 +1,1468 @@ +From f1140fd98666fbdb35dfe13a6b3f58fedcb1ad0b Mon Sep 17 00:00:00 2001 +Date: Mon, 29 Apr 2024 17:37:57 +0200 +Subject: [PATCH 1/3] gs-plugin-appstream: Simplify XbSilo locking + +Instead of holding RW lock on the internal silo variable, simply return +a reference to it and work with it like with an immutable object. That +simplifies locking and makes the code cleaner. It can also make the code +quicker, in some cases. +--- + plugins/core/gs-plugin-appstream.c | 194 ++++++++++++++++------------- + 1 file changed, 107 insertions(+), 87 deletions(-) + +diff --git a/plugins/core/gs-plugin-appstream.c b/plugins/core/gs-plugin-appstream.c +index 7ccbac12a5..5749a175f3 100644 +--- a/plugins/core/gs-plugin-appstream.c ++++ b/plugins/core/gs-plugin-appstream.c +@@ -36,7 +36,7 @@ struct _GsPluginAppstream + GsWorkerThread *worker; /* (owned) */ + + XbSilo *silo; +- GRWLock silo_lock; ++ GMutex silo_lock; + gchar *silo_filename; + GHashTable *silo_installed_by_desktopid; + GHashTable *silo_installed_by_id; +@@ -65,7 +65,7 @@ gs_plugin_appstream_dispose (GObject *object) + g_clear_pointer (&self->silo_installed_by_desktopid, g_hash_table_unref); + g_clear_pointer (&self->silo_installed_by_id, g_hash_table_unref); + g_clear_object (&self->settings); +- g_rw_lock_clear (&self->silo_lock); ++ g_mutex_clear (&self->silo_lock); + g_clear_object (&self->worker); + g_clear_pointer (&self->file_monitors, g_ptr_array_unref); + +@@ -77,9 +77,7 @@ gs_plugin_appstream_init (GsPluginAppstream *self) + { + GApplication *application = g_application_get_default (); + +- /* XbSilo needs external locking as we destroy the silo and build a new +- * one when something changes */ +- g_rw_lock_init (&self->silo_lock); ++ g_mutex_init (&self->silo_lock); + + /* require settings */ + self->settings = g_settings_new ("org.gnome.software"); +@@ -530,10 +528,13 @@ gs_add_appstream_metainfo_location (GPtrArray *locations, const gchar *root) + g_build_filename (root, "appdata", NULL)); + } + +-static gboolean +-gs_plugin_appstream_check_silo (GsPluginAppstream *self, +- GCancellable *cancellable, +- GError **error) ++static XbSilo * ++gs_plugin_appstream_ref_silo (GsPluginAppstream *self, ++ gchar **out_silo_filename, ++ GHashTable **out_silo_installed_by_desktopid, ++ GHashTable **out_silo_installed_by_id, ++ GCancellable *cancellable, ++ GError **error) + { + const gchar *test_xml; + g_autofree gchar *blobfn = NULL; +@@ -541,21 +542,25 @@ gs_plugin_appstream_check_silo (GsPluginAppstream *self, + g_autoptr(XbNode) n = NULL; + g_autoptr(GFile) file = NULL; + g_autoptr(GPtrArray) installed = NULL; +- g_autoptr(GRWLockReaderLocker) reader_locker = NULL; +- g_autoptr(GRWLockWriterLocker) writer_locker = NULL; ++ g_autoptr(GMutexLocker) locker = NULL; + g_autoptr(GPtrArray) parent_appdata = g_ptr_array_new_with_free_func (g_free); + g_autoptr(GPtrArray) parent_appstream = NULL; + g_autoptr(GMainContext) old_thread_default = NULL; + +- reader_locker = g_rw_lock_reader_locker_new (&self->silo_lock); ++ locker = g_mutex_locker_new (&self->silo_lock); + /* everything is okay */ + if (self->silo != NULL && xb_silo_is_valid (self->silo) && +- g_atomic_int_get (&self->file_monitor_stamp_current) == g_atomic_int_get (&self->file_monitor_stamp)) +- return TRUE; +- g_clear_pointer (&reader_locker, g_rw_lock_reader_locker_free); ++ g_atomic_int_get (&self->file_monitor_stamp_current) == g_atomic_int_get (&self->file_monitor_stamp)) { ++ if (out_silo_filename != NULL) ++ *out_silo_filename = g_strdup (self->silo_filename); ++ if (out_silo_installed_by_desktopid != NULL) ++ *out_silo_installed_by_desktopid = self->silo_installed_by_desktopid ? g_hash_table_ref (self->silo_installed_by_desktopid) : NULL; ++ if (out_silo_installed_by_id != NULL) ++ *out_silo_installed_by_id = self->silo_installed_by_id ? g_hash_table_ref (self->silo_installed_by_id) : NULL; ++ return g_object_ref (self->silo); ++ } + + /* drat! silo needs regenerating */ +- writer_locker = g_rw_lock_writer_locker_new (&self->silo_lock); + reload: + g_clear_object (&self->silo); + g_clear_pointer (&self->silo_filename, g_free); +@@ -594,7 +599,7 @@ gs_plugin_appstream_check_silo (GsPluginAppstream *self, + if (!xb_builder_source_load_xml (source, test_xml, + XB_BUILDER_SOURCE_FLAG_NONE, + error)) +- return FALSE; ++ return NULL; + fixup1 = xb_builder_fixup_new ("AddOriginKeywords", + gs_plugin_appstream_add_origin_keyword_cb, + self, NULL); +@@ -640,7 +645,7 @@ gs_plugin_appstream_check_silo (GsPluginAppstream *self, + if (!gs_plugin_appstream_load_appstream (self, builder, fn, cancellable, error)) { + if (old_thread_default != NULL) + g_main_context_push_thread_default (old_thread_default); +- return FALSE; ++ return NULL; + } + } + for (guint i = 0; i < parent_appdata->len; i++) { +@@ -648,7 +653,7 @@ gs_plugin_appstream_check_silo (GsPluginAppstream *self, + if (!gs_plugin_appstream_load_appdata (self, builder, fn, cancellable, error)) { + if (old_thread_default != NULL) + g_main_context_push_thread_default (old_thread_default); +- return FALSE; ++ return NULL; + } + } + for (guint i = 0; i < parent_desktop->len; i++) { +@@ -657,7 +662,7 @@ gs_plugin_appstream_check_silo (GsPluginAppstream *self, + if (!gs_appstream_load_desktop_files (builder, dir, NULL, &file_monitor, cancellable, error)) { + if (old_thread_default != NULL) + g_main_context_push_thread_default (old_thread_default); +- return FALSE; ++ return NULL; + } + gs_plugin_appstream_maybe_store_file_monitor (self, file_monitor); + } +@@ -678,7 +683,7 @@ gs_plugin_appstream_check_silo (GsPluginAppstream *self, + GS_UTILS_CACHE_FLAG_CREATE_DIRECTORY, + error); + if (blobfn == NULL) +- return FALSE; ++ return NULL; + file = g_file_new_for_path (blobfn); + g_debug ("ensuring %s", blobfn); + +@@ -696,7 +701,7 @@ gs_plugin_appstream_check_silo (GsPluginAppstream *self, + if (self->silo == NULL) { + if (old_thread_default != NULL) + g_main_context_push_thread_default (old_thread_default); +- return FALSE; ++ return NULL; + } + + if (old_thread_default != NULL) +@@ -717,7 +722,7 @@ gs_plugin_appstream_check_silo (GsPluginAppstream *self, + GS_PLUGIN_ERROR, + GS_PLUGIN_ERROR_NOT_SUPPORTED, + "No AppStream data found"); +- return FALSE; ++ return NULL; + } + + g_clear_object (&n); +@@ -768,7 +773,13 @@ gs_plugin_appstream_check_silo (GsPluginAppstream *self, + } + + /* success */ +- return TRUE; ++ if (out_silo_filename != NULL) ++ *out_silo_filename = g_strdup (self->silo_filename); ++ if (out_silo_installed_by_desktopid != NULL) ++ *out_silo_installed_by_desktopid = self->silo_installed_by_desktopid ? g_hash_table_ref (self->silo_installed_by_desktopid) : NULL; ++ if (out_silo_installed_by_id != NULL) ++ *out_silo_installed_by_id = self->silo_installed_by_id ? g_hash_table_ref (self->silo_installed_by_id) : NULL; ++ return g_object_ref (self->silo); + } + + static void +@@ -776,7 +787,6 @@ gs_plugin_appstream_reload (GsPlugin *plugin) + { + GsPluginAppstream *self; + g_autoptr(GsAppList) list = NULL; +- g_autoptr(GRWLockWriterLocker) writer_locker = NULL; + guint sz; + + g_return_if_fail (GS_IS_PLUGIN_APPSTREAM (plugin)); +@@ -790,9 +800,8 @@ gs_plugin_appstream_reload (GsPlugin *plugin) + } + + self = GS_PLUGIN_APPSTREAM (plugin); +- writer_locker = g_rw_lock_writer_locker_new (&self->silo_lock); +- if (self->silo != NULL) +- xb_silo_invalidate (self->silo); ++ /* simpler than getting the silo and setting it invalid */ ++ g_atomic_int_inc (&self->file_monitor_stamp); + } + + static gint +@@ -834,11 +843,13 @@ setup_thread_cb (GTask *task, + GCancellable *cancellable) + { + GsPluginAppstream *self = GS_PLUGIN_APPSTREAM (source_object); ++ g_autoptr(XbSilo) silo = NULL; + g_autoptr(GError) local_error = NULL; + + assert_in_worker (self); + +- if (!gs_plugin_appstream_check_silo (self, cancellable, &local_error)) ++ silo = gs_plugin_appstream_ref_silo (self, NULL, NULL, NULL, cancellable, &local_error); ++ if (silo == NULL) + g_task_return_error (task, g_steal_pointer (&local_error)); + else + g_task_return_boolean (task, TRUE); +@@ -910,21 +921,21 @@ url_to_app_thread_cb (GTask *task, + GsPluginAppstream *self = GS_PLUGIN_APPSTREAM (source_object); + GsPluginUrlToAppData *data = task_data; + g_autoptr(GsAppList) list = NULL; +- g_autoptr(GRWLockReaderLocker) locker = NULL; ++ g_autoptr(XbSilo) silo = NULL; + g_autoptr(GError) local_error = NULL; + + assert_in_worker (self); + + /* check silo is valid */ +- if (!gs_plugin_appstream_check_silo (self, cancellable, &local_error)) { ++ silo = gs_plugin_appstream_ref_silo (self, NULL, NULL, NULL, cancellable, &local_error); ++ if (silo == NULL) { + g_task_return_error (task, g_steal_pointer (&local_error)); + return; + } + +- locker = g_rw_lock_reader_locker_new (&self->silo_lock); + list = gs_app_list_new (); + +- if (gs_appstream_url_to_app (GS_PLUGIN (self), self->silo, list, data->url, cancellable, &local_error)) ++ if (gs_appstream_url_to_app (GS_PLUGIN (self), silo, list, data->url, cancellable, &local_error)) + g_task_return_pointer (task, g_steal_pointer (&list), g_object_unref); + else + g_task_return_error (task, g_steal_pointer (&local_error)); +@@ -1006,17 +1017,14 @@ gs_plugin_appstream_set_compulsory_quirk (GsApp *app, XbNode *component) + static gboolean + gs_plugin_appstream_refine_state (GsPluginAppstream *self, + GsApp *app, ++ GHashTable *silo_installed_by_id, + GError **error) + { +- g_autoptr(GRWLockReaderLocker) locker = NULL; +- + /* Ignore apps with no ID */ +- if (gs_app_get_id (app) == NULL) ++ if (gs_app_get_id (app) == NULL || silo_installed_by_id == NULL) + return TRUE; + +- locker = g_rw_lock_reader_locker_new (&self->silo_lock); +- +- if (g_hash_table_contains (self->silo_installed_by_id, gs_app_get_id (app))) ++ if (g_hash_table_contains (silo_installed_by_id, gs_app_get_id (app))) + gs_app_set_state (app, GS_APP_STATE_INSTALLED); + return TRUE; + } +@@ -1027,20 +1035,21 @@ gs_plugin_refine_from_id (GsPluginAppstream *self, + GsPluginRefineFlags flags, + GHashTable *apps_by_id, + GHashTable *apps_by_origin_and_id, ++ XbSilo *silo, ++ const gchar *silo_filename, ++ GHashTable *silo_installed_by_desktopid, ++ GHashTable *silo_installed_by_id, + gboolean *found, + GError **error) + { + const gchar *id, *origin; + GPtrArray *components; +- g_autoptr(GRWLockReaderLocker) locker = NULL; + + /* not enough info to find */ + id = gs_app_get_id (app); + if (id == NULL) + return TRUE; + +- locker = g_rw_lock_reader_locker_new (&self->silo_lock); +- + origin = gs_app_get_origin_appstream (app); + + /* look in AppStream then fall back to AppData */ +@@ -1056,15 +1065,15 @@ gs_plugin_refine_from_id (GsPluginAppstream *self, + + for (guint i = 0; i < components->len; i++) { + XbNode *component = g_ptr_array_index (components, i); +- if (!gs_appstream_refine_app (GS_PLUGIN (self), app, self->silo, component, flags, self->silo_installed_by_desktopid, +- self->silo_filename ? self->silo_filename : "", self->default_scope, error)) ++ if (!gs_appstream_refine_app (GS_PLUGIN (self), app, silo, component, flags, silo_installed_by_desktopid, ++ silo_filename ? silo_filename : "", self->default_scope, error)) + return FALSE; + gs_plugin_appstream_set_compulsory_quirk (app, component); + } + + /* if an installed desktop or appdata file exists set to installed */ + if (gs_app_get_state (app) == GS_APP_STATE_UNKNOWN) { +- if (!gs_plugin_appstream_refine_state (self, app, error)) ++ if (!gs_plugin_appstream_refine_state (self, app, silo_installed_by_id, error)) + return FALSE; + } + +@@ -1077,6 +1086,10 @@ static gboolean + gs_plugin_refine_from_pkgname (GsPluginAppstream *self, + GsApp *app, + GsPluginRefineFlags flags, ++ XbSilo *silo, ++ const gchar *silo_filename, ++ GHashTable *silo_installed_by_desktopid, ++ GHashTable *silo_installed_by_id, + GError **error) + { + GPtrArray *sources = gs_app_get_sources (app); +@@ -1089,33 +1102,30 @@ gs_plugin_refine_from_pkgname (GsPluginAppstream *self, + /* find all apps when matching any prefixes */ + for (guint j = 0; j < sources->len; j++) { + const gchar *pkgname = g_ptr_array_index (sources, j); +- g_autoptr(GRWLockReaderLocker) locker = NULL; + g_autoptr(GString) xpath = g_string_new (NULL); + g_autoptr(XbNode) component = NULL; + +- locker = g_rw_lock_reader_locker_new (&self->silo_lock); +- + /* prefer actual apps and then fallback to anything else */ + xb_string_append_union (xpath, "components/component[@type='desktop-application']/pkgname[text()='%s']/..", pkgname); + xb_string_append_union (xpath, "components/component[@type='console-application']/pkgname[text()='%s']/..", pkgname); + xb_string_append_union (xpath, "components/component[@type='web-application']/pkgname[text()='%s']/..", pkgname); + xb_string_append_union (xpath, "components/component/pkgname[text()='%s']/..", pkgname); +- component = xb_silo_query_first (self->silo, xpath->str, &error_local); ++ component = xb_silo_query_first (silo, xpath->str, &error_local); + if (component == NULL) { + if (g_error_matches (error_local, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) + continue; + g_propagate_error (error, g_steal_pointer (&error_local)); + return FALSE; + } +- if (!gs_appstream_refine_app (GS_PLUGIN (self), app, self->silo, component, flags, self->silo_installed_by_desktopid, +- self->silo_filename ? self->silo_filename : "", self->default_scope, error)) ++ if (!gs_appstream_refine_app (GS_PLUGIN (self), app, silo, component, flags, silo_installed_by_desktopid, ++ silo_filename ? silo_filename : "", self->default_scope, error)) + return FALSE; + gs_plugin_appstream_set_compulsory_quirk (app, component); + } + + /* if an installed desktop or appdata file exists set to installed */ + if (gs_app_get_state (app) == GS_APP_STATE_UNKNOWN) { +- if (!gs_plugin_appstream_refine_state (self, app, error)) ++ if (!gs_plugin_appstream_refine_state (self, app, silo_installed_by_id, error)) + return FALSE; + } + +@@ -1153,6 +1163,10 @@ static gboolean refine_wildcard (GsPluginAppstream *self, + GsAppList *list, + GsPluginRefineFlags refine_flags, + GHashTable *apps_by_id, ++ XbSilo *silo, ++ const gchar *silo_filename, ++ GHashTable *silo_installed_by_desktopid, ++ GHashTable *silo_installed_by_id, + GCancellable *cancellable, + GError **error); + +@@ -1171,13 +1185,17 @@ refine_thread_cb (GTask *task, + g_autoptr(GHashTable) apps_by_id = NULL; + g_autoptr(GHashTable) apps_by_origin_and_id = NULL; + g_autoptr(GPtrArray) components = NULL; +- g_autoptr(GRWLockReaderLocker) locker = NULL; ++ g_autoptr(XbSilo) silo = NULL; ++ g_autofree gchar *silo_filename = NULL; ++ g_autoptr(GHashTable) silo_installed_by_desktopid = NULL; ++ g_autoptr(GHashTable) silo_installed_by_id = NULL; + g_autoptr(GError) local_error = NULL; + + assert_in_worker (self); + + /* check silo is valid */ +- if (!gs_plugin_appstream_check_silo (self, cancellable, &local_error)) { ++ silo = gs_plugin_appstream_ref_silo (self, &silo_filename, &silo_installed_by_desktopid, &silo_installed_by_id, cancellable, &local_error); ++ if (silo == NULL) { + g_task_return_error (task, g_steal_pointer (&local_error)); + return; + } +@@ -1185,9 +1203,7 @@ refine_thread_cb (GTask *task, + apps_by_id = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_ptr_array_unref); + apps_by_origin_and_id = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_ptr_array_unref); + +- locker = g_rw_lock_reader_locker_new (&self->silo_lock); +- +- components = xb_silo_query (self->silo, "components/component/id", 0, NULL); ++ components = xb_silo_query (silo, "components/component/id", 0, NULL); + for (guint i = 0; components != NULL && i < components->len; i++) { + XbNode *node = g_ptr_array_index (components, i); + g_autoptr(XbNode) component_node = xb_node_get_parent (node); +@@ -1234,7 +1250,7 @@ refine_thread_cb (GTask *task, + } + + g_clear_pointer (&components, g_ptr_array_unref); +- components = xb_silo_query (self->silo, "component/id", 0, NULL); ++ components = xb_silo_query (silo, "component/id", 0, NULL); + for (guint i = 0; components != NULL && i < components->len; i++) { + XbNode *node = g_ptr_array_index (components, i); + g_autoptr(XbNode) component_node = xb_node_get_parent (node); +@@ -1262,12 +1278,14 @@ refine_thread_cb (GTask *task, + continue; + + /* find by ID then fall back to package name */ +- if (!gs_plugin_refine_from_id (self, app, flags, apps_by_id, apps_by_origin_and_id, &found, &local_error)) { ++ if (!gs_plugin_refine_from_id (self, app, flags, apps_by_id, apps_by_origin_and_id, silo, silo_filename, ++ silo_installed_by_desktopid, silo_installed_by_id, &found, &local_error)) { + g_task_return_error (task, g_steal_pointer (&local_error)); + return; + } + if (!found) { +- if (!gs_plugin_refine_from_pkgname (self, app, flags, &local_error)) { ++ if (!gs_plugin_refine_from_pkgname (self, app, flags, silo, silo_filename, ++ silo_installed_by_desktopid, silo_installed_by_id, &local_error)) { + g_task_return_error (task, g_steal_pointer (&local_error)); + return; + } +@@ -1286,7 +1304,8 @@ refine_thread_cb (GTask *task, + GsApp *app = gs_app_list_index (app_list, j); + + if (gs_app_has_quirk (app, GS_APP_QUIRK_IS_WILDCARD) && +- !refine_wildcard (self, app, list, flags, apps_by_id, cancellable, &local_error)) { ++ !refine_wildcard (self, app, list, flags, apps_by_id, silo, silo_filename, ++ silo_installed_by_desktopid, silo_installed_by_id,cancellable, &local_error)) { + g_task_return_error (task, g_steal_pointer (&local_error)); + return; + } +@@ -1311,20 +1330,21 @@ refine_wildcard (GsPluginAppstream *self, + GsAppList *list, + GsPluginRefineFlags refine_flags, + GHashTable *apps_by_id, ++ XbSilo *silo, ++ const gchar *silo_filename, ++ GHashTable *silo_installed_by_desktopid, ++ GHashTable *silo_installed_by_id, + GCancellable *cancellable, + GError **error) + { + const gchar *id; + GPtrArray *components; +- g_autoptr(GRWLockReaderLocker) locker = NULL; + + /* not enough info to find */ + id = gs_app_get_id (app); + if (id == NULL) + return TRUE; + +- locker = g_rw_lock_reader_locker_new (&self->silo_lock); +- + components = g_hash_table_lookup (apps_by_id, id); + if (components == NULL) + return TRUE; +@@ -1333,20 +1353,20 @@ refine_wildcard (GsPluginAppstream *self, + g_autoptr(GsApp) new = NULL; + + /* new app */ +- new = gs_appstream_create_app (GS_PLUGIN (self), self->silo, component, self->silo_filename ? self->silo_filename : "", ++ new = gs_appstream_create_app (GS_PLUGIN (self), silo, component, silo_filename ? silo_filename : "", + self->default_scope, error); + if (new == NULL) + return FALSE; + gs_app_set_scope (new, AS_COMPONENT_SCOPE_SYSTEM); + gs_app_subsume_metadata (new, app); +- if (!gs_appstream_refine_app (GS_PLUGIN (self), new, self->silo, component, refine_flags, self->silo_installed_by_desktopid, +- self->silo_filename ? self->silo_filename : "", self->default_scope, error)) ++ if (!gs_appstream_refine_app (GS_PLUGIN (self), new, silo, component, refine_flags, silo_installed_by_desktopid, ++ silo_filename ? silo_filename : "", self->default_scope, error)) + return FALSE; + gs_plugin_appstream_set_compulsory_quirk (new, component); + + /* if an installed desktop or appdata file exists set to installed */ + if (gs_app_get_state (new) == GS_APP_STATE_UNKNOWN) { +- if (!gs_plugin_appstream_refine_state (self, new, error)) ++ if (!gs_plugin_appstream_refine_state (self, new, silo_installed_by_id, error)) + return FALSE; + } + +@@ -1398,21 +1418,20 @@ refine_categories_thread_cb (GTask *task, + GCancellable *cancellable) + { + GsPluginAppstream *self = GS_PLUGIN_APPSTREAM (source_object); +- g_autoptr(GRWLockReaderLocker) locker = NULL; ++ g_autoptr(XbSilo) silo = NULL; + GsPluginRefineCategoriesData *data = task_data; + g_autoptr(GError) local_error = NULL; + + assert_in_worker (self); + + /* check silo is valid */ +- if (!gs_plugin_appstream_check_silo (self, cancellable, &local_error)) { ++ silo = gs_plugin_appstream_ref_silo (self, NULL, NULL, NULL, cancellable, &local_error); ++ if (silo == NULL) { + g_task_return_error (task, g_steal_pointer (&local_error)); + return; + } + +- locker = g_rw_lock_reader_locker_new (&self->silo_lock); +- +- if (!gs_appstream_refine_category_sizes (self->silo, data->list, cancellable, &local_error)) { ++ if (!gs_appstream_refine_category_sizes (silo, data->list, cancellable, &local_error)) { + g_task_return_error (task, g_steal_pointer (&local_error)); + return; + } +@@ -1462,7 +1481,7 @@ list_apps_thread_cb (GTask *task, + GCancellable *cancellable) + { + GsPluginAppstream *self = GS_PLUGIN_APPSTREAM (source_object); +- g_autoptr(GRWLockReaderLocker) locker = NULL; ++ g_autoptr(XbSilo) silo = NULL; + g_autoptr(GsAppList) list = gs_app_list_new (); + GsPluginListAppsData *data = task_data; + GDateTime *released_since = NULL; +@@ -1516,65 +1535,64 @@ list_apps_thread_cb (GTask *task, + } + + /* check silo is valid */ +- if (!gs_plugin_appstream_check_silo (self, cancellable, &local_error)) { ++ silo = gs_plugin_appstream_ref_silo (self, NULL, NULL, NULL, cancellable, &local_error); ++ if (silo == NULL) { + g_task_return_error (task, g_steal_pointer (&local_error)); + return; + } + +- locker = g_rw_lock_reader_locker_new (&self->silo_lock); +- + if (released_since != NULL && +- !gs_appstream_add_recent (GS_PLUGIN (self), self->silo, list, age_secs, ++ !gs_appstream_add_recent (GS_PLUGIN (self), silo, list, age_secs, + cancellable, &local_error)) { + g_task_return_error (task, g_steal_pointer (&local_error)); + return; + } + + if (is_curated != GS_APP_QUERY_TRISTATE_UNSET && +- !gs_appstream_add_popular (self->silo, list, cancellable, &local_error)) { ++ !gs_appstream_add_popular (silo, list, cancellable, &local_error)) { + g_task_return_error (task, g_steal_pointer (&local_error)); + return; + } + + if (is_featured != GS_APP_QUERY_TRISTATE_UNSET && +- !gs_appstream_add_featured (self->silo, list, cancellable, &local_error)) { ++ !gs_appstream_add_featured (silo, list, cancellable, &local_error)) { + g_task_return_error (task, g_steal_pointer (&local_error)); + return; + } + + if (category != NULL && +- !gs_appstream_add_category_apps (GS_PLUGIN (self), self->silo, category, list, cancellable, &local_error)) { ++ !gs_appstream_add_category_apps (GS_PLUGIN (self), silo, category, list, cancellable, &local_error)) { + g_task_return_error (task, g_steal_pointer (&local_error)); + return; + } + + if (is_installed == GS_APP_QUERY_TRISTATE_TRUE && +- !gs_appstream_add_installed (GS_PLUGIN (self), self->silo, list, cancellable, &local_error)) { ++ !gs_appstream_add_installed (GS_PLUGIN (self), silo, list, cancellable, &local_error)) { + g_task_return_error (task, g_steal_pointer (&local_error)); + return; + } + + if (deployment_featured != NULL && +- !gs_appstream_add_deployment_featured (self->silo, deployment_featured, list, ++ !gs_appstream_add_deployment_featured (silo, deployment_featured, list, + cancellable, &local_error)) { + g_task_return_error (task, g_steal_pointer (&local_error)); + return; + } + + if (developers != NULL && +- !gs_appstream_search_developer_apps (GS_PLUGIN (self), self->silo, developers, list, cancellable, &local_error)) { ++ !gs_appstream_search_developer_apps (GS_PLUGIN (self), silo, developers, list, cancellable, &local_error)) { + g_task_return_error (task, g_steal_pointer (&local_error)); + return; + } + + if (keywords != NULL && +- !gs_appstream_search (GS_PLUGIN (self), self->silo, keywords, list, cancellable, &local_error)) { ++ !gs_appstream_search (GS_PLUGIN (self), silo, keywords, list, cancellable, &local_error)) { + g_task_return_error (task, g_steal_pointer (&local_error)); + return; + } + + if (alternate_of != NULL && +- !gs_appstream_add_alternates (self->silo, alternate_of, list, cancellable, &local_error)) { ++ !gs_appstream_add_alternates (silo, alternate_of, list, cancellable, &local_error)) { + g_task_return_error (task, g_steal_pointer (&local_error)); + return; + } +@@ -1623,12 +1641,14 @@ refresh_metadata_thread_cb (GTask *task, + GCancellable *cancellable) + { + GsPluginAppstream *self = GS_PLUGIN_APPSTREAM (source_object); ++ g_autoptr(XbSilo) silo = NULL; + g_autoptr(GError) local_error = NULL; + + assert_in_worker (self); + + /* Checking the silo will refresh it if needed. */ +- if (!gs_plugin_appstream_check_silo (self, cancellable, &local_error)) ++ silo = gs_plugin_appstream_ref_silo (self, NULL, NULL, NULL, cancellable, &local_error); ++ if (silo == NULL) + g_task_return_error (task, g_steal_pointer (&local_error)); + else + g_task_return_boolean (task, TRUE); +-- +GitLab + + +From cf04c32b5fb1fd267096fad8dd11a22429ad788a Mon Sep 17 00:00:00 2001 +Date: Mon, 29 Apr 2024 17:45:08 +0200 +Subject: [PATCH 2/3] gs-plugin-appstream: Rename file_monitor_stamp to + silo_change_stamp + +Since it's used also in the gs_plugin_appstream_reload() and works +like a change indicator, name it appropriately to avoid confusion. +--- + plugins/core/gs-plugin-appstream.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/plugins/core/gs-plugin-appstream.c b/plugins/core/gs-plugin-appstream.c +index 5749a175f3..99fe5a1432 100644 +--- a/plugins/core/gs-plugin-appstream.c ++++ b/plugins/core/gs-plugin-appstream.c +@@ -46,8 +46,8 @@ struct _GsPluginAppstream + GPtrArray *file_monitors; /* (owned) (element-type GFileMonitor) */ + /* The stamps help to avoid locking the silo lock in the main thread + and also to detect changes while loading other appstream data. */ +- gint file_monitor_stamp; /* the file monitor stamp, increased on every file monitor change */ +- gint file_monitor_stamp_current; /* the currently known file monitor stamp, checked for changes */ ++ gint silo_change_stamp; /* the silo change stamp, increased on every silo change */ ++ gint silo_change_stamp_current; /* the currently known silo change stamp, checked for changes */ + }; + + G_DEFINE_TYPE (GsPluginAppstream, gs_plugin_appstream, GS_TYPE_PLUGIN) +@@ -224,7 +224,7 @@ gs_plugin_appstream_file_monitor_changed_cb (GFileMonitor *monitor, + gpointer user_data) + { + GsPluginAppstream *self = user_data; +- g_atomic_int_inc (&self->file_monitor_stamp); ++ g_atomic_int_inc (&self->silo_change_stamp); + } + + static void +@@ -550,7 +550,7 @@ gs_plugin_appstream_ref_silo (GsPluginAppstream *self, + locker = g_mutex_locker_new (&self->silo_lock); + /* everything is okay */ + if (self->silo != NULL && xb_silo_is_valid (self->silo) && +- g_atomic_int_get (&self->file_monitor_stamp_current) == g_atomic_int_get (&self->file_monitor_stamp)) { ++ g_atomic_int_get (&self->silo_change_stamp_current) == g_atomic_int_get (&self->silo_change_stamp)) { + if (out_silo_filename != NULL) + *out_silo_filename = g_strdup (self->silo_filename); + if (out_silo_installed_by_desktopid != NULL) +@@ -568,7 +568,7 @@ gs_plugin_appstream_ref_silo (GsPluginAppstream *self, + g_clear_pointer (&blobfn, g_free); + self->default_scope = AS_COMPONENT_SCOPE_UNKNOWN; + g_ptr_array_set_size (self->file_monitors, 0); +- g_atomic_int_set (&self->file_monitor_stamp_current, g_atomic_int_get (&self->file_monitor_stamp)); ++ g_atomic_int_set (&self->silo_change_stamp_current, g_atomic_int_get (&self->silo_change_stamp)); + + /* FIXME: https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1422 */ + old_thread_default = g_main_context_ref_thread_default (); +@@ -707,7 +707,7 @@ gs_plugin_appstream_ref_silo (GsPluginAppstream *self, + if (old_thread_default != NULL) + g_main_context_push_thread_default (old_thread_default); + +- if (g_atomic_int_get (&self->file_monitor_stamp_current) != g_atomic_int_get (&self->file_monitor_stamp)) { ++ if (g_atomic_int_get (&self->silo_change_stamp_current) != g_atomic_int_get (&self->silo_change_stamp)) { + g_ptr_array_set_size (parent_appdata, 0); + g_ptr_array_set_size (parent_appstream, 0); + g_debug ("appstream: File monitors reported change while loading appstream data, reloading..."); +@@ -800,8 +800,8 @@ gs_plugin_appstream_reload (GsPlugin *plugin) + } + + self = GS_PLUGIN_APPSTREAM (plugin); +- /* simpler than getting the silo and setting it invalid */ +- g_atomic_int_inc (&self->file_monitor_stamp); ++ /* Invalidate the reference to the current silo */ ++ g_atomic_int_inc (&self->silo_change_stamp); + } + + static gint +-- +GitLab + + +From 59b301b8a878f3e81359909a8d4107715eb60a35 Mon Sep 17 00:00:00 2001 +Date: Tue, 30 Apr 2024 13:13:36 +0200 +Subject: [PATCH 3/3] flatpak: Simplify XbSilo locking + +Instead of holding RW lock on the internal silo variable, simply return +a reference to it and work with it like with an immutable object. That +simplifies locking and makes the code cleaner. It can also make the code +quicker, in some cases. +--- + plugins/flatpak/gs-flatpak.c | 307 +++++++++++++++++++---------------- + 1 file changed, 163 insertions(+), 144 deletions(-) + +diff --git a/plugins/flatpak/gs-flatpak.c b/plugins/flatpak/gs-flatpak.c +index 2e175fd08e..9893cf88b7 100644 +--- a/plugins/flatpak/gs-flatpak.c ++++ b/plugins/flatpak/gs-flatpak.c +@@ -54,9 +54,11 @@ struct _GsFlatpak { + AsComponentScope scope; + GsPlugin *plugin; + XbSilo *silo; +- GRWLock silo_lock; ++ GMutex silo_lock; + gchar *silo_filename; + GHashTable *silo_installed_by_desktopid; ++ gint silo_change_stamp; ++ gint silo_change_stamp_current; + gchar *id; + guint changed_id; + GHashTable *app_silos; +@@ -654,10 +656,7 @@ gs_flatpak_create_source (GsFlatpak *self, FlatpakRemote *xremote) + static void + gs_flatpak_invalidate_silo (GsFlatpak *self) + { +- g_rw_lock_writer_lock (&self->silo_lock); +- if (self->silo != NULL) +- xb_silo_invalidate (self->silo); +- g_rw_lock_writer_unlock (&self->silo_lock); ++ g_atomic_int_inc (&self->silo_change_stamp); + } + + static void +@@ -1085,32 +1084,39 @@ gs_flatpak_rescan_installed (GsFlatpak *self, + g_debug ("Failed to read flatpak .desktop files in %s: %s", path, error_local->message); + } + +-static gboolean +-gs_flatpak_rescan_appstream_store (GsFlatpak *self, +- gboolean interactive, +- GCancellable *cancellable, +- GError **error) ++static XbSilo * ++gs_flatpak_ref_silo (GsFlatpak *self, ++ gboolean interactive, ++ gchar **out_silo_filename, ++ GHashTable **out_silo_installed_by_desktopid, ++ GCancellable *cancellable, ++ GError **error) + { + g_autofree gchar *blobfn = NULL; + g_autoptr(GFile) file = NULL; + g_autoptr(GPtrArray) xremotes = NULL; + g_autoptr(GPtrArray) desktop_paths = NULL; +- g_autoptr(GRWLockReaderLocker) reader_locker = NULL; +- g_autoptr(GRWLockWriterLocker) writer_locker = NULL; ++ g_autoptr(GMutexLocker) locker = NULL; + g_autoptr(XbBuilder) builder = NULL; + g_autoptr(GMainContext) old_thread_default = NULL; + +- reader_locker = g_rw_lock_reader_locker_new (&self->silo_lock); ++ locker = g_mutex_locker_new (&self->silo_lock); + /* everything is okay */ +- if (self->silo != NULL && xb_silo_is_valid (self->silo)) +- return TRUE; +- g_clear_pointer (&reader_locker, g_rw_lock_reader_locker_free); ++ if (self->silo != NULL && xb_silo_is_valid (self->silo) && ++ g_atomic_int_get (&self->silo_change_stamp_current) == g_atomic_int_get (&self->silo_change_stamp)) { ++ if (out_silo_filename != NULL) ++ *out_silo_filename = g_strdup (self->silo_filename); ++ if (out_silo_installed_by_desktopid != NULL && self->silo_installed_by_desktopid) ++ *out_silo_installed_by_desktopid = g_hash_table_ref (self->silo_installed_by_desktopid); ++ return g_object_ref (self->silo); ++ } + + /* drat! silo needs regenerating */ +- writer_locker = g_rw_lock_writer_locker_new (&self->silo_lock); ++ reload: + g_clear_object (&self->silo); + g_clear_pointer (&self->silo_filename, g_free); + g_clear_pointer (&self->silo_installed_by_desktopid, g_hash_table_unref); ++ g_atomic_int_set (&self->silo_change_stamp_current, g_atomic_int_get (&self->silo_change_stamp)); + + /* FIXME: https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1422 */ + old_thread_default = g_main_context_ref_thread_default (); +@@ -1138,7 +1144,7 @@ gs_flatpak_rescan_appstream_store (GsFlatpak *self, + error); + if (xremotes == NULL) { + gs_flatpak_error_convert (error); +- return FALSE; ++ return NULL; + } + for (guint i = 0; i < xremotes->len; i++) { + g_autoptr(GError) error_local = NULL; +@@ -1152,7 +1158,7 @@ gs_flatpak_rescan_appstream_store (GsFlatpak *self, + flatpak_remote_get_name (xremote), error_local->message); + if (g_cancellable_set_error_if_cancelled (cancellable, error)) { + gs_flatpak_error_convert (error); +- return FALSE; ++ return NULL; + } + } + } +@@ -1176,7 +1182,7 @@ gs_flatpak_rescan_appstream_store (GsFlatpak *self, + GS_UTILS_CACHE_FLAG_CREATE_DIRECTORY, + error); + if (blobfn == NULL) +- return FALSE; ++ return NULL; + file = g_file_new_for_path (blobfn); + g_debug ("ensuring %s", blobfn); + +@@ -1195,6 +1201,17 @@ gs_flatpak_rescan_appstream_store (GsFlatpak *self, + if (old_thread_default != NULL) + g_main_context_push_thread_default (old_thread_default); + ++ if (g_atomic_int_get (&self->silo_change_stamp_current) != g_atomic_int_get (&self->silo_change_stamp)) { ++ g_clear_pointer (&blobfn, g_free); ++ g_clear_pointer (&xremotes, g_ptr_array_unref); ++ g_clear_pointer (&desktop_paths, g_ptr_array_unref); ++ g_clear_pointer (&old_thread_default, g_main_context_unref); ++ g_clear_object (&file); ++ g_clear_object (&builder); ++ g_debug ("flatpak: Reported change while loading appstream data, reloading..."); ++ goto reload; ++ } ++ + if (self->silo != NULL) { + g_autoptr(GPtrArray) installed = NULL; + g_autoptr(XbNode) info_filename = NULL; +@@ -1218,66 +1235,46 @@ gs_flatpak_rescan_appstream_store (GsFlatpak *self, + info_filename = xb_silo_query_first (self->silo, "/info/filename", NULL); + if (info_filename != NULL) + self->silo_filename = g_strdup (xb_node_get_text (info_filename)); ++ ++ if (out_silo_filename != NULL) ++ *out_silo_filename = g_strdup (self->silo_filename); ++ if (out_silo_installed_by_desktopid != NULL && self->silo_installed_by_desktopid) ++ *out_silo_installed_by_desktopid = g_hash_table_ref (self->silo_installed_by_desktopid); ++ return g_object_ref (self->silo); + } + +- /* success */ +- return self->silo != NULL; ++ return NULL; + } + + static gboolean + gs_flatpak_rescan_app_data (GsFlatpak *self, + gboolean interactive, ++ XbSilo **out_silo, ++ gchar **out_silo_filename, ++ GHashTable **out_silo_installed_by_desktopid, + GCancellable *cancellable, + GError **error) + { ++ g_autoptr(XbSilo) silo = NULL; ++ + if (self->requires_full_rescan) { + gboolean res = gs_flatpak_refresh (self, 60, interactive, cancellable, error); +- if (res) ++ if (res) { + self->requires_full_rescan = FALSE; +- else ++ } else { + gs_flatpak_internal_data_changed (self); +- return res; ++ return res; ++ } + } + +- if (!gs_flatpak_rescan_appstream_store (self, interactive, cancellable, error)) { ++ silo = gs_flatpak_ref_silo (self, interactive, out_silo_filename, out_silo_installed_by_desktopid, cancellable, error); ++ if (silo == NULL) { + gs_flatpak_internal_data_changed (self); + return FALSE; + } + +- return TRUE; +-} +- +-/* Returns with a read lock held on @self->silo_lock on success. +- The *locker should be NULL when being called. */ +-static gboolean +-ensure_flatpak_silo_with_locker (GsFlatpak *self, +- GRWLockReaderLocker **locker, +- gboolean interactive, +- GCancellable *cancellable, +- GError **error) +-{ +- /* should not hold the lock when called */ +- g_return_val_if_fail (*locker == NULL, FALSE); +- +- /* ensure valid */ +- if (!gs_flatpak_rescan_app_data (self, interactive, cancellable, error)) +- return FALSE; +- +- *locker = g_rw_lock_reader_locker_new (&self->silo_lock); +- +- while (self->silo == NULL) { +- g_clear_pointer (locker, g_rw_lock_reader_locker_free); +- +- if (!gs_flatpak_rescan_appstream_store (self, interactive, cancellable, error)) { +- gs_flatpak_internal_data_changed (self); +- return FALSE; +- } +- +- /* At this point either rescan_appstream_store() returned an error or it successfully +- * initialised self->silo. There is the possibility that another thread will invalidate +- * the silo before we regain the lock. If so, we’ll have to rescan again. */ +- *locker = g_rw_lock_reader_locker_new (&self->silo_lock); +- } ++ if (out_silo != NULL) ++ *out_silo = g_steal_pointer (&silo); + + return TRUE; + } +@@ -1412,6 +1409,7 @@ gs_flatpak_refresh_appstream (GsFlatpak *self, + { + gboolean ret; + g_autoptr(GPtrArray) xremotes = NULL; ++ g_autoptr(XbSilo) silo = NULL; + + /* get remotes */ + xremotes = flatpak_installation_list_remotes (gs_flatpak_get_installation (self, interactive), +@@ -1498,7 +1496,8 @@ gs_flatpak_refresh_appstream (GsFlatpak *self, + } + + /* ensure the AppStream silo is up to date */ +- if (!gs_flatpak_rescan_appstream_store (self, interactive, cancellable, error)) { ++ silo = gs_flatpak_ref_silo (self, interactive, NULL, NULL, cancellable, error); ++ if (silo == NULL) { + gs_flatpak_internal_data_changed (self); + return FALSE; + } +@@ -1646,7 +1645,7 @@ gs_flatpak_add_sources (GsFlatpak *self, + FlatpakInstallation *installation = gs_flatpak_get_installation (self, interactive); + + /* refresh */ +- if (!gs_flatpak_rescan_app_data (self, interactive, cancellable, error)) ++ if (!gs_flatpak_rescan_app_data (self, interactive, NULL, NULL, NULL, cancellable, error)) + return FALSE; + + /* get installed apps and runtimes */ +@@ -2080,7 +2079,7 @@ gs_flatpak_add_updates (GsFlatpak *self, + FlatpakInstallation *installation = gs_flatpak_get_installation (self, interactive); + + /* ensure valid */ +- if (!gs_flatpak_rescan_app_data (self, interactive, cancellable, error)) ++ if (!gs_flatpak_rescan_app_data (self, interactive, NULL, NULL, NULL, cancellable, error)) + return FALSE; + + /* get all the updatable apps and runtimes */ +@@ -2390,10 +2389,8 @@ gs_flatpak_create_fake_ref (GsApp *app, GError **error) + return xref; + } + +-/* the _unlocked() version doesn't call gs_flatpak_rescan_app_data, +- * in order to avoid taking the writer lock on self->silo_lock */ + static gboolean +-gs_flatpak_refine_app_state_unlocked (GsFlatpak *self, ++gs_flatpak_refine_app_state_internal (GsFlatpak *self, + GsApp *app, + gboolean interactive, + gboolean force_state_update, +@@ -2505,10 +2502,10 @@ gs_flatpak_refine_app_state (GsFlatpak *self, + GError **error) + { + /* ensure valid */ +- if (!gs_flatpak_rescan_app_data (self, interactive, cancellable, error)) ++ if (!gs_flatpak_rescan_app_data (self, interactive, NULL, NULL, NULL, cancellable, error)) + return FALSE; + +- return gs_flatpak_refine_app_state_unlocked (self, app, interactive, force_state_update, cancellable, error); ++ return gs_flatpak_refine_app_state_internal (self, app, interactive, force_state_update, cancellable, error); + } + + static GsApp * +@@ -2594,7 +2591,7 @@ gs_flatpak_create_runtime (GsFlatpak *self, + gs_flatpak_app_set_ref_name (app, split[0]); + gs_flatpak_app_set_ref_arch (app, split[1]); + +- if (!gs_flatpak_refine_app_state_unlocked (self, app, interactive, FALSE, NULL, &local_error)) ++ if (!gs_flatpak_refine_app_state_internal (self, app, interactive, FALSE, NULL, &local_error)) + g_debug ("Failed to refine state for runtime '%s': %s", gs_app_get_unique_id (app), local_error->message); + + /* save in the cache */ +@@ -2984,7 +2981,7 @@ gs_plugin_refine_item_size (GsFlatpak *self, + + /* is the app_runtime already installed? */ + app_runtime = gs_app_get_runtime (app); +- if (!gs_flatpak_refine_app_state_unlocked (self, ++ if (!gs_flatpak_refine_app_state_internal (self, + app_runtime, + interactive, + FALSE, +@@ -3096,6 +3093,8 @@ gs_flatpak_refine_appstream_from_bytes (GsFlatpak *self, + GBytes *appstream_gz, + GsPluginRefineFlags flags, + gboolean interactive, ++ const gchar *silo_filename, ++ GHashTable *silo_installed_by_desktopid, + GCancellable *cancellable, + GError **error) + { +@@ -3229,8 +3228,8 @@ gs_flatpak_refine_appstream_from_bytes (GsFlatpak *self, + } + + /* copy details from AppStream to app */ +- if (!gs_appstream_refine_app (self->plugin, app, silo, component_node, flags, self->silo_installed_by_desktopid, +- self->silo_filename ? self->silo_filename : "", self->scope, error)) ++ if (!gs_appstream_refine_app (self->plugin, app, silo, component_node, flags, silo_installed_by_desktopid, ++ silo_filename ? silo_filename : "", self->scope, error)) + return FALSE; + + if (gs_app_get_origin (app)) +@@ -3324,6 +3323,8 @@ static gboolean + gs_flatpak_refine_appstream (GsFlatpak *self, + GsApp *app, + XbSilo *silo, ++ const gchar *silo_filename, ++ GHashTable *silo_installed_by_desktopid, + GsPluginRefineFlags flags, + GHashTable *components_by_bundle, + gboolean interactive, +@@ -3410,11 +3411,12 @@ gs_flatpak_refine_appstream (GsFlatpak *self, + appstream_gz, + flags, + interactive, ++ silo_filename, silo_installed_by_desktopid, + cancellable, error); + } + +- if (!gs_appstream_refine_app (self->plugin, app, silo, component, flags, self->silo_installed_by_desktopid, +- self->silo_filename ? self->silo_filename : "", self->scope, error)) ++ if (!gs_appstream_refine_app (self->plugin, app, silo, component, flags, silo_installed_by_desktopid, ++ silo_filename ? silo_filename : "", self->scope, error)) + return FALSE; + + /* use the default release as the version number */ +@@ -3423,13 +3425,15 @@ gs_flatpak_refine_appstream (GsFlatpak *self, + } + + static gboolean +-gs_flatpak_refine_app_unlocked (GsFlatpak *self, ++gs_flatpak_refine_app_internal (GsFlatpak *self, + GsApp *app, + GsPluginRefineFlags flags, + gboolean interactive, + gboolean force_state_update, + GHashTable *components_by_bundle, +- GRWLockReaderLocker **locker, ++ XbSilo *silo, ++ const gchar *silo_filename, ++ GHashTable *silo_installed_by_desktopid, + GCancellable *cancellable, + GError **error) + { +@@ -3440,13 +3444,9 @@ gs_flatpak_refine_app_unlocked (GsFlatpak *self, + if (gs_app_get_bundle_kind (app) != AS_BUNDLE_KIND_FLATPAK) + return TRUE; + +- g_clear_pointer (locker, g_rw_lock_reader_locker_free); +- +- if (!ensure_flatpak_silo_with_locker (self, locker, interactive, cancellable, error)) +- return FALSE; +- + /* always do AppStream properties */ +- if (!gs_flatpak_refine_appstream (self, app, self->silo, flags, components_by_bundle, interactive, cancellable, error)) ++ if (!gs_flatpak_refine_appstream (self, app, silo, silo_filename, silo_installed_by_desktopid, ++ flags, components_by_bundle, interactive, cancellable, error)) + return FALSE; + + /* AppStream sets the source to appname/arch/branch */ +@@ -3456,7 +3456,7 @@ gs_flatpak_refine_app_unlocked (GsFlatpak *self, + } + + /* check the installed state */ +- if (!gs_flatpak_refine_app_state_unlocked (self, app, interactive, force_state_update, cancellable, error)) { ++ if (!gs_flatpak_refine_app_state_internal (self, app, interactive, force_state_update, cancellable, error)) { + g_prefix_error (error, "failed to get state: "); + return FALSE; + } +@@ -3473,7 +3473,8 @@ gs_flatpak_refine_app_unlocked (GsFlatpak *self, + + /* if the state was changed, perhaps set the version from the release */ + if (old_state != gs_app_get_state (app)) { +- if (!gs_flatpak_refine_appstream (self, app, self->silo, flags, components_by_bundle, interactive, cancellable, error)) ++ if (!gs_flatpak_refine_appstream (self, app, silo, silo_filename, silo_installed_by_desktopid, ++ flags, components_by_bundle, interactive, cancellable, error)) + return FALSE; + } + +@@ -3567,11 +3568,16 @@ gs_flatpak_refine_addons (GsFlatpak *self, + gboolean interactive, + GCancellable *cancellable) + { +- g_autoptr(GRWLockReaderLocker) locker = NULL; ++ g_autoptr(XbSilo) silo = NULL; ++ g_autofree gchar *silo_filename = NULL; ++ g_autoptr(GHashTable) silo_installed_by_desktopid = NULL; + g_autoptr(GsAppList) addons = NULL; + g_autoptr(GString) errors = NULL; + guint ii, sz; + ++ if (!gs_flatpak_rescan_app_data (self, interactive, &silo, &silo_filename, &silo_installed_by_desktopid, cancellable, NULL)) ++ return; ++ + addons = gs_app_dup_addons (parent_app); + sz = addons ? gs_app_list_length (addons) : 0; + +@@ -3582,7 +3588,8 @@ gs_flatpak_refine_addons (GsFlatpak *self, + if (state != gs_app_get_state (addon)) + continue; + +- if (!gs_flatpak_refine_app_unlocked (self, addon, flags, interactive, TRUE, NULL, &locker, cancellable, &local_error)) { ++ if (!gs_flatpak_refine_app_internal (self, addon, flags, interactive, TRUE, NULL, silo, silo_filename, ++ silo_installed_by_desktopid, cancellable, &local_error)) { + if (errors) + g_string_append_c (errors, '\n'); + else +@@ -3614,13 +3621,16 @@ gs_flatpak_refine_app (GsFlatpak *self, + GCancellable *cancellable, + GError **error) + { +- g_autoptr(GRWLockReaderLocker) locker = NULL; ++ g_autoptr(XbSilo) silo = NULL; ++ g_autoptr(GHashTable) silo_installed_by_desktopid = NULL; ++ g_autofree gchar *silo_filename = NULL; + + /* ensure valid */ +- if (!gs_flatpak_rescan_app_data (self, interactive, cancellable, error)) ++ if (!gs_flatpak_rescan_app_data (self, interactive, &silo, &silo_filename, &silo_installed_by_desktopid, cancellable, error)) + return FALSE; + +- return gs_flatpak_refine_app_unlocked (self, app, flags, interactive, force_state_update, NULL, &locker, cancellable, error); ++ return gs_flatpak_refine_app_internal (self, app, flags, interactive, force_state_update, NULL, ++ silo, silo_filename, silo_installed_by_desktopid, cancellable, error); + } + + gboolean +@@ -3634,7 +3644,9 @@ gs_flatpak_refine_wildcard (GsFlatpak *self, GsApp *app, + const gchar *id; + GPtrArray* components = NULL; + g_autoptr(GError) error_local = NULL; +- g_autoptr(GRWLockReaderLocker) locker = NULL; ++ g_autoptr(XbSilo) silo = NULL; ++ g_autoptr(GHashTable) silo_installed_by_desktopid = NULL; ++ g_autofree gchar *silo_filename = NULL; + + GS_PROFILER_BEGIN_SCOPED (FlatpakRefineWildcard, "Flatpak (refine wildcard)", NULL); + +@@ -3643,7 +3655,8 @@ gs_flatpak_refine_wildcard (GsFlatpak *self, GsApp *app, + if (id == NULL) + return TRUE; + +- if (!ensure_flatpak_silo_with_locker (self, &locker, interactive, cancellable, error)) ++ silo = gs_flatpak_ref_silo (self, interactive, &silo_filename, &silo_installed_by_desktopid, cancellable, error); ++ if (silo == NULL) + return FALSE; + + GS_PROFILER_BEGIN_SCOPED (FlatpakRefineWildcardQuerySilo, "Flatpak (query silo)", NULL); +@@ -3653,7 +3666,7 @@ gs_flatpak_refine_wildcard (GsFlatpak *self, GsApp *app, + } else { + g_autoptr(GPtrArray) components_with_id = NULL; + *inout_components_by_id = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_ptr_array_unref); +- components_with_id = xb_silo_query (self->silo, "components/component/id", 0, &error_local); ++ components_with_id = xb_silo_query (silo, "components/component/id", 0, &error_local); + if (components_with_id == NULL) { + if (g_error_matches (error_local, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) + return TRUE; +@@ -3686,7 +3699,7 @@ gs_flatpak_refine_wildcard (GsFlatpak *self, GsApp *app, + g_autoptr(GPtrArray) bundles = NULL; + + *inout_components_by_bundle = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); +- bundles = xb_silo_query (self->silo, "/components/component/bundle[@type='flatpak']", 0, NULL); ++ bundles = xb_silo_query (silo, "/components/component/bundle[@type='flatpak']", 0, NULL); + for (guint b = 0; bundles != NULL && b < bundles->len; b++) { + XbNode *bundle_node = g_ptr_array_index (bundles, b); + g_autoptr(XbNode) component_node = xb_node_get_parent (bundle_node); +@@ -3709,7 +3722,7 @@ gs_flatpak_refine_wildcard (GsFlatpak *self, GsApp *app, + g_autoptr(GsApp) new = NULL; + + GS_PROFILER_BEGIN_SCOPED (FlatpakRefineWildcardCreateAppstreamApp, "Flatpak (create Appstream app)", NULL); +- new = gs_appstream_create_app (self->plugin, self->silo, component, self->silo_filename ? self->silo_filename : "", ++ new = gs_appstream_create_app (self->plugin, silo, component, silo_filename ? silo_filename : "", + self->scope, error); + GS_PROFILER_END_SCOPED (FlatpakRefineWildcardCreateAppstreamApp); + +@@ -3761,7 +3774,8 @@ gs_flatpak_refine_wildcard (GsFlatpak *self, GsApp *app, + g_debug ("Failed to get ref info for '%s' from wildcard '%s', skipping it...", gs_app_get_id (new), id); + } else { + GS_PROFILER_BEGIN_SCOPED (FlatpakRefineWildcardRefineNewApp, "Flatpak (refine new app)", NULL); +- if (!gs_flatpak_refine_app_unlocked (self, new, refine_flags, interactive, FALSE, *inout_components_by_bundle, &locker, cancellable, error)) ++ if (!gs_flatpak_refine_app_internal (self, new, refine_flags, interactive, FALSE, *inout_components_by_bundle, ++ silo, silo_filename, silo_installed_by_desktopid, cancellable, error)) + return FALSE; + GS_PROFILER_END_SCOPED (FlatpakRefineWildcardRefineNewApp); + +@@ -3894,10 +3908,18 @@ gs_flatpak_file_to_app_bundle (GsFlatpak *self, + /* load AppStream */ + appstream_gz = flatpak_bundle_ref_get_appstream (xref_bundle); + if (appstream_gz != NULL) { ++ g_autofree gchar *silo_filename = NULL; ++ g_autoptr(GHashTable) silo_installed_by_desktopid = NULL; ++ g_autoptr(XbSilo) tmp_silo = NULL; ++ ++ tmp_silo = gs_flatpak_ref_silo (self, interactive, &silo_filename, &silo_installed_by_desktopid, cancellable, error); ++ if (tmp_silo == NULL) ++ return NULL; + if (!gs_flatpak_refine_appstream_from_bytes (self, app, NULL, NULL, + appstream_gz, + GS_PLUGIN_REFINE_FLAGS_REQUIRE_ID, + interactive, ++ silo_filename, silo_installed_by_desktopid, + cancellable, error)) + return NULL; + } else { +@@ -3995,6 +4017,9 @@ gs_flatpak_file_to_app_ref (GsFlatpak *self, + g_autoptr(GsApp) app = NULL; + g_autoptr(XbBuilder) builder = xb_builder_new (); + g_autoptr(XbSilo) silo = NULL; ++ g_autoptr(XbSilo) tmp_silo = NULL; ++ g_autoptr(GHashTable) silo_installed_by_desktopid = NULL; ++ g_autofree gchar *silo_filename = NULL; + g_autofree gchar *origin_url = NULL; + g_autofree gchar *ref_comment = NULL; + g_autofree gchar *ref_description = NULL; +@@ -4274,8 +4299,12 @@ gs_flatpak_file_to_app_ref (GsFlatpak *self, + g_debug ("showing AppStream data: %s", xml); + } + ++ tmp_silo = gs_flatpak_ref_silo (self, interactive, &silo_filename, &silo_installed_by_desktopid, cancellable, error); ++ if (tmp_silo == NULL) ++ return NULL; ++ + /* get extra AppStream data if available */ +- if (!gs_flatpak_refine_appstream (self, app, silo, ++ if (!gs_flatpak_refine_appstream (self, app, silo, silo_filename, silo_installed_by_desktopid, + GS_PLUGIN_REFINE_FLAGS_MASK, + NULL, + interactive, +@@ -4296,17 +4325,16 @@ gs_flatpak_search (GsFlatpak *self, + GError **error) + { + g_autoptr(GsAppList) list_tmp = gs_app_list_new (); +- g_autoptr(GRWLockReaderLocker) locker = NULL; + g_autoptr(GMutexLocker) app_silo_locker = NULL; + g_autoptr(GPtrArray) silos_to_remove = g_ptr_array_new (); ++ g_autoptr(XbSilo) silo = NULL; + GHashTableIter iter; + gpointer key, value; + +- if (!ensure_flatpak_silo_with_locker (self, &locker, interactive, cancellable, error)) ++ if (!gs_flatpak_rescan_app_data (self, interactive, &silo, NULL, NULL, cancellable, error)) + return FALSE; + +- if (!gs_appstream_search (self->plugin, self->silo, values, list_tmp, +- cancellable, error)) ++ if (!gs_appstream_search (self->plugin, silo, values, list_tmp, cancellable, error)) + return FALSE; + + gs_flatpak_ensure_remote_title (self, interactive, cancellable); +@@ -4353,8 +4381,8 @@ gs_flatpak_search (GsFlatpak *self, + } + + for (guint i = 0; i < silos_to_remove->len; i++) { +- const char *silo = g_ptr_array_index (silos_to_remove, i); +- g_hash_table_remove (self->app_silos, silo); ++ const char *app_ref = g_ptr_array_index (silos_to_remove, i); ++ g_hash_table_remove (self->app_silos, app_ref); + } + + return TRUE; +@@ -4369,17 +4397,16 @@ gs_flatpak_search_developer_apps (GsFlatpak *self, + GError **error) + { + g_autoptr(GsAppList) list_tmp = gs_app_list_new (); +- g_autoptr(GRWLockReaderLocker) locker = NULL; + g_autoptr(GMutexLocker) app_silo_locker = NULL; + g_autoptr(GPtrArray) silos_to_remove = g_ptr_array_new (); ++ g_autoptr(XbSilo) silo = NULL; + GHashTableIter iter; + gpointer key, value; + +- if (!ensure_flatpak_silo_with_locker (self, &locker, interactive, cancellable, error)) ++ if (!gs_flatpak_rescan_app_data (self, interactive, &silo, NULL, NULL, cancellable, error)) + return FALSE; + +- if (!gs_appstream_search_developer_apps (self->plugin, self->silo, values, list_tmp, +- cancellable, error)) ++ if (!gs_appstream_search_developer_apps (self->plugin, silo, values, list_tmp, cancellable, error)) + return FALSE; + + gs_flatpak_ensure_remote_title (self, interactive, cancellable); +@@ -4426,8 +4453,8 @@ gs_flatpak_search_developer_apps (GsFlatpak *self, + } + + for (guint i = 0; i < silos_to_remove->len; i++) { +- const char *silo = g_ptr_array_index (silos_to_remove, i); +- g_hash_table_remove (self->app_silos, silo); ++ const char *app_ref = g_ptr_array_index (silos_to_remove, i); ++ g_hash_table_remove (self->app_silos, app_ref); + } + + return TRUE; +@@ -4441,14 +4468,12 @@ gs_flatpak_add_category_apps (GsFlatpak *self, + GCancellable *cancellable, + GError **error) + { +- g_autoptr(GRWLockReaderLocker) locker = NULL; ++ g_autoptr(XbSilo) silo = NULL; + +- if (!ensure_flatpak_silo_with_locker (self, &locker, interactive, cancellable, error)) ++ if (!gs_flatpak_rescan_app_data (self, interactive, &silo, NULL, NULL, cancellable, error)) + return FALSE; + +- return gs_appstream_add_category_apps (self->plugin, self->silo, +- category, list, +- cancellable, error); ++ return gs_appstream_add_category_apps (self->plugin, silo, category, list, cancellable, error); + } + + gboolean +@@ -4458,12 +4483,12 @@ gs_flatpak_refine_category_sizes (GsFlatpak *self, + GCancellable *cancellable, + GError **error) + { +- g_autoptr(GRWLockReaderLocker) locker = NULL; ++ g_autoptr(XbSilo) silo = NULL; + +- if (!ensure_flatpak_silo_with_locker (self, &locker, interactive, cancellable, error)) ++ if (!gs_flatpak_rescan_app_data (self, interactive, &silo, NULL, NULL, cancellable, error)) + return FALSE; + +- return gs_appstream_refine_category_sizes (self->silo, list, cancellable, error); ++ return gs_appstream_refine_category_sizes (silo, list, cancellable, error); + } + + gboolean +@@ -4474,13 +4499,12 @@ gs_flatpak_add_popular (GsFlatpak *self, + GError **error) + { + g_autoptr(GsAppList) list_tmp = gs_app_list_new (); +- g_autoptr(GRWLockReaderLocker) locker = NULL; ++ g_autoptr(XbSilo) silo = NULL; + +- if (!ensure_flatpak_silo_with_locker (self, &locker, interactive, cancellable, error)) ++ if (!gs_flatpak_rescan_app_data (self, interactive, &silo, NULL, NULL, cancellable, error)) + return FALSE; + +- if (!gs_appstream_add_popular (self->silo, list_tmp, +- cancellable, error)) ++ if (!gs_appstream_add_popular (silo, list_tmp, cancellable, error)) + return FALSE; + + gs_app_list_add_list (list, list_tmp); +@@ -4496,13 +4520,12 @@ gs_flatpak_add_featured (GsFlatpak *self, + GError **error) + { + g_autoptr(GsAppList) list_tmp = gs_app_list_new (); +- g_autoptr(GRWLockReaderLocker) locker = NULL; ++ g_autoptr(XbSilo) silo = NULL; + +- if (!ensure_flatpak_silo_with_locker (self, &locker, interactive, cancellable, error)) ++ if (!gs_flatpak_rescan_app_data (self, interactive, &silo, NULL, NULL, cancellable, error)) + return FALSE; + +- if (!gs_appstream_add_featured (self->silo, list_tmp, +- cancellable, error)) ++ if (!gs_appstream_add_featured (silo, list_tmp, cancellable, error)) + return FALSE; + + gs_app_list_add_list (list, list_tmp); +@@ -4518,12 +4541,12 @@ gs_flatpak_add_deployment_featured (GsFlatpak *self, + GCancellable *cancellable, + GError **error) + { +- g_autoptr(GRWLockReaderLocker) locker = NULL; ++ g_autoptr(XbSilo) silo = NULL; + +- if (!ensure_flatpak_silo_with_locker (self, &locker, interactive, cancellable, error)) ++ if (!gs_flatpak_rescan_app_data (self, interactive, &silo, NULL, NULL, cancellable, error)) + return FALSE; + +- return gs_appstream_add_deployment_featured (self->silo, deployments, list, cancellable, error); ++ return gs_appstream_add_deployment_featured (silo, deployments, list, cancellable, error); + } + + gboolean +@@ -4535,13 +4558,12 @@ gs_flatpak_add_alternates (GsFlatpak *self, + GError **error) + { + g_autoptr(GsAppList) list_tmp = gs_app_list_new (); +- g_autoptr(GRWLockReaderLocker) locker = NULL; ++ g_autoptr(XbSilo) silo = NULL; + +- if (!ensure_flatpak_silo_with_locker (self, &locker, interactive, cancellable, error)) ++ if (!gs_flatpak_rescan_app_data (self, interactive, &silo, NULL, NULL, cancellable, error)) + return FALSE; + +- if (!gs_appstream_add_alternates (self->silo, app, list_tmp, +- cancellable, error)) ++ if (!gs_appstream_add_alternates (silo, app, list_tmp, cancellable, error)) + return FALSE; + + gs_app_list_add_list (list, list_tmp); +@@ -4558,13 +4580,12 @@ gs_flatpak_add_recent (GsFlatpak *self, + GError **error) + { + g_autoptr(GsAppList) list_tmp = gs_app_list_new (); +- g_autoptr(GRWLockReaderLocker) locker = NULL; ++ g_autoptr(XbSilo) silo = NULL; + +- if (!ensure_flatpak_silo_with_locker (self, &locker, interactive, cancellable, error)) ++ if (!gs_flatpak_rescan_app_data (self, interactive, &silo, NULL, NULL, cancellable, error)) + return FALSE; + +- if (!gs_appstream_add_recent (self->plugin, self->silo, list_tmp, age, +- cancellable, error)) ++ if (!gs_appstream_add_recent (self->plugin, silo, list_tmp, age, cancellable, error)) + return FALSE; + + gs_flatpak_claim_app_list (self, list_tmp, interactive); +@@ -4582,12 +4603,12 @@ gs_flatpak_url_to_app (GsFlatpak *self, + GError **error) + { + g_autoptr(GsAppList) list_tmp = gs_app_list_new (); +- g_autoptr(GRWLockReaderLocker) locker = NULL; ++ g_autoptr(XbSilo) silo = NULL; + +- if (!ensure_flatpak_silo_with_locker (self, &locker, interactive, cancellable, error)) ++ if (!gs_flatpak_rescan_app_data (self, interactive, &silo, NULL, NULL, cancellable, error)) + return FALSE; + +- if (!gs_appstream_url_to_app (self->plugin, self->silo, list_tmp, url, cancellable, error)) ++ if (!gs_appstream_url_to_app (self->plugin, silo, list_tmp, url, cancellable, error)) + return FALSE; + + gs_flatpak_claim_app_list (self, list_tmp, interactive); +@@ -4638,10 +4659,8 @@ gs_flatpak_finalize (GObject *object) + g_signal_handler_disconnect (self->monitor, self->changed_id); + self->changed_id = 0; + } +- if (self->silo != NULL) +- g_object_unref (self->silo); +- if (self->monitor != NULL) +- g_object_unref (self->monitor); ++ g_clear_object (&self->silo); ++ g_clear_object (&self->monitor); + g_clear_pointer (&self->silo_filename, g_free); + g_clear_pointer (&self->silo_installed_by_desktopid, g_hash_table_unref); + +@@ -4654,7 +4673,7 @@ gs_flatpak_finalize (GObject *object) + g_object_unref (self->plugin); + g_hash_table_unref (self->broken_remotes); + g_mutex_clear (&self->broken_remotes_mutex); +- g_rw_lock_clear (&self->silo_lock); ++ g_mutex_clear (&self->silo_lock); + g_hash_table_unref (self->app_silos); + g_mutex_clear (&self->app_silos_mutex); + g_clear_pointer (&self->remote_title, g_hash_table_unref); +@@ -4675,7 +4694,7 @@ gs_flatpak_init (GsFlatpak *self) + { + /* XbSilo needs external locking as we destroy the silo and build a new + * one when something changes */ +- g_rw_lock_init (&self->silo_lock); ++ g_mutex_init (&self->silo_lock); + + g_mutex_init (&self->installed_refs_mutex); + self->installed_refs = NULL; +-- +GitLab + diff --git a/gnome-software.spec b/gnome-software.spec index d744445..5b8b2b4 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -26,13 +26,15 @@ Name: gnome-software Version: 47.2 -Release: 2%{?dist} +Release: 3%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later URL: https://apps.gnome.org/Software Source0: https://download.gnome.org/sources/gnome-software/47/%{name}-%{tarball_version}.tar.xz +Patch01: 0001-crash-under-gs_appstream_gather_merge_data.patch + # ostree and flatpak not on i686 for Fedora and RHEL 10 # https://github.com/containers/composefs/pull/229#issuecomment-1838735764 %if 0%{?fedora} || 0%{?rhel} >= 10 @@ -288,6 +290,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Mon Dec 09 2024 Milan Crha - 47.2-3 +- Resolves: #2272232 (Crash under gs_appstream_gather_merge_data()) + * Thu Dec 05 2024 Yaakov Selkowitz - 47.2-2 - Rebuild for fwupd 2.0 From 27805dcecbe0166032de3430d33fcca2ecec26af Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Tue, 7 Jan 2025 08:57:23 +0100 Subject: [PATCH 082/116] Update to 48.alpha2 --- ...under-gs_appstream_gather_merge_data.patch | 1468 ----------------- gnome-software.spec | 13 +- sources | 2 +- 3 files changed, 8 insertions(+), 1475 deletions(-) delete mode 100644 0001-crash-under-gs_appstream_gather_merge_data.patch diff --git a/0001-crash-under-gs_appstream_gather_merge_data.patch b/0001-crash-under-gs_appstream_gather_merge_data.patch deleted file mode 100644 index b52cefd..0000000 --- a/0001-crash-under-gs_appstream_gather_merge_data.patch +++ /dev/null @@ -1,1468 +0,0 @@ -From f1140fd98666fbdb35dfe13a6b3f58fedcb1ad0b Mon Sep 17 00:00:00 2001 -Date: Mon, 29 Apr 2024 17:37:57 +0200 -Subject: [PATCH 1/3] gs-plugin-appstream: Simplify XbSilo locking - -Instead of holding RW lock on the internal silo variable, simply return -a reference to it and work with it like with an immutable object. That -simplifies locking and makes the code cleaner. It can also make the code -quicker, in some cases. ---- - plugins/core/gs-plugin-appstream.c | 194 ++++++++++++++++------------- - 1 file changed, 107 insertions(+), 87 deletions(-) - -diff --git a/plugins/core/gs-plugin-appstream.c b/plugins/core/gs-plugin-appstream.c -index 7ccbac12a5..5749a175f3 100644 ---- a/plugins/core/gs-plugin-appstream.c -+++ b/plugins/core/gs-plugin-appstream.c -@@ -36,7 +36,7 @@ struct _GsPluginAppstream - GsWorkerThread *worker; /* (owned) */ - - XbSilo *silo; -- GRWLock silo_lock; -+ GMutex silo_lock; - gchar *silo_filename; - GHashTable *silo_installed_by_desktopid; - GHashTable *silo_installed_by_id; -@@ -65,7 +65,7 @@ gs_plugin_appstream_dispose (GObject *object) - g_clear_pointer (&self->silo_installed_by_desktopid, g_hash_table_unref); - g_clear_pointer (&self->silo_installed_by_id, g_hash_table_unref); - g_clear_object (&self->settings); -- g_rw_lock_clear (&self->silo_lock); -+ g_mutex_clear (&self->silo_lock); - g_clear_object (&self->worker); - g_clear_pointer (&self->file_monitors, g_ptr_array_unref); - -@@ -77,9 +77,7 @@ gs_plugin_appstream_init (GsPluginAppstream *self) - { - GApplication *application = g_application_get_default (); - -- /* XbSilo needs external locking as we destroy the silo and build a new -- * one when something changes */ -- g_rw_lock_init (&self->silo_lock); -+ g_mutex_init (&self->silo_lock); - - /* require settings */ - self->settings = g_settings_new ("org.gnome.software"); -@@ -530,10 +528,13 @@ gs_add_appstream_metainfo_location (GPtrArray *locations, const gchar *root) - g_build_filename (root, "appdata", NULL)); - } - --static gboolean --gs_plugin_appstream_check_silo (GsPluginAppstream *self, -- GCancellable *cancellable, -- GError **error) -+static XbSilo * -+gs_plugin_appstream_ref_silo (GsPluginAppstream *self, -+ gchar **out_silo_filename, -+ GHashTable **out_silo_installed_by_desktopid, -+ GHashTable **out_silo_installed_by_id, -+ GCancellable *cancellable, -+ GError **error) - { - const gchar *test_xml; - g_autofree gchar *blobfn = NULL; -@@ -541,21 +542,25 @@ gs_plugin_appstream_check_silo (GsPluginAppstream *self, - g_autoptr(XbNode) n = NULL; - g_autoptr(GFile) file = NULL; - g_autoptr(GPtrArray) installed = NULL; -- g_autoptr(GRWLockReaderLocker) reader_locker = NULL; -- g_autoptr(GRWLockWriterLocker) writer_locker = NULL; -+ g_autoptr(GMutexLocker) locker = NULL; - g_autoptr(GPtrArray) parent_appdata = g_ptr_array_new_with_free_func (g_free); - g_autoptr(GPtrArray) parent_appstream = NULL; - g_autoptr(GMainContext) old_thread_default = NULL; - -- reader_locker = g_rw_lock_reader_locker_new (&self->silo_lock); -+ locker = g_mutex_locker_new (&self->silo_lock); - /* everything is okay */ - if (self->silo != NULL && xb_silo_is_valid (self->silo) && -- g_atomic_int_get (&self->file_monitor_stamp_current) == g_atomic_int_get (&self->file_monitor_stamp)) -- return TRUE; -- g_clear_pointer (&reader_locker, g_rw_lock_reader_locker_free); -+ g_atomic_int_get (&self->file_monitor_stamp_current) == g_atomic_int_get (&self->file_monitor_stamp)) { -+ if (out_silo_filename != NULL) -+ *out_silo_filename = g_strdup (self->silo_filename); -+ if (out_silo_installed_by_desktopid != NULL) -+ *out_silo_installed_by_desktopid = self->silo_installed_by_desktopid ? g_hash_table_ref (self->silo_installed_by_desktopid) : NULL; -+ if (out_silo_installed_by_id != NULL) -+ *out_silo_installed_by_id = self->silo_installed_by_id ? g_hash_table_ref (self->silo_installed_by_id) : NULL; -+ return g_object_ref (self->silo); -+ } - - /* drat! silo needs regenerating */ -- writer_locker = g_rw_lock_writer_locker_new (&self->silo_lock); - reload: - g_clear_object (&self->silo); - g_clear_pointer (&self->silo_filename, g_free); -@@ -594,7 +599,7 @@ gs_plugin_appstream_check_silo (GsPluginAppstream *self, - if (!xb_builder_source_load_xml (source, test_xml, - XB_BUILDER_SOURCE_FLAG_NONE, - error)) -- return FALSE; -+ return NULL; - fixup1 = xb_builder_fixup_new ("AddOriginKeywords", - gs_plugin_appstream_add_origin_keyword_cb, - self, NULL); -@@ -640,7 +645,7 @@ gs_plugin_appstream_check_silo (GsPluginAppstream *self, - if (!gs_plugin_appstream_load_appstream (self, builder, fn, cancellable, error)) { - if (old_thread_default != NULL) - g_main_context_push_thread_default (old_thread_default); -- return FALSE; -+ return NULL; - } - } - for (guint i = 0; i < parent_appdata->len; i++) { -@@ -648,7 +653,7 @@ gs_plugin_appstream_check_silo (GsPluginAppstream *self, - if (!gs_plugin_appstream_load_appdata (self, builder, fn, cancellable, error)) { - if (old_thread_default != NULL) - g_main_context_push_thread_default (old_thread_default); -- return FALSE; -+ return NULL; - } - } - for (guint i = 0; i < parent_desktop->len; i++) { -@@ -657,7 +662,7 @@ gs_plugin_appstream_check_silo (GsPluginAppstream *self, - if (!gs_appstream_load_desktop_files (builder, dir, NULL, &file_monitor, cancellable, error)) { - if (old_thread_default != NULL) - g_main_context_push_thread_default (old_thread_default); -- return FALSE; -+ return NULL; - } - gs_plugin_appstream_maybe_store_file_monitor (self, file_monitor); - } -@@ -678,7 +683,7 @@ gs_plugin_appstream_check_silo (GsPluginAppstream *self, - GS_UTILS_CACHE_FLAG_CREATE_DIRECTORY, - error); - if (blobfn == NULL) -- return FALSE; -+ return NULL; - file = g_file_new_for_path (blobfn); - g_debug ("ensuring %s", blobfn); - -@@ -696,7 +701,7 @@ gs_plugin_appstream_check_silo (GsPluginAppstream *self, - if (self->silo == NULL) { - if (old_thread_default != NULL) - g_main_context_push_thread_default (old_thread_default); -- return FALSE; -+ return NULL; - } - - if (old_thread_default != NULL) -@@ -717,7 +722,7 @@ gs_plugin_appstream_check_silo (GsPluginAppstream *self, - GS_PLUGIN_ERROR, - GS_PLUGIN_ERROR_NOT_SUPPORTED, - "No AppStream data found"); -- return FALSE; -+ return NULL; - } - - g_clear_object (&n); -@@ -768,7 +773,13 @@ gs_plugin_appstream_check_silo (GsPluginAppstream *self, - } - - /* success */ -- return TRUE; -+ if (out_silo_filename != NULL) -+ *out_silo_filename = g_strdup (self->silo_filename); -+ if (out_silo_installed_by_desktopid != NULL) -+ *out_silo_installed_by_desktopid = self->silo_installed_by_desktopid ? g_hash_table_ref (self->silo_installed_by_desktopid) : NULL; -+ if (out_silo_installed_by_id != NULL) -+ *out_silo_installed_by_id = self->silo_installed_by_id ? g_hash_table_ref (self->silo_installed_by_id) : NULL; -+ return g_object_ref (self->silo); - } - - static void -@@ -776,7 +787,6 @@ gs_plugin_appstream_reload (GsPlugin *plugin) - { - GsPluginAppstream *self; - g_autoptr(GsAppList) list = NULL; -- g_autoptr(GRWLockWriterLocker) writer_locker = NULL; - guint sz; - - g_return_if_fail (GS_IS_PLUGIN_APPSTREAM (plugin)); -@@ -790,9 +800,8 @@ gs_plugin_appstream_reload (GsPlugin *plugin) - } - - self = GS_PLUGIN_APPSTREAM (plugin); -- writer_locker = g_rw_lock_writer_locker_new (&self->silo_lock); -- if (self->silo != NULL) -- xb_silo_invalidate (self->silo); -+ /* simpler than getting the silo and setting it invalid */ -+ g_atomic_int_inc (&self->file_monitor_stamp); - } - - static gint -@@ -834,11 +843,13 @@ setup_thread_cb (GTask *task, - GCancellable *cancellable) - { - GsPluginAppstream *self = GS_PLUGIN_APPSTREAM (source_object); -+ g_autoptr(XbSilo) silo = NULL; - g_autoptr(GError) local_error = NULL; - - assert_in_worker (self); - -- if (!gs_plugin_appstream_check_silo (self, cancellable, &local_error)) -+ silo = gs_plugin_appstream_ref_silo (self, NULL, NULL, NULL, cancellable, &local_error); -+ if (silo == NULL) - g_task_return_error (task, g_steal_pointer (&local_error)); - else - g_task_return_boolean (task, TRUE); -@@ -910,21 +921,21 @@ url_to_app_thread_cb (GTask *task, - GsPluginAppstream *self = GS_PLUGIN_APPSTREAM (source_object); - GsPluginUrlToAppData *data = task_data; - g_autoptr(GsAppList) list = NULL; -- g_autoptr(GRWLockReaderLocker) locker = NULL; -+ g_autoptr(XbSilo) silo = NULL; - g_autoptr(GError) local_error = NULL; - - assert_in_worker (self); - - /* check silo is valid */ -- if (!gs_plugin_appstream_check_silo (self, cancellable, &local_error)) { -+ silo = gs_plugin_appstream_ref_silo (self, NULL, NULL, NULL, cancellable, &local_error); -+ if (silo == NULL) { - g_task_return_error (task, g_steal_pointer (&local_error)); - return; - } - -- locker = g_rw_lock_reader_locker_new (&self->silo_lock); - list = gs_app_list_new (); - -- if (gs_appstream_url_to_app (GS_PLUGIN (self), self->silo, list, data->url, cancellable, &local_error)) -+ if (gs_appstream_url_to_app (GS_PLUGIN (self), silo, list, data->url, cancellable, &local_error)) - g_task_return_pointer (task, g_steal_pointer (&list), g_object_unref); - else - g_task_return_error (task, g_steal_pointer (&local_error)); -@@ -1006,17 +1017,14 @@ gs_plugin_appstream_set_compulsory_quirk (GsApp *app, XbNode *component) - static gboolean - gs_plugin_appstream_refine_state (GsPluginAppstream *self, - GsApp *app, -+ GHashTable *silo_installed_by_id, - GError **error) - { -- g_autoptr(GRWLockReaderLocker) locker = NULL; -- - /* Ignore apps with no ID */ -- if (gs_app_get_id (app) == NULL) -+ if (gs_app_get_id (app) == NULL || silo_installed_by_id == NULL) - return TRUE; - -- locker = g_rw_lock_reader_locker_new (&self->silo_lock); -- -- if (g_hash_table_contains (self->silo_installed_by_id, gs_app_get_id (app))) -+ if (g_hash_table_contains (silo_installed_by_id, gs_app_get_id (app))) - gs_app_set_state (app, GS_APP_STATE_INSTALLED); - return TRUE; - } -@@ -1027,20 +1035,21 @@ gs_plugin_refine_from_id (GsPluginAppstream *self, - GsPluginRefineFlags flags, - GHashTable *apps_by_id, - GHashTable *apps_by_origin_and_id, -+ XbSilo *silo, -+ const gchar *silo_filename, -+ GHashTable *silo_installed_by_desktopid, -+ GHashTable *silo_installed_by_id, - gboolean *found, - GError **error) - { - const gchar *id, *origin; - GPtrArray *components; -- g_autoptr(GRWLockReaderLocker) locker = NULL; - - /* not enough info to find */ - id = gs_app_get_id (app); - if (id == NULL) - return TRUE; - -- locker = g_rw_lock_reader_locker_new (&self->silo_lock); -- - origin = gs_app_get_origin_appstream (app); - - /* look in AppStream then fall back to AppData */ -@@ -1056,15 +1065,15 @@ gs_plugin_refine_from_id (GsPluginAppstream *self, - - for (guint i = 0; i < components->len; i++) { - XbNode *component = g_ptr_array_index (components, i); -- if (!gs_appstream_refine_app (GS_PLUGIN (self), app, self->silo, component, flags, self->silo_installed_by_desktopid, -- self->silo_filename ? self->silo_filename : "", self->default_scope, error)) -+ if (!gs_appstream_refine_app (GS_PLUGIN (self), app, silo, component, flags, silo_installed_by_desktopid, -+ silo_filename ? silo_filename : "", self->default_scope, error)) - return FALSE; - gs_plugin_appstream_set_compulsory_quirk (app, component); - } - - /* if an installed desktop or appdata file exists set to installed */ - if (gs_app_get_state (app) == GS_APP_STATE_UNKNOWN) { -- if (!gs_plugin_appstream_refine_state (self, app, error)) -+ if (!gs_plugin_appstream_refine_state (self, app, silo_installed_by_id, error)) - return FALSE; - } - -@@ -1077,6 +1086,10 @@ static gboolean - gs_plugin_refine_from_pkgname (GsPluginAppstream *self, - GsApp *app, - GsPluginRefineFlags flags, -+ XbSilo *silo, -+ const gchar *silo_filename, -+ GHashTable *silo_installed_by_desktopid, -+ GHashTable *silo_installed_by_id, - GError **error) - { - GPtrArray *sources = gs_app_get_sources (app); -@@ -1089,33 +1102,30 @@ gs_plugin_refine_from_pkgname (GsPluginAppstream *self, - /* find all apps when matching any prefixes */ - for (guint j = 0; j < sources->len; j++) { - const gchar *pkgname = g_ptr_array_index (sources, j); -- g_autoptr(GRWLockReaderLocker) locker = NULL; - g_autoptr(GString) xpath = g_string_new (NULL); - g_autoptr(XbNode) component = NULL; - -- locker = g_rw_lock_reader_locker_new (&self->silo_lock); -- - /* prefer actual apps and then fallback to anything else */ - xb_string_append_union (xpath, "components/component[@type='desktop-application']/pkgname[text()='%s']/..", pkgname); - xb_string_append_union (xpath, "components/component[@type='console-application']/pkgname[text()='%s']/..", pkgname); - xb_string_append_union (xpath, "components/component[@type='web-application']/pkgname[text()='%s']/..", pkgname); - xb_string_append_union (xpath, "components/component/pkgname[text()='%s']/..", pkgname); -- component = xb_silo_query_first (self->silo, xpath->str, &error_local); -+ component = xb_silo_query_first (silo, xpath->str, &error_local); - if (component == NULL) { - if (g_error_matches (error_local, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) - continue; - g_propagate_error (error, g_steal_pointer (&error_local)); - return FALSE; - } -- if (!gs_appstream_refine_app (GS_PLUGIN (self), app, self->silo, component, flags, self->silo_installed_by_desktopid, -- self->silo_filename ? self->silo_filename : "", self->default_scope, error)) -+ if (!gs_appstream_refine_app (GS_PLUGIN (self), app, silo, component, flags, silo_installed_by_desktopid, -+ silo_filename ? silo_filename : "", self->default_scope, error)) - return FALSE; - gs_plugin_appstream_set_compulsory_quirk (app, component); - } - - /* if an installed desktop or appdata file exists set to installed */ - if (gs_app_get_state (app) == GS_APP_STATE_UNKNOWN) { -- if (!gs_plugin_appstream_refine_state (self, app, error)) -+ if (!gs_plugin_appstream_refine_state (self, app, silo_installed_by_id, error)) - return FALSE; - } - -@@ -1153,6 +1163,10 @@ static gboolean refine_wildcard (GsPluginAppstream *self, - GsAppList *list, - GsPluginRefineFlags refine_flags, - GHashTable *apps_by_id, -+ XbSilo *silo, -+ const gchar *silo_filename, -+ GHashTable *silo_installed_by_desktopid, -+ GHashTable *silo_installed_by_id, - GCancellable *cancellable, - GError **error); - -@@ -1171,13 +1185,17 @@ refine_thread_cb (GTask *task, - g_autoptr(GHashTable) apps_by_id = NULL; - g_autoptr(GHashTable) apps_by_origin_and_id = NULL; - g_autoptr(GPtrArray) components = NULL; -- g_autoptr(GRWLockReaderLocker) locker = NULL; -+ g_autoptr(XbSilo) silo = NULL; -+ g_autofree gchar *silo_filename = NULL; -+ g_autoptr(GHashTable) silo_installed_by_desktopid = NULL; -+ g_autoptr(GHashTable) silo_installed_by_id = NULL; - g_autoptr(GError) local_error = NULL; - - assert_in_worker (self); - - /* check silo is valid */ -- if (!gs_plugin_appstream_check_silo (self, cancellable, &local_error)) { -+ silo = gs_plugin_appstream_ref_silo (self, &silo_filename, &silo_installed_by_desktopid, &silo_installed_by_id, cancellable, &local_error); -+ if (silo == NULL) { - g_task_return_error (task, g_steal_pointer (&local_error)); - return; - } -@@ -1185,9 +1203,7 @@ refine_thread_cb (GTask *task, - apps_by_id = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_ptr_array_unref); - apps_by_origin_and_id = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_ptr_array_unref); - -- locker = g_rw_lock_reader_locker_new (&self->silo_lock); -- -- components = xb_silo_query (self->silo, "components/component/id", 0, NULL); -+ components = xb_silo_query (silo, "components/component/id", 0, NULL); - for (guint i = 0; components != NULL && i < components->len; i++) { - XbNode *node = g_ptr_array_index (components, i); - g_autoptr(XbNode) component_node = xb_node_get_parent (node); -@@ -1234,7 +1250,7 @@ refine_thread_cb (GTask *task, - } - - g_clear_pointer (&components, g_ptr_array_unref); -- components = xb_silo_query (self->silo, "component/id", 0, NULL); -+ components = xb_silo_query (silo, "component/id", 0, NULL); - for (guint i = 0; components != NULL && i < components->len; i++) { - XbNode *node = g_ptr_array_index (components, i); - g_autoptr(XbNode) component_node = xb_node_get_parent (node); -@@ -1262,12 +1278,14 @@ refine_thread_cb (GTask *task, - continue; - - /* find by ID then fall back to package name */ -- if (!gs_plugin_refine_from_id (self, app, flags, apps_by_id, apps_by_origin_and_id, &found, &local_error)) { -+ if (!gs_plugin_refine_from_id (self, app, flags, apps_by_id, apps_by_origin_and_id, silo, silo_filename, -+ silo_installed_by_desktopid, silo_installed_by_id, &found, &local_error)) { - g_task_return_error (task, g_steal_pointer (&local_error)); - return; - } - if (!found) { -- if (!gs_plugin_refine_from_pkgname (self, app, flags, &local_error)) { -+ if (!gs_plugin_refine_from_pkgname (self, app, flags, silo, silo_filename, -+ silo_installed_by_desktopid, silo_installed_by_id, &local_error)) { - g_task_return_error (task, g_steal_pointer (&local_error)); - return; - } -@@ -1286,7 +1304,8 @@ refine_thread_cb (GTask *task, - GsApp *app = gs_app_list_index (app_list, j); - - if (gs_app_has_quirk (app, GS_APP_QUIRK_IS_WILDCARD) && -- !refine_wildcard (self, app, list, flags, apps_by_id, cancellable, &local_error)) { -+ !refine_wildcard (self, app, list, flags, apps_by_id, silo, silo_filename, -+ silo_installed_by_desktopid, silo_installed_by_id,cancellable, &local_error)) { - g_task_return_error (task, g_steal_pointer (&local_error)); - return; - } -@@ -1311,20 +1330,21 @@ refine_wildcard (GsPluginAppstream *self, - GsAppList *list, - GsPluginRefineFlags refine_flags, - GHashTable *apps_by_id, -+ XbSilo *silo, -+ const gchar *silo_filename, -+ GHashTable *silo_installed_by_desktopid, -+ GHashTable *silo_installed_by_id, - GCancellable *cancellable, - GError **error) - { - const gchar *id; - GPtrArray *components; -- g_autoptr(GRWLockReaderLocker) locker = NULL; - - /* not enough info to find */ - id = gs_app_get_id (app); - if (id == NULL) - return TRUE; - -- locker = g_rw_lock_reader_locker_new (&self->silo_lock); -- - components = g_hash_table_lookup (apps_by_id, id); - if (components == NULL) - return TRUE; -@@ -1333,20 +1353,20 @@ refine_wildcard (GsPluginAppstream *self, - g_autoptr(GsApp) new = NULL; - - /* new app */ -- new = gs_appstream_create_app (GS_PLUGIN (self), self->silo, component, self->silo_filename ? self->silo_filename : "", -+ new = gs_appstream_create_app (GS_PLUGIN (self), silo, component, silo_filename ? silo_filename : "", - self->default_scope, error); - if (new == NULL) - return FALSE; - gs_app_set_scope (new, AS_COMPONENT_SCOPE_SYSTEM); - gs_app_subsume_metadata (new, app); -- if (!gs_appstream_refine_app (GS_PLUGIN (self), new, self->silo, component, refine_flags, self->silo_installed_by_desktopid, -- self->silo_filename ? self->silo_filename : "", self->default_scope, error)) -+ if (!gs_appstream_refine_app (GS_PLUGIN (self), new, silo, component, refine_flags, silo_installed_by_desktopid, -+ silo_filename ? silo_filename : "", self->default_scope, error)) - return FALSE; - gs_plugin_appstream_set_compulsory_quirk (new, component); - - /* if an installed desktop or appdata file exists set to installed */ - if (gs_app_get_state (new) == GS_APP_STATE_UNKNOWN) { -- if (!gs_plugin_appstream_refine_state (self, new, error)) -+ if (!gs_plugin_appstream_refine_state (self, new, silo_installed_by_id, error)) - return FALSE; - } - -@@ -1398,21 +1418,20 @@ refine_categories_thread_cb (GTask *task, - GCancellable *cancellable) - { - GsPluginAppstream *self = GS_PLUGIN_APPSTREAM (source_object); -- g_autoptr(GRWLockReaderLocker) locker = NULL; -+ g_autoptr(XbSilo) silo = NULL; - GsPluginRefineCategoriesData *data = task_data; - g_autoptr(GError) local_error = NULL; - - assert_in_worker (self); - - /* check silo is valid */ -- if (!gs_plugin_appstream_check_silo (self, cancellable, &local_error)) { -+ silo = gs_plugin_appstream_ref_silo (self, NULL, NULL, NULL, cancellable, &local_error); -+ if (silo == NULL) { - g_task_return_error (task, g_steal_pointer (&local_error)); - return; - } - -- locker = g_rw_lock_reader_locker_new (&self->silo_lock); -- -- if (!gs_appstream_refine_category_sizes (self->silo, data->list, cancellable, &local_error)) { -+ if (!gs_appstream_refine_category_sizes (silo, data->list, cancellable, &local_error)) { - g_task_return_error (task, g_steal_pointer (&local_error)); - return; - } -@@ -1462,7 +1481,7 @@ list_apps_thread_cb (GTask *task, - GCancellable *cancellable) - { - GsPluginAppstream *self = GS_PLUGIN_APPSTREAM (source_object); -- g_autoptr(GRWLockReaderLocker) locker = NULL; -+ g_autoptr(XbSilo) silo = NULL; - g_autoptr(GsAppList) list = gs_app_list_new (); - GsPluginListAppsData *data = task_data; - GDateTime *released_since = NULL; -@@ -1516,65 +1535,64 @@ list_apps_thread_cb (GTask *task, - } - - /* check silo is valid */ -- if (!gs_plugin_appstream_check_silo (self, cancellable, &local_error)) { -+ silo = gs_plugin_appstream_ref_silo (self, NULL, NULL, NULL, cancellable, &local_error); -+ if (silo == NULL) { - g_task_return_error (task, g_steal_pointer (&local_error)); - return; - } - -- locker = g_rw_lock_reader_locker_new (&self->silo_lock); -- - if (released_since != NULL && -- !gs_appstream_add_recent (GS_PLUGIN (self), self->silo, list, age_secs, -+ !gs_appstream_add_recent (GS_PLUGIN (self), silo, list, age_secs, - cancellable, &local_error)) { - g_task_return_error (task, g_steal_pointer (&local_error)); - return; - } - - if (is_curated != GS_APP_QUERY_TRISTATE_UNSET && -- !gs_appstream_add_popular (self->silo, list, cancellable, &local_error)) { -+ !gs_appstream_add_popular (silo, list, cancellable, &local_error)) { - g_task_return_error (task, g_steal_pointer (&local_error)); - return; - } - - if (is_featured != GS_APP_QUERY_TRISTATE_UNSET && -- !gs_appstream_add_featured (self->silo, list, cancellable, &local_error)) { -+ !gs_appstream_add_featured (silo, list, cancellable, &local_error)) { - g_task_return_error (task, g_steal_pointer (&local_error)); - return; - } - - if (category != NULL && -- !gs_appstream_add_category_apps (GS_PLUGIN (self), self->silo, category, list, cancellable, &local_error)) { -+ !gs_appstream_add_category_apps (GS_PLUGIN (self), silo, category, list, cancellable, &local_error)) { - g_task_return_error (task, g_steal_pointer (&local_error)); - return; - } - - if (is_installed == GS_APP_QUERY_TRISTATE_TRUE && -- !gs_appstream_add_installed (GS_PLUGIN (self), self->silo, list, cancellable, &local_error)) { -+ !gs_appstream_add_installed (GS_PLUGIN (self), silo, list, cancellable, &local_error)) { - g_task_return_error (task, g_steal_pointer (&local_error)); - return; - } - - if (deployment_featured != NULL && -- !gs_appstream_add_deployment_featured (self->silo, deployment_featured, list, -+ !gs_appstream_add_deployment_featured (silo, deployment_featured, list, - cancellable, &local_error)) { - g_task_return_error (task, g_steal_pointer (&local_error)); - return; - } - - if (developers != NULL && -- !gs_appstream_search_developer_apps (GS_PLUGIN (self), self->silo, developers, list, cancellable, &local_error)) { -+ !gs_appstream_search_developer_apps (GS_PLUGIN (self), silo, developers, list, cancellable, &local_error)) { - g_task_return_error (task, g_steal_pointer (&local_error)); - return; - } - - if (keywords != NULL && -- !gs_appstream_search (GS_PLUGIN (self), self->silo, keywords, list, cancellable, &local_error)) { -+ !gs_appstream_search (GS_PLUGIN (self), silo, keywords, list, cancellable, &local_error)) { - g_task_return_error (task, g_steal_pointer (&local_error)); - return; - } - - if (alternate_of != NULL && -- !gs_appstream_add_alternates (self->silo, alternate_of, list, cancellable, &local_error)) { -+ !gs_appstream_add_alternates (silo, alternate_of, list, cancellable, &local_error)) { - g_task_return_error (task, g_steal_pointer (&local_error)); - return; - } -@@ -1623,12 +1641,14 @@ refresh_metadata_thread_cb (GTask *task, - GCancellable *cancellable) - { - GsPluginAppstream *self = GS_PLUGIN_APPSTREAM (source_object); -+ g_autoptr(XbSilo) silo = NULL; - g_autoptr(GError) local_error = NULL; - - assert_in_worker (self); - - /* Checking the silo will refresh it if needed. */ -- if (!gs_plugin_appstream_check_silo (self, cancellable, &local_error)) -+ silo = gs_plugin_appstream_ref_silo (self, NULL, NULL, NULL, cancellable, &local_error); -+ if (silo == NULL) - g_task_return_error (task, g_steal_pointer (&local_error)); - else - g_task_return_boolean (task, TRUE); --- -GitLab - - -From cf04c32b5fb1fd267096fad8dd11a22429ad788a Mon Sep 17 00:00:00 2001 -Date: Mon, 29 Apr 2024 17:45:08 +0200 -Subject: [PATCH 2/3] gs-plugin-appstream: Rename file_monitor_stamp to - silo_change_stamp - -Since it's used also in the gs_plugin_appstream_reload() and works -like a change indicator, name it appropriately to avoid confusion. ---- - plugins/core/gs-plugin-appstream.c | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - -diff --git a/plugins/core/gs-plugin-appstream.c b/plugins/core/gs-plugin-appstream.c -index 5749a175f3..99fe5a1432 100644 ---- a/plugins/core/gs-plugin-appstream.c -+++ b/plugins/core/gs-plugin-appstream.c -@@ -46,8 +46,8 @@ struct _GsPluginAppstream - GPtrArray *file_monitors; /* (owned) (element-type GFileMonitor) */ - /* The stamps help to avoid locking the silo lock in the main thread - and also to detect changes while loading other appstream data. */ -- gint file_monitor_stamp; /* the file monitor stamp, increased on every file monitor change */ -- gint file_monitor_stamp_current; /* the currently known file monitor stamp, checked for changes */ -+ gint silo_change_stamp; /* the silo change stamp, increased on every silo change */ -+ gint silo_change_stamp_current; /* the currently known silo change stamp, checked for changes */ - }; - - G_DEFINE_TYPE (GsPluginAppstream, gs_plugin_appstream, GS_TYPE_PLUGIN) -@@ -224,7 +224,7 @@ gs_plugin_appstream_file_monitor_changed_cb (GFileMonitor *monitor, - gpointer user_data) - { - GsPluginAppstream *self = user_data; -- g_atomic_int_inc (&self->file_monitor_stamp); -+ g_atomic_int_inc (&self->silo_change_stamp); - } - - static void -@@ -550,7 +550,7 @@ gs_plugin_appstream_ref_silo (GsPluginAppstream *self, - locker = g_mutex_locker_new (&self->silo_lock); - /* everything is okay */ - if (self->silo != NULL && xb_silo_is_valid (self->silo) && -- g_atomic_int_get (&self->file_monitor_stamp_current) == g_atomic_int_get (&self->file_monitor_stamp)) { -+ g_atomic_int_get (&self->silo_change_stamp_current) == g_atomic_int_get (&self->silo_change_stamp)) { - if (out_silo_filename != NULL) - *out_silo_filename = g_strdup (self->silo_filename); - if (out_silo_installed_by_desktopid != NULL) -@@ -568,7 +568,7 @@ gs_plugin_appstream_ref_silo (GsPluginAppstream *self, - g_clear_pointer (&blobfn, g_free); - self->default_scope = AS_COMPONENT_SCOPE_UNKNOWN; - g_ptr_array_set_size (self->file_monitors, 0); -- g_atomic_int_set (&self->file_monitor_stamp_current, g_atomic_int_get (&self->file_monitor_stamp)); -+ g_atomic_int_set (&self->silo_change_stamp_current, g_atomic_int_get (&self->silo_change_stamp)); - - /* FIXME: https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1422 */ - old_thread_default = g_main_context_ref_thread_default (); -@@ -707,7 +707,7 @@ gs_plugin_appstream_ref_silo (GsPluginAppstream *self, - if (old_thread_default != NULL) - g_main_context_push_thread_default (old_thread_default); - -- if (g_atomic_int_get (&self->file_monitor_stamp_current) != g_atomic_int_get (&self->file_monitor_stamp)) { -+ if (g_atomic_int_get (&self->silo_change_stamp_current) != g_atomic_int_get (&self->silo_change_stamp)) { - g_ptr_array_set_size (parent_appdata, 0); - g_ptr_array_set_size (parent_appstream, 0); - g_debug ("appstream: File monitors reported change while loading appstream data, reloading..."); -@@ -800,8 +800,8 @@ gs_plugin_appstream_reload (GsPlugin *plugin) - } - - self = GS_PLUGIN_APPSTREAM (plugin); -- /* simpler than getting the silo and setting it invalid */ -- g_atomic_int_inc (&self->file_monitor_stamp); -+ /* Invalidate the reference to the current silo */ -+ g_atomic_int_inc (&self->silo_change_stamp); - } - - static gint --- -GitLab - - -From 59b301b8a878f3e81359909a8d4107715eb60a35 Mon Sep 17 00:00:00 2001 -Date: Tue, 30 Apr 2024 13:13:36 +0200 -Subject: [PATCH 3/3] flatpak: Simplify XbSilo locking - -Instead of holding RW lock on the internal silo variable, simply return -a reference to it and work with it like with an immutable object. That -simplifies locking and makes the code cleaner. It can also make the code -quicker, in some cases. ---- - plugins/flatpak/gs-flatpak.c | 307 +++++++++++++++++++---------------- - 1 file changed, 163 insertions(+), 144 deletions(-) - -diff --git a/plugins/flatpak/gs-flatpak.c b/plugins/flatpak/gs-flatpak.c -index 2e175fd08e..9893cf88b7 100644 ---- a/plugins/flatpak/gs-flatpak.c -+++ b/plugins/flatpak/gs-flatpak.c -@@ -54,9 +54,11 @@ struct _GsFlatpak { - AsComponentScope scope; - GsPlugin *plugin; - XbSilo *silo; -- GRWLock silo_lock; -+ GMutex silo_lock; - gchar *silo_filename; - GHashTable *silo_installed_by_desktopid; -+ gint silo_change_stamp; -+ gint silo_change_stamp_current; - gchar *id; - guint changed_id; - GHashTable *app_silos; -@@ -654,10 +656,7 @@ gs_flatpak_create_source (GsFlatpak *self, FlatpakRemote *xremote) - static void - gs_flatpak_invalidate_silo (GsFlatpak *self) - { -- g_rw_lock_writer_lock (&self->silo_lock); -- if (self->silo != NULL) -- xb_silo_invalidate (self->silo); -- g_rw_lock_writer_unlock (&self->silo_lock); -+ g_atomic_int_inc (&self->silo_change_stamp); - } - - static void -@@ -1085,32 +1084,39 @@ gs_flatpak_rescan_installed (GsFlatpak *self, - g_debug ("Failed to read flatpak .desktop files in %s: %s", path, error_local->message); - } - --static gboolean --gs_flatpak_rescan_appstream_store (GsFlatpak *self, -- gboolean interactive, -- GCancellable *cancellable, -- GError **error) -+static XbSilo * -+gs_flatpak_ref_silo (GsFlatpak *self, -+ gboolean interactive, -+ gchar **out_silo_filename, -+ GHashTable **out_silo_installed_by_desktopid, -+ GCancellable *cancellable, -+ GError **error) - { - g_autofree gchar *blobfn = NULL; - g_autoptr(GFile) file = NULL; - g_autoptr(GPtrArray) xremotes = NULL; - g_autoptr(GPtrArray) desktop_paths = NULL; -- g_autoptr(GRWLockReaderLocker) reader_locker = NULL; -- g_autoptr(GRWLockWriterLocker) writer_locker = NULL; -+ g_autoptr(GMutexLocker) locker = NULL; - g_autoptr(XbBuilder) builder = NULL; - g_autoptr(GMainContext) old_thread_default = NULL; - -- reader_locker = g_rw_lock_reader_locker_new (&self->silo_lock); -+ locker = g_mutex_locker_new (&self->silo_lock); - /* everything is okay */ -- if (self->silo != NULL && xb_silo_is_valid (self->silo)) -- return TRUE; -- g_clear_pointer (&reader_locker, g_rw_lock_reader_locker_free); -+ if (self->silo != NULL && xb_silo_is_valid (self->silo) && -+ g_atomic_int_get (&self->silo_change_stamp_current) == g_atomic_int_get (&self->silo_change_stamp)) { -+ if (out_silo_filename != NULL) -+ *out_silo_filename = g_strdup (self->silo_filename); -+ if (out_silo_installed_by_desktopid != NULL && self->silo_installed_by_desktopid) -+ *out_silo_installed_by_desktopid = g_hash_table_ref (self->silo_installed_by_desktopid); -+ return g_object_ref (self->silo); -+ } - - /* drat! silo needs regenerating */ -- writer_locker = g_rw_lock_writer_locker_new (&self->silo_lock); -+ reload: - g_clear_object (&self->silo); - g_clear_pointer (&self->silo_filename, g_free); - g_clear_pointer (&self->silo_installed_by_desktopid, g_hash_table_unref); -+ g_atomic_int_set (&self->silo_change_stamp_current, g_atomic_int_get (&self->silo_change_stamp)); - - /* FIXME: https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1422 */ - old_thread_default = g_main_context_ref_thread_default (); -@@ -1138,7 +1144,7 @@ gs_flatpak_rescan_appstream_store (GsFlatpak *self, - error); - if (xremotes == NULL) { - gs_flatpak_error_convert (error); -- return FALSE; -+ return NULL; - } - for (guint i = 0; i < xremotes->len; i++) { - g_autoptr(GError) error_local = NULL; -@@ -1152,7 +1158,7 @@ gs_flatpak_rescan_appstream_store (GsFlatpak *self, - flatpak_remote_get_name (xremote), error_local->message); - if (g_cancellable_set_error_if_cancelled (cancellable, error)) { - gs_flatpak_error_convert (error); -- return FALSE; -+ return NULL; - } - } - } -@@ -1176,7 +1182,7 @@ gs_flatpak_rescan_appstream_store (GsFlatpak *self, - GS_UTILS_CACHE_FLAG_CREATE_DIRECTORY, - error); - if (blobfn == NULL) -- return FALSE; -+ return NULL; - file = g_file_new_for_path (blobfn); - g_debug ("ensuring %s", blobfn); - -@@ -1195,6 +1201,17 @@ gs_flatpak_rescan_appstream_store (GsFlatpak *self, - if (old_thread_default != NULL) - g_main_context_push_thread_default (old_thread_default); - -+ if (g_atomic_int_get (&self->silo_change_stamp_current) != g_atomic_int_get (&self->silo_change_stamp)) { -+ g_clear_pointer (&blobfn, g_free); -+ g_clear_pointer (&xremotes, g_ptr_array_unref); -+ g_clear_pointer (&desktop_paths, g_ptr_array_unref); -+ g_clear_pointer (&old_thread_default, g_main_context_unref); -+ g_clear_object (&file); -+ g_clear_object (&builder); -+ g_debug ("flatpak: Reported change while loading appstream data, reloading..."); -+ goto reload; -+ } -+ - if (self->silo != NULL) { - g_autoptr(GPtrArray) installed = NULL; - g_autoptr(XbNode) info_filename = NULL; -@@ -1218,66 +1235,46 @@ gs_flatpak_rescan_appstream_store (GsFlatpak *self, - info_filename = xb_silo_query_first (self->silo, "/info/filename", NULL); - if (info_filename != NULL) - self->silo_filename = g_strdup (xb_node_get_text (info_filename)); -+ -+ if (out_silo_filename != NULL) -+ *out_silo_filename = g_strdup (self->silo_filename); -+ if (out_silo_installed_by_desktopid != NULL && self->silo_installed_by_desktopid) -+ *out_silo_installed_by_desktopid = g_hash_table_ref (self->silo_installed_by_desktopid); -+ return g_object_ref (self->silo); - } - -- /* success */ -- return self->silo != NULL; -+ return NULL; - } - - static gboolean - gs_flatpak_rescan_app_data (GsFlatpak *self, - gboolean interactive, -+ XbSilo **out_silo, -+ gchar **out_silo_filename, -+ GHashTable **out_silo_installed_by_desktopid, - GCancellable *cancellable, - GError **error) - { -+ g_autoptr(XbSilo) silo = NULL; -+ - if (self->requires_full_rescan) { - gboolean res = gs_flatpak_refresh (self, 60, interactive, cancellable, error); -- if (res) -+ if (res) { - self->requires_full_rescan = FALSE; -- else -+ } else { - gs_flatpak_internal_data_changed (self); -- return res; -+ return res; -+ } - } - -- if (!gs_flatpak_rescan_appstream_store (self, interactive, cancellable, error)) { -+ silo = gs_flatpak_ref_silo (self, interactive, out_silo_filename, out_silo_installed_by_desktopid, cancellable, error); -+ if (silo == NULL) { - gs_flatpak_internal_data_changed (self); - return FALSE; - } - -- return TRUE; --} -- --/* Returns with a read lock held on @self->silo_lock on success. -- The *locker should be NULL when being called. */ --static gboolean --ensure_flatpak_silo_with_locker (GsFlatpak *self, -- GRWLockReaderLocker **locker, -- gboolean interactive, -- GCancellable *cancellable, -- GError **error) --{ -- /* should not hold the lock when called */ -- g_return_val_if_fail (*locker == NULL, FALSE); -- -- /* ensure valid */ -- if (!gs_flatpak_rescan_app_data (self, interactive, cancellable, error)) -- return FALSE; -- -- *locker = g_rw_lock_reader_locker_new (&self->silo_lock); -- -- while (self->silo == NULL) { -- g_clear_pointer (locker, g_rw_lock_reader_locker_free); -- -- if (!gs_flatpak_rescan_appstream_store (self, interactive, cancellable, error)) { -- gs_flatpak_internal_data_changed (self); -- return FALSE; -- } -- -- /* At this point either rescan_appstream_store() returned an error or it successfully -- * initialised self->silo. There is the possibility that another thread will invalidate -- * the silo before we regain the lock. If so, we’ll have to rescan again. */ -- *locker = g_rw_lock_reader_locker_new (&self->silo_lock); -- } -+ if (out_silo != NULL) -+ *out_silo = g_steal_pointer (&silo); - - return TRUE; - } -@@ -1412,6 +1409,7 @@ gs_flatpak_refresh_appstream (GsFlatpak *self, - { - gboolean ret; - g_autoptr(GPtrArray) xremotes = NULL; -+ g_autoptr(XbSilo) silo = NULL; - - /* get remotes */ - xremotes = flatpak_installation_list_remotes (gs_flatpak_get_installation (self, interactive), -@@ -1498,7 +1496,8 @@ gs_flatpak_refresh_appstream (GsFlatpak *self, - } - - /* ensure the AppStream silo is up to date */ -- if (!gs_flatpak_rescan_appstream_store (self, interactive, cancellable, error)) { -+ silo = gs_flatpak_ref_silo (self, interactive, NULL, NULL, cancellable, error); -+ if (silo == NULL) { - gs_flatpak_internal_data_changed (self); - return FALSE; - } -@@ -1646,7 +1645,7 @@ gs_flatpak_add_sources (GsFlatpak *self, - FlatpakInstallation *installation = gs_flatpak_get_installation (self, interactive); - - /* refresh */ -- if (!gs_flatpak_rescan_app_data (self, interactive, cancellable, error)) -+ if (!gs_flatpak_rescan_app_data (self, interactive, NULL, NULL, NULL, cancellable, error)) - return FALSE; - - /* get installed apps and runtimes */ -@@ -2080,7 +2079,7 @@ gs_flatpak_add_updates (GsFlatpak *self, - FlatpakInstallation *installation = gs_flatpak_get_installation (self, interactive); - - /* ensure valid */ -- if (!gs_flatpak_rescan_app_data (self, interactive, cancellable, error)) -+ if (!gs_flatpak_rescan_app_data (self, interactive, NULL, NULL, NULL, cancellable, error)) - return FALSE; - - /* get all the updatable apps and runtimes */ -@@ -2390,10 +2389,8 @@ gs_flatpak_create_fake_ref (GsApp *app, GError **error) - return xref; - } - --/* the _unlocked() version doesn't call gs_flatpak_rescan_app_data, -- * in order to avoid taking the writer lock on self->silo_lock */ - static gboolean --gs_flatpak_refine_app_state_unlocked (GsFlatpak *self, -+gs_flatpak_refine_app_state_internal (GsFlatpak *self, - GsApp *app, - gboolean interactive, - gboolean force_state_update, -@@ -2505,10 +2502,10 @@ gs_flatpak_refine_app_state (GsFlatpak *self, - GError **error) - { - /* ensure valid */ -- if (!gs_flatpak_rescan_app_data (self, interactive, cancellable, error)) -+ if (!gs_flatpak_rescan_app_data (self, interactive, NULL, NULL, NULL, cancellable, error)) - return FALSE; - -- return gs_flatpak_refine_app_state_unlocked (self, app, interactive, force_state_update, cancellable, error); -+ return gs_flatpak_refine_app_state_internal (self, app, interactive, force_state_update, cancellable, error); - } - - static GsApp * -@@ -2594,7 +2591,7 @@ gs_flatpak_create_runtime (GsFlatpak *self, - gs_flatpak_app_set_ref_name (app, split[0]); - gs_flatpak_app_set_ref_arch (app, split[1]); - -- if (!gs_flatpak_refine_app_state_unlocked (self, app, interactive, FALSE, NULL, &local_error)) -+ if (!gs_flatpak_refine_app_state_internal (self, app, interactive, FALSE, NULL, &local_error)) - g_debug ("Failed to refine state for runtime '%s': %s", gs_app_get_unique_id (app), local_error->message); - - /* save in the cache */ -@@ -2984,7 +2981,7 @@ gs_plugin_refine_item_size (GsFlatpak *self, - - /* is the app_runtime already installed? */ - app_runtime = gs_app_get_runtime (app); -- if (!gs_flatpak_refine_app_state_unlocked (self, -+ if (!gs_flatpak_refine_app_state_internal (self, - app_runtime, - interactive, - FALSE, -@@ -3096,6 +3093,8 @@ gs_flatpak_refine_appstream_from_bytes (GsFlatpak *self, - GBytes *appstream_gz, - GsPluginRefineFlags flags, - gboolean interactive, -+ const gchar *silo_filename, -+ GHashTable *silo_installed_by_desktopid, - GCancellable *cancellable, - GError **error) - { -@@ -3229,8 +3228,8 @@ gs_flatpak_refine_appstream_from_bytes (GsFlatpak *self, - } - - /* copy details from AppStream to app */ -- if (!gs_appstream_refine_app (self->plugin, app, silo, component_node, flags, self->silo_installed_by_desktopid, -- self->silo_filename ? self->silo_filename : "", self->scope, error)) -+ if (!gs_appstream_refine_app (self->plugin, app, silo, component_node, flags, silo_installed_by_desktopid, -+ silo_filename ? silo_filename : "", self->scope, error)) - return FALSE; - - if (gs_app_get_origin (app)) -@@ -3324,6 +3323,8 @@ static gboolean - gs_flatpak_refine_appstream (GsFlatpak *self, - GsApp *app, - XbSilo *silo, -+ const gchar *silo_filename, -+ GHashTable *silo_installed_by_desktopid, - GsPluginRefineFlags flags, - GHashTable *components_by_bundle, - gboolean interactive, -@@ -3410,11 +3411,12 @@ gs_flatpak_refine_appstream (GsFlatpak *self, - appstream_gz, - flags, - interactive, -+ silo_filename, silo_installed_by_desktopid, - cancellable, error); - } - -- if (!gs_appstream_refine_app (self->plugin, app, silo, component, flags, self->silo_installed_by_desktopid, -- self->silo_filename ? self->silo_filename : "", self->scope, error)) -+ if (!gs_appstream_refine_app (self->plugin, app, silo, component, flags, silo_installed_by_desktopid, -+ silo_filename ? silo_filename : "", self->scope, error)) - return FALSE; - - /* use the default release as the version number */ -@@ -3423,13 +3425,15 @@ gs_flatpak_refine_appstream (GsFlatpak *self, - } - - static gboolean --gs_flatpak_refine_app_unlocked (GsFlatpak *self, -+gs_flatpak_refine_app_internal (GsFlatpak *self, - GsApp *app, - GsPluginRefineFlags flags, - gboolean interactive, - gboolean force_state_update, - GHashTable *components_by_bundle, -- GRWLockReaderLocker **locker, -+ XbSilo *silo, -+ const gchar *silo_filename, -+ GHashTable *silo_installed_by_desktopid, - GCancellable *cancellable, - GError **error) - { -@@ -3440,13 +3444,9 @@ gs_flatpak_refine_app_unlocked (GsFlatpak *self, - if (gs_app_get_bundle_kind (app) != AS_BUNDLE_KIND_FLATPAK) - return TRUE; - -- g_clear_pointer (locker, g_rw_lock_reader_locker_free); -- -- if (!ensure_flatpak_silo_with_locker (self, locker, interactive, cancellable, error)) -- return FALSE; -- - /* always do AppStream properties */ -- if (!gs_flatpak_refine_appstream (self, app, self->silo, flags, components_by_bundle, interactive, cancellable, error)) -+ if (!gs_flatpak_refine_appstream (self, app, silo, silo_filename, silo_installed_by_desktopid, -+ flags, components_by_bundle, interactive, cancellable, error)) - return FALSE; - - /* AppStream sets the source to appname/arch/branch */ -@@ -3456,7 +3456,7 @@ gs_flatpak_refine_app_unlocked (GsFlatpak *self, - } - - /* check the installed state */ -- if (!gs_flatpak_refine_app_state_unlocked (self, app, interactive, force_state_update, cancellable, error)) { -+ if (!gs_flatpak_refine_app_state_internal (self, app, interactive, force_state_update, cancellable, error)) { - g_prefix_error (error, "failed to get state: "); - return FALSE; - } -@@ -3473,7 +3473,8 @@ gs_flatpak_refine_app_unlocked (GsFlatpak *self, - - /* if the state was changed, perhaps set the version from the release */ - if (old_state != gs_app_get_state (app)) { -- if (!gs_flatpak_refine_appstream (self, app, self->silo, flags, components_by_bundle, interactive, cancellable, error)) -+ if (!gs_flatpak_refine_appstream (self, app, silo, silo_filename, silo_installed_by_desktopid, -+ flags, components_by_bundle, interactive, cancellable, error)) - return FALSE; - } - -@@ -3567,11 +3568,16 @@ gs_flatpak_refine_addons (GsFlatpak *self, - gboolean interactive, - GCancellable *cancellable) - { -- g_autoptr(GRWLockReaderLocker) locker = NULL; -+ g_autoptr(XbSilo) silo = NULL; -+ g_autofree gchar *silo_filename = NULL; -+ g_autoptr(GHashTable) silo_installed_by_desktopid = NULL; - g_autoptr(GsAppList) addons = NULL; - g_autoptr(GString) errors = NULL; - guint ii, sz; - -+ if (!gs_flatpak_rescan_app_data (self, interactive, &silo, &silo_filename, &silo_installed_by_desktopid, cancellable, NULL)) -+ return; -+ - addons = gs_app_dup_addons (parent_app); - sz = addons ? gs_app_list_length (addons) : 0; - -@@ -3582,7 +3588,8 @@ gs_flatpak_refine_addons (GsFlatpak *self, - if (state != gs_app_get_state (addon)) - continue; - -- if (!gs_flatpak_refine_app_unlocked (self, addon, flags, interactive, TRUE, NULL, &locker, cancellable, &local_error)) { -+ if (!gs_flatpak_refine_app_internal (self, addon, flags, interactive, TRUE, NULL, silo, silo_filename, -+ silo_installed_by_desktopid, cancellable, &local_error)) { - if (errors) - g_string_append_c (errors, '\n'); - else -@@ -3614,13 +3621,16 @@ gs_flatpak_refine_app (GsFlatpak *self, - GCancellable *cancellable, - GError **error) - { -- g_autoptr(GRWLockReaderLocker) locker = NULL; -+ g_autoptr(XbSilo) silo = NULL; -+ g_autoptr(GHashTable) silo_installed_by_desktopid = NULL; -+ g_autofree gchar *silo_filename = NULL; - - /* ensure valid */ -- if (!gs_flatpak_rescan_app_data (self, interactive, cancellable, error)) -+ if (!gs_flatpak_rescan_app_data (self, interactive, &silo, &silo_filename, &silo_installed_by_desktopid, cancellable, error)) - return FALSE; - -- return gs_flatpak_refine_app_unlocked (self, app, flags, interactive, force_state_update, NULL, &locker, cancellable, error); -+ return gs_flatpak_refine_app_internal (self, app, flags, interactive, force_state_update, NULL, -+ silo, silo_filename, silo_installed_by_desktopid, cancellable, error); - } - - gboolean -@@ -3634,7 +3644,9 @@ gs_flatpak_refine_wildcard (GsFlatpak *self, GsApp *app, - const gchar *id; - GPtrArray* components = NULL; - g_autoptr(GError) error_local = NULL; -- g_autoptr(GRWLockReaderLocker) locker = NULL; -+ g_autoptr(XbSilo) silo = NULL; -+ g_autoptr(GHashTable) silo_installed_by_desktopid = NULL; -+ g_autofree gchar *silo_filename = NULL; - - GS_PROFILER_BEGIN_SCOPED (FlatpakRefineWildcard, "Flatpak (refine wildcard)", NULL); - -@@ -3643,7 +3655,8 @@ gs_flatpak_refine_wildcard (GsFlatpak *self, GsApp *app, - if (id == NULL) - return TRUE; - -- if (!ensure_flatpak_silo_with_locker (self, &locker, interactive, cancellable, error)) -+ silo = gs_flatpak_ref_silo (self, interactive, &silo_filename, &silo_installed_by_desktopid, cancellable, error); -+ if (silo == NULL) - return FALSE; - - GS_PROFILER_BEGIN_SCOPED (FlatpakRefineWildcardQuerySilo, "Flatpak (query silo)", NULL); -@@ -3653,7 +3666,7 @@ gs_flatpak_refine_wildcard (GsFlatpak *self, GsApp *app, - } else { - g_autoptr(GPtrArray) components_with_id = NULL; - *inout_components_by_id = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_ptr_array_unref); -- components_with_id = xb_silo_query (self->silo, "components/component/id", 0, &error_local); -+ components_with_id = xb_silo_query (silo, "components/component/id", 0, &error_local); - if (components_with_id == NULL) { - if (g_error_matches (error_local, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) - return TRUE; -@@ -3686,7 +3699,7 @@ gs_flatpak_refine_wildcard (GsFlatpak *self, GsApp *app, - g_autoptr(GPtrArray) bundles = NULL; - - *inout_components_by_bundle = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); -- bundles = xb_silo_query (self->silo, "/components/component/bundle[@type='flatpak']", 0, NULL); -+ bundles = xb_silo_query (silo, "/components/component/bundle[@type='flatpak']", 0, NULL); - for (guint b = 0; bundles != NULL && b < bundles->len; b++) { - XbNode *bundle_node = g_ptr_array_index (bundles, b); - g_autoptr(XbNode) component_node = xb_node_get_parent (bundle_node); -@@ -3709,7 +3722,7 @@ gs_flatpak_refine_wildcard (GsFlatpak *self, GsApp *app, - g_autoptr(GsApp) new = NULL; - - GS_PROFILER_BEGIN_SCOPED (FlatpakRefineWildcardCreateAppstreamApp, "Flatpak (create Appstream app)", NULL); -- new = gs_appstream_create_app (self->plugin, self->silo, component, self->silo_filename ? self->silo_filename : "", -+ new = gs_appstream_create_app (self->plugin, silo, component, silo_filename ? silo_filename : "", - self->scope, error); - GS_PROFILER_END_SCOPED (FlatpakRefineWildcardCreateAppstreamApp); - -@@ -3761,7 +3774,8 @@ gs_flatpak_refine_wildcard (GsFlatpak *self, GsApp *app, - g_debug ("Failed to get ref info for '%s' from wildcard '%s', skipping it...", gs_app_get_id (new), id); - } else { - GS_PROFILER_BEGIN_SCOPED (FlatpakRefineWildcardRefineNewApp, "Flatpak (refine new app)", NULL); -- if (!gs_flatpak_refine_app_unlocked (self, new, refine_flags, interactive, FALSE, *inout_components_by_bundle, &locker, cancellable, error)) -+ if (!gs_flatpak_refine_app_internal (self, new, refine_flags, interactive, FALSE, *inout_components_by_bundle, -+ silo, silo_filename, silo_installed_by_desktopid, cancellable, error)) - return FALSE; - GS_PROFILER_END_SCOPED (FlatpakRefineWildcardRefineNewApp); - -@@ -3894,10 +3908,18 @@ gs_flatpak_file_to_app_bundle (GsFlatpak *self, - /* load AppStream */ - appstream_gz = flatpak_bundle_ref_get_appstream (xref_bundle); - if (appstream_gz != NULL) { -+ g_autofree gchar *silo_filename = NULL; -+ g_autoptr(GHashTable) silo_installed_by_desktopid = NULL; -+ g_autoptr(XbSilo) tmp_silo = NULL; -+ -+ tmp_silo = gs_flatpak_ref_silo (self, interactive, &silo_filename, &silo_installed_by_desktopid, cancellable, error); -+ if (tmp_silo == NULL) -+ return NULL; - if (!gs_flatpak_refine_appstream_from_bytes (self, app, NULL, NULL, - appstream_gz, - GS_PLUGIN_REFINE_FLAGS_REQUIRE_ID, - interactive, -+ silo_filename, silo_installed_by_desktopid, - cancellable, error)) - return NULL; - } else { -@@ -3995,6 +4017,9 @@ gs_flatpak_file_to_app_ref (GsFlatpak *self, - g_autoptr(GsApp) app = NULL; - g_autoptr(XbBuilder) builder = xb_builder_new (); - g_autoptr(XbSilo) silo = NULL; -+ g_autoptr(XbSilo) tmp_silo = NULL; -+ g_autoptr(GHashTable) silo_installed_by_desktopid = NULL; -+ g_autofree gchar *silo_filename = NULL; - g_autofree gchar *origin_url = NULL; - g_autofree gchar *ref_comment = NULL; - g_autofree gchar *ref_description = NULL; -@@ -4274,8 +4299,12 @@ gs_flatpak_file_to_app_ref (GsFlatpak *self, - g_debug ("showing AppStream data: %s", xml); - } - -+ tmp_silo = gs_flatpak_ref_silo (self, interactive, &silo_filename, &silo_installed_by_desktopid, cancellable, error); -+ if (tmp_silo == NULL) -+ return NULL; -+ - /* get extra AppStream data if available */ -- if (!gs_flatpak_refine_appstream (self, app, silo, -+ if (!gs_flatpak_refine_appstream (self, app, silo, silo_filename, silo_installed_by_desktopid, - GS_PLUGIN_REFINE_FLAGS_MASK, - NULL, - interactive, -@@ -4296,17 +4325,16 @@ gs_flatpak_search (GsFlatpak *self, - GError **error) - { - g_autoptr(GsAppList) list_tmp = gs_app_list_new (); -- g_autoptr(GRWLockReaderLocker) locker = NULL; - g_autoptr(GMutexLocker) app_silo_locker = NULL; - g_autoptr(GPtrArray) silos_to_remove = g_ptr_array_new (); -+ g_autoptr(XbSilo) silo = NULL; - GHashTableIter iter; - gpointer key, value; - -- if (!ensure_flatpak_silo_with_locker (self, &locker, interactive, cancellable, error)) -+ if (!gs_flatpak_rescan_app_data (self, interactive, &silo, NULL, NULL, cancellable, error)) - return FALSE; - -- if (!gs_appstream_search (self->plugin, self->silo, values, list_tmp, -- cancellable, error)) -+ if (!gs_appstream_search (self->plugin, silo, values, list_tmp, cancellable, error)) - return FALSE; - - gs_flatpak_ensure_remote_title (self, interactive, cancellable); -@@ -4353,8 +4381,8 @@ gs_flatpak_search (GsFlatpak *self, - } - - for (guint i = 0; i < silos_to_remove->len; i++) { -- const char *silo = g_ptr_array_index (silos_to_remove, i); -- g_hash_table_remove (self->app_silos, silo); -+ const char *app_ref = g_ptr_array_index (silos_to_remove, i); -+ g_hash_table_remove (self->app_silos, app_ref); - } - - return TRUE; -@@ -4369,17 +4397,16 @@ gs_flatpak_search_developer_apps (GsFlatpak *self, - GError **error) - { - g_autoptr(GsAppList) list_tmp = gs_app_list_new (); -- g_autoptr(GRWLockReaderLocker) locker = NULL; - g_autoptr(GMutexLocker) app_silo_locker = NULL; - g_autoptr(GPtrArray) silos_to_remove = g_ptr_array_new (); -+ g_autoptr(XbSilo) silo = NULL; - GHashTableIter iter; - gpointer key, value; - -- if (!ensure_flatpak_silo_with_locker (self, &locker, interactive, cancellable, error)) -+ if (!gs_flatpak_rescan_app_data (self, interactive, &silo, NULL, NULL, cancellable, error)) - return FALSE; - -- if (!gs_appstream_search_developer_apps (self->plugin, self->silo, values, list_tmp, -- cancellable, error)) -+ if (!gs_appstream_search_developer_apps (self->plugin, silo, values, list_tmp, cancellable, error)) - return FALSE; - - gs_flatpak_ensure_remote_title (self, interactive, cancellable); -@@ -4426,8 +4453,8 @@ gs_flatpak_search_developer_apps (GsFlatpak *self, - } - - for (guint i = 0; i < silos_to_remove->len; i++) { -- const char *silo = g_ptr_array_index (silos_to_remove, i); -- g_hash_table_remove (self->app_silos, silo); -+ const char *app_ref = g_ptr_array_index (silos_to_remove, i); -+ g_hash_table_remove (self->app_silos, app_ref); - } - - return TRUE; -@@ -4441,14 +4468,12 @@ gs_flatpak_add_category_apps (GsFlatpak *self, - GCancellable *cancellable, - GError **error) - { -- g_autoptr(GRWLockReaderLocker) locker = NULL; -+ g_autoptr(XbSilo) silo = NULL; - -- if (!ensure_flatpak_silo_with_locker (self, &locker, interactive, cancellable, error)) -+ if (!gs_flatpak_rescan_app_data (self, interactive, &silo, NULL, NULL, cancellable, error)) - return FALSE; - -- return gs_appstream_add_category_apps (self->plugin, self->silo, -- category, list, -- cancellable, error); -+ return gs_appstream_add_category_apps (self->plugin, silo, category, list, cancellable, error); - } - - gboolean -@@ -4458,12 +4483,12 @@ gs_flatpak_refine_category_sizes (GsFlatpak *self, - GCancellable *cancellable, - GError **error) - { -- g_autoptr(GRWLockReaderLocker) locker = NULL; -+ g_autoptr(XbSilo) silo = NULL; - -- if (!ensure_flatpak_silo_with_locker (self, &locker, interactive, cancellable, error)) -+ if (!gs_flatpak_rescan_app_data (self, interactive, &silo, NULL, NULL, cancellable, error)) - return FALSE; - -- return gs_appstream_refine_category_sizes (self->silo, list, cancellable, error); -+ return gs_appstream_refine_category_sizes (silo, list, cancellable, error); - } - - gboolean -@@ -4474,13 +4499,12 @@ gs_flatpak_add_popular (GsFlatpak *self, - GError **error) - { - g_autoptr(GsAppList) list_tmp = gs_app_list_new (); -- g_autoptr(GRWLockReaderLocker) locker = NULL; -+ g_autoptr(XbSilo) silo = NULL; - -- if (!ensure_flatpak_silo_with_locker (self, &locker, interactive, cancellable, error)) -+ if (!gs_flatpak_rescan_app_data (self, interactive, &silo, NULL, NULL, cancellable, error)) - return FALSE; - -- if (!gs_appstream_add_popular (self->silo, list_tmp, -- cancellable, error)) -+ if (!gs_appstream_add_popular (silo, list_tmp, cancellable, error)) - return FALSE; - - gs_app_list_add_list (list, list_tmp); -@@ -4496,13 +4520,12 @@ gs_flatpak_add_featured (GsFlatpak *self, - GError **error) - { - g_autoptr(GsAppList) list_tmp = gs_app_list_new (); -- g_autoptr(GRWLockReaderLocker) locker = NULL; -+ g_autoptr(XbSilo) silo = NULL; - -- if (!ensure_flatpak_silo_with_locker (self, &locker, interactive, cancellable, error)) -+ if (!gs_flatpak_rescan_app_data (self, interactive, &silo, NULL, NULL, cancellable, error)) - return FALSE; - -- if (!gs_appstream_add_featured (self->silo, list_tmp, -- cancellable, error)) -+ if (!gs_appstream_add_featured (silo, list_tmp, cancellable, error)) - return FALSE; - - gs_app_list_add_list (list, list_tmp); -@@ -4518,12 +4541,12 @@ gs_flatpak_add_deployment_featured (GsFlatpak *self, - GCancellable *cancellable, - GError **error) - { -- g_autoptr(GRWLockReaderLocker) locker = NULL; -+ g_autoptr(XbSilo) silo = NULL; - -- if (!ensure_flatpak_silo_with_locker (self, &locker, interactive, cancellable, error)) -+ if (!gs_flatpak_rescan_app_data (self, interactive, &silo, NULL, NULL, cancellable, error)) - return FALSE; - -- return gs_appstream_add_deployment_featured (self->silo, deployments, list, cancellable, error); -+ return gs_appstream_add_deployment_featured (silo, deployments, list, cancellable, error); - } - - gboolean -@@ -4535,13 +4558,12 @@ gs_flatpak_add_alternates (GsFlatpak *self, - GError **error) - { - g_autoptr(GsAppList) list_tmp = gs_app_list_new (); -- g_autoptr(GRWLockReaderLocker) locker = NULL; -+ g_autoptr(XbSilo) silo = NULL; - -- if (!ensure_flatpak_silo_with_locker (self, &locker, interactive, cancellable, error)) -+ if (!gs_flatpak_rescan_app_data (self, interactive, &silo, NULL, NULL, cancellable, error)) - return FALSE; - -- if (!gs_appstream_add_alternates (self->silo, app, list_tmp, -- cancellable, error)) -+ if (!gs_appstream_add_alternates (silo, app, list_tmp, cancellable, error)) - return FALSE; - - gs_app_list_add_list (list, list_tmp); -@@ -4558,13 +4580,12 @@ gs_flatpak_add_recent (GsFlatpak *self, - GError **error) - { - g_autoptr(GsAppList) list_tmp = gs_app_list_new (); -- g_autoptr(GRWLockReaderLocker) locker = NULL; -+ g_autoptr(XbSilo) silo = NULL; - -- if (!ensure_flatpak_silo_with_locker (self, &locker, interactive, cancellable, error)) -+ if (!gs_flatpak_rescan_app_data (self, interactive, &silo, NULL, NULL, cancellable, error)) - return FALSE; - -- if (!gs_appstream_add_recent (self->plugin, self->silo, list_tmp, age, -- cancellable, error)) -+ if (!gs_appstream_add_recent (self->plugin, silo, list_tmp, age, cancellable, error)) - return FALSE; - - gs_flatpak_claim_app_list (self, list_tmp, interactive); -@@ -4582,12 +4603,12 @@ gs_flatpak_url_to_app (GsFlatpak *self, - GError **error) - { - g_autoptr(GsAppList) list_tmp = gs_app_list_new (); -- g_autoptr(GRWLockReaderLocker) locker = NULL; -+ g_autoptr(XbSilo) silo = NULL; - -- if (!ensure_flatpak_silo_with_locker (self, &locker, interactive, cancellable, error)) -+ if (!gs_flatpak_rescan_app_data (self, interactive, &silo, NULL, NULL, cancellable, error)) - return FALSE; - -- if (!gs_appstream_url_to_app (self->plugin, self->silo, list_tmp, url, cancellable, error)) -+ if (!gs_appstream_url_to_app (self->plugin, silo, list_tmp, url, cancellable, error)) - return FALSE; - - gs_flatpak_claim_app_list (self, list_tmp, interactive); -@@ -4638,10 +4659,8 @@ gs_flatpak_finalize (GObject *object) - g_signal_handler_disconnect (self->monitor, self->changed_id); - self->changed_id = 0; - } -- if (self->silo != NULL) -- g_object_unref (self->silo); -- if (self->monitor != NULL) -- g_object_unref (self->monitor); -+ g_clear_object (&self->silo); -+ g_clear_object (&self->monitor); - g_clear_pointer (&self->silo_filename, g_free); - g_clear_pointer (&self->silo_installed_by_desktopid, g_hash_table_unref); - -@@ -4654,7 +4673,7 @@ gs_flatpak_finalize (GObject *object) - g_object_unref (self->plugin); - g_hash_table_unref (self->broken_remotes); - g_mutex_clear (&self->broken_remotes_mutex); -- g_rw_lock_clear (&self->silo_lock); -+ g_mutex_clear (&self->silo_lock); - g_hash_table_unref (self->app_silos); - g_mutex_clear (&self->app_silos_mutex); - g_clear_pointer (&self->remote_title, g_hash_table_unref); -@@ -4675,7 +4694,7 @@ gs_flatpak_init (GsFlatpak *self) - { - /* XbSilo needs external locking as we destroy the silo and build a new - * one when something changes */ -- g_rw_lock_init (&self->silo_lock); -+ g_mutex_init (&self->silo_lock); - - g_mutex_init (&self->installed_refs_mutex); - self->installed_refs = NULL; --- -GitLab - diff --git a/gnome-software.spec b/gnome-software.spec index 5b8b2b4..708b3f5 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -18,22 +18,20 @@ %bcond dkms %[!0%{?rhel}] # this is not a library version -%define gs_plugin_version 21 +%define gs_plugin_version 22 %global tarball_version %%(echo %{version} | tr '~' '.') %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 47.2 -Release: 3%{?dist} +Version: 48~alpha2 +Release: 1%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later URL: https://apps.gnome.org/Software -Source0: https://download.gnome.org/sources/gnome-software/47/%{name}-%{tarball_version}.tar.xz - -Patch01: 0001-crash-under-gs_appstream_gather_merge_data.patch +Source0: https://download.gnome.org/sources/gnome-software/48/%{name}-%{tarball_version}.tar.xz # ostree and flatpak not on i686 for Fedora and RHEL 10 # https://github.com/containers/composefs/pull/229#issuecomment-1838735764 @@ -290,6 +288,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Tue Jan 07 2025 Milan Crha - 48~alpha2-1 +- Update to 48.alpha2 + * Mon Dec 09 2024 Milan Crha - 47.2-3 - Resolves: #2272232 (Crash under gs_appstream_gather_merge_data()) diff --git a/sources b/sources index 4b9ac1c..c1aa6d8 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-47.2.tar.xz) = 60de4a3c3237bfdc0dbbefdeccb00c97af7332a36c6beb5610fb6a416508e8b4712fd007e395ad283a3f9cb8d3e0f3a56c134ff28b3f22953a448188a1005cb6 +SHA512 (gnome-software-48.alpha2.tar.xz) = 89471657b9fe10b621b15916ced35e24aff133cdb003b57535393a47eac99bef392442cce466a6a8519997cc845f0aa4a4416b79cc3bb8e10b72da17bbfdb0b6 From 0589468f3c6d5d31a4ca5fba6a0c8e5c4c8956bd Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Tue, 14 Jan 2025 18:05:07 +0100 Subject: [PATCH 083/116] Update to 48.alpha3 --- gnome-software.spec | 5 ++++- sources | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index 708b3f5..a45bc57 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -25,7 +25,7 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 48~alpha2 +Version: 48~alpha3 Release: 1%{?dist} Summary: A software center for GNOME @@ -288,6 +288,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Tue Jan 14 2025 Milan Crha - 48~alpha3-1 +- Update to 48.alpha3 + * Tue Jan 07 2025 Milan Crha - 48~alpha2-1 - Update to 48.alpha2 diff --git a/sources b/sources index c1aa6d8..4aa7442 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-48.alpha2.tar.xz) = 89471657b9fe10b621b15916ced35e24aff133cdb003b57535393a47eac99bef392442cce466a6a8519997cc845f0aa4a4416b79cc3bb8e10b72da17bbfdb0b6 +SHA512 (gnome-software-48.alpha3.tar.xz) = 8b05264b77c667687b1f98e9a325b6e8829328387984830bb697f1fa91ef0eef3743bbf30c0440596b655195dcc825a4d1ec56a5d2d9b2d2d87adc3118fc91f2 From 1f728b9f4b847dfbb5a02d36092e4aef0366c999 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 16 Jan 2025 22:56:23 +0000 Subject: [PATCH 084/116] Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild --- gnome-software.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gnome-software.spec b/gnome-software.spec index a45bc57..02e5395 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -26,7 +26,7 @@ Name: gnome-software Version: 48~alpha3 -Release: 1%{?dist} +Release: 2%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -288,6 +288,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Thu Jan 16 2025 Fedora Release Engineering - 48~alpha3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + * Tue Jan 14 2025 Milan Crha - 48~alpha3-1 - Update to 48.alpha3 From 539e242884a19daed280a1b30eee235b9f94668a Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 3 Feb 2025 09:00:10 +0100 Subject: [PATCH 085/116] Update to 48.beta --- gnome-software.spec | 7 +++++-- sources | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index 02e5395..26aca7c 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -25,8 +25,8 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 48~alpha3 -Release: 2%{?dist} +Version: 48~beta +Release: 1%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -288,6 +288,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Mon Feb 03 2025 Milan Crha - 48~beta-1 +- Update to 48.beta + * Thu Jan 16 2025 Fedora Release Engineering - 48~alpha3-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild diff --git a/sources b/sources index 4aa7442..c07dbaa 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-48.alpha3.tar.xz) = 8b05264b77c667687b1f98e9a325b6e8829328387984830bb697f1fa91ef0eef3743bbf30c0440596b655195dcc825a4d1ec56a5d2d9b2d2d87adc3118fc91f2 +SHA512 (gnome-software-48.beta.tar.xz) = 7f6744bea6e1adb136f9bccd619c9753fa94d5f00a19a3a9e8ef2806b1ea572345abe7462b20ba66e86c9a77a25a0c6cd94ffafd6607f8712e15ed66ebe3dec4 From f46e9e0cb86e66161e17be26e8bda2fbcbc05286 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 3 Mar 2025 09:38:54 +0100 Subject: [PATCH 086/116] Update to 48.rc --- gnome-software.spec | 19 +++++++++++-------- sources | 2 +- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index 26aca7c..3f2562c 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -1,11 +1,11 @@ -%global appstream_version 0.14.0 -%global flatpak_version 1.9.1 -%global fwupd_version 1.5.6 -%global glib2_version 2.70.0 -%global gtk4_version 4.14.0 +%global appstream_version 0.16.4 +%global flatpak_version 1.14.1 +%global fwupd_version 1.6.2 +%global glib2_version 2.76.0 +%global gtk4_version 4.16.0 %global json_glib_version 1.6.0 -%global libadwaita_version 1.6~alpha -%global libxmlb_version 0.1.7 +%global libadwaita_version 1.6.0 +%global libxmlb_version 0.3.4 %global packagekit_version 1.2.5 # Disable WebApps for RHEL builds @@ -25,7 +25,7 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 48~beta +Version: 48~rc Release: 1%{?dist} Summary: A software center for GNOME @@ -288,6 +288,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Mon Mar 03 2025 Milan Crha - 48~rc-1 +- Update to 48.rc + * Mon Feb 03 2025 Milan Crha - 48~beta-1 - Update to 48.beta diff --git a/sources b/sources index c07dbaa..029e225 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-48.beta.tar.xz) = 7f6744bea6e1adb136f9bccd619c9753fa94d5f00a19a3a9e8ef2806b1ea572345abe7462b20ba66e86c9a77a25a0c6cd94ffafd6607f8712e15ed66ebe3dec4 +SHA512 (gnome-software-48.rc.tar.xz) = 830e70fc6af22e6f70047ef13f2307548f939c8191370de10cdfba9a9fc907297aa06831eebc859bf442889e3782e5168d559ad115a32c3623f5179b16489703 From 909247b0df67611394949fc4cbc492ade7d68393 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 14 Mar 2025 09:47:52 +0100 Subject: [PATCH 087/116] Update to 48.0 --- gnome-software.spec | 5 ++++- sources | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index 3f2562c..cf92bf5 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -25,7 +25,7 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 48~rc +Version: 48.0 Release: 1%{?dist} Summary: A software center for GNOME @@ -288,6 +288,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Mar 14 2025 Milan Crha - 48.0-1 +- Update to 48.0 + * Mon Mar 03 2025 Milan Crha - 48~rc-1 - Update to 48.rc diff --git a/sources b/sources index 029e225..08e726a 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-48.rc.tar.xz) = 830e70fc6af22e6f70047ef13f2307548f939c8191370de10cdfba9a9fc907297aa06831eebc859bf442889e3782e5168d559ad115a32c3623f5179b16489703 +SHA512 (gnome-software-48.0.tar.xz) = ec61395a4376dfbe281337c29822f3854ab240c32172011b5bb589ef4d9c5ee7f1e4dc559e6cdaf5d24c728eb3e01dc7cd6069813c23e280dbb5aaf8f6336742 From 807d38c4d22e6b29f599ab09bf29993421a8ed33 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 11 Apr 2025 08:37:11 +0200 Subject: [PATCH 088/116] Update to 48.1 --- gnome-software.spec | 5 ++++- sources | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index cf92bf5..763ed62 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -25,7 +25,7 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 48.0 +Version: 48.1 Release: 1%{?dist} Summary: A software center for GNOME @@ -288,6 +288,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Fri Apr 11 2025 Milan Crha - 48.1-1 +- Update to 48.1 + * Fri Mar 14 2025 Milan Crha - 48.0-1 - Update to 48.0 diff --git a/sources b/sources index 08e726a..31b7ac3 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-48.0.tar.xz) = ec61395a4376dfbe281337c29822f3854ab240c32172011b5bb589ef4d9c5ee7f1e4dc559e6cdaf5d24c728eb3e01dc7cd6069813c23e280dbb5aaf8f6336742 +SHA512 (gnome-software-48.1.tar.xz) = 7cb1e7a7527e65e6283916cecee55fa4e65d71e538ced65af488d28e94801755d2ab961d2f4603cec0f781893e298fee109df4a839ee99fc3de2cefb82f25a97 From c3fcc6a85e3cac28893a05bb162a01efc02eba08 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Tue, 29 Apr 2025 11:05:44 +0200 Subject: [PATCH 089/116] Switch from PackageKit to DNF5 plugin --- 0001-dnf5-plugin.patch | 5565 ++++++++++++++++++++++++++++++++++++++++ gnome-software.spec | 35 +- 2 files changed, 5599 insertions(+), 1 deletion(-) create mode 100644 0001-dnf5-plugin.patch diff --git a/0001-dnf5-plugin.patch b/0001-dnf5-plugin.patch new file mode 100644 index 0000000..f7b5b67 --- /dev/null +++ b/0001-dnf5-plugin.patch @@ -0,0 +1,5565 @@ +at commit 31a1ad73cc4fa28b0d352a7ac392bec76e9c10a4 +Date: Wed Apr 2 14:21:03 2025 +0200 + +diff --git a/meson_options.txt b/meson_options.txt +index bc32ba561..523f572cd 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -2,6 +2,7 @@ option('tests', type : 'boolean', value : true, description : 'enable tests') + option('man', type : 'boolean', value : true, description : 'enable man pages') + option('packagekit', type : 'boolean', value : true, description : 'enable PackageKit support') + option('packagekit_autoremove', type : 'boolean', value : false, description : 'autoremove packages in PackageKit') ++option('dnf5', type : 'boolean', value : true, description : 'enable dnf5 support') + option('polkit', type : 'boolean', value : true, description : 'enable PolKit support') + option('eos_updater', type : 'boolean', value : false, description : 'enable eos-updater support') + option('fwupd', type : 'boolean', value : true, description : 'enable fwupd support') +diff --git a/plugins/dnf5/gs-dnf5-progress-helper.c b/plugins/dnf5/gs-dnf5-progress-helper.c +new file mode 100644 +index 000000000..d720adc87 +--- /dev/null ++++ b/plugins/dnf5/gs-dnf5-progress-helper.c +@@ -0,0 +1,532 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- ++ * vi:set noexpandtab tabstop=8 shiftwidth=8: ++ * ++ * Copyright (C) 2024 Red Hat ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++ ++#include ++ ++#include "gs-dnf5-generated.h" ++ ++#include "gs-dnf5-progress-helper.h" ++ ++struct _GsDnf5ProgressHelper ++{ ++ GObject parent; ++ ++ GsDnf5RpmRpm *rpm_proxy; /* (owned) */ ++ GsDnf5Base *base_proxy; /* (owned) */ ++ GsApp *app; /* (owned) */ ++ gchar *session_object_path; /* (owned) */ ++ GHashTable *ongoing_downloads; /* (owned); gchar * (download_id) ~> DownloadInfo * */ ++ GsAppState recover_download_state; ++ guint64 to_download_total; ++ guint64 downloaded_total; ++ ++ gulong download_add_new_id; ++ gulong download_progress_id; ++ gulong download_mirror_failure_id; ++ gulong download_end_id; ++ gulong transaction_before_begin_id; ++ gulong transaction_after_complete_id; ++ gulong transaction_elem_progress_id; ++ gulong transaction_action_progress_id; ++ gulong transaction_action_start_id; ++ gulong transaction_action_stop_id; ++ gulong transaction_script_error_id; ++ gulong transaction_script_start_id; ++ gulong transaction_script_stop_id; ++ gulong transaction_transaction_progress_id; ++ gulong transaction_transaction_start_id; ++ gulong transaction_transaction_stop_id; ++ gulong transaction_unpack_error_id; ++ gulong transaction_verify_progress_id; ++ gulong transaction_verify_start_id; ++ gulong transaction_verify_stop_id; ++}; ++ ++G_DEFINE_TYPE (GsDnf5ProgressHelper, gs_dnf5_progress_helper, G_TYPE_OBJECT) ++ ++static void ++gs_dnf5_update_download_progress (GsDnf5ProgressHelper *self) ++{ ++ if (self->to_download_total > 0) ++ gs_app_set_progress (self->app, 100 * self->downloaded_total / self->to_download_total); ++} ++ ++typedef struct { ++ guint64 downloaded; ++ guint64 total; ++} DownloadInfo; ++ ++static void ++gs_dnf5_download_add_new_cb (GsDnf5Base *object, ++ const gchar *arg_session_object_path, ++ const gchar *arg_download_id, ++ const gchar *arg_description, ++ gint64 arg_total_to_download, ++ GsDnf5ProgressHelper *self) ++{ ++ DownloadInfo *download_info; ++ ++ if (g_strcmp0 (self->session_object_path, arg_session_object_path) != 0) ++ return; ++ g_debug ("%s: download_id:'%s' description:'%s' total_to_download:%" G_GINT64_FORMAT, ++ G_STRFUNC, arg_download_id, arg_description, arg_total_to_download); ++ g_return_if_fail (arg_download_id != NULL); ++ ++ if (arg_total_to_download <= 0) ++ return; ++ ++ if (g_hash_table_size (self->ongoing_downloads) == 0) { ++ self->recover_download_state = gs_app_get_state (self->app); ++ self->to_download_total = 0; ++ self->downloaded_total = 0; ++ gs_app_set_state (self->app, GS_APP_STATE_DOWNLOADING); ++ } ++ ++ download_info = g_new0 (DownloadInfo, 1); ++ download_info->total = arg_total_to_download; ++ ++ g_hash_table_insert (self->ongoing_downloads, g_strdup (arg_download_id), download_info); ++ self->to_download_total += arg_total_to_download; ++ ++ gs_app_set_size_download (self->app, GS_SIZE_TYPE_VALID, self->to_download_total); ++ gs_dnf5_update_download_progress (self); ++} ++ ++static void ++gs_dnf5_download_end_cb (GsDnf5Base *object, ++ const gchar *arg_session_object_path, ++ const gchar *arg_download_id, ++ guint arg_transfer_status, ++ const gchar *arg_message, ++ GsDnf5ProgressHelper *self) ++{ ++ DownloadInfo *download_info; ++ ++ if (g_strcmp0 (self->session_object_path, arg_session_object_path) != 0) ++ return; ++ g_debug ("%s: download_id:'%s' transfer_status:%u message:'%s'", ++ G_STRFUNC, arg_download_id, arg_transfer_status, arg_message); ++ g_return_if_fail (arg_download_id != NULL); ++ ++ download_info = g_hash_table_lookup (self->ongoing_downloads, arg_download_id); ++ if (download_info != NULL) { ++ self->downloaded_total -= download_info->downloaded; ++ self->downloaded_total += download_info->total; ++ ++ /* remove after being done with the `download_info`, because it frees it */ ++ g_hash_table_remove (self->ongoing_downloads, arg_download_id); ++ download_info = NULL; ++ ++ /* it's the last package to be downloaded */ ++ if (g_hash_table_size (self->ongoing_downloads) == 0) { ++ gs_app_set_state (self->app, self->recover_download_state); ++ gs_app_set_progress (self->app, GS_APP_PROGRESS_UNKNOWN); ++ gs_app_set_size_download (self->app, GS_SIZE_TYPE_UNKNOWN, 0); ++ } else { ++ gs_dnf5_update_download_progress (self); ++ } ++ } ++} ++ ++static void ++gs_dnf5_download_mirror_failure_cb (GsDnf5Base *object, ++ const gchar *arg_session_object_path, ++ const gchar *arg_download_id, ++ const gchar *arg_message, ++ const gchar *arg_url, ++ const gchar *arg_metadata, ++ GsDnf5ProgressHelper *self) ++{ ++ if (g_strcmp0 (self->session_object_path, arg_session_object_path) != 0) ++ return; ++ g_debug ("%s: download_id:'%s' message:'%s' url:'%s' metadata:'%s'", ++ G_STRFUNC, arg_download_id, arg_message, arg_url, arg_metadata); ++} ++ ++static void ++gs_dnf5_download_progress_cb (GsDnf5Base *object, ++ const gchar *arg_session_object_path, ++ const gchar *arg_download_id, ++ gint64 arg_total_to_download, ++ gint64 arg_downloaded, ++ GsDnf5ProgressHelper *self) ++{ ++ DownloadInfo *download_info; ++ ++ if (g_strcmp0 (self->session_object_path, arg_session_object_path) != 0) ++ return; ++ g_debug ("%s: download_id:'%s' total_to_download:%" G_GINT64_FORMAT " downloaded:%" G_GINT64_FORMAT, ++ G_STRFUNC, arg_download_id, arg_total_to_download, arg_downloaded); ++ ++ download_info = g_hash_table_lookup (self->ongoing_downloads, arg_download_id); ++ if (download_info != NULL) { ++ self->downloaded_total += arg_downloaded - download_info->downloaded; ++ download_info->downloaded = arg_downloaded; ++ if (download_info->downloaded != (guint64) arg_total_to_download) { ++ self->to_download_total -= download_info->total; ++ download_info->total = arg_total_to_download; ++ self->to_download_total += download_info->total; ++ gs_app_set_size_download (self->app, GS_SIZE_TYPE_VALID, self->to_download_total); ++ } ++ gs_dnf5_update_download_progress (self); ++ } ++} ++ ++static void ++gs_dnf5_transaction_before_begin_cb (GsDnf5RpmRpm *object, ++ const gchar *arg_session_object_path, ++ guint64 arg_total, ++ GsDnf5ProgressHelper *self) ++{ ++ if (g_strcmp0 (self->session_object_path, arg_session_object_path) != 0) ++ return; ++ gs_app_set_progress (self->app, 0); ++ g_debug ("%s: total:%" G_GUINT64_FORMAT, G_STRFUNC, arg_total); ++} ++ ++static void ++gs_dnf5_transaction_after_complete_cb (GsDnf5RpmRpm *object, ++ const gchar *arg_session_object_path, ++ gboolean arg_success, ++ GsDnf5ProgressHelper *self) ++{ ++ if (g_strcmp0 (self->session_object_path, arg_session_object_path) != 0) ++ return; ++ g_debug ("%s: success:%d", G_STRFUNC, arg_success); ++ gs_app_set_progress (self->app, 100); ++} ++ ++static void ++gs_dnf5_transaction_elem_progress_cb (GsDnf5RpmRpm *object, ++ const gchar *arg_session_object_path, ++ const gchar *arg_nevra, ++ guint64 arg_processed, ++ guint64 arg_total, ++ GsDnf5ProgressHelper *self) ++{ ++ if (g_strcmp0 (self->session_object_path, arg_session_object_path) != 0) ++ return; ++ g_debug ("%s: nevra:'%s' progress:%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT, G_STRFUNC, arg_nevra, arg_processed, arg_total); ++ if (arg_total != 0) ++ gs_app_set_progress (self->app, arg_processed * 100 / arg_total); ++} ++ ++static void ++gs_dnf5_transaction_action_progress_cb (GsDnf5RpmRpm *object, ++ const gchar *arg_session_object_path, ++ const gchar *arg_nevra, ++ guint64 arg_processed, ++ guint64 arg_total, ++ GsDnf5ProgressHelper *self) ++{ ++ if (g_strcmp0 (self->session_object_path, arg_session_object_path) != 0) ++ return; ++ g_debug ("%s: nevra:'%s' progress:%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT, G_STRFUNC, arg_nevra, arg_processed, arg_total); ++} ++ ++static void ++gs_dnf5_transaction_action_start_cb (GsDnf5RpmRpm *object, ++ const gchar *arg_session_object_path, ++ const gchar *arg_nevra, ++ guint arg_action, ++ guint64 arg_total, ++ GsDnf5ProgressHelper *self) ++{ ++ if (g_strcmp0 (self->session_object_path, arg_session_object_path) != 0) ++ return; ++ g_debug ("%s: nevra:'%s' action:%u total:%" G_GUINT64_FORMAT, G_STRFUNC, arg_nevra, arg_action, arg_total); ++} ++ ++static void ++gs_dnf5_transaction_action_stop_cb (GsDnf5RpmRpm *object, ++ const gchar *arg_session_object_path, ++ const gchar *arg_nevra, ++ guint64 arg_total, ++ GsDnf5ProgressHelper *self) ++{ ++ if (g_strcmp0 (self->session_object_path, arg_session_object_path) != 0) ++ return; ++ g_debug ("%s: nevra:'%s' total:%" G_GUINT64_FORMAT, G_STRFUNC, arg_nevra, arg_total); ++} ++ ++static void ++gs_dnf5_transaction_script_error_cb (GsDnf5RpmRpm *object, ++ const gchar *arg_session_object_path, ++ const gchar *arg_nevra, ++ guint arg_scriptlet_type, ++ guint64 arg_return_code, ++ GsDnf5ProgressHelper *self) ++{ ++ if (g_strcmp0 (self->session_object_path, arg_session_object_path) != 0) ++ return; ++ g_debug ("%s: nevra:'%s' scriptlet-type:%u return-code:%" G_GUINT64_FORMAT, G_STRFUNC, arg_nevra, arg_scriptlet_type, arg_return_code); ++} ++ ++static void ++gs_dnf5_transaction_script_start_cb (GsDnf5RpmRpm *object, ++ const gchar *arg_session_object_path, ++ const gchar *arg_nevra, ++ guint arg_scriptlet_type, ++ GsDnf5ProgressHelper *self) ++{ ++ if (g_strcmp0 (self->session_object_path, arg_session_object_path) != 0) ++ return; ++ g_debug ("%s: nevra:'%s' scriptlet-type:%u", G_STRFUNC, arg_nevra, arg_scriptlet_type); ++} ++ ++static void ++gs_dnf5_transaction_script_stop_cb (GsDnf5RpmRpm *object, ++ const gchar *arg_session_object_path, ++ const gchar *arg_nevra, ++ guint arg_scriptlet_type, ++ guint64 arg_return_code, ++ GsDnf5ProgressHelper *self) ++{ ++ if (g_strcmp0 (self->session_object_path, arg_session_object_path) != 0) ++ return; ++ g_debug ("%s: nevra:'%s' scriptlet-type:%u return-code:%" G_GUINT64_FORMAT, G_STRFUNC, arg_nevra, arg_scriptlet_type, arg_return_code); ++} ++ ++static void ++gs_dnf5_transaction_transaction_progress_cb (GsDnf5RpmRpm *object, ++ const gchar *arg_session_object_path, ++ guint64 arg_processed, ++ guint64 arg_total, ++ GsDnf5ProgressHelper *self) ++{ ++ if (g_strcmp0 (self->session_object_path, arg_session_object_path) != 0) ++ return; ++ g_debug ("%s: progress:%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT, G_STRFUNC, arg_processed, arg_total); ++} ++ ++static void ++gs_dnf5_transaction_transaction_start_cb (GsDnf5RpmRpm *object, ++ const gchar *arg_session_object_path, ++ guint64 arg_total, ++ GsDnf5ProgressHelper *self) ++{ ++ if (g_strcmp0 (self->session_object_path, arg_session_object_path) != 0) ++ return; ++ g_debug ("%s: total:%" G_GUINT64_FORMAT, G_STRFUNC, arg_total); ++} ++ ++static void ++gs_dnf5_transaction_transaction_stop_cb (GsDnf5RpmRpm *object, ++ const gchar *arg_session_object_path, ++ guint64 arg_total, ++ GsDnf5ProgressHelper *self) ++{ ++ if (g_strcmp0 (self->session_object_path, arg_session_object_path) != 0) ++ return; ++ g_debug ("%s: total:%" G_GUINT64_FORMAT, G_STRFUNC, arg_total); ++} ++ ++static void ++gs_dnf5_transaction_unpack_error_cb (GsDnf5RpmRpm *object, ++ const gchar *arg_session_object_path, ++ const gchar *arg_nevra, ++ GsDnf5ProgressHelper *self) ++{ ++ if (g_strcmp0 (self->session_object_path, arg_session_object_path) != 0) ++ return; ++ g_debug ("%s: nevra:'%s'", G_STRFUNC, arg_nevra); ++} ++ ++static void ++gs_dnf5_transaction_verify_progress_cb (GsDnf5RpmRpm *object, ++ const gchar *arg_session_object_path, ++ guint64 arg_processed, ++ guint64 arg_total, ++ GsDnf5ProgressHelper *self) ++{ ++ if (g_strcmp0 (self->session_object_path, arg_session_object_path) != 0) ++ return; ++ g_debug ("%s: progress:%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT, G_STRFUNC, arg_processed, arg_total); ++} ++ ++static void ++gs_dnf5_transaction_verify_start_cb (GsDnf5RpmRpm *object, ++ const gchar *arg_session_object_path, ++ guint64 arg_total, ++ GsDnf5ProgressHelper *self) ++{ ++ if (g_strcmp0 (self->session_object_path, arg_session_object_path) != 0) ++ return; ++ g_debug ("%s: total:%" G_GUINT64_FORMAT, G_STRFUNC, arg_total); ++} ++ ++static void ++gs_dnf5_transaction_verify_stop_cb (GsDnf5RpmRpm *object, ++ const gchar *arg_session_object_path, ++ guint64 arg_total, ++ GsDnf5ProgressHelper *self) ++{ ++ if (g_strcmp0 (self->session_object_path, arg_session_object_path) != 0) ++ return; ++ g_debug ("%s: total:%" G_GUINT64_FORMAT, G_STRFUNC, arg_total); ++} ++ ++static void ++gs_dnf5_progress_helper_dispose (GObject *object) ++{ ++ GsDnf5ProgressHelper *self = GS_DNF5_PROGRESS_HELPER (object); ++ GObject *base_proxy = G_OBJECT (self->base_proxy); ++ GObject *rpm_proxy = G_OBJECT (self->rpm_proxy); ++ ++ #define clear_signal_handler(_proxy, _id) G_STMT_START { \ ++ if (_id) { \ ++ g_signal_handler_disconnect (_proxy, _id); \ ++ _id = 0; \ ++ } \ ++ } G_STMT_END ++ ++ clear_signal_handler (base_proxy, self->download_add_new_id); ++ clear_signal_handler (base_proxy, self->download_progress_id); ++ clear_signal_handler (base_proxy, self->download_mirror_failure_id); ++ clear_signal_handler (base_proxy, self->download_end_id); ++ ++ clear_signal_handler (rpm_proxy, self->transaction_before_begin_id); ++ clear_signal_handler (rpm_proxy, self->transaction_after_complete_id); ++ clear_signal_handler (rpm_proxy, self->transaction_elem_progress_id); ++ clear_signal_handler (rpm_proxy, self->transaction_action_progress_id); ++ clear_signal_handler (rpm_proxy, self->transaction_action_start_id); ++ clear_signal_handler (rpm_proxy, self->transaction_action_stop_id); ++ clear_signal_handler (rpm_proxy, self->transaction_script_error_id); ++ clear_signal_handler (rpm_proxy, self->transaction_script_start_id); ++ clear_signal_handler (rpm_proxy, self->transaction_script_stop_id); ++ clear_signal_handler (rpm_proxy, self->transaction_transaction_progress_id); ++ clear_signal_handler (rpm_proxy, self->transaction_transaction_start_id); ++ clear_signal_handler (rpm_proxy, self->transaction_transaction_stop_id); ++ clear_signal_handler (rpm_proxy, self->transaction_unpack_error_id); ++ clear_signal_handler (rpm_proxy, self->transaction_verify_progress_id); ++ clear_signal_handler (rpm_proxy, self->transaction_verify_start_id); ++ clear_signal_handler (rpm_proxy, self->transaction_verify_stop_id); ++ ++ #undef clear_signal_handler ++ ++ gs_app_set_progress (self->app, GS_APP_PROGRESS_UNKNOWN); ++ ++ G_OBJECT_CLASS (gs_dnf5_progress_helper_parent_class)->dispose (object); ++} ++ ++static void ++gs_dnf5_progress_helper_finalize (GObject *object) ++{ ++ GsDnf5ProgressHelper *self = GS_DNF5_PROGRESS_HELPER (object); ++ ++ g_clear_object (&self->base_proxy); ++ g_clear_object (&self->rpm_proxy); ++ g_clear_object (&self->app); ++ g_clear_pointer (&self->session_object_path, g_free); ++ g_clear_pointer (&self->ongoing_downloads, g_hash_table_destroy); ++ ++ G_OBJECT_CLASS (gs_dnf5_progress_helper_parent_class)->finalize (object); ++} ++ ++static void ++gs_dnf5_progress_helper_class_init (GsDnf5ProgressHelperClass *klass) ++{ ++ GObjectClass *object_class = G_OBJECT_CLASS (klass); ++ ++ object_class->dispose = gs_dnf5_progress_helper_dispose; ++ object_class->finalize = gs_dnf5_progress_helper_finalize; ++} ++ ++static void ++gs_dnf5_progress_helper_init (GsDnf5ProgressHelper *self) ++{ ++ self->ongoing_downloads = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); ++} ++ ++GsDnf5ProgressHelper * ++gs_dnf5_progress_helper_new (GsDnf5Base *base_proxy, ++ GsDnf5RpmRpm *rpm_proxy, ++ GsApp *progress_app, ++ const gchar *session_object_path) ++{ ++ GsDnf5ProgressHelper *self; ++ ++ g_return_val_if_fail (GS_DNF5_IS_BASE (base_proxy), NULL); ++ g_return_val_if_fail (GS_DNF5_IS_RPM_RPM (rpm_proxy), NULL); ++ g_return_val_if_fail (GS_IS_APP (progress_app), NULL); ++ g_return_val_if_fail (session_object_path != NULL, NULL); ++ ++ self = g_object_new (GS_TYPE_DNF5_PROGRESS_HELPER, NULL); ++ self->base_proxy = g_object_ref (base_proxy); ++ self->rpm_proxy = g_object_ref (rpm_proxy); ++ self->app = g_object_ref (progress_app); ++ self->session_object_path = g_strdup (session_object_path); ++ ++ gs_app_set_progress (self->app, GS_APP_PROGRESS_UNKNOWN); ++ ++ self->download_add_new_id = ++ g_signal_connect_object (base_proxy, "download_add_new", ++ G_CALLBACK (gs_dnf5_download_add_new_cb), self, 0); ++ self->download_progress_id = ++ g_signal_connect_object (base_proxy, "download_progress", ++ G_CALLBACK (gs_dnf5_download_progress_cb), self, 0); ++ self->download_mirror_failure_id = ++ g_signal_connect_object (base_proxy, "download_mirror_failure", ++ G_CALLBACK (gs_dnf5_download_mirror_failure_cb), self, 0); ++ self->download_end_id = ++ g_signal_connect_object (base_proxy, "download_end", ++ G_CALLBACK (gs_dnf5_download_end_cb), self, 0); ++ ++ self->transaction_before_begin_id = ++ g_signal_connect_object (rpm_proxy, "transaction_before_begin", ++ G_CALLBACK (gs_dnf5_transaction_before_begin_cb), self, 0); ++ self->transaction_after_complete_id = ++ g_signal_connect_object (rpm_proxy, "transaction_after_complete", ++ G_CALLBACK (gs_dnf5_transaction_after_complete_cb), self, 0); ++ self->transaction_elem_progress_id = ++ g_signal_connect_object (rpm_proxy, "transaction_elem_progress", ++ G_CALLBACK (gs_dnf5_transaction_elem_progress_cb), self, 0); ++ self->transaction_action_progress_id = ++ g_signal_connect_object (rpm_proxy, "transaction_action_progress", ++ G_CALLBACK (gs_dnf5_transaction_action_progress_cb), self, 0); ++ self->transaction_action_start_id = ++ g_signal_connect_object (rpm_proxy, "transaction_action_start", ++ G_CALLBACK (gs_dnf5_transaction_action_start_cb), self, 0); ++ self->transaction_action_stop_id = ++ g_signal_connect_object (rpm_proxy, "transaction_action_stop", ++ G_CALLBACK (gs_dnf5_transaction_action_stop_cb), self, 0); ++ self->transaction_script_error_id = ++ g_signal_connect_object (rpm_proxy, "transaction_script_error", ++ G_CALLBACK (gs_dnf5_transaction_script_error_cb), self, 0); ++ self->transaction_script_start_id = ++ g_signal_connect_object (rpm_proxy, "transaction_script_start", ++ G_CALLBACK (gs_dnf5_transaction_script_start_cb), self, 0); ++ self->transaction_script_stop_id = ++ g_signal_connect_object (rpm_proxy, "transaction_script_stop", ++ G_CALLBACK (gs_dnf5_transaction_script_stop_cb), self, 0); ++ self->transaction_transaction_progress_id = ++ g_signal_connect_object (rpm_proxy, "transaction_transaction_progress", ++ G_CALLBACK (gs_dnf5_transaction_transaction_progress_cb), self, 0); ++ self->transaction_transaction_start_id = ++ g_signal_connect_object (rpm_proxy, "transaction_transaction_start", ++ G_CALLBACK (gs_dnf5_transaction_transaction_start_cb), self, 0); ++ self->transaction_transaction_stop_id = ++ g_signal_connect_object (rpm_proxy, "transaction_transaction_stop", ++ G_CALLBACK (gs_dnf5_transaction_transaction_stop_cb), self, 0); ++ self->transaction_unpack_error_id = ++ g_signal_connect_object (rpm_proxy, "transaction_unpack_error", ++ G_CALLBACK (gs_dnf5_transaction_unpack_error_cb), self, 0); ++ self->transaction_verify_progress_id = ++ g_signal_connect_object (rpm_proxy, "transaction_verify_progress", ++ G_CALLBACK (gs_dnf5_transaction_verify_progress_cb), self, 0); ++ self->transaction_verify_start_id = ++ g_signal_connect_object (rpm_proxy, "transaction_verify_start", ++ G_CALLBACK (gs_dnf5_transaction_verify_start_cb), self, 0); ++ self->transaction_verify_stop_id = ++ g_signal_connect_object (rpm_proxy, "transaction_verify_stop", ++ G_CALLBACK (gs_dnf5_transaction_verify_stop_cb), self, 0); ++ ++ return self; ++} +diff --git a/plugins/dnf5/gs-dnf5-progress-helper.h b/plugins/dnf5/gs-dnf5-progress-helper.h +new file mode 100644 +index 000000000..73d528d54 +--- /dev/null ++++ b/plugins/dnf5/gs-dnf5-progress-helper.h +@@ -0,0 +1,30 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- ++ * vi:set noexpandtab tabstop=8 shiftwidth=8: ++ * ++ * Copyright (C) 2024 Red Hat ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#pragma once ++ ++#include ++#include ++ ++#include ++ ++#include "gs-dnf5-generated.h" ++ ++G_BEGIN_DECLS ++ ++#define GS_TYPE_DNF5_PROGRESS_HELPER (gs_dnf5_progress_helper_get_type ()) ++ ++G_DECLARE_FINAL_TYPE (GsDnf5ProgressHelper, gs_dnf5_progress_helper, GS, DNF5_PROGRESS_HELPER, GObject) ++ ++GsDnf5ProgressHelper * ++ gs_dnf5_progress_helper_new (GsDnf5Base *base_proxy, ++ GsDnf5RpmRpm *rpm_proxy, ++ GsApp *progress_app, ++ const gchar *session_object_path); ++ ++G_END_DECLS +diff --git a/plugins/dnf5/gs-plugin-dnf5.c b/plugins/dnf5/gs-plugin-dnf5.c +new file mode 100644 +index 000000000..93f22dc4f +--- /dev/null ++++ b/plugins/dnf5/gs-plugin-dnf5.c +@@ -0,0 +1,3738 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- ++ * vi:set noexpandtab tabstop=8 shiftwidth=8: ++ * ++ * Copyright (C) 2024 Red Hat ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++/* ++ * SECTION: dnf5 plugin. ++ * ++ * Talks to dnf5 to manage packages through dnf. ++ */ ++ ++#include ++ ++#include ++#include ++ ++#include "gs-app-private.h" ++ ++#include "gs-worker-thread.h" ++#include "gs-dnf5-generated.h" ++#include "gs-dnf5-rpm-generated.h" ++#include "gs-dnf5-progress-helper.h" ++ ++#include "gs-plugin-dnf5.h" ++ ++#define GS_DNF5_RELEASEVER_DEFAULT NULL ++#define GS_DNF5_INTERFACE_RPM_DNF "org.rpm.dnf.v0" ++#define GS_DNF5_OBJECT_PATH_RPM_DNF "/org/rpm/dnf/v0" ++ ++/* for how long a session can be left opened until it's auto-closed */ ++#define GS_SESSION_LIFETIME_SECS (5 * 60) ++ ++struct _GsPluginDnf5 ++{ ++ GsPlugin parent; ++ ++ GsWorkerThread *worker; /* (owned) */ ++ GDBusConnection *connection; ++ GsDnf5RpmTransaction *rpm_transaction_proxy; ++ guint rpm_transaction_watch_id; ++ gint calling_rpm; ++ ++ struct _SessionData { ++ GMutex mutex; ++ GCond cond; ++ guint autoclose_timer; ++ GsDnf5SessionManager *proxy; ++ gchar *object_path; ++ guint n_used; ++ gint needs_reset; ++ } session_data; ++ ++ struct _DependencySizesData { ++ GMutex mutex; ++ GPtrArray *apps; /* (element-type GsApp) */ ++ GCancellable *cancellable; /* non-NULL, when an op is running */ ++ } dependency_sizes_data; ++}; ++ ++G_DEFINE_TYPE (GsPluginDnf5, gs_plugin_dnf5, GS_TYPE_PLUGIN) ++ ++#define assert_in_worker(self) \ ++ g_assert (gs_worker_thread_is_in_worker_context (self->worker)) ++ ++static gint ++gs_dnf5_get_priority_for_interactivity (gboolean interactive) ++{ ++ return interactive ? G_PRIORITY_DEFAULT : G_PRIORITY_LOW; ++} ++ ++static void ++gs_dnf5_convert_error (GError **error) ++{ ++ gboolean not_authorized; ++ if (error == NULL || *error == NULL) ++ return; ++ ++ /* The message is not localized in the dnf5, thus this should work */ ++ not_authorized = strstr ((*error)->message, "GDBus.Error:org.rpm.dnf.v0.Error: Not authorized") != NULL; ++ ++ g_dbus_error_strip_remote_error (*error); ++ gs_utils_error_convert_gdbus (error); ++ if (not_authorized && g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_DBUS_ERROR)) { ++ (*error)->domain = GS_PLUGIN_ERROR; ++ (*error)->code = GS_PLUGIN_ERROR_AUTH_REQUIRED; ++ } else if (g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_DBUS_ERROR) || ( ++ !gs_utils_error_convert_gdbus (error) && ++ !gs_utils_error_convert_gio (error))) { ++ (*error)->domain = GS_PLUGIN_ERROR; ++ (*error)->code = GS_PLUGIN_ERROR_FAILED; ++ } ++} ++ ++static void ++gs_dnf5_report_error (GsPluginDnf5 *self, ++ const GError *error, ++ gboolean interactive) ++{ ++ g_autoptr(GsPluginEvent) event = NULL; ++ ++ event = gs_plugin_event_new ("error", error, ++ NULL); ++ if (interactive) ++ gs_plugin_event_add_flag (event, GS_PLUGIN_EVENT_FLAG_INTERACTIVE); ++ gs_plugin_event_add_flag (event, GS_PLUGIN_EVENT_FLAG_WARNING); ++ gs_plugin_report_event (GS_PLUGIN (self), event); ++} ++ ++/* The session reset is used to refresh information about the packages, ++ like after a package install/uninstall, it might not be noticed by ++ the daemon internal structures that the package is installed/uninstalled. */ ++static void ++gs_dnf5_mark_session_needs_reset (GsPluginDnf5 *self) ++{ ++ g_atomic_int_set (&self->session_data.needs_reset, 1); ++} ++ ++static void ++gs_dnf5_rpm_start_transaction_cb (GsDnf5RpmTransaction *proxy, ++ const gchar *dbcookie, ++ guint transaction_id, ++ gpointer user_data) ++{ ++ GsPluginDnf5 *self = user_data; ++ ++ g_debug ("%s: %p: dbcookie:'%s' transaction_id:%u", G_STRFUNC, self, dbcookie, transaction_id); ++} ++ ++static void ++gs_dnf5_rpm_end_transaction_cb (GsDnf5RpmTransaction *proxy, ++ const gchar *dbcookie, ++ guint transaction_id, ++ gpointer user_data) ++{ ++ GsPluginDnf5 *self = user_data; ++ ++ g_debug ("%s: %p: dbcookie:'%s' transaction_id:%u", G_STRFUNC, self, dbcookie, transaction_id); ++ ++ /* the transactions are for install/uninstall, thus ++ mark the connection to require a reset() */ ++ gs_dnf5_mark_session_needs_reset (self); ++ ++ /* also do not know what precisely changed, thus a heavy hammer */ ++ gs_plugin_reload (GS_PLUGIN (self)); ++} ++ ++static void ++gs_dnf5_got_rpm_transaction_proxy_cb (GObject *source_object, ++ GAsyncResult *result, ++ gpointer user_data) ++{ ++ g_autoptr(GsPluginDnf5) self = user_data; ++ g_autoptr(GError) local_error = NULL; ++ ++ self->rpm_transaction_proxy = gs_dnf5_rpm_transaction_proxy_new_finish (result, &local_error); ++ ++ if (self->rpm_transaction_proxy != NULL) { ++ g_debug ("Opened RPM Transaction D-Bus proxy"); ++ ++ g_signal_connect_object (self->rpm_transaction_proxy, "start-transaction", ++ G_CALLBACK (gs_dnf5_rpm_start_transaction_cb), self, 0); ++ g_signal_connect_object (self->rpm_transaction_proxy, "end-transaction", ++ G_CALLBACK (gs_dnf5_rpm_end_transaction_cb), self, 0); ++ } else { ++ g_debug ("Failed to open RPM Transaction proxy: %s", local_error ? local_error->message : "Unknown error"); ++ } ++} ++ ++static void ++gs_dnf5_rpm_transaction_appeared_cb (GDBusConnection *connection, ++ const gchar *name, ++ const gchar *name_owner, ++ gpointer user_data) ++{ ++ GsPluginDnf5 *self = user_data; ++ ++ g_debug ("%s: name:'%s' owner:'%s' existing-proxy:%p calling_rpm:%d", ++ G_STRFUNC, name, name_owner, self->rpm_transaction_proxy, ++ g_atomic_int_get (&self->calling_rpm)); ++ ++ if (name_owner != NULL && *name_owner != '\0' && !g_atomic_int_get (&self->calling_rpm)) { ++ g_clear_object (&self->rpm_transaction_proxy); ++ gs_dnf5_rpm_transaction_proxy_new (self->connection, ++ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, ++ "org.rpm.announce", ++ "/org/rpm/Transaction", ++ NULL, ++ gs_dnf5_got_rpm_transaction_proxy_cb, ++ g_object_ref (self)); ++ } ++} ++ ++static void ++gs_dnf5_rpm_transaction_vanished_cb (GDBusConnection *connection, ++ const gchar *name, ++ gpointer user_data) ++{ ++ GsPluginDnf5 *self = user_data; ++ ++ g_debug ("%s: name:'%s' existing-proxy:%p", G_STRFUNC, name, self->rpm_transaction_proxy); ++ ++ g_clear_object (&self->rpm_transaction_proxy); ++} ++ ++static void ++gs_dnf5_bus_get_cb (GObject *source_object, ++ GAsyncResult *result, ++ gpointer user_data) ++{ ++ g_autoptr(GTask) task = user_data; ++ g_autoptr(GError) local_error = NULL; ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (g_task_get_source_object (task)); ++ ++ self->connection = g_bus_get_finish (result, &local_error); ++ gs_dnf5_convert_error (&local_error); ++ ++ if (self->connection != NULL) { ++ self->rpm_transaction_watch_id = g_bus_watch_name_on_connection (self->connection, ++ "org.rpm.announce", ++ G_BUS_NAME_WATCHER_FLAGS_NONE, ++ gs_dnf5_rpm_transaction_appeared_cb, ++ gs_dnf5_rpm_transaction_vanished_cb, ++ self, ++ NULL); ++ } ++ ++ if (self->connection != NULL) ++ g_task_return_boolean (task, TRUE); ++ else ++ g_task_return_error (task, g_steal_pointer (&local_error)); ++} ++ ++static void ++gs_plugin_dnf5_setup_async (GsPlugin *plugin, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (plugin); ++ g_autoptr(GTask) task = NULL; ++ ++ g_debug ("dnf5 setup"); ++ ++ /* Start up a worker thread to process all the plugin’s function calls. */ ++ self->worker = gs_worker_thread_new ("gs-plugin-dnf5"); ++ ++ task = g_task_new (plugin, cancellable, callback, user_data); ++ g_task_set_source_tag (task, gs_plugin_dnf5_setup_async); ++ ++ g_bus_get (G_BUS_TYPE_SYSTEM, cancellable, gs_dnf5_bus_get_cb, g_steal_pointer (&task)); ++} ++ ++static gboolean ++gs_plugin_dnf5_setup_finish (GsPlugin *plugin, ++ GAsyncResult *result, ++ GError **error) ++{ ++ return g_task_propagate_boolean (G_TASK (result), error); ++} ++ ++static void ++gs_dnf5_shutdown_cb (GObject *source_object, ++ GAsyncResult *result, ++ gpointer user_data) ++{ ++ g_autoptr(GTask) task = user_data; ++ GsPluginDnf5 *self = g_task_get_source_object (task); ++ g_autoptr(GsWorkerThread) worker = NULL; ++ g_autoptr(GError) local_error = NULL; ++ ++ worker = g_steal_pointer (&self->worker); ++ ++ if (!gs_worker_thread_shutdown_finish (worker, result, &local_error)) ++ g_task_return_error (task, g_steal_pointer (&local_error)); ++ else ++ g_task_return_boolean (task, TRUE); ++} ++ ++static void ++gs_plugin_dnf5_shutdown_async (GsPlugin *plugin, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (plugin); ++ g_autoptr(GTask) task = NULL; ++ g_autoptr(GCancellable) dependency_sizes_cancellable = NULL; ++ ++ task = g_task_new (plugin, cancellable, callback, user_data); ++ g_task_set_source_tag (task, gs_plugin_dnf5_shutdown_async); ++ ++ /* stop any dependency sizes ongoing operation */ ++ g_mutex_lock (&self->dependency_sizes_data.mutex); ++ if (self->dependency_sizes_data.cancellable) ++ dependency_sizes_cancellable = g_object_ref (self->dependency_sizes_data.cancellable); ++ g_mutex_unlock (&self->dependency_sizes_data.mutex); ++ if (dependency_sizes_cancellable != NULL) ++ g_cancellable_cancel (dependency_sizes_cancellable); ++ ++ /* Stop the worker thread. */ ++ gs_worker_thread_shutdown_async (self->worker, cancellable, gs_dnf5_shutdown_cb, g_steal_pointer (&task)); ++} ++ ++static gboolean ++gs_plugin_dnf5_shutdown_finish (GsPlugin *plugin, ++ GAsyncResult *result, ++ GError **error) ++{ ++ return g_task_propagate_boolean (G_TASK (result), error); ++} ++ ++static void ++gs_dnf5_close_session_real (GsDnf5SessionManager *proxy, ++ const gchar *session_path) ++{ ++ g_autoptr(GError) local_error = NULL; ++ gboolean result = FALSE; ++ ++ /* Not passing operation's cancellable, because it can be cancelled by the user, ++ but the session needs to be closed. */ ++ if (gs_dnf5_session_manager_call_close_session_sync (proxy, session_path, &result, NULL, &local_error)) ++ g_warn_if_fail (result); ++ else ++ g_debug ("Failed to close session: %s", local_error->message); ++} ++ ++static gboolean ++gs_dnf5_autoclose_session_cb (gpointer user_data) ++{ ++ GsPluginDnf5 *self = user_data; ++ g_autoptr(GMutexLocker) locker = g_mutex_locker_new (&self->session_data.mutex); ++ ++ self->session_data.autoclose_timer = 0; ++ if (self->session_data.n_used == 0 && self->session_data.proxy != NULL) { ++ gs_dnf5_close_session_real (self->session_data.proxy, self->session_data.object_path); ++ ++ g_clear_object (&self->session_data.proxy); ++ g_clear_pointer (&self->session_data.object_path, g_free); ++ } ++ ++ return G_SOURCE_REMOVE; ++} ++ ++static gboolean ++gs_dnf5_reset_session_sync (GsPluginDnf5 *self, ++ const gchar *session_path, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ g_autoptr(GsDnf5Base) base_proxy = NULL; ++ g_autofree gchar *error_msg = NULL; ++ gboolean success = FALSE; ++ ++ base_proxy = gs_dnf5_base_proxy_new_sync (self->connection, ++ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, ++ GS_DNF5_INTERFACE_RPM_DNF, ++ session_path, ++ cancellable, ++ error); ++ if (base_proxy == NULL) { ++ gs_dnf5_convert_error (error); ++ g_prefix_error_literal (error, "Failed to create Base proxy: "); ++ return FALSE; ++ } ++ ++ if (!gs_dnf5_base_call_reset_sync (base_proxy, &success, &error_msg, cancellable, error)) { ++ gs_dnf5_convert_error (error); ++ g_prefix_error_literal (error, "Failed to call Base::reset(): "); ++ return FALSE; ++ } ++ ++ if (!success) { ++ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to execute Base::reset(): %s", error_msg ? error_msg : "Unknown error"); ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++static gchar * /* (transfer full) */ ++gs_dnf5_open_session (GsPluginDnf5 *self, ++ const gchar *releasever, ++ GsDnf5SessionManager **out_proxy, /* (transfer full) */ ++ GCancellable *cancellable, ++ GError **error) ++{ ++ g_autoptr(GMutexLocker) locker = g_mutex_locker_new (&self->session_data.mutex); ++ g_autoptr(GVariantBuilder) options_builder = NULL; ++ g_autofree gchar *session_path = NULL; ++ ++ if (releasever == GS_DNF5_RELEASEVER_DEFAULT) { ++ if (self->session_data.autoclose_timer) { ++ g_source_remove (self->session_data.autoclose_timer); ++ self->session_data.autoclose_timer = 0; ++ } ++ ++ if (self->session_data.proxy != NULL) { ++ GsDnf5SessionManager *proxy = self->session_data.proxy; ++ ++ while (g_atomic_int_get (&self->session_data.needs_reset) && ++ !g_cancellable_is_cancelled (cancellable)) { ++ g_autoptr(GError) local_error = NULL; ++ if (self->session_data.n_used > 0) { ++ g_debug ("Existing session needs reset, waiting for opened operations to finish"); ++ while (self->session_data.n_used && g_atomic_int_get (&self->session_data.needs_reset)) { ++ g_cond_wait_until (&self->session_data.cond, &self->session_data.mutex, ++ /* check whether was cancelled up to three times per second */ ++ g_get_monotonic_time () + (G_TIME_SPAN_SECOND / 3)); ++ ++ if (g_cancellable_set_error_if_cancelled (cancellable, error)) ++ return NULL; ++ } ++ } ++ ++ if (g_cancellable_set_error_if_cancelled (cancellable, error)) ++ return NULL; ++ ++ if (g_atomic_int_get (&self->session_data.needs_reset)) { ++ gboolean success; ++ ++ success = gs_dnf5_reset_session_sync (self, self->session_data.object_path, cancellable, &local_error); ++ g_atomic_int_set (&self->session_data.needs_reset, 0); ++ ++ /* let any waiter for session reset know the conditions changed */ ++ g_cond_broadcast (&self->session_data.cond); ++ ++ if (success) { ++ g_debug ("Successfully reset existing session"); ++ } else { ++ g_debug ("Failed to reset existing session: %s", local_error ? local_error->message : "Unknown error"); ++ break; ++ } ++ } else { ++ g_debug ("Wanted to reset the session, but someone else did that already, thus skipping the reset"); ++ break; ++ } ++ } ++ ++ if (g_cancellable_set_error_if_cancelled (cancellable, error)) ++ return NULL; ++ ++ if (proxy == self->session_data.proxy) { ++ self->session_data.n_used++; ++ g_debug ("Using existing session"); ++ *out_proxy = g_object_ref (self->session_data.proxy); ++ return g_strdup (self->session_data.object_path); ++ } ++ } ++ } ++ ++ g_debug ("Creating new session"); ++ *out_proxy = gs_dnf5_session_manager_proxy_new_sync (self->connection, ++ G_DBUS_PROXY_FLAGS_NONE, ++ GS_DNF5_INTERFACE_RPM_DNF, ++ GS_DNF5_OBJECT_PATH_RPM_DNF, ++ cancellable, ++ error); ++ ++ if (*out_proxy == NULL) { ++ gs_dnf5_convert_error (error); ++ g_prefix_error_literal (error, "Failed to get Session Manager: "); ++ return NULL; ++ } ++ ++ options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ ++ if (releasever != GS_DNF5_RELEASEVER_DEFAULT) { ++ g_variant_builder_add (options_builder, "{sv}", "releasever", ++ g_variant_new_string (releasever)); ++ } else { ++ g_autoptr(GVariantBuilder) config = NULL; ++ ++ config = g_variant_builder_new (G_VARIANT_TYPE ("a{ss}")); ++ g_variant_builder_add (config, "{ss}", "optional_metadata_types", ++ "appstream"); ++ ++ g_variant_builder_add (options_builder, "{sv}", "config", ++ g_variant_builder_end (config)); ++ } ++ ++ if (!gs_dnf5_session_manager_call_open_session_sync (*out_proxy, ++ g_variant_builder_end (options_builder), ++ &session_path, ++ cancellable, ++ error)) { ++ gs_dnf5_convert_error (error); ++ g_prefix_error_literal (error, "Failed to open session: "); ++ return NULL; ++ } ++ ++ if (releasever == GS_DNF5_RELEASEVER_DEFAULT) { ++ g_assert (self->session_data.proxy == NULL); ++ self->session_data.proxy = g_object_ref (*out_proxy); ++ self->session_data.object_path = g_strdup (session_path); ++ self->session_data.n_used = 1; ++ } ++ ++ return g_steal_pointer (&session_path); ++} ++ ++static void ++gs_dnf5_close_session (GsPluginDnf5 *self, ++ GsDnf5SessionManager *proxy, ++ const gchar *session_path) ++{ ++ g_autoptr(GMutexLocker) locker = g_mutex_locker_new (&self->session_data.mutex); ++ ++ if (self->session_data.proxy == proxy) { ++ g_assert (self->session_data.n_used > 0); ++ self->session_data.n_used--; ++ ++ /* let any waiter for session reset know the n_used changed */ ++ g_cond_broadcast (&self->session_data.cond); ++ ++ if (self->session_data.n_used == 0) { ++ g_assert (self->session_data.autoclose_timer == 0); ++ self->session_data.autoclose_timer = g_timeout_add_seconds (GS_SESSION_LIFETIME_SECS, gs_dnf5_autoclose_session_cb, self); ++ } ++ } else { ++ gs_dnf5_close_session_real (proxy, session_path); ++ } ++} ++ ++/* Returns whether to continue */ ++typedef gboolean (* GsDnf5ForeachFunc) (GsPluginDnf5 *self, ++ GVariant *value, ++ gpointer user_data, ++ GCancellable *cancellable, ++ GError **error); ++ ++static gboolean ++gs_dnf5_foreach_item (GsPluginDnf5 *self, ++ GVariant *array, ++ GsDnf5ForeachFunc func, ++ gpointer user_data, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ GVariantIter iter; ++ GVariant *child; ++ ++ g_variant_iter_init (&iter, array); ++ while (child = g_variant_iter_next_value (&iter), child != NULL) { ++ g_autoptr(GError) local_error = NULL; ++ gboolean done; ++ ++ done = !func (self, child, user_data, cancellable, &local_error); ++ g_variant_unref (child); ++ ++ if (local_error) { ++ g_propagate_error (error, g_steal_pointer (&local_error)); ++ return FALSE; ++ } ++ ++ if (g_cancellable_set_error_if_cancelled (cancellable, error)) ++ return FALSE; ++ ++ if (done) ++ break; ++ } ++ ++ return TRUE; ++} ++ ++static void ++gs_dnf5_app_set_str (GVariantDict *dict, ++ const gchar *key, ++ GsApp *app, ++ void (*set_func) (GsApp *app, ++ const gchar *value)) ++{ ++ g_autoptr(GVariant) value = NULL; ++ ++ value = g_variant_dict_lookup_value (dict, key, G_VARIANT_TYPE_STRING); ++ if (value != NULL) ++ set_func (app, g_variant_get_string (value, NULL)); ++} ++ ++static void ++gs_dnf5_app_set_str2 (GVariantDict *dict, ++ const gchar *key, ++ GsApp *app, ++ void (*set_func) (GsApp *app, ++ GsAppQuality quality, ++ const gchar *value)) ++{ ++ g_autoptr(GVariant) value = NULL; ++ ++ value = g_variant_dict_lookup_value (dict, key, G_VARIANT_TYPE_STRING); ++ if (value != NULL) ++ set_func (app, GS_APP_QUALITY_NORMAL, g_variant_get_string (value, NULL)); ++} ++ ++static void ++gs_dnf5_app_set_size (GVariantDict *dict, ++ const gchar *key, ++ GsApp *app, ++ void (*set_func) (GsApp *app, ++ GsSizeType size_type, ++ guint64 size_bytes)) ++{ ++ g_autoptr(GVariant) value = NULL; ++ ++ value = g_variant_dict_lookup_value (dict, key, G_VARIANT_TYPE_UINT64); ++ if (value != NULL) ++ set_func (app, GS_SIZE_TYPE_VALID, g_variant_get_uint64 (value)); ++} ++ ++static gchar * ++gs_dnf5_dup_version_from_dict (GVariantDict *dict) ++{ ++ g_autoptr(GVariant) version = NULL; ++ ++ version = g_variant_dict_lookup_value (dict, "version", G_VARIANT_TYPE_STRING); ++ if (version != NULL) { ++ const gchar *version_str = g_variant_get_string (version, NULL); ++ if (version_str != NULL && *version_str != '\0') { ++ g_autoptr(GVariant) release = NULL; ++ const gchar *release_str = NULL; ++ release = g_variant_dict_lookup_value (dict, "release", G_VARIANT_TYPE_STRING); ++ if (release != NULL) ++ release_str = g_variant_get_string (release, NULL); ++ if (release_str != NULL && *release_str != '\0') { ++ g_autofree gchar *version_release_str = g_strconcat (version_str, "-", release_str, NULL); ++ return g_steal_pointer (&version_release_str); ++ } else { ++ return g_strdup (version_str); ++ } ++ } ++ } ++ ++ return NULL; ++} ++ ++static void ++gs_dnf5_app_set_version (GVariantDict *dict, ++ GsApp *app, ++ void (*set_func) (GsApp *app, ++ const gchar *value)) ++{ ++ g_autofree gchar *ver_str = gs_dnf5_dup_version_from_dict (dict); ++ if (ver_str != NULL) ++ set_func (app, ver_str); ++} ++ ++static void ++gs_plugin_dnf5_set_packaging_format (GsApp *app) ++{ ++ gs_app_set_metadata (app, "GnomeSoftware::PackagingFormat", "RPM"); ++ gs_app_set_metadata (app, "GnomeSoftware::PackagingBaseCssColor", "error_color"); ++} ++ ++static void ++gs_dnf5_update_app_state (GsApp *app, ++ GsAppState state, ++ GVariantDict *dict) ++{ ++ if (state == GS_APP_STATE_UNKNOWN) { ++ g_autoptr(GVariant) value = NULL; ++ value = g_variant_dict_lookup_value (dict, "is_installed", G_VARIANT_TYPE_BOOLEAN); ++ if (value == NULL) ++ return; ++ if (g_variant_get_boolean (value)) ++ state = GS_APP_STATE_INSTALLED; ++ else ++ state = GS_APP_STATE_AVAILABLE; ++ } ++ /* The state can be only installed, available or updatable */ ++ if (gs_app_get_state (app) == state || ++ gs_app_get_state (app) == GS_APP_STATE_UPDATABLE) ++ return; ++ if (gs_app_get_state (app) == GS_APP_STATE_UNKNOWN) ++ gs_app_set_state (app, state); ++ else if (gs_app_get_state (app) != GS_APP_STATE_INSTALLED || ++ state == GS_APP_STATE_UPDATABLE) ++ gs_app_set_state (app, state); ++} ++ ++static void ++gs_dnf5_update_app_changelogs (GsApp *app, ++ GVariantDict *dict) ++{ ++ GVariantIter iter; ++ GVariant *child; ++ g_autoptr(GString) changes = NULL; ++ g_autoptr(GVariant) changelogs = NULL; ++ ++ changelogs = g_variant_dict_lookup_value (dict, "changelogs", NULL); ++ if (changelogs == NULL) ++ return; ++ ++ g_variant_iter_init (&iter, changelogs); ++ while (child = g_variant_iter_next_value (&iter), child != NULL) { ++ gint64 when = 0; ++ const gchar *whom = NULL; ++ const gchar *what = NULL; ++ ++ g_variant_get (child, "(x&s&s)", &when, &whom, &what); ++ ++ if (whom != NULL && what != NULL) { ++ g_autofree gchar *tmp = NULL; ++ const gchar *eml_start, *eml_end; ++ ++ /* Hide the email address in the changes */ ++ eml_start = strchr (whom, '<'); ++ eml_end = strrchr (whom, '>'); ++ if (eml_start != NULL && eml_start < eml_end) { ++ if (g_ascii_isspace (eml_end[1])) ++ eml_end++; ++ tmp = g_malloc0 (strlen (whom) + 1); ++ strncpy (tmp, whom, eml_start - whom); ++ strcat (tmp, eml_end + 1); ++ whom = tmp; ++ } ++ ++ if (changes == NULL) ++ changes = g_string_new (""); ++ else ++ g_string_append (changes, "\n\n"); ++ g_string_append (changes, whom); ++ g_string_append_c (changes, '\n'); ++ g_string_append (changes, what); ++ } ++ ++ g_variant_unref (child); ++ } ++ ++ if (changes != NULL) ++ gs_app_set_update_details_text (app, changes->str); ++} ++ ++typedef struct { ++ GsAppList *list; ++ GsAppState set_state; ++ GHashTable *nevra_to_app; /* (nullable): gchar *nevra ~> GsApp * */ ++ GHashTable *replaces; /* (nullable): GINT_TO_POINTER(pkg-id) ~> gchar *old_version */ ++} ReadPackageData; ++ ++static gboolean ++gs_dnf5_read_package_cb (GsPluginDnf5 *self, ++ GVariant *package_array, ++ gpointer user_data, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ ReadPackageData *rpd = user_data; ++ GsAppList *list = rpd->list; ++ GHashTable *nevra_to_app = rpd->nevra_to_app; ++ g_autofree gchar *name = NULL; ++ g_autoptr(GsApp) app = NULL; ++ g_autoptr(GVariantDict) dict = NULL; ++ g_autoptr(GVariant) value = NULL; ++ ++ dict = g_variant_dict_new (package_array); ++ ++ value = g_variant_dict_lookup_value (dict, "name", G_VARIANT_TYPE_STRING); ++ if (value != NULL) { ++ const gchar *name_const = g_variant_get_string (value, NULL); ++ app = gs_plugin_cache_lookup (GS_PLUGIN (self), name_const); ++ if (app == NULL) ++ name = g_strdup (name_const); ++ g_clear_pointer (&value, g_variant_unref); ++ } ++ ++ if (app == NULL) { ++ app = gs_app_new (NULL); ++ gs_app_set_management_plugin (app, GS_PLUGIN (self)); ++ gs_app_set_metadata (app, "GnomeSoftware::Creator", gs_plugin_get_name (GS_PLUGIN (self))); ++ gs_plugin_dnf5_set_packaging_format (app); ++ gs_app_set_kind (app, AS_COMPONENT_KIND_GENERIC); ++ gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE); ++ gs_app_set_scope (app, AS_COMPONENT_SCOPE_SYSTEM); ++ ++ gs_dnf5_app_set_str (dict, "name", app, gs_app_add_source); ++ gs_dnf5_app_set_str (dict, "nevra", app, gs_app_add_source_id); ++ gs_dnf5_app_set_str2 (dict, "name", app, gs_app_set_name); ++ gs_dnf5_app_set_str2 (dict, "summary", app, gs_app_set_summary); ++ gs_dnf5_app_set_str2 (dict, "description", app, gs_app_set_description); ++ gs_dnf5_app_set_str2 (dict, "license", app, gs_app_set_license); ++ gs_dnf5_app_set_size (dict, "install_size", app, gs_app_set_size_installed); ++ gs_dnf5_app_set_size (dict, "download_size", app, gs_app_set_size_download); ++ ++ value = g_variant_dict_lookup_value (dict, "url", G_VARIANT_TYPE_STRING); ++ if (value != NULL) { ++ gs_app_set_url (app, AS_URL_KIND_HOMEPAGE, g_variant_get_string (value, NULL)); ++ g_clear_pointer (&value, g_variant_unref); ++ } ++ ++ gs_plugin_cache_add (GS_PLUGIN (self), name, app); ++ } ++ ++ gs_dnf5_update_app_changelogs (app, dict); ++ gs_dnf5_update_app_state (app, rpd->set_state, dict); ++ ++ if (rpd->set_state == GS_APP_STATE_UPDATABLE) { ++ gs_dnf5_app_set_version (dict, app, gs_app_set_update_version); ++ gs_app_add_quirk (app, GS_APP_QUIRK_NEEDS_REBOOT); ++ } else { ++ gs_dnf5_app_set_version (dict, app, gs_app_set_version); ++ } ++ ++ if (nevra_to_app != NULL) { ++ g_clear_pointer (&value, g_variant_unref); ++ value = g_variant_dict_lookup_value (dict, "nevra", G_VARIANT_TYPE_STRING); ++ if (value != NULL) { ++ const gchar *nevra_const = g_variant_get_string (value, NULL); ++ if (nevra_const != NULL && *nevra_const != '\0') ++ g_hash_table_insert (nevra_to_app, g_strdup (nevra_const), g_object_ref (app)); ++ } ++ } ++ ++ gs_app_list_add (list, app); ++ ++ return TRUE; ++} ++ ++static gboolean ++gs_dnf5_read_repo_cb (GsPluginDnf5 *self, ++ GVariant *package_array, ++ gpointer user_data, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ GsAppList *list = user_data; ++ g_autoptr(GsApp) app = NULL; ++ g_autoptr(GVariantDict) dict = NULL; ++ g_autoptr(GVariant) value = NULL; ++ const gchar *id; ++ ++ dict = g_variant_dict_new (package_array); ++ ++ value = g_variant_dict_lookup_value (dict, "id", G_VARIANT_TYPE_STRING); ++ if (value == NULL) ++ return TRUE; ++ ++ id = g_variant_get_string (value, NULL); ++ if (id == NULL || *id == '\0') ++ return TRUE; ++ ++ /* Skip sub-repos */ ++ if (g_str_has_suffix (id, "-source") || ++ g_str_has_suffix (id, "-debuginfo") || ++ g_str_has_suffix (id, "-testing")) ++ return TRUE; ++ ++ g_clear_pointer (&value, g_variant_unref); ++ id = NULL; ++ ++ app = gs_app_new (NULL); ++ gs_app_set_management_plugin (app, GS_PLUGIN (self)); ++ gs_app_set_kind (app, AS_COMPONENT_KIND_REPOSITORY); ++ gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE); ++ gs_app_set_scope (app, AS_COMPONENT_SCOPE_SYSTEM); ++ gs_app_add_quirk (app, GS_APP_QUIRK_NOT_LAUNCHABLE); ++ gs_app_set_metadata (app, "GnomeSoftware::Creator", gs_plugin_get_name (GS_PLUGIN (self))); ++ gs_plugin_dnf5_set_packaging_format (app); ++ gs_app_set_metadata (app, "GnomeSoftware::SortKey", "300"); ++ gs_app_set_origin_ui (app, _("Packages")); ++ ++ gs_dnf5_app_set_str (dict, "id", app, gs_app_set_id); ++ gs_dnf5_app_set_str2 (dict, "name", app, gs_app_set_name); ++ gs_dnf5_app_set_str2 (dict, "name", app, gs_app_set_description); ++ ++ value = g_variant_dict_lookup_value (dict, "enabled", G_VARIANT_TYPE_BOOLEAN); ++ if (value != NULL) { ++ gs_app_set_state (app, g_variant_get_boolean (value) ? ++ GS_APP_STATE_INSTALLED : GS_APP_STATE_AVAILABLE); ++ g_clear_pointer (&value, g_variant_unref); ++ } else { ++ gs_app_set_state (app, GS_APP_STATE_INSTALLED); ++ } ++ ++ gs_app_list_add (list, app); ++ ++ return TRUE; ++} ++ ++static gboolean ++gs_dnf5_refine_from_advisory_packages_cb (GsPluginDnf5 *self, ++ GVariant *array, ++ gpointer user_data, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ GHashTable *nevra_to_app = user_data; ++ g_autoptr(GVariantDict) dict = NULL; ++ g_autoptr(GVariant) var_nevra = NULL; ++ ++ dict = g_variant_dict_new (array); ++ ++ var_nevra = g_variant_dict_lookup_value (dict, "nevra", G_VARIANT_TYPE_STRING); ++ if (var_nevra != NULL) { ++ const gchar *nevra = g_variant_get_string (var_nevra, NULL); ++ if (nevra != NULL) { ++ GsApp *app; ++ ++ app = g_hash_table_lookup (nevra_to_app, nevra); ++ if (app != NULL) ++ gs_app_set_update_urgency (app, AS_URGENCY_KIND_CRITICAL); ++ } ++ } ++ ++ return TRUE; ++} ++ ++static gboolean ++gs_dnf5_refine_from_advisory_collections_cb (GsPluginDnf5 *self, ++ GVariant *array, ++ gpointer user_data, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ GHashTable *nevra_to_app = user_data; ++ g_autoptr(GVariantDict) dict = NULL; ++ g_autoptr(GVariant) packages = NULL; ++ gboolean res = TRUE; ++ ++ dict = g_variant_dict_new (array); ++ ++ packages = g_variant_dict_lookup_value (dict, "packages", G_VARIANT_TYPE_ARRAY); ++ if (packages != NULL) ++ res = gs_dnf5_foreach_item (self, packages, gs_dnf5_refine_from_advisory_packages_cb, nevra_to_app, cancellable, error); ++ ++ return res; ++} ++ ++static gboolean ++gs_dnf5_refine_from_advisory_cb (GsPluginDnf5 *self, ++ GVariant *array, ++ gpointer user_data, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ GHashTable *nevra_to_app = user_data; ++ g_autoptr(GVariantDict) dict = NULL; ++ g_autoptr(GVariant) collections = NULL; ++ g_autoptr(GVariant) severity = NULL; ++ gboolean res = TRUE; ++ ++ dict = g_variant_dict_new (array); ++ ++ /* ensure only advisories with severity 'critical' are traversed */ ++ severity = g_variant_dict_lookup_value (dict, "severity", G_VARIANT_TYPE_STRING); ++ if (severity == NULL || g_variant_get_string (severity, NULL) == NULL || ++ g_ascii_strcasecmp (g_variant_get_string (severity, NULL), "critical") != 0) ++ return TRUE; ++ ++ collections = g_variant_dict_lookup_value (dict, "collections", G_VARIANT_TYPE_ARRAY); ++ if (collections != NULL) ++ res = gs_dnf5_foreach_item (self, collections, gs_dnf5_refine_from_advisory_collections_cb, nevra_to_app, cancellable, error); ++ ++ return res; ++} ++ ++static GVariant * ++gs_dnf5_dup_package_attrs (void) ++{ ++ g_autoptr(GVariantBuilder) attrs_builder = NULL; ++ ++ attrs_builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); ++ g_variant_builder_add (attrs_builder, "s", "nevra"); ++ g_variant_builder_add (attrs_builder, "s", "name"); ++ g_variant_builder_add (attrs_builder, "s", "epoch"); ++ g_variant_builder_add (attrs_builder, "s", "version"); ++ g_variant_builder_add (attrs_builder, "s", "release"); ++ g_variant_builder_add (attrs_builder, "s", "arch"); ++ g_variant_builder_add (attrs_builder, "s", "repo_id"); ++ g_variant_builder_add (attrs_builder, "s", "install_size"); ++ g_variant_builder_add (attrs_builder, "s", "download_size"); ++ g_variant_builder_add (attrs_builder, "s", "is_installed"); ++ g_variant_builder_add (attrs_builder, "s", "summary"); ++ g_variant_builder_add (attrs_builder, "s", "url"); ++ g_variant_builder_add (attrs_builder, "s", "license"); ++ g_variant_builder_add (attrs_builder, "s", "description"); ++ g_variant_builder_add (attrs_builder, "s", "changelogs"); ++ ++ return g_variant_builder_end (attrs_builder); ++} ++ ++static void ++gs_dnf5_gather_async_result_cb (GObject *source_object, ++ GAsyncResult *result, ++ gpointer user_data) ++{ ++ GAsyncResult **out_result = user_data; ++ *out_result = g_object_ref (result); ++} ++ ++static void ++gs_dnf5_confirm_key_response_cb (GObject *source_object, ++ GAsyncResult *result, ++ gpointer user_data) ++{ ++ g_autoptr(GError) local_error = NULL; ++ ++ if (!gs_dnf5_rpm_repo_call_confirm_key_finish (GS_DNF5_RPM_REPO (source_object), result, &local_error)) ++ g_debug ("Failed to confirm key: %s", local_error->message); ++} ++ ++typedef struct { ++ gchar *title; ++ gchar *msg; ++ gchar *details; ++ gchar *accept_label; ++ gchar *key_id; ++ GsPluginDnf5 *self; /* (owned) */ ++ GWeakRef repo_proxy_weakref; /* GsDnf5RpmRepo */ ++} QuestionData; ++ ++static void ++question_data_free (QuestionData *data) ++{ ++ if (data != NULL) { ++ g_free (data->title); ++ g_free (data->msg); ++ g_free (data->details); ++ g_free (data->accept_label); ++ g_free (data->key_id); ++ g_clear_object (&data->self); ++ g_weak_ref_clear (&data->repo_proxy_weakref); ++ g_free (data); ++ } ++} ++ ++static gboolean ++gs_dnf5_ask_question_idle_cb (gpointer user_data) ++{ ++ QuestionData *data = user_data; ++ g_autoptr(GsDnf5RpmRepo) repo_proxy = NULL; ++ ++ repo_proxy = g_weak_ref_get (&data->repo_proxy_weakref); ++ if (repo_proxy != NULL) { ++ gboolean confirmed; ++ ++ confirmed = gs_plugin_ask_untrusted (GS_PLUGIN (data->self), data->title, data->msg, data->details, data->accept_label); ++ ++ gs_dnf5_rpm_repo_call_confirm_key (repo_proxy, data->key_id, confirmed, NULL, gs_dnf5_confirm_key_response_cb, NULL); ++ } ++ ++ return G_SOURCE_REMOVE; ++} ++ ++typedef struct { ++ GsPluginDnf5 *self; /* (not owned) */ ++ const gchar *session_path; /* (not owned) */ ++ GsDnf5RpmRepo *repo_proxy; /* (not owned) */ ++} RepoKeyImportData; ++ ++static void ++gs_dnf5_repo_key_import_request_cb (GsDnf5Base *object, ++ const gchar *arg_session_object_path, ++ const gchar *arg_key_id, ++ const gchar *const *arg_user_ids, ++ const gchar *arg_key_fingerprint, ++ const gchar *arg_key_url, ++ gint64 arg_timestamp, ++ RepoKeyImportData *repo_key_import_data) ++{ ++ QuestionData *data; ++ g_autoptr(GString) user_ids = NULL; ++ g_autofree gchar *key_filename = NULL; ++ g_autoptr(GString) str_fingerprint = NULL; ++ GString *details = NULL; ++ const gchar *fingerprint; ++ const gchar *from; ++ ++ if (g_strcmp0 (repo_key_import_data->session_path, arg_session_object_path) != 0) ++ return; ++ ++ user_ids = g_string_new (NULL); ++ for (guint i = 0; arg_user_ids != NULL && arg_user_ids[i] != NULL; i++) { ++ if (i > 0) ++ g_string_append (user_ids, ", "); ++ g_string_append_c (user_ids, '"'); ++ g_string_append (user_ids, arg_user_ids[i]); ++ g_string_append_c (user_ids, '"'); ++ } ++ ++ g_debug ("%s: key_id:'%s' user_ids:[%s] key_fingerprint:'%s' key_url:'%s' timestamp:%" G_GINT64_FORMAT, ++ G_STRFUNC, arg_key_id, user_ids->str, arg_key_fingerprint, arg_key_url, arg_timestamp); ++ ++ if (g_ascii_strncasecmp (arg_key_url, "file:", 5) == 0) ++ key_filename = g_filename_from_uri (arg_key_url, NULL, NULL); ++ ++ if ((strlen (arg_key_fingerprint) % 4) == 0) { ++ str_fingerprint = g_string_new (arg_key_fingerprint); ++ for (gint i = str_fingerprint->len - 4; i > 0; i -= 4) { ++ g_string_insert_c (str_fingerprint, i, ' '); ++ } ++ } ++ ++ details = g_string_new (""); ++ ++ from = key_filename != NULL ? key_filename : arg_key_url; ++ fingerprint = str_fingerprint != NULL ? str_fingerprint->str : arg_key_fingerprint; ++ ++ #define add_nonempty_line(_format, _value) G_STMT_START { \ ++ if ((_value) != NULL && *(_value) != '\0') { \ ++ g_string_append_printf (details, _format, _value); \ ++ g_string_append_c (details, '\n'); \ ++ } \ ++ } G_STMT_END ++ ++ /* Translators: the '%s' is replaced with the key user name */ ++ add_nonempty_line (_("Key user: %s"), user_ids->str); ++ /* Translators: the '%s' is replaced with the key fingerprint, a few hex digits */ ++ add_nonempty_line (_("Fingerprint: %s"), fingerprint); ++ /* Translators: the '%s' is replaced with the local path or a URI to the key */ ++ add_nonempty_line (_("From: %s"), from); ++ ++ #undef add_nonempty_line ++ ++ data = g_new0 (QuestionData, 1); ++ data->title = g_strdup (_("Import Key")); ++ /* Translators: the '%s' is replaced with the key ID, usually a few hex digits */ ++ data->msg = g_strdup_printf (_("Do you want to import key %s?"), arg_key_id); ++ data->details = g_string_free (details, FALSE); ++ data->accept_label = g_strdup (_("_Import Key")); ++ data->key_id = g_strdup (arg_key_id); ++ data->self = g_object_ref (repo_key_import_data->self); ++ g_weak_ref_init (&data->repo_proxy_weakref, repo_key_import_data->repo_proxy); ++ ++ g_idle_add_full (G_PRIORITY_HIGH_IDLE, gs_dnf5_ask_question_idle_cb, data, (GDestroyNotify) question_data_free); ++} ++ ++static void ++gs_dnf5_goal_cancelled_cb (GObject *source_object, ++ GAsyncResult *result, ++ gpointer user_data) ++{ ++ g_autoptr(GCancellable) run_cancellable = user_data; ++ g_autoptr(GError) local_error = NULL; ++ g_autofree gchar *error_message = NULL; ++ gboolean succeeded = FALSE; ++ ++ if (gs_dnf5_goal_call_cancel_finish (GS_DNF5_GOAL (source_object), &succeeded, &error_message, result, &local_error)) { ++ if (succeeded) { ++ g_debug ("%s: Transaction cancelled by the user", G_STRFUNC); ++ g_cancellable_cancel (run_cancellable); ++ } else { ++ g_debug ("%s: Cannot cancel transaction: %s", G_STRFUNC, error_message); ++ } ++ } else if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { ++ g_debug ("%s: Failed to cancel transaction: %s", G_STRFUNC, local_error->message); ++ } ++} ++ ++static gboolean ++gs_dnf5_reset_transaction_sync (GsPluginDnf5 *self, ++ const gchar *session_path, ++ GsDnf5RpmRpm *rpm_proxy, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ g_autoptr(GsDnf5Goal) goal_proxy = NULL; ++ ++ goal_proxy = gs_dnf5_goal_proxy_new_sync (self->connection, ++ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, ++ GS_DNF5_INTERFACE_RPM_DNF, ++ session_path, ++ cancellable, ++ error); ++ if (goal_proxy == NULL) { ++ gs_dnf5_convert_error (error); ++ g_prefix_error_literal (error, "Failed to create Goal proxy: "); ++ return FALSE; ++ } ++ ++ return gs_dnf5_goal_call_reset_sync (goal_proxy, cancellable, error); ++} ++ ++/* this is needed to receive D-Bus signals about progress in the worker thread */ ++static gboolean ++gs_dnf5_goal_call_do_transaction_sync_wrapper (GsDnf5Goal *proxy, ++ GVariant *arg_options, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ g_autoptr(GMainContext) main_context = g_main_context_ref_thread_default (); ++ g_autoptr(GAsyncResult) async_result = NULL; ++ gs_dnf5_goal_call_do_transaction (proxy, arg_options, cancellable, gs_dnf5_gather_async_result_cb, &async_result); ++ while (!async_result) ++ g_main_context_iteration (main_context, TRUE); ++ return gs_dnf5_goal_call_do_transaction_finish (proxy, async_result, error); ++} ++ ++typedef struct { ++ GsDnf5Goal *goal_proxy; ++ GCancellable *run_cancellable; ++} TransactionData; ++ ++static void ++gs_dnf5_transaction_cancelled_cb (GCancellable *parent_cancellable, ++ TransactionData *transaction_data) ++{ ++ gs_dnf5_goal_call_cancel (transaction_data->goal_proxy, transaction_data->run_cancellable, ++ gs_dnf5_goal_cancelled_cb, g_object_ref (transaction_data->run_cancellable)); ++} ++ ++typedef enum { ++ GS_DNF5_TRANSACTION_FLAG_NONE = 0, ++ GS_DNF5_TRANSACTION_FLAG_OFFLINE = 1 << 0, ++ GS_DNF5_TRANSACTION_FLAG_RESOLVE_ONLY = 1 << 1 ++} GsDnf5TransactionFlags; ++ ++static gboolean ++gs_dnf5_run_transaction (GsPluginDnf5 *self, ++ const gchar *session_path, ++ GsDnf5RpmRpm *rpm_proxy, ++ GsApp *progress_app, ++ GsDnf5TransactionFlags flags, ++ GVariant **out_transaction, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ g_autoptr(GsDnf5Base) base_proxy = NULL; ++ g_autoptr(GsDnf5Goal) goal_proxy = NULL; ++ g_autoptr(GsDnf5RpmRepo) repo_proxy = NULL; ++ g_autoptr(GVariantBuilder) options_builder = NULL; ++ g_autoptr(GVariant) transaction = NULL; ++ g_autoptr(GsDnf5ProgressHelper) helper = NULL; ++ g_autoptr(GCancellable) run_cancellable = NULL; ++ RepoKeyImportData repo_key_import_data; ++ TransactionData transaction_data; ++ gulong repo_key_import_id; ++ gulong cancellable_id = 0; ++ guint result = 0; ++ gboolean success; ++ ++ base_proxy = gs_dnf5_base_proxy_new_sync (self->connection, ++ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, ++ GS_DNF5_INTERFACE_RPM_DNF, ++ session_path, ++ cancellable, ++ error); ++ if (base_proxy == NULL) { ++ gs_dnf5_convert_error (error); ++ g_prefix_error_literal (error, "Failed to create Base proxy: "); ++ return FALSE; ++ } ++ ++ repo_proxy = gs_dnf5_rpm_repo_proxy_new_sync (self->connection, ++ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, ++ GS_DNF5_INTERFACE_RPM_DNF, ++ session_path, ++ cancellable, ++ error); ++ if (repo_proxy == NULL) { ++ gs_dnf5_convert_error (error); ++ g_prefix_error_literal (error, "Failed to create Repo proxy: "); ++ return FALSE; ++ } ++ ++ goal_proxy = gs_dnf5_goal_proxy_new_sync (self->connection, ++ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, ++ GS_DNF5_INTERFACE_RPM_DNF, ++ session_path, ++ cancellable, ++ error); ++ if (goal_proxy == NULL) { ++ gs_dnf5_convert_error (error); ++ g_prefix_error_literal (error, "Failed to create Goal proxy: "); ++ return FALSE; ++ } ++ ++ g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (goal_proxy), G_MAXINT); ++ ++ options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ ++ if (progress_app != NULL) ++ helper = gs_dnf5_progress_helper_new (base_proxy, rpm_proxy, progress_app, session_path); ++ ++ repo_key_import_data.self = self; ++ repo_key_import_data.session_path = session_path; ++ repo_key_import_data.repo_proxy = repo_proxy; ++ repo_key_import_id = g_signal_connect (base_proxy, "repo_key_import_request", ++ G_CALLBACK (gs_dnf5_repo_key_import_request_cb), &repo_key_import_data); ++ ++ if (!gs_dnf5_goal_call_resolve_sync (goal_proxy, ++ g_variant_builder_end (options_builder), ++ &transaction, ++ &result, ++ cancellable, ++ error)) { ++ gs_dnf5_convert_error (error); ++ g_prefix_error_literal (error, "Failed to resolve transaction: "); ++ g_signal_handler_disconnect (base_proxy, repo_key_import_id); ++ return FALSE; ++ } ++ ++ if (out_transaction != NULL && transaction != NULL) ++ *out_transaction = g_variant_ref_sink (transaction); ++ ++ /* 0 ... all fine, 1 ... there are warnings, 2 ... failed */ ++ if (result == 2) { ++ g_auto(GStrv) problems = NULL; ++ ++ if (gs_dnf5_goal_call_get_transaction_problems_string_sync (goal_proxy, &problems, cancellable, error) && ++ problems != NULL) { ++ /* extra space at the end, but no harm, it reuses translated string */ ++ GString *msg = g_string_new ("Failed to resolve transaction: "); ++ for (guint i = 0; problems[i] != NULL; i++) { ++ g_string_append_c (msg, '\n'); ++ g_string_append (msg, problems[i]); ++ } ++ g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, msg->str); ++ } else { ++ g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, ++ _("Unknown error")); ++ g_prefix_error (error, "Failed to resolve transaction: "); ++ } ++ g_signal_handler_disconnect (base_proxy, repo_key_import_id); ++ return FALSE; ++ } ++ ++ g_clear_pointer (&options_builder, g_variant_builder_unref); ++ ++ if ((flags & GS_DNF5_TRANSACTION_FLAG_RESOLVE_ONLY) != 0) { ++ g_signal_handler_disconnect (base_proxy, repo_key_import_id); ++ return TRUE; ++ } ++ ++ options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ if ((flags & GS_DNF5_TRANSACTION_FLAG_OFFLINE) != 0) { ++ g_variant_builder_add (options_builder, "{sv}", "offline", ++ g_variant_new_boolean (TRUE)); ++ } ++ ++ run_cancellable = g_cancellable_new (); ++ if (cancellable != NULL) { ++ transaction_data.goal_proxy = goal_proxy; ++ transaction_data.run_cancellable = run_cancellable; ++ ++ cancellable_id = g_cancellable_connect (cancellable, G_CALLBACK (gs_dnf5_transaction_cancelled_cb), ++ &transaction_data, NULL); ++ } ++ ++ success = gs_dnf5_goal_call_do_transaction_sync_wrapper (goal_proxy, ++ g_variant_builder_end (options_builder), ++ run_cancellable, ++ error); ++ ++ g_cancellable_disconnect (cancellable, cancellable_id); ++ g_signal_handler_disconnect (base_proxy, repo_key_import_id); ++ ++ /* in case there is a pending async call result for the cancel() invocation */ ++ g_cancellable_cancel (run_cancellable); ++ ++ if (!success) { ++ g_auto(GStrv) problems = NULL; ++ ++ gs_dnf5_convert_error (error); ++ g_prefix_error_literal (error, "Failed to run transaction: "); ++ ++ if (error != NULL && *error != NULL && ++ gs_dnf5_goal_call_get_transaction_problems_string_sync (goal_proxy, &problems, cancellable, NULL) && ++ problems != NULL) { ++ GString *msg = g_string_new ((*error)->message); ++ for (guint i = 0; problems[i] != NULL; i++) { ++ g_string_append_c (msg, '\n'); ++ g_string_append (msg, problems[i]); ++ } ++ g_clear_error (error); ++ g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, msg->str); ++ } ++ } ++ ++ return success; ++} ++ ++enum OpKindType { OP_KIND_UNKNOWN, OP_KIND_INSTALL, OP_KIND_UPGRADE, OP_KIND_DOWNGRADE, OP_KIND_REINSTALL, OP_KIND_REMOVE, OP_KIND_REPLACED }; ++ ++static enum OpKindType ++gs_dnf5_get_package_op_kind (GVariant *item_array) ++{ ++ struct _op_kinds { ++ const gchar *name; ++ enum OpKindType kind; ++ } op_kinds[] = { ++ { "Install", OP_KIND_INSTALL }, ++ { "Upgrade", OP_KIND_UPGRADE }, ++ { "Downgrade", OP_KIND_DOWNGRADE }, ++ { "Reinstall", OP_KIND_REINSTALL }, ++ { "Remove", OP_KIND_REMOVE }, ++ { "Replaced", OP_KIND_REPLACED } ++ }; ++ const gchar *str = NULL; ++ ++ g_variant_get_child (item_array, 0, "&s", &str); ++ if (str == NULL || g_ascii_strcasecmp (str, "package") != 0) ++ return OP_KIND_UNKNOWN; ++ ++ g_variant_get_child (item_array, 1, "&s", &str); ++ if (str == NULL) ++ return OP_KIND_UNKNOWN; ++ ++ for (guint i = 0; i < G_N_ELEMENTS (op_kinds); i++) { ++ if (g_ascii_strcasecmp (str, op_kinds[i].name) == 0) { ++ return op_kinds[i].kind; ++ } ++ } ++ ++ return OP_KIND_UNKNOWN; ++} ++ ++static gboolean ++gs_dnf5_gather_update_replaces_cb (GsPluginDnf5 *self, ++ GVariant *item_array, ++ gpointer user_data, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ ReadPackageData *rpd = user_data; ++ enum OpKindType op_kind = gs_dnf5_get_package_op_kind (item_array); ++ ++ if (op_kind == OP_KIND_REPLACED && rpd->replaces) { ++ g_autoptr(GVariantDict) dict = NULL; ++ g_autoptr(GVariant) value = NULL; ++ ++ value = g_variant_get_child_value (item_array, 4); ++ dict = g_variant_dict_new (value); ++ g_clear_pointer (&value, g_variant_unref); ++ ++ value = g_variant_dict_lookup_value (dict, "id", G_VARIANT_TYPE_INT32); ++ if (value != NULL) { ++ gint32 id = g_variant_get_int32 (value); ++ gchar *version = gs_dnf5_dup_version_from_dict (dict); ++ if (version != NULL) ++ g_hash_table_insert (rpd->replaces, GINT_TO_POINTER (id), version); ++ } ++ } ++ ++ return TRUE; ++} ++ ++typedef struct _UpdateReplacesData { ++ GsApp *app; ++ GHashTable *replaces; ++} UpdateReplacesData; ++ ++static gboolean ++gs_dnf5_gather_update_replaced_pkgs_cb (GsPluginDnf5 *self, ++ GVariant *item_array, ++ gpointer user_data, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ UpdateReplacesData *upd = user_data; ++ gint32 replaces_id = g_variant_get_int32 (item_array); ++ const gchar *old_version = g_hash_table_lookup (upd->replaces, GINT_TO_POINTER (replaces_id)); ++ if (old_version != NULL) ++ gs_app_set_version (upd->app, old_version); ++ ++ return TRUE; ++} ++ ++static gboolean ++gs_dnf5_gather_updates_from_transaction_cb (GsPluginDnf5 *self, ++ GVariant *item_array, ++ gpointer user_data, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ ReadPackageData *rpd = user_data; ++ enum OpKindType op_kind = gs_dnf5_get_package_op_kind (item_array); ++ const gchar *str; ++ g_autoptr(GVariantDict) dict = NULL; ++ g_autoptr(GVariant) value = NULL; ++ g_autoptr(GsApp) upd_app = NULL; ++ g_autoptr(GString) nevra = NULL; ++ GsApp *known_app; ++ ++ if (op_kind == OP_KIND_UNKNOWN || op_kind == OP_KIND_REPLACED) ++ return TRUE; ++ ++ value = g_variant_get_child_value (item_array, 4); ++ dict = g_variant_dict_new (value); ++ g_clear_pointer (&value, g_variant_unref); ++ ++ value = g_variant_dict_lookup_value (dict, "name", G_VARIANT_TYPE_STRING); ++ if (value == NULL) ++ return TRUE; ++ str = g_variant_get_string (value, NULL); ++ if (str == NULL) ++ return TRUE; ++ ++ nevra = g_string_new (str); ++ ++ g_clear_pointer (&value, g_variant_unref); ++ value = g_variant_dict_lookup_value (dict, "evr", G_VARIANT_TYPE_STRING); ++ if (value == NULL) ++ return TRUE; ++ str = g_variant_get_string (value, NULL); ++ if (str == NULL) ++ return TRUE; ++ ++ g_string_append_c (nevra, '-'); ++ g_string_append (nevra, str); ++ ++ g_clear_pointer (&value, g_variant_unref); ++ value = g_variant_dict_lookup_value (dict, "arch", G_VARIANT_TYPE_STRING); ++ if (value == NULL) ++ return TRUE; ++ str = g_variant_get_string (value, NULL); ++ if (str == NULL) ++ return TRUE; ++ ++ g_string_append_c (nevra, '.'); ++ g_string_append (nevra, str); ++ ++ known_app = g_hash_table_lookup (rpd->nevra_to_app, nevra->str); ++ if (known_app != NULL) { ++ upd_app = g_object_ref (known_app); ++ if (gs_app_get_version (upd_app) == NULL) ++ gs_dnf5_app_set_version (dict, upd_app, gs_app_set_version); ++ else ++ gs_dnf5_app_set_version (dict, upd_app, gs_app_set_update_version); ++ ++ if (rpd->replaces != NULL) { ++ g_autoptr(GVariantDict) dict2 = NULL; ++ ++ g_clear_pointer (&value, g_variant_unref); ++ value = g_variant_get_child_value (item_array, 3); ++ dict2 = g_variant_dict_new (value); ++ g_clear_pointer (&value, g_variant_unref); ++ value = g_variant_dict_lookup_value (dict2, "replaces", G_VARIANT_TYPE_ARRAY); ++ if (value != NULL) { ++ UpdateReplacesData upd = { 0, }; ++ ++ upd.app = upd_app; ++ upd.replaces = rpd->replaces; ++ ++ if (!gs_dnf5_foreach_item (self, value, gs_dnf5_gather_update_replaced_pkgs_cb, &upd, cancellable, error)) ++ return FALSE; ++ } ++ } ++ } else { ++ upd_app = gs_app_new (NULL); ++ gs_app_set_management_plugin (upd_app, GS_PLUGIN (self)); ++ gs_app_set_metadata (upd_app, "GnomeSoftware::Creator", gs_plugin_get_name (GS_PLUGIN (self))); ++ gs_plugin_dnf5_set_packaging_format (upd_app); ++ gs_app_set_kind (upd_app, AS_COMPONENT_KIND_GENERIC); ++ gs_app_set_bundle_kind (upd_app, AS_BUNDLE_KIND_PACKAGE); ++ gs_app_set_scope (upd_app, AS_COMPONENT_SCOPE_SYSTEM); ++ gs_app_add_quirk (upd_app, GS_APP_QUIRK_HIDE_EVERYWHERE); ++ gs_app_add_quirk (upd_app, GS_APP_QUIRK_NEEDS_REBOOT); ++ ++ gs_dnf5_app_set_str (dict, "name", upd_app, gs_app_add_source); ++ gs_dnf5_app_set_str2 (dict, "name", upd_app, gs_app_set_name); ++ gs_dnf5_app_set_version (dict, upd_app, gs_app_set_version); ++ gs_app_add_source_id (upd_app, nevra->str); ++ ++ gs_app_list_add (rpd->list, upd_app); ++ g_hash_table_insert (rpd->nevra_to_app, g_string_free (g_steal_pointer (&nevra), FALSE), g_object_ref (upd_app)); ++ } ++ ++ gs_dnf5_app_set_size (dict, "install_size", upd_app, gs_app_set_size_installed); ++ gs_dnf5_app_set_size (dict, "download_size", upd_app, gs_app_set_size_download); ++ ++ switch (op_kind) { ++ case OP_KIND_INSTALL: ++ gs_app_set_state (upd_app, GS_APP_STATE_AVAILABLE); ++ break; ++ case OP_KIND_UPGRADE: ++ case OP_KIND_DOWNGRADE: ++ case OP_KIND_REINSTALL: ++ gs_app_set_state (upd_app, GS_APP_STATE_UPDATABLE); ++ break; ++ case OP_KIND_REMOVE: ++ gs_app_set_state (upd_app, GS_APP_STATE_UNAVAILABLE); ++ break; ++ case OP_KIND_REPLACED: ++ case OP_KIND_UNKNOWN: ++ default: ++ g_warn_if_reached (); ++ break; ++ } ++ ++ return TRUE; ++} ++ ++/* Run in @worker. */ ++static void ++gs_dnf5_list_apps_thread_cb (GTask *task, ++ gpointer source_object, ++ gpointer task_data, ++ GCancellable *cancellable) ++{ ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (source_object); ++ GsAppQueryTristate is_for_update = GS_APP_QUERY_TRISTATE_UNSET; ++ GsAppQueryTristate is_source = GS_APP_QUERY_TRISTATE_UNSET; ++ GsPluginListAppsData *data = task_data; ++ const gchar * const *provides_files = NULL; ++ const gchar *provides_tag = NULL; ++ GsAppQueryProvidesType provides_type = GS_APP_QUERY_PROVIDES_UNKNOWN; ++ g_autofree gchar *session_path = NULL; ++ g_autoptr(GsAppList) list = NULL; ++ g_autoptr(GsDnf5SessionManager) session_manager = NULL; ++ g_autoptr(GsDnf5RpmRpm) rpm_proxy = NULL; ++ g_autoptr(GError) local_error = NULL; ++ gboolean success = TRUE; ++ ++ assert_in_worker (self); ++ ++ if (data->query != NULL) { ++ is_for_update = gs_app_query_get_is_for_update (data->query); ++ is_source = gs_app_query_get_is_source (data->query); ++ provides_files = gs_app_query_get_provides_files (data->query); ++ provides_type = gs_app_query_get_provides (data->query, &provides_tag); ++ } ++ ++ if ((is_for_update == GS_APP_QUERY_TRISTATE_UNSET && ++ is_source == GS_APP_QUERY_TRISTATE_UNSET && ++ provides_tag == NULL && ++ provides_files == NULL) || ++ is_for_update == GS_APP_QUERY_TRISTATE_FALSE || ++ is_source == GS_APP_QUERY_TRISTATE_FALSE || ++ gs_app_query_get_n_properties_set (data->query) != 1) { ++ g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, ++ "Unsupported query"); ++ return; ++ } ++ ++ session_path = gs_dnf5_open_session (self, GS_DNF5_RELEASEVER_DEFAULT, &session_manager, cancellable, &local_error); ++ if (session_path == NULL) { ++ gs_dnf5_convert_error (&local_error); ++ g_task_return_error (task, g_steal_pointer (&local_error)); ++ return; ++ } ++ ++ rpm_proxy = gs_dnf5_rpm_rpm_proxy_new_sync (self->connection, ++ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, ++ GS_DNF5_INTERFACE_RPM_DNF, ++ session_path, ++ cancellable, ++ &local_error); ++ success = rpm_proxy != NULL; ++ if (!success) { ++ gs_dnf5_convert_error (&local_error); ++ g_prefix_error_literal (&local_error, "Failed to create Rpm proxy: "); ++ } ++ ++ if (success) { ++ g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (rpm_proxy), G_MAXINT); ++ list = gs_app_list_new (); ++ ++ if (is_for_update == GS_APP_QUERY_TRISTATE_TRUE) { ++ g_autoptr(GVariantBuilder) options_builder = NULL; ++ g_autoptr(GVariant) result = NULL; ++ ++ g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (rpm_proxy), G_MAXINT); ++ ++ options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ g_variant_builder_add (options_builder, "{sv}", "package_attrs", ++ gs_dnf5_dup_package_attrs ()); ++ g_variant_builder_add (options_builder, "{sv}", "with_provides", ++ g_variant_new_boolean (FALSE)); ++ g_variant_builder_add (options_builder, "{sv}", "with_filenames", ++ g_variant_new_boolean (FALSE)); ++ g_variant_builder_add (options_builder, "{sv}", "with_src", ++ g_variant_new_boolean (FALSE)); ++ g_variant_builder_add (options_builder, "{sv}", "scope", ++ g_variant_new_string ("upgrades")); ++ ++ success = gs_dnf5_rpm_rpm_call_list_sync (rpm_proxy, ++ g_variant_builder_end (options_builder), ++ &result, ++ cancellable, ++ &local_error); ++ ++ if (success) { ++ g_autoptr(GHashTable) nevra_to_app = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); ++ g_autoptr(GHashTable) replaces = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); ++ ReadPackageData rpd = { 0, }; ++ rpd.list = list; ++ rpd.set_state = GS_APP_STATE_UPDATABLE; ++ rpd.nevra_to_app = nevra_to_app; ++ rpd.replaces = replaces; ++ ++ success = gs_dnf5_foreach_item (self, result, gs_dnf5_read_package_cb, &rpd, cancellable, &local_error); ++ ++ if (success && g_hash_table_size (nevra_to_app) > 0) { ++ g_autoptr(GVariantBuilder) options_builder2 = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ g_autoptr(GVariant) transaction = NULL; ++ const gchar * const packages[2] = { NULL, NULL }; ++ ++ success = gs_dnf5_reset_transaction_sync (self, session_path, rpm_proxy, cancellable, &local_error); ++ ++ success = success && ++ gs_dnf5_rpm_rpm_call_upgrade_sync (rpm_proxy, ++ packages, ++ g_variant_builder_end (options_builder2), ++ cancellable, ++ &local_error); ++ success = success && ++ gs_dnf5_run_transaction (self, session_path, rpm_proxy, NULL, ++ GS_DNF5_TRANSACTION_FLAG_RESOLVE_ONLY, ++ &transaction, cancellable, &local_error); ++ if (success && transaction != NULL) { ++ success = gs_dnf5_foreach_item (self, transaction, ++ gs_dnf5_gather_update_replaces_cb, &rpd, ++ cancellable, &local_error); ++ success = success && ++ gs_dnf5_foreach_item (self, transaction, ++ gs_dnf5_gather_updates_from_transaction_cb, &rpd, ++ cancellable, &local_error); ++ } ++ } ++ ++ if (success && g_hash_table_size (nevra_to_app) > 0) { ++ g_autoptr(GsDnf5Advisory) advisory_proxy = NULL; ++ g_autoptr(GError) local_error2 = NULL; ++ gboolean adv_success; ++ ++ advisory_proxy = gs_dnf5_advisory_proxy_new_sync (self->connection, ++ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, ++ GS_DNF5_INTERFACE_RPM_DNF, ++ session_path, ++ cancellable, ++ &local_error2); ++ adv_success = advisory_proxy != NULL; ++ ++ if (adv_success) { ++ g_autoptr(GVariantBuilder) adv_options_builder = NULL; ++ g_autoptr(GVariantBuilder) attrs_builder = NULL; ++ g_autoptr(GVariantBuilder) severities_builder = NULL; ++ g_autoptr(GVariant) adv_result = NULL; ++ ++ attrs_builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); ++ g_variant_builder_add (attrs_builder, "s", "severity"); ++ g_variant_builder_add (attrs_builder, "s", "collections"); ++ ++ severities_builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); ++ g_variant_builder_add (severities_builder, "s", "critical"); ++ ++ adv_options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ g_variant_builder_add (adv_options_builder, "{sv}", "advisory_attrs", ++ g_variant_builder_end (attrs_builder)); ++ g_variant_builder_add (adv_options_builder, "{sv}", "availability", ++ g_variant_new_string ("updates")); ++ g_variant_builder_add (adv_options_builder, "{sv}", "severities", ++ g_variant_builder_end (severities_builder)); ++ ++ adv_success = gs_dnf5_advisory_call_list_sync (advisory_proxy, ++ g_variant_builder_end (adv_options_builder), ++ &adv_result, ++ cancellable, ++ &local_error2); ++ if (adv_success) { ++ adv_success = gs_dnf5_foreach_item (self, adv_result, ++ gs_dnf5_refine_from_advisory_cb, nevra_to_app, ++ cancellable, &local_error2); ++ } else { ++ g_debug ("Failed to call Advisory::list: %s", local_error2->message); ++ } ++ } else { ++ g_debug ("Failed to create Advisory proxy: %s", local_error2->message); ++ } ++ } ++ } else { ++ gs_dnf5_convert_error (&local_error); ++ g_prefix_error_literal (&local_error, "Failed to call Rpm::list: "); ++ } ++ } else if (is_source == GS_APP_QUERY_TRISTATE_TRUE) { ++ g_autoptr(GsDnf5RpmRepo) repo_proxy = NULL; ++ ++ repo_proxy = gs_dnf5_rpm_repo_proxy_new_sync (self->connection, ++ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, ++ GS_DNF5_INTERFACE_RPM_DNF, ++ session_path, ++ cancellable, ++ &local_error); ++ success = repo_proxy != NULL; ++ if (success) { ++ g_autoptr(GVariantBuilder) options_builder = NULL; ++ g_autoptr(GVariantBuilder) attrs_builder = NULL; ++ g_autoptr(GVariant) result = NULL; ++ ++ g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (repo_proxy), G_MAXINT); ++ ++ attrs_builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); ++ g_variant_builder_add (attrs_builder, "s", "id"); ++ g_variant_builder_add (attrs_builder, "s", "name"); ++ g_variant_builder_add (attrs_builder, "s", "enabled"); ++ ++ options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ g_variant_builder_add (options_builder, "{sv}", "repo_attrs", ++ g_variant_builder_end (attrs_builder)); ++ g_variant_builder_add (options_builder, "{sv}", "enable_disable", ++ g_variant_new_string ("all")); ++ ++ success = gs_dnf5_rpm_repo_call_list_sync (repo_proxy, ++ g_variant_builder_end (options_builder), ++ &result, ++ cancellable, ++ &local_error); ++ ++ if (success) { ++ success = gs_dnf5_foreach_item (self, result, gs_dnf5_read_repo_cb, list, cancellable, &local_error); ++ } else { ++ gs_dnf5_convert_error (&local_error); ++ g_prefix_error_literal (&local_error, "Failed to call list: "); ++ } ++ } else { ++ gs_dnf5_convert_error (&local_error); ++ g_prefix_error_literal (&local_error, "Failed to create Rpm repo proxy: "); ++ } ++ } else if (provides_files != NULL) { ++ g_autoptr(GVariantBuilder) patterns_builder = NULL; ++ g_autoptr(GVariantBuilder) options_builder = NULL; ++ g_autoptr(GVariant) result = NULL; ++ ++ patterns_builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); ++ for (guint i = 0; provides_files[i] != NULL; i++) { ++ g_variant_builder_add (patterns_builder, "s", provides_files[i]); ++ } ++ ++ options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ g_variant_builder_add (options_builder, "{sv}", "scope", ++ g_variant_new_string ("all")); ++ g_variant_builder_add (options_builder, "{sv}", "with_nevra", ++ g_variant_new_boolean (FALSE)); ++ g_variant_builder_add (options_builder, "{sv}", "with_provides", ++ g_variant_new_boolean (TRUE)); ++ g_variant_builder_add (options_builder, "{sv}", "with_filenames", ++ g_variant_new_boolean (TRUE)); ++ g_variant_builder_add (options_builder, "{sv}", "with_src", ++ g_variant_new_boolean (FALSE)); ++ g_variant_builder_add (options_builder, "{sv}", "package_attrs", ++ gs_dnf5_dup_package_attrs ()); ++ g_variant_builder_add (options_builder, "{sv}", "patterns", ++ g_variant_builder_end (patterns_builder)); ++ ++ success = gs_dnf5_rpm_rpm_call_list_sync (rpm_proxy, ++ g_variant_builder_end (options_builder), ++ &result, ++ cancellable, ++ &local_error); ++ ++ if (success) { ++ ReadPackageData rpd = { 0, }; ++ rpd.list = list; ++ rpd.set_state = GS_APP_STATE_UNKNOWN; ++ rpd.nevra_to_app = NULL; ++ success = gs_dnf5_foreach_item (self, result, gs_dnf5_read_package_cb, &rpd, cancellable, &local_error); ++ } else { ++ gs_dnf5_convert_error (&local_error); ++ g_prefix_error_literal (&local_error, "Failed to call list: "); ++ } ++ } else if (provides_tag != NULL) { ++ g_autoptr(GVariantBuilder) patterns_builder = NULL; ++ g_autoptr(GVariantBuilder) options_builder = NULL; ++ g_autoptr(GVariant) result = NULL; ++ g_autofree gchar *pattern1 = NULL, *pattern2 = NULL; ++ ++ patterns_builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); ++ ++ switch (provides_type) { ++ case GS_APP_QUERY_PROVIDES_PACKAGE_NAME: ++ g_variant_builder_add (patterns_builder, "s", provides_tag); ++ break; ++ case GS_APP_QUERY_PROVIDES_GSTREAMER: ++ pattern1 = g_strdup_printf ("gstreamer0.10(%s)", provides_tag); ++ pattern2 = g_strdup_printf ("gstreamer1(%s)", provides_tag); ++ break; ++ case GS_APP_QUERY_PROVIDES_FONT: ++ pattern1 = g_strdup_printf ("font(%s)", provides_tag); ++ break; ++ case GS_APP_QUERY_PROVIDES_MIME_HANDLER: ++ pattern1 = g_strdup_printf ("mimehandler(%s)", provides_tag); ++ break; ++ case GS_APP_QUERY_PROVIDES_PS_DRIVER: ++ pattern1 = g_strdup_printf ("postscriptdriver(%s)", provides_tag); ++ break; ++ case GS_APP_QUERY_PROVIDES_PLASMA: ++ pattern1 = g_strdup_printf ("plasma4(%s)", provides_tag); ++ pattern2 = g_strdup_printf ("plasma5(%s)", provides_tag); ++ break; ++ case GS_APP_QUERY_PROVIDES_UNKNOWN: ++ default: ++ g_assert_not_reached (); ++ } ++ if (pattern1 != NULL) ++ g_variant_builder_add (patterns_builder, "s", pattern1); ++ if (pattern2 != NULL) ++ g_variant_builder_add (patterns_builder, "s", pattern2); ++ ++ options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ g_variant_builder_add (options_builder, "{sv}", "scope", ++ g_variant_new_string ("all")); ++ g_variant_builder_add (options_builder, "{sv}", "with_nevra", ++ g_variant_new_boolean (provides_type == GS_APP_QUERY_PROVIDES_PACKAGE_NAME)); ++ g_variant_builder_add (options_builder, "{sv}", "with_provides", ++ g_variant_new_boolean (provides_type != GS_APP_QUERY_PROVIDES_PACKAGE_NAME)); ++ g_variant_builder_add (options_builder, "{sv}", "with_filenames", ++ g_variant_new_boolean (FALSE)); ++ g_variant_builder_add (options_builder, "{sv}", "with_src", ++ g_variant_new_boolean (FALSE)); ++ g_variant_builder_add (options_builder, "{sv}", "package_attrs", ++ gs_dnf5_dup_package_attrs ()); ++ g_variant_builder_add (options_builder, "{sv}", "patterns", ++ g_variant_builder_end (patterns_builder)); ++ ++ success = gs_dnf5_rpm_rpm_call_list_sync (rpm_proxy, ++ g_variant_builder_end (options_builder), ++ &result, ++ cancellable, ++ &local_error); ++ ++ if (success) { ++ ReadPackageData rpd = { 0, }; ++ rpd.list = list; ++ rpd.set_state = GS_APP_STATE_UNKNOWN; ++ rpd.nevra_to_app = NULL; ++ success = gs_dnf5_foreach_item (self, result, gs_dnf5_read_package_cb, &rpd, cancellable, &local_error); ++ } else { ++ gs_dnf5_convert_error (&local_error); ++ g_prefix_error_literal (&local_error, "Failed to call list: "); ++ } ++ } else { ++ g_assert_not_reached (); ++ } ++ } ++ ++ gs_dnf5_close_session (self, session_manager, session_path); ++ ++ if (success) { ++ g_task_return_pointer (task, g_steal_pointer (&list), g_object_unref); ++ } else { ++ gs_dnf5_convert_error (&local_error); ++ g_task_return_error (task, g_steal_pointer (&local_error)); ++ } ++} ++ ++static void ++gs_plugin_dnf5_list_apps_async (GsPlugin *plugin, ++ GsAppQuery *query, ++ GsPluginListAppsFlags flags, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (plugin); ++ gboolean interactive = (flags & GS_PLUGIN_LIST_APPS_FLAGS_INTERACTIVE) != 0; ++ g_autoptr(GTask) task = NULL; ++ ++ task = gs_plugin_list_apps_data_new_task (plugin, query, flags, ++ cancellable, callback, user_data); ++ g_task_set_source_tag (task, gs_plugin_dnf5_list_apps_async); ++ ++ gs_worker_thread_queue (self->worker, gs_dnf5_get_priority_for_interactivity (interactive), ++ gs_dnf5_list_apps_thread_cb, g_steal_pointer (&task)); ++} ++ ++static GsAppList * ++gs_plugin_dnf5_list_apps_finish (GsPlugin *plugin, ++ GAsyncResult *result, ++ GError **error) ++{ ++ return g_task_propagate_pointer (G_TASK (result), error); ++} ++ ++static gboolean ++gs_dnf5_gather_dependency_sizes_cb (GsPluginDnf5 *self, ++ GVariant *item_array, ++ gpointer user_data, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ GsApp *main_app = user_data; ++ const gchar *str; ++ g_autoptr(GVariantDict) dict = NULL; ++ g_autoptr(GVariant) value = NULL; ++ g_autoptr(GsApp) dep_app = NULL; ++ ++ g_variant_get_child (item_array, 0, "&s", &str); ++ if (str == NULL || g_ascii_strcasecmp (str, "package") != 0) ++ return TRUE; ++ ++ g_variant_get_child (item_array, 2, "&s", &str); ++ if (str == NULL || g_ascii_strcasecmp (str, "dependency") != 0) ++ return TRUE; ++ ++ value = g_variant_get_child_value (item_array, 4); ++ dict = g_variant_dict_new (value); ++ g_clear_pointer (&value, g_variant_unref); ++ ++ value = g_variant_dict_lookup_value (dict, "name", G_VARIANT_TYPE_STRING); ++ if (value == NULL) ++ return TRUE; ++ str = g_variant_get_string (value, NULL); ++ if (str == NULL) ++ return TRUE; ++ /* the app itself is in the list too */ ++ if (g_strcmp0 (gs_app_get_source_default (main_app), str) == 0) ++ return TRUE; ++ ++ /* always create a new app, no cached can be used here */ ++ dep_app = gs_app_new (NULL); ++ gs_app_set_management_plugin (dep_app, GS_PLUGIN (self)); ++ gs_app_set_metadata (dep_app, "GnomeSoftware::Creator", gs_plugin_get_name (GS_PLUGIN (self))); ++ gs_plugin_dnf5_set_packaging_format (dep_app); ++ gs_app_set_kind (dep_app, AS_COMPONENT_KIND_GENERIC); ++ gs_app_set_bundle_kind (dep_app, AS_BUNDLE_KIND_PACKAGE); ++ gs_app_set_scope (dep_app, AS_COMPONENT_SCOPE_SYSTEM); ++ gs_app_add_quirk (dep_app, GS_APP_QUIRK_HIDE_EVERYWHERE); ++ ++ gs_dnf5_app_set_str (dict, "name", dep_app, gs_app_add_source); ++ gs_dnf5_app_set_str (dict, "nevra", dep_app, gs_app_add_source_id); ++ gs_dnf5_app_set_str2 (dict, "name", dep_app, gs_app_set_name); ++ gs_dnf5_app_set_str2 (dict, "summary", dep_app, gs_app_set_summary); ++ gs_dnf5_app_set_str2 (dict, "description", dep_app, gs_app_set_description); ++ gs_dnf5_app_set_str2 (dict, "license", dep_app, gs_app_set_license); ++ gs_dnf5_app_set_size (dict, "install_size", dep_app, gs_app_set_size_installed); ++ gs_dnf5_app_set_size (dict, "download_size", dep_app, gs_app_set_size_download); ++ ++ gs_dnf5_update_app_state (dep_app, GS_APP_STATE_UNKNOWN, dict); ++ ++ gs_app_add_related (main_app, dep_app); ++ ++ return TRUE; ++} ++ ++static gpointer ++gs_dnf5_dependency_sizes_thread (gpointer thread_data) ++{ ++ g_autofree GWeakRef *weakref = thread_data; ++ g_autoptr(GsPluginDnf5) self = g_weak_ref_get (weakref); ++ g_autoptr(GCancellable) cancellable = NULL; ++ g_autoptr(GError) local_error = NULL; ++ guint index = 0; ++ ++ if (self == NULL) ++ return NULL; ++ ++ g_mutex_lock (&self->dependency_sizes_data.mutex); ++ ++ if (self->dependency_sizes_data.cancellable != NULL) ++ cancellable = g_object_ref (self->dependency_sizes_data.cancellable); ++ ++ while (self->dependency_sizes_data.apps != NULL && index < self->dependency_sizes_data.apps->len && ++ !g_cancellable_is_cancelled (self->dependency_sizes_data.cancellable)) { ++ GsApp *app = g_ptr_array_index (self->dependency_sizes_data.apps, index); ++ g_autofree gchar *session_path = NULL; ++ g_autoptr(GsDnf5SessionManager) session_manager = NULL; ++ g_autoptr(GsDnf5RpmRpm) rpm_proxy = NULL; ++ gboolean success; ++ ++ index++; ++ ++ if (gs_app_is_installed (app) || ++ gs_app_list_length (gs_app_get_related (app)) > 0) ++ continue; ++ ++ g_mutex_unlock (&self->dependency_sizes_data.mutex); ++ ++ /* need to use temporary session, because the goals are piled up and cannot be cancelled yet */ ++ session_path = gs_dnf5_open_session (self, GS_DNF5_RELEASEVER_DEFAULT, &session_manager, cancellable, &local_error); ++ ++ success = session_path != NULL; ++ if (!success) ++ gs_dnf5_convert_error (&local_error); ++ ++ if (success) { ++ rpm_proxy = gs_dnf5_rpm_rpm_proxy_new_sync (self->connection, ++ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, ++ GS_DNF5_INTERFACE_RPM_DNF, ++ session_path, ++ cancellable, ++ &local_error); ++ success = rpm_proxy != NULL; ++ if (!success) { ++ gs_dnf5_convert_error (&local_error); ++ g_prefix_error_literal (&local_error, "Failed to create Rpm proxy: "); ++ } ++ } ++ ++ if (success) { ++ g_autoptr(GVariantBuilder) options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ g_autoptr(GVariant) transaction = NULL; ++ const gchar *package_name = gs_app_get_source_default (app); ++ const gchar *packages[2] = { NULL, NULL }; ++ ++ packages[0] = package_name; ++ ++ success = gs_dnf5_reset_transaction_sync (self, session_path, rpm_proxy, cancellable, &local_error); ++ ++ success = success && ++ gs_dnf5_rpm_rpm_call_install_sync (rpm_proxy, ++ (const gchar * const *) packages, ++ g_variant_builder_end (options_builder), ++ cancellable, ++ &local_error); ++ success = success && ++ gs_dnf5_run_transaction (self, session_path, rpm_proxy, NULL, ++ GS_DNF5_TRANSACTION_FLAG_RESOLVE_ONLY, ++ &transaction, cancellable, &local_error); ++ if (success && transaction != NULL) ++ success = gs_dnf5_foreach_item (self, transaction, gs_dnf5_gather_dependency_sizes_cb, app, cancellable, &local_error); ++ } ++ ++ gs_dnf5_close_session (self, session_manager, session_path); ++ ++ g_mutex_lock (&self->dependency_sizes_data.mutex); ++ ++ if (!success) ++ break; ++ } ++ ++ g_clear_pointer (&self->dependency_sizes_data.apps, g_ptr_array_unref); ++ g_clear_object (&self->dependency_sizes_data.cancellable); ++ g_mutex_unlock (&self->dependency_sizes_data.mutex); ++ ++ if (local_error != NULL) ++ g_debug ("Failed to get app dependency sizes: %s", local_error->message); ++ ++ return NULL; ++} ++ ++static gboolean ++gs_dnf5_get_dependency_sizes_sync (GsPluginDnf5 *self, ++ GHashTable *apps, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ g_autoptr(GMutexLocker) locker = g_mutex_locker_new (&self->session_data.mutex); ++ GHashTableIter iter; ++ gpointer value = NULL; ++ gboolean need_thread = FALSE; ++ ++ g_hash_table_iter_init (&iter, apps); ++ while (g_hash_table_iter_next (&iter, NULL, &value)) { ++ GsApp *app = value; ++ GsAppList *related = gs_app_get_related (app); ++ ++ if (gs_app_has_quirk (app, GS_APP_QUIRK_HIDE_EVERYWHERE) || ++ gs_app_get_state (app) == GS_APP_STATE_AVAILABLE_LOCAL || ++ gs_app_is_installed (app) || ++ gs_app_list_length (related) > 0) ++ continue; ++ ++ /* getting list of the dependencies to be installed can take a long time, thus run it ++ in a new thread, to not block the refine job */ ++ if (self->dependency_sizes_data.apps == NULL) { ++ need_thread = TRUE; ++ self->dependency_sizes_data.apps = g_ptr_array_new_with_free_func (g_object_unref); ++ } ++ ++ if (!g_ptr_array_find (self->dependency_sizes_data.apps, app, NULL)) ++ g_ptr_array_add (self->dependency_sizes_data.apps, g_object_ref (app)); ++ } ++ ++ if (need_thread) { ++ GWeakRef *weakref = g_new0 (GWeakRef, 1); ++ ++ g_assert (self->dependency_sizes_data.cancellable == NULL); ++ self->dependency_sizes_data.cancellable = g_cancellable_new (); ++ ++ g_weak_ref_set (weakref, self); ++ ++ g_thread_unref (g_thread_new ("gs-dnf5-dependency-sizes", gs_dnf5_dependency_sizes_thread, g_steal_pointer (&weakref))); ++ } ++ ++ return TRUE; ++} ++ ++static gboolean ++gs_dnf5_refine_cb (GsPluginDnf5 *self, ++ GVariant *package_array, ++ gpointer user_data, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ GHashTable *apps = user_data; ++ const gchar *name; ++ GsApp *app; ++ g_autoptr(GVariantDict) dict = NULL; ++ g_autoptr(GVariant) value = NULL; ++ ++ dict = g_variant_dict_new (package_array); ++ ++ value = g_variant_dict_lookup_value (dict, "name", G_VARIANT_TYPE_STRING); ++ if (value == NULL) ++ return TRUE; ++ name = g_variant_get_string (value, NULL); ++ if (name == NULL) ++ return TRUE; ++ app = g_hash_table_lookup (apps, name); ++ if (app == NULL) ++ return TRUE; ++ ++ if (gs_app_has_management_plugin (app, NULL) && ++ gs_app_get_bundle_kind (app) == AS_BUNDLE_KIND_PACKAGE && ++ gs_app_get_scope (app) == AS_COMPONENT_SCOPE_SYSTEM) { ++ gs_app_set_management_plugin (app, GS_PLUGIN (self)); ++ gs_plugin_dnf5_set_packaging_format (app); ++ } ++ ++ gs_dnf5_app_set_version (dict, app, gs_app_set_version); ++ gs_dnf5_app_set_size (dict, "install_size", app, gs_app_set_size_installed); ++ gs_dnf5_app_set_size (dict, "download_size", app, gs_app_set_size_download); ++ ++ gs_dnf5_update_app_state (app, GS_APP_STATE_UNKNOWN, dict); ++ ++ return TRUE; ++} ++ ++/* Run in @worker. */ ++static void ++gs_dnf5_refine_thread_cb (GTask *task, ++ gpointer source_object, ++ gpointer task_data, ++ GCancellable *cancellable) ++{ ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (source_object); ++ GsPlugin *plugin = GS_PLUGIN (self); ++ GsPluginRefineData *data = task_data; ++ g_autofree gchar *session_path = NULL; ++ g_autoptr(GHashTable) apps = NULL; ++ g_autoptr(GsDnf5SessionManager) session_manager = NULL; ++ g_autoptr(GsDnf5RpmRpm) rpm_proxy = NULL; ++ g_autoptr(GError) local_error = NULL; ++ gboolean success = TRUE; ++ ++ assert_in_worker (self); ++ ++ apps = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); ++ for (guint i = 0; i < gs_app_list_length (data->list); i++) { ++ GsApp *app = gs_app_list_index (data->list, i); ++ if (!gs_app_has_quirk (app, GS_APP_QUIRK_IS_WILDCARD) && ( ++ gs_app_get_state (app) == GS_APP_STATE_UNKNOWN || ++ ((data->flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_SIZE_DATA) != 0 && ++ gs_app_list_length (gs_app_get_related (app)) == 0))) { ++ if (gs_app_get_source_default (app) != NULL && ++ ((gs_app_has_management_plugin (app, NULL) && ++ gs_app_get_bundle_kind (app) == AS_BUNDLE_KIND_PACKAGE && ++ gs_app_get_scope (app) == AS_COMPONENT_SCOPE_SYSTEM) || ++ gs_app_has_management_plugin (app, plugin))) ++ g_hash_table_insert (apps, g_strdup (gs_app_get_source_default (app)), g_object_ref (app)); ++ } ++ } ++ ++ if (g_hash_table_size (apps) == 0) { ++ g_task_return_boolean (task, TRUE); ++ return; ++ } ++ ++ session_path = gs_dnf5_open_session (self, GS_DNF5_RELEASEVER_DEFAULT, &session_manager, cancellable, &local_error); ++ if (session_path == NULL) { ++ gs_dnf5_convert_error (&local_error); ++ g_task_return_error (task, g_steal_pointer (&local_error)); ++ return; ++ } ++ ++ rpm_proxy = gs_dnf5_rpm_rpm_proxy_new_sync (self->connection, ++ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, ++ GS_DNF5_INTERFACE_RPM_DNF, ++ session_path, ++ cancellable, ++ &local_error); ++ success = rpm_proxy != NULL; ++ if (!success) { ++ gs_dnf5_convert_error (&local_error); ++ g_prefix_error_literal (&local_error, "Failed to create Rpm proxy: "); ++ } ++ ++ if (success) { ++ g_autoptr(GVariantBuilder) attrs_builder = NULL; ++ g_autoptr(GVariantBuilder) options_builder = NULL; ++ g_autoptr(GVariantBuilder) patterns_builder = NULL; ++ g_autoptr(GVariant) result = NULL; ++ GHashTableIter iter; ++ gpointer key = NULL; ++ ++ g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (rpm_proxy), G_MAXINT); ++ ++ patterns_builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); ++ g_hash_table_iter_init (&iter, apps); ++ while (g_hash_table_iter_next (&iter, &key, NULL)) { ++ const gchar *name = key; ++ g_variant_builder_add (patterns_builder, "s", name); ++ } ++ ++ attrs_builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); ++ g_variant_builder_add (attrs_builder, "s", "name"); ++ g_variant_builder_add (attrs_builder, "s", "version"); ++ g_variant_builder_add (attrs_builder, "s", "install_size"); ++ g_variant_builder_add (attrs_builder, "s", "download_size"); ++ g_variant_builder_add (attrs_builder, "s", "is_installed"); ++ ++ options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ g_variant_builder_add (options_builder, "{sv}", "patterns", ++ g_variant_builder_end (patterns_builder)); ++ g_variant_builder_add (options_builder, "{sv}", "package_attrs", ++ g_variant_builder_end (attrs_builder)); ++ g_variant_builder_add (options_builder, "{sv}", "with_nevra", ++ g_variant_new_boolean (TRUE)); ++ g_variant_builder_add (options_builder, "{sv}", "with_provides", ++ g_variant_new_boolean (FALSE)); ++ g_variant_builder_add (options_builder, "{sv}", "with_filenames", ++ g_variant_new_boolean (FALSE)); ++ g_variant_builder_add (options_builder, "{sv}", "with_src", ++ g_variant_new_boolean (FALSE)); ++ g_variant_builder_add (options_builder, "{sv}", "scope", ++ g_variant_new_string ("all")); ++ g_variant_builder_add (options_builder, "{sv}", "latest_limit", ++ g_variant_new_int32 (1)); ++ ++ success = gs_dnf5_rpm_rpm_call_list_sync (rpm_proxy, ++ g_variant_builder_end (options_builder), ++ &result, ++ cancellable, ++ &local_error); ++ ++ if (success) { ++ success = gs_dnf5_foreach_item (self, result, gs_dnf5_refine_cb, apps, cancellable, &local_error); ++ ++ if (success && ++ (data->flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_SIZE_DATA) != 0) { ++ /* do not panic when cannot get dependency sizes for the apps */ ++ if (!gs_dnf5_get_dependency_sizes_sync (self, apps, cancellable, &local_error)) { ++ g_debug ("Failed to get dependency sizes: %s", local_error->message); ++ g_clear_error (&local_error); ++ } ++ } ++ } else { ++ gs_dnf5_convert_error (&local_error); ++ g_prefix_error_literal (&local_error, "Failed to call list: "); ++ } ++ } ++ ++ gs_dnf5_close_session (self, session_manager, session_path); ++ ++ if (success) { ++ g_task_return_boolean (task, TRUE); ++ } else { ++ gs_dnf5_convert_error (&local_error); ++ g_task_return_error (task, g_steal_pointer (&local_error)); ++ } ++} ++ ++static void ++gs_plugin_dnf5_refine_async (GsPlugin *plugin, ++ GsAppList *list, ++ GsPluginRefineFlags flags, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (plugin); ++ gboolean interactive = gs_plugin_has_flags (plugin, GS_PLUGIN_FLAGS_INTERACTIVE); ++ g_autoptr(GTask) task = NULL; ++ ++ task = gs_plugin_refine_data_new_task (plugin, list, flags, ++ cancellable, callback, user_data); ++ g_task_set_source_tag (task, gs_plugin_dnf5_refine_async); ++ ++ gs_worker_thread_queue (self->worker, gs_dnf5_get_priority_for_interactivity (interactive), ++ gs_dnf5_refine_thread_cb, g_steal_pointer (&task)); ++} ++ ++static gboolean ++gs_plugin_dnf5_refine_finish (GsPlugin *plugin, ++ GAsyncResult *result, ++ GError **error) ++{ ++ return g_task_propagate_boolean (G_TASK (result), error); ++} ++ ++/* Run in @worker. */ ++static void ++gs_dnf5_refresh_metadata_thread_cb (GTask *task, ++ gpointer source_object, ++ gpointer task_data, ++ GCancellable *cancellable) ++{ ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (source_object); ++ g_autofree gchar *session_path = NULL; ++ g_autoptr(GsDnf5SessionManager) session_manager = NULL; ++ g_autoptr(GsDnf5Base) base_proxy = NULL; ++ g_autoptr(GError) local_error = NULL; ++ gboolean success = TRUE; ++ ++ assert_in_worker (self); ++ ++ session_path = gs_dnf5_open_session (self, GS_DNF5_RELEASEVER_DEFAULT, &session_manager, cancellable, &local_error); ++ if (session_path == NULL) { ++ gs_dnf5_convert_error (&local_error); ++ g_task_return_error (task, g_steal_pointer (&local_error)); ++ return; ++ } ++ ++ base_proxy = gs_dnf5_base_proxy_new_sync (self->connection, ++ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, ++ GS_DNF5_INTERFACE_RPM_DNF, ++ session_path, ++ cancellable, ++ &local_error); ++ success = base_proxy != NULL; ++ if (!success) { ++ gs_dnf5_convert_error (&local_error); ++ g_prefix_error_literal (&local_error, "Failed to create Base proxy: "); ++ } ++ ++ if (success && GPOINTER_TO_INT (task_data) == 1) { ++ g_autofree gchar *op_error_msg = NULL; ++ gboolean op_success = FALSE; ++ ++ success = gs_dnf5_base_call_clean_sync (base_proxy, ++ "expire-cache", ++ &op_success, ++ &op_error_msg, ++ cancellable, ++ &local_error); ++ if (!success) ++ g_debug ("Failed to call expire-cache: %s", local_error->message); ++ else if (!op_success) ++ g_debug ("Failed to expire-cache: %s", op_error_msg); ++ ++ /* ignore expire-cache error, only log about it */ ++ g_clear_error (&local_error); ++ ++ /* reset the session, to take the expiration into the effect */ ++ success = gs_dnf5_reset_session_sync (self, session_path, cancellable, &local_error); ++ } ++ ++ if (success) { ++ gboolean result = FALSE; ++ ++ g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (base_proxy), G_MAXINT); ++ ++ success = gs_dnf5_base_call_read_all_repos_sync (base_proxy, &result, cancellable, &local_error); ++ ++ /* 'result' is ignored here, due to no error provided */ ++ if (!success) { ++ gs_dnf5_convert_error (&local_error); ++ g_prefix_error_literal (&local_error, "Failed to call read-all-repos: "); ++ } ++ } ++ ++ gs_dnf5_close_session (self, session_manager, session_path); ++ ++ if (success) { ++ g_task_return_boolean (task, TRUE); ++ } else { ++ gs_dnf5_convert_error (&local_error); ++ g_task_return_error (task, g_steal_pointer (&local_error)); ++ } ++} ++ ++static void ++gs_plugin_dnf5_refresh_metadata_async (GsPlugin *plugin, ++ guint64 cache_age_secs, ++ GsPluginRefreshMetadataFlags flags, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (plugin); ++ gboolean interactive = (flags & GS_PLUGIN_REFRESH_METADATA_FLAGS_INTERACTIVE) != 0; ++ g_autoptr(GTask) task = NULL; ++ ++ task = g_task_new (self, cancellable, callback, user_data); ++ g_task_set_source_tag (task, gs_plugin_dnf5_refresh_metadata_async); ++ /* no need to save whole structure, the seconds are not used at all, ++ thus make it only a flag whether to invalidate the cache or not first */ ++ g_task_set_task_data (task, GINT_TO_POINTER (cache_age_secs < 60 ? 1 : 0), NULL); ++ ++ gs_worker_thread_queue (self->worker, gs_dnf5_get_priority_for_interactivity (interactive), ++ gs_dnf5_refresh_metadata_thread_cb, g_steal_pointer (&task)); ++} ++ ++static gboolean ++gs_plugin_dnf5_refresh_metadata_finish (GsPlugin *plugin, ++ GAsyncResult *result, ++ GError **error) ++{ ++ return g_task_propagate_boolean (G_TASK (result), error); ++} ++ ++void ++gs_plugin_adopt_app (GsPlugin *plugin, ++ GsApp *app) ++{ ++ if (gs_app_get_bundle_kind (app) == AS_BUNDLE_KIND_PACKAGE && ++ gs_app_get_scope (app) == AS_COMPONENT_SCOPE_SYSTEM) { ++ gs_app_set_management_plugin (app, plugin); ++ gs_plugin_dnf5_set_packaging_format (app); ++ return; ++ } else if (gs_app_get_kind (app) == AS_COMPONENT_KIND_OPERATING_SYSTEM) { ++ gs_app_set_management_plugin (app, plugin); ++ } ++} ++ ++static gboolean ++gs_dnf5_install_update (GsPlugin *plugin, ++ GsAppList *list, ++ gboolean is_install, ++ gboolean interactive, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (plugin); ++ g_autofree gchar *session_path = NULL; ++ g_autoptr(GPtrArray) packages = NULL; ++ g_autoptr(GsAppList) used_apps = NULL; ++ g_autoptr(GsDnf5SessionManager) session_manager = NULL; ++ g_autoptr(GsDnf5RpmRpm) rpm_proxy = NULL; ++ g_autoptr(GsApp) progress_app = NULL; ++ gboolean success; ++ ++ /* queue for install if installation needs the network */ ++ if (!gs_plugin_get_network_available (plugin)) { ++ if (is_install) { ++ for (guint i = 0; i < gs_app_list_length (list); i++) { ++ GsApp *app = gs_app_list_index (list, i); ++ if (gs_app_has_management_plugin (app, plugin)) { ++ if (gs_app_get_kind (app) == AS_COMPONENT_KIND_REPOSITORY) { ++ g_warn_if_reached (); ++ continue; ++ } ++ ++ gs_app_set_state (app, GS_APP_STATE_QUEUED_FOR_INSTALL); ++ } ++ } ++ } ++ return TRUE; ++ } ++ ++ packages = g_ptr_array_new_with_free_func (g_free); ++ used_apps = gs_app_list_new (); ++ ++ for (guint i = 0; i < gs_app_list_length (list); i++) { ++ GsApp *app = gs_app_list_index (list, i); ++ if (gs_app_has_management_plugin (app, plugin)) { ++ const gchar *source = gs_app_get_source_default (app); ++ if (source != NULL) { ++ GFile *local_file = gs_app_get_local_file (app); ++ if (local_file != NULL) ++ g_ptr_array_add (packages, g_file_get_uri (local_file)); ++ else ++ g_ptr_array_add (packages, g_strdup (source)); ++ gs_app_list_add (used_apps, app); ++ if (progress_app == NULL) ++ progress_app = g_object_ref (app); ++ } ++ } else if (gs_app_has_quirk (app, GS_APP_QUIRK_IS_PROXY)) { ++ GsAppList *related = gs_app_get_related (app); ++ for (guint j = 0; j < gs_app_list_length (related); j++) { ++ GsApp *rel_app = gs_app_list_index (related, j); ++ if (gs_app_has_management_plugin (rel_app, plugin)) { ++ const gchar *source = gs_app_get_source_default (rel_app); ++ if (source != NULL) { ++ GFile *local_file = gs_app_get_local_file (rel_app); ++ if (local_file != NULL) ++ g_ptr_array_add (packages, g_file_get_uri (local_file)); ++ else ++ g_ptr_array_add (packages, g_strdup (source)); ++ gs_app_list_add (used_apps, rel_app); ++ } ++ } ++ } ++ if (progress_app == NULL) ++ progress_app = g_object_ref (app); ++ } ++ } ++ ++ if (packages->len == 0) { ++ g_set_error_literal (error, ++ GS_PLUGIN_ERROR, ++ GS_PLUGIN_ERROR_NOT_SUPPORTED, ++ "installing not available"); ++ return FALSE; ++ } ++ ++ session_path = gs_dnf5_open_session (self, GS_DNF5_RELEASEVER_DEFAULT, &session_manager, cancellable, error); ++ if (session_path == NULL) { ++ gs_dnf5_convert_error (error); ++ return FALSE; ++ } ++ ++ for (guint i = 0; i < gs_app_list_length (used_apps); i++) { ++ GsApp *app = gs_app_list_index (used_apps, i); ++ g_autoptr(GsAppList) addons = NULL; ++ ++ if (gs_app_get_kind (app) == AS_COMPONENT_KIND_REPOSITORY) { ++ g_warn_if_reached (); ++ continue; ++ } ++ ++ if (is_install) { ++ gs_app_set_state (app, GS_APP_STATE_INSTALLING); ++ addons = gs_app_dup_addons (app); ++ } ++ for (guint j = 0; addons != NULL && j < gs_app_list_length (addons); j++) { ++ GsApp *addon = gs_app_list_index (addons, j); ++ if (gs_app_get_to_be_installed (addon)) { ++ const gchar *addon_source = gs_app_get_source_default (app); ++ if (addon_source != NULL) { ++ g_ptr_array_add (packages, g_strdup (addon_source)); ++ if (is_install) ++ gs_app_set_state (addon, GS_APP_STATE_INSTALLING); ++ } ++ } ++ } ++ } ++ ++ rpm_proxy = gs_dnf5_rpm_rpm_proxy_new_sync (self->connection, ++ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, ++ GS_DNF5_INTERFACE_RPM_DNF, ++ session_path, ++ cancellable, ++ error); ++ success = rpm_proxy != NULL; ++ if (success) { ++ g_autoptr(GVariantBuilder) options_builder = NULL; ++ ++ g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (rpm_proxy), G_MAXINT); ++ ++ options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ ++ /* NULL-terminate the array, to be like strv */ ++ g_ptr_array_add (packages, NULL); ++ ++ success = gs_dnf5_reset_transaction_sync (self, session_path, rpm_proxy, cancellable, error); ++ ++ if (success && is_install) { ++ success = gs_dnf5_rpm_rpm_call_install_sync (rpm_proxy, ++ (const gchar * const *) packages->pdata, ++ g_variant_builder_end (options_builder), ++ cancellable, ++ error); ++ } else if (success) { ++ success = gs_dnf5_rpm_rpm_call_upgrade_sync (rpm_proxy, ++ (const gchar * const *) packages->pdata, ++ g_variant_builder_end (options_builder), ++ cancellable, ++ error); ++ } ++ success = success && gs_dnf5_run_transaction (self, session_path, rpm_proxy, progress_app, ++ is_install ? GS_DNF5_TRANSACTION_FLAG_NONE : GS_DNF5_TRANSACTION_FLAG_OFFLINE, ++ NULL, cancellable, error); ++ if (success && !is_install) { ++ /* ensure the update is finished with the 'reboot' action */ ++ g_autoptr(GsDnf5Offline) offline_proxy = NULL; ++ ++ offline_proxy = gs_dnf5_offline_proxy_new_sync (self->connection, ++ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, ++ GS_DNF5_INTERFACE_RPM_DNF, ++ session_path, ++ cancellable, ++ error); ++ success = offline_proxy != NULL; ++ if (success) { ++ g_autofree gchar *op_error_msg = NULL; ++ gboolean op_success = FALSE; ++ ++ success = gs_dnf5_offline_call_set_finish_action_sync (offline_proxy, "reboot", &op_success, &op_error_msg, cancellable, error); ++ if (success && !op_success) { ++ success = FALSE; ++ if (op_error_msg != NULL) { ++ g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, op_error_msg); ++ g_prefix_error_literal (error, "Failed to set finish action: "); ++ } ++ } else if (!success) { ++ gs_dnf5_convert_error (error); ++ g_prefix_error_literal (error, "Failed to set finish action: "); ++ } ++ } else { ++ gs_dnf5_convert_error (error); ++ g_prefix_error_literal (error, "Failed to create Offline proxy: "); ++ } ++ } ++ } else { ++ gs_dnf5_convert_error (error); ++ g_prefix_error_literal (error, "Failed to create Rpm proxy: "); ++ } ++ ++ gs_dnf5_close_session (self, session_manager, session_path); ++ ++ if (success) { ++ gs_dnf5_mark_session_needs_reset (self); ++ } else { ++ gs_dnf5_convert_error (error); ++ ++ if (error != NULL && *error != NULL) ++ gs_dnf5_report_error (self, *error, interactive); ++ } ++ ++ for (guint i = 0; i < gs_app_list_length (used_apps); i++) { ++ GsApp *app = gs_app_list_index (used_apps, i); ++ g_autoptr(GsAppList) addons = NULL; ++ ++ if (gs_app_get_state (app) == GS_APP_STATE_INSTALLING) { ++ if (success) { ++ gs_app_set_state (app, GS_APP_STATE_INSTALLED); ++ gs_app_set_size_download (app, GS_SIZE_TYPE_VALID, 0); ++ } else { ++ gs_app_set_state_recover (app); ++ } ++ } else if (success) { ++ /* apps prepared for offline update are downloaded */ ++ gs_app_set_size_download (app, GS_SIZE_TYPE_VALID, 0); ++ } ++ ++ if (is_install) ++ addons = gs_app_dup_addons (app); ++ for (guint j = 0; addons != NULL && j < gs_app_list_length (addons); j++) { ++ GsApp *addon = gs_app_list_index (addons, j); ++ if (gs_app_get_state (addon) == GS_APP_STATE_INSTALLING) { ++ if (success) { ++ gs_app_set_state (addon, GS_APP_STATE_INSTALLED); ++ gs_app_set_size_download (addon, GS_SIZE_TYPE_VALID, 0); ++ } else { ++ gs_app_set_state_recover (addon); ++ } ++ } else if (success) { ++ /* apps prepared for offline update are downloaded */ ++ gs_app_set_size_download (app, GS_SIZE_TYPE_VALID, 0); ++ } ++ } ++ } ++ ++ return success; ++} ++ ++/* Run in @worker. */ ++static void ++gs_dnf5_install_apps_thread_cb (GTask *task, ++ gpointer source_object, ++ gpointer task_data, ++ GCancellable *cancellable) ++{ ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (source_object); ++ GsPlugin *plugin = GS_PLUGIN (self); ++ GsPluginInstallAppsData *data = task_data; ++ g_autoptr(GError) local_error = NULL; ++ gboolean success; ++ ++ assert_in_worker (self); ++ ++ g_atomic_int_inc (&self->calling_rpm); ++ ++ success = gs_dnf5_install_update (plugin, data->apps, TRUE, ++ (data->flags & GS_PLUGIN_INSTALL_APPS_FLAGS_INTERACTIVE) != 0, ++ cancellable, &local_error); ++ ++ g_atomic_int_dec_and_test (&self->calling_rpm); ++ ++ if (success) ++ g_task_return_boolean (task, TRUE); ++ else ++ g_task_return_error (task, g_steal_pointer (&local_error)); ++} ++ ++static void ++gs_plugin_dnf5_install_apps_async (GsPlugin *plugin, ++ GsAppList *apps, ++ GsPluginInstallAppsFlags flags, ++ GsPluginProgressCallback progress_callback, ++ gpointer progress_user_data, ++ GsPluginAppNeedsUserActionCallback app_needs_user_action_callback, ++ gpointer app_needs_user_action_data, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (plugin); ++ gboolean interactive = (flags & GS_PLUGIN_INSTALL_APPS_FLAGS_INTERACTIVE) != 0; ++ g_autoptr(GTask) task = NULL; ++ ++ task = gs_plugin_install_apps_data_new_task (plugin, apps, flags, progress_callback, progress_user_data, ++ app_needs_user_action_callback, app_needs_user_action_data, ++ cancellable, callback, user_data); ++ g_task_set_source_tag (task, gs_plugin_dnf5_install_apps_async); ++ ++ gs_worker_thread_queue (self->worker, gs_dnf5_get_priority_for_interactivity (interactive), ++ gs_dnf5_install_apps_thread_cb, g_steal_pointer (&task)); ++} ++ ++static gboolean ++gs_plugin_dnf5_install_apps_finish (GsPlugin *plugin, ++ GAsyncResult *result, ++ GError **error) ++{ ++ return g_task_propagate_boolean (G_TASK (result), error); ++} ++ ++/* Run in @worker. */ ++static void ++gs_dnf5_uninstall_apps_thread_cb (GTask *task, ++ gpointer source_object, ++ gpointer task_data, ++ GCancellable *cancellable) ++{ ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (source_object); ++ GsPlugin *plugin = GS_PLUGIN (self); ++ GsPluginUninstallAppsData *data = task_data; ++ g_autofree gchar *session_path = NULL; ++ g_autoptr(GPtrArray) touched_apps = NULL; ++ g_autoptr(GPtrArray) packages = NULL; ++ g_autoptr(GsDnf5SessionManager) session_manager = NULL; ++ g_autoptr(GsDnf5RpmRpm) rpm_proxy = NULL; ++ g_autoptr(GsApp) progress_app = NULL; ++ g_autoptr(GError) local_error = NULL; ++ gboolean success; ++ ++ assert_in_worker (self); ++ ++ touched_apps = g_ptr_array_new_with_free_func (g_object_unref); ++ packages = g_ptr_array_new_with_free_func (g_free); ++ ++ for (guint i = 0; i < gs_app_list_length (data->apps); i++) { ++ g_autoptr(GsAppList) addons = NULL; ++ GsApp *app = gs_app_list_index (data->apps, i); ++ const gchar *source; ++ if (!gs_app_has_management_plugin (app, plugin)) ++ continue; ++ if (gs_app_get_kind (app) == AS_COMPONENT_KIND_REPOSITORY) { ++ g_warn_if_reached (); ++ continue; ++ } ++ source = gs_app_get_source_default (app); ++ if (source == NULL) { ++ g_task_return_new_error (task, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_NOT_SUPPORTED, ++ "remove not available"); ++ return; ++ } ++ g_ptr_array_add (packages, g_strdup (source)); ++ g_ptr_array_add (touched_apps, g_object_ref (app)); ++ gs_app_set_state (app, GS_APP_STATE_REMOVING); ++ ++ if (progress_app == NULL) ++ progress_app = g_object_ref (app); ++ ++ addons = gs_app_dup_addons (app); ++ for (guint j = 0; addons != NULL && j < gs_app_list_length (addons); j++) { ++ GsApp *addon = gs_app_list_index (addons, j); ++ if (gs_app_get_state (addon) == GS_APP_STATE_INSTALLED) { ++ const gchar *addon_source = gs_app_get_source_default (addon); ++ if (addon_source != NULL) { ++ g_ptr_array_add (packages, g_strdup (addon_source)); ++ g_ptr_array_add (touched_apps, g_object_ref (addon)); ++ gs_app_set_state (addon, GS_APP_STATE_REMOVING); ++ } ++ } ++ } ++ } ++ ++ if (packages->len == 0) { ++ g_task_return_boolean (task, TRUE); ++ return; ++ } ++ ++ session_path = gs_dnf5_open_session (self, GS_DNF5_RELEASEVER_DEFAULT, &session_manager, cancellable, &local_error); ++ if (session_path == NULL) { ++ gs_dnf5_convert_error (&local_error); ++ g_task_return_error (task, g_steal_pointer (&local_error)); ++ return; ++ } ++ ++ g_atomic_int_inc (&self->calling_rpm); ++ ++ rpm_proxy = gs_dnf5_rpm_rpm_proxy_new_sync (self->connection, ++ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, ++ GS_DNF5_INTERFACE_RPM_DNF, ++ session_path, ++ cancellable, ++ &local_error); ++ success = rpm_proxy != NULL; ++ if (success) { ++ g_autoptr(GVariantBuilder) options_builder = NULL; ++ ++ g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (rpm_proxy), G_MAXINT); ++ ++ options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ g_variant_builder_add (options_builder, "{sv}", "strict", ++ g_variant_new_boolean (FALSE)); ++ ++ /* NULL-terminate the array, to be like strv */ ++ g_ptr_array_add (packages, NULL); ++ ++ success = gs_dnf5_reset_transaction_sync (self, session_path, rpm_proxy, cancellable, &local_error); ++ ++ success = success && ++ gs_dnf5_rpm_rpm_call_remove_sync (rpm_proxy, ++ (const gchar * const *) packages->pdata, ++ g_variant_builder_end (options_builder), ++ cancellable, ++ &local_error); ++ success = success && gs_dnf5_run_transaction (self, session_path, rpm_proxy, progress_app, GS_DNF5_TRANSACTION_FLAG_NONE, NULL, cancellable, &local_error); ++ } else { ++ gs_dnf5_convert_error (&local_error); ++ g_prefix_error_literal (&local_error, "Failed to create Rpm proxy: "); ++ } ++ ++ gs_dnf5_close_session (self, session_manager, session_path); ++ g_atomic_int_dec_and_test (&self->calling_rpm); ++ ++ if (success) { ++ gs_dnf5_mark_session_needs_reset (self); ++ } else { ++ gs_dnf5_convert_error (&local_error); ++ gs_dnf5_report_error (self, local_error, (data->flags & GS_PLUGIN_UNINSTALL_APPS_FLAGS_INTERACTIVE) != 0); ++ } ++ ++ for (guint i = 0; i < touched_apps->len; i++) { ++ GsApp *app = g_ptr_array_index (touched_apps, i); ++ if (gs_app_get_state (app) == GS_APP_STATE_REMOVING) { ++ if (success) ++ gs_app_set_state (app, GS_APP_STATE_UNKNOWN); ++ else ++ gs_app_set_state_recover (app); ++ } ++ } ++ ++ if (success) ++ g_task_return_boolean (task, TRUE); ++ else ++ g_task_return_error (task, g_steal_pointer (&local_error)); ++} ++ ++static void ++gs_plugin_dnf5_uninstall_apps_async (GsPlugin *plugin, ++ GsAppList *apps, ++ GsPluginUninstallAppsFlags flags, ++ GsPluginProgressCallback progress_callback, ++ gpointer progress_user_data, ++ GsPluginAppNeedsUserActionCallback app_needs_user_action_callback, ++ gpointer app_needs_user_action_data, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (plugin); ++ gboolean interactive = (flags & GS_PLUGIN_UNINSTALL_APPS_FLAGS_INTERACTIVE) != 0; ++ g_autoptr(GTask) task = NULL; ++ ++ task = gs_plugin_uninstall_apps_data_new_task (plugin, apps, flags, progress_callback, progress_user_data, ++ app_needs_user_action_callback, app_needs_user_action_data, ++ cancellable, callback, user_data); ++ g_task_set_source_tag (task, gs_plugin_dnf5_uninstall_apps_async); ++ ++ gs_worker_thread_queue (self->worker, gs_dnf5_get_priority_for_interactivity (interactive), ++ gs_dnf5_uninstall_apps_thread_cb, g_steal_pointer (&task)); ++} ++ ++static gboolean ++gs_plugin_dnf5_uninstall_apps_finish (GsPlugin *plugin, ++ GAsyncResult *result, ++ GError **error) ++{ ++ return g_task_propagate_boolean (G_TASK (result), error); ++} ++ ++/* Run in @worker. */ ++static void ++gs_dnf5_update_apps_thread_cb (GTask *task, ++ gpointer source_object, ++ gpointer task_data, ++ GCancellable *cancellable) ++{ ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (source_object); ++ GsPlugin *plugin = GS_PLUGIN (self); ++ GsPluginUpdateAppsData *data = task_data; ++ g_autoptr(GError) local_error = NULL; ++ gboolean success; ++ ++ assert_in_worker (self); ++ ++ g_atomic_int_inc (&self->calling_rpm); ++ ++ success = gs_dnf5_install_update (plugin, data->apps, FALSE, ++ (data->flags & GS_PLUGIN_UPDATE_APPS_FLAGS_INTERACTIVE) != 0, ++ cancellable, &local_error); ++ ++ g_atomic_int_dec_and_test (&self->calling_rpm); ++ ++ if (success) ++ g_task_return_boolean (task, TRUE); ++ else ++ g_task_return_error (task, g_steal_pointer (&local_error)); ++} ++ ++static void ++gs_plugin_dnf5_update_apps_async (GsPlugin *plugin, ++ GsAppList *apps, ++ GsPluginUpdateAppsFlags flags, ++ GsPluginProgressCallback progress_callback, ++ gpointer progress_user_data, ++ GsPluginAppNeedsUserActionCallback app_needs_user_action_callback, ++ gpointer app_needs_user_action_data, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (plugin); ++ gboolean interactive = (flags & GS_PLUGIN_UPDATE_APPS_FLAGS_INTERACTIVE) != 0; ++ g_autoptr(GTask) task = NULL; ++ ++ task = gs_plugin_update_apps_data_new_task (plugin, apps, flags, progress_callback, progress_user_data, ++ app_needs_user_action_callback, app_needs_user_action_data, ++ cancellable, callback, user_data); ++ g_task_set_source_tag (task, gs_plugin_dnf5_update_apps_async); ++ ++ gs_worker_thread_queue (self->worker, gs_dnf5_get_priority_for_interactivity (interactive), ++ gs_dnf5_update_apps_thread_cb, g_steal_pointer (&task)); ++} ++ ++static gboolean ++gs_plugin_dnf5_update_apps_finish (GsPlugin *plugin, ++ GAsyncResult *result, ++ GError **error) ++{ ++ return g_task_propagate_boolean (G_TASK (result), error); ++} ++ ++static gboolean ++gs_dnf5_manage_repository_sync (GsPluginDnf5 *self, ++ GsApp *repository, ++ gboolean enable, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ g_autofree gchar *session_path = NULL; ++ g_autoptr(GsDnf5SessionManager) session_manager = NULL; ++ g_autoptr(GsDnf5RpmRepo) repo_proxy = NULL; ++ gboolean success; ++ ++ if (!gs_app_has_management_plugin (repository, GS_PLUGIN (self))) ++ return TRUE; ++ ++ if (gs_app_get_kind (repository) != AS_COMPONENT_KIND_REPOSITORY) { ++ g_set_error (error, ++ GS_PLUGIN_ERROR, ++ GS_PLUGIN_ERROR_NOT_SUPPORTED, ++ "wrong app kind (%s) passed to manage_repository", ++ as_component_kind_to_string (gs_app_get_kind (repository))); ++ return FALSE; ++ } ++ ++ session_path = gs_dnf5_open_session (self, GS_DNF5_RELEASEVER_DEFAULT, &session_manager, cancellable, error); ++ if (session_path == NULL) { ++ gs_dnf5_convert_error (error); ++ return FALSE; ++ } ++ ++ repo_proxy = gs_dnf5_rpm_repo_proxy_new_sync (self->connection, ++ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, ++ GS_DNF5_INTERFACE_RPM_DNF, ++ session_path, ++ cancellable, ++ error); ++ success = repo_proxy != NULL; ++ if (!success) { ++ gs_dnf5_convert_error (error); ++ g_prefix_error_literal (error, "Failed to create Rpm proxy: "); ++ } ++ ++ if (success) { ++ const gchar *ids[2] = { NULL, NULL }; ++ ++ g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (repo_proxy), G_MAXINT); ++ ++ ids[0] = gs_app_get_id (repository); ++ ++ if (enable) ++ success = gs_dnf5_rpm_repo_call_enable_sync (repo_proxy, ids, cancellable, error); ++ else ++ success = gs_dnf5_rpm_repo_call_disable_sync (repo_proxy, ids, cancellable, error); ++ ++ if (success) { ++ if (enable) ++ gs_app_set_state (repository, GS_APP_STATE_INSTALLED); ++ else ++ gs_app_set_state (repository, GS_APP_STATE_AVAILABLE); ++ } else { ++ gs_dnf5_convert_error (error); ++ g_prefix_error (error, "Failed to call %s: ", enable ? "enable" : "disable"); ++ } ++ } ++ ++ gs_dnf5_close_session (self, session_manager, session_path); ++ ++ return success; ++} ++ ++/* Run in @worker. */ ++static void ++gs_dnf5_enable_repository_thread_cb (GTask *task, ++ gpointer source_object, ++ gpointer task_data, ++ GCancellable *cancellable) ++{ ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (source_object); ++ GsPluginManageRepositoryData *data = task_data; ++ g_autoptr(GError) local_error = NULL; ++ ++ assert_in_worker (self); ++ ++ if (gs_dnf5_manage_repository_sync (self, data->repository, TRUE, cancellable, &local_error)) { ++ g_task_return_boolean (task, TRUE); ++ } else { ++ gs_dnf5_convert_error (&local_error); ++ g_task_return_error (task, g_steal_pointer (&local_error)); ++ } ++} ++ ++static void ++gs_plugin_dnf5_enable_repository_async (GsPlugin *plugin, ++ GsApp *repository, ++ GsPluginManageRepositoryFlags flags, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (plugin); ++ gboolean interactive = (flags & GS_PLUGIN_MANAGE_REPOSITORY_FLAGS_INTERACTIVE) != 0; ++ g_autoptr(GTask) task = NULL; ++ ++ task = gs_plugin_manage_repository_data_new_task (plugin, repository, flags, ++ cancellable, callback, user_data); ++ g_task_set_source_tag (task, gs_plugin_dnf5_enable_repository_async); ++ ++ gs_worker_thread_queue (self->worker, gs_dnf5_get_priority_for_interactivity (interactive), ++ gs_dnf5_enable_repository_thread_cb, g_steal_pointer (&task)); ++} ++ ++static gboolean ++gs_plugin_dnf5_enable_repository_finish (GsPlugin *plugin, ++ GAsyncResult *result, ++ GError **error) ++{ ++ return g_task_propagate_boolean (G_TASK (result), error); ++} ++ ++/* Run in @worker. */ ++static void ++gs_dnf5_disable_repository_thread_cb (GTask *task, ++ gpointer source_object, ++ gpointer task_data, ++ GCancellable *cancellable) ++{ ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (source_object); ++ GsPluginManageRepositoryData *data = task_data; ++ g_autoptr(GError) local_error = NULL; ++ ++ assert_in_worker (self); ++ ++ if (gs_dnf5_manage_repository_sync (self, data->repository, FALSE, cancellable, &local_error)) { ++ g_task_return_boolean (task, TRUE); ++ } else { ++ gs_dnf5_convert_error (&local_error); ++ g_task_return_error (task, g_steal_pointer (&local_error)); ++ } ++} ++ ++static void ++gs_plugin_dnf5_disable_repository_async (GsPlugin *plugin, ++ GsApp *repository, ++ GsPluginManageRepositoryFlags flags, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (plugin); ++ gboolean interactive = (flags & GS_PLUGIN_MANAGE_REPOSITORY_FLAGS_INTERACTIVE) != 0; ++ g_autoptr(GTask) task = NULL; ++ ++ task = gs_plugin_manage_repository_data_new_task (plugin, repository, flags, ++ cancellable, callback, user_data); ++ g_task_set_source_tag (task, gs_plugin_dnf5_disable_repository_async); ++ ++ gs_worker_thread_queue (self->worker, gs_dnf5_get_priority_for_interactivity (interactive), ++ gs_dnf5_disable_repository_thread_cb, g_steal_pointer (&task)); ++} ++ ++static gboolean ++gs_plugin_dnf5_disable_repository_finish (GsPlugin *plugin, ++ GAsyncResult *result, ++ GError **error) ++{ ++ return g_task_propagate_boolean (G_TASK (result), error); ++} ++ ++static gboolean ++gs_dnf5_pick_rpm_desktop_file_cb (GsPlugin *plugin, ++ GsApp *app, ++ const gchar *filename, ++ GKeyFile *key_file, ++ gpointer user_data) ++{ ++ return strstr (filename, "/snapd/") == NULL && ++ strstr (filename, "/snap/") == NULL && ++ strstr (filename, "/flatpak/") == NULL && ++ g_key_file_has_group (key_file, "Desktop Entry") && ++ !g_key_file_has_key (key_file, "Desktop Entry", "X-Flatpak", NULL) && ++ !g_key_file_has_key (key_file, "Desktop Entry", "X-SnapInstanceName", NULL); ++} ++ ++static void ++gs_plugin_dnf5_launch_async (GsPlugin *plugin, ++ GsApp *app, ++ GsPluginLaunchFlags flags, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ gs_plugin_app_launch_filtered_async (plugin, app, flags, ++ gs_dnf5_pick_rpm_desktop_file_cb, NULL, ++ cancellable, ++ callback, user_data); ++} ++ ++static gboolean ++gs_plugin_dnf5_launch_finish (GsPlugin *plugin, ++ GAsyncResult *result, ++ GError **error) ++{ ++ return gs_plugin_app_launch_filtered_finish (plugin, result, error); ++} ++ ++static gboolean ++gs_dnf5_file_to_app_sync (GsPluginDnf5 *self, ++ GsAppList *list, ++ GFile *file, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ g_autofree gchar *content_type = NULL; ++ g_autofree gchar *session_path = NULL; ++ g_autoptr(GsDnf5SessionManager) session_manager = NULL; ++ g_autoptr(GsDnf5RpmRpm) rpm_proxy = NULL; ++ gboolean success = TRUE; ++ const gchar *mimetypes[] = { ++ "application/x-app-package", ++ "application/x-deb", ++ "application/vnd.debian.binary-package", ++ "application/x-redhat-package-manager", ++ "application/x-rpm", ++ NULL }; ++ ++ /* does this match any of the mimetypes we support */ ++ content_type = gs_utils_get_content_type (file, cancellable, error); ++ if (content_type == NULL) ++ return FALSE; ++ if (!g_strv_contains (mimetypes, content_type)) ++ return TRUE; ++ ++ session_path = gs_dnf5_open_session (self, GS_DNF5_RELEASEVER_DEFAULT, &session_manager, cancellable, error); ++ if (session_path == NULL) { ++ gs_dnf5_convert_error (error); ++ return FALSE; ++ } ++ ++ rpm_proxy = gs_dnf5_rpm_rpm_proxy_new_sync (self->connection, ++ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, ++ GS_DNF5_INTERFACE_RPM_DNF, ++ session_path, ++ cancellable, ++ error); ++ success = rpm_proxy != NULL; ++ if (!success) { ++ gs_dnf5_convert_error (error); ++ g_prefix_error_literal (error, "Failed to create Rpm proxy: "); ++ } ++ ++ if (success) { ++ g_autoptr(GVariantBuilder) options_builder = NULL; ++ g_autoptr(GVariantBuilder) patterns_builder = NULL; ++ g_autoptr(GVariant) result = NULL; ++ g_autofree gchar *file_uri = NULL; ++ ++ file_uri = g_file_get_path (file); ++ ++ g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (rpm_proxy), G_MAXINT); ++ ++ patterns_builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); ++ g_variant_builder_add (patterns_builder, "s", file_uri); ++ ++ options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ g_variant_builder_add (options_builder, "{sv}", "patterns", ++ g_variant_builder_end (patterns_builder)); ++ g_variant_builder_add (options_builder, "{sv}", "package_attrs", ++ gs_dnf5_dup_package_attrs ()); ++ g_variant_builder_add (options_builder, "{sv}", "with_provides", ++ g_variant_new_boolean (FALSE)); ++ g_variant_builder_add (options_builder, "{sv}", "with_filenames", ++ g_variant_new_boolean (FALSE)); ++ g_variant_builder_add (options_builder, "{sv}", "with_src", ++ g_variant_new_boolean (FALSE)); ++ g_variant_builder_add (options_builder, "{sv}", "scope", ++ g_variant_new_string ("all")); ++ ++ success = gs_dnf5_rpm_rpm_call_list_sync (rpm_proxy, ++ g_variant_builder_end (options_builder), ++ &result, ++ cancellable, ++ error); ++ ++ if (success) { ++ g_autofree gchar *basename = g_file_get_basename (file); ++ ReadPackageData rpd = { 0, }; ++ rpd.list = list; ++ rpd.set_state = GS_APP_STATE_AVAILABLE_LOCAL; ++ rpd.nevra_to_app = NULL; ++ success = gs_dnf5_foreach_item (self, result, gs_dnf5_read_package_cb, &rpd, cancellable, error); ++ ++ if (success) { ++ for (guint i = 0; i < gs_app_list_length (list); i++) { ++ GsApp *app = gs_app_list_index (list, i); ++ /* it's already downloaded, because it's a local file */ ++ gs_app_set_size_download (app, GS_SIZE_TYPE_VALID, 0); ++ gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE); ++ gs_app_set_local_file (app, file); ++ gs_app_set_metadata (app, "GnomeSoftware::packagename-value", basename); ++ } ++ } ++ } else { ++ gs_dnf5_convert_error (error); ++ g_prefix_error_literal (error, "Failed to call list: "); ++ } ++ } ++ ++ gs_dnf5_close_session (self, session_manager, session_path); ++ ++ return success; ++} ++ ++static void ++gs_dnf5_file_to_app_thread_cb (GTask *task, ++ gpointer source_object, ++ gpointer task_data, ++ GCancellable *cancellable) ++{ ++ g_autoptr(GsAppList) list = gs_app_list_new (); ++ g_autoptr(GError) local_error = NULL; ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (source_object); ++ GsPluginFileToAppData *data = task_data; ++ ++ if (gs_dnf5_file_to_app_sync (self, list, data->file, cancellable, &local_error)) { ++ g_task_return_pointer (task, g_steal_pointer (&list), g_object_unref); ++ } else if (local_error != NULL) { ++ g_task_return_error (task, g_steal_pointer (&local_error)); ++ } else { ++ g_task_return_pointer (task, g_steal_pointer (&list), g_object_unref); ++ } ++} ++ ++static void ++gs_plugin_dnf5_file_to_app_async (GsPlugin *plugin, ++ GFile *file, ++ GsPluginFileToAppFlags flags, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ g_autoptr(GTask) task = NULL; ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (plugin); ++ gboolean interactive = (flags & GS_PLUGIN_FILE_TO_APP_FLAGS_INTERACTIVE) != 0; ++ ++ task = gs_plugin_file_to_app_data_new_task (plugin, file, flags, cancellable, callback, user_data); ++ g_task_set_source_tag (task, gs_plugin_dnf5_file_to_app_async); ++ ++ /* Queue a job to get the apps. */ ++ gs_worker_thread_queue (self->worker, gs_dnf5_get_priority_for_interactivity (interactive), ++ gs_dnf5_file_to_app_thread_cb, g_steal_pointer (&task)); ++} ++ ++static GsAppList * ++gs_plugin_dnf5_file_to_app_finish (GsPlugin *plugin, ++ GAsyncResult *result, ++ GError **error) ++{ ++ return g_task_propagate_pointer (G_TASK (result), error); ++} ++ ++static gboolean ++gs_dnf5_system_upgrade_sync (GsPluginDnf5 *self, ++ const gchar *releasever, ++ GsApp *progress_app, ++ gboolean download_only, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ g_autofree gchar *session_path = NULL; ++ g_autoptr(GsAppList) list = NULL; ++ g_autoptr(GsDnf5SessionManager) session_manager = NULL; ++ g_autoptr(GsDnf5Offline) offline_proxy = NULL; ++ g_autoptr(GsDnf5RpmRpm) rpm_proxy = NULL; ++ gboolean success; ++ ++ session_path = gs_dnf5_open_session (self, releasever, &session_manager, cancellable, error); ++ if (session_path == NULL) { ++ gs_dnf5_convert_error (error); ++ return FALSE; ++ } ++ ++ rpm_proxy = gs_dnf5_rpm_rpm_proxy_new_sync (self->connection, ++ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, ++ GS_DNF5_INTERFACE_RPM_DNF, ++ session_path, ++ cancellable, ++ error); ++ success = rpm_proxy != NULL; ++ if (!success) { ++ gs_dnf5_convert_error (error); ++ g_prefix_error_literal (error, "Failed to create Rpm proxy: "); ++ } ++ ++ if (success) { ++ offline_proxy = gs_dnf5_offline_proxy_new_sync (self->connection, ++ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, ++ GS_DNF5_INTERFACE_RPM_DNF, ++ session_path, ++ cancellable, ++ error); ++ success = offline_proxy != NULL; ++ if (!success) { ++ gs_dnf5_convert_error (error); ++ g_prefix_error_literal (error, "Failed to create Offline proxy: "); ++ } ++ } ++ ++ if (success) { ++ gboolean pending = FALSE; ++ g_autoptr(GVariant) transaction_status = NULL; ++ ++ if (gs_dnf5_offline_call_get_status_sync (offline_proxy, &pending, &transaction_status, cancellable, error) && ++ pending && transaction_status != NULL) { ++ const gchar *target_releasever = NULL; ++ gboolean found = g_variant_lookup (transaction_status, "target_releasever", "&s", &target_releasever); ++ if (found && g_strcmp0 (target_releasever, releasever) == 0) { ++ g_debug ("There is prepared an upgrade for version '%s' already, skipping preparation", releasever); ++ gs_dnf5_close_session (self, session_manager, session_path); ++ return TRUE; ++ } else if (found && target_releasever != NULL) { ++ g_debug ("There is prepared an update for version '%s', but needs version '%s', redo preparation", target_releasever, releasever); ++ } ++ } ++ } ++ ++ if (success) { ++ g_autoptr(GVariantBuilder) options_builder = NULL; ++ g_autoptr(GVariant) result = NULL; ++ ++ g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (rpm_proxy), G_MAXINT); ++ ++ options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ ++ success = gs_dnf5_reset_transaction_sync (self, session_path, rpm_proxy, cancellable, error); ++ ++ success = success && ++ gs_dnf5_rpm_rpm_call_system_upgrade_sync (rpm_proxy, ++ g_variant_builder_end (options_builder), ++ cancellable, ++ error); ++ ++ if (success) { ++ success = gs_dnf5_run_transaction (self, session_path, rpm_proxy, progress_app, GS_DNF5_TRANSACTION_FLAG_OFFLINE, NULL, cancellable, error); ++ ++ if (success && !download_only) { ++ g_autofree gchar *op_error_msg = NULL; ++ gboolean op_success = FALSE; ++ ++ /* ensure the upgrade is finished with the 'reboot' action */ ++ success = gs_dnf5_offline_call_set_finish_action_sync (offline_proxy, "reboot", &op_success, &op_error_msg, cancellable, error); ++ if (success && !op_success) { ++ success = FALSE; ++ if (op_error_msg != NULL) { ++ g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, op_error_msg); ++ g_prefix_error_literal (error, "Failed to set finish action: "); ++ } ++ } else if (!success) { ++ gs_dnf5_convert_error (error); ++ g_prefix_error_literal (error, "Failed to set finish action: "); ++ } ++ } ++ } else { ++ gs_dnf5_convert_error (error); ++ g_prefix_error_literal (error, "Failed to call system_upgrade: "); ++ } ++ } ++ ++ gs_dnf5_close_session (self, session_manager, session_path); ++ ++ return success; ++} ++ ++/* Run in @worker. */ ++static void ++gs_dnf5_download_upgrade_thread_cb (GTask *task, ++ gpointer source_object, ++ gpointer task_data, ++ GCancellable *cancellable) ++{ ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (source_object); ++ GsPluginDownloadUpgradeData *data = task_data; ++ g_autoptr(GError) local_error = NULL; ++ ++ assert_in_worker (self); ++ ++ gs_app_set_state (data->app, GS_APP_STATE_DOWNLOADING); ++ ++ if (gs_dnf5_system_upgrade_sync (self, gs_app_get_version (data->app), data->app, TRUE, cancellable, &local_error)) { ++ gs_app_set_state (data->app, GS_APP_STATE_UPDATABLE); ++ g_task_return_boolean (task, TRUE); ++ } else { ++ gs_app_set_state (data->app, GS_APP_STATE_AVAILABLE); ++ gs_dnf5_convert_error (&local_error); ++ gs_dnf5_report_error (self, local_error, (data->flags & GS_PLUGIN_DOWNLOAD_UPGRADE_FLAGS_INTERACTIVE) != 0); ++ g_task_return_error (task, g_steal_pointer (&local_error)); ++ } ++} ++ ++static void ++gs_plugin_dnf5_download_upgrade_async (GsPlugin *plugin, ++ GsApp *app, ++ GsPluginDownloadUpgradeFlags flags, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (plugin); ++ g_autoptr(GTask) task = NULL; ++ gboolean interactive = (flags & GS_PLUGIN_DOWNLOAD_UPGRADE_FLAGS_INTERACTIVE) != 0; ++ ++ task = gs_plugin_download_upgrade_data_new_task (plugin, app, flags, cancellable, callback, user_data); ++ g_task_set_source_tag (task, gs_plugin_dnf5_download_upgrade_async); ++ ++ /* only process this app if was created by this plugin */ ++ if (!gs_app_has_management_plugin (app, plugin)) { ++ g_task_return_boolean (task, TRUE); ++ return; ++ } ++ ++ /* check is distro-upgrade */ ++ if (gs_app_get_kind (app) != AS_COMPONENT_KIND_OPERATING_SYSTEM) { ++ g_task_return_boolean (task, TRUE); ++ return; ++ } ++ ++ gs_worker_thread_queue (self->worker, gs_dnf5_get_priority_for_interactivity (interactive), ++ gs_dnf5_download_upgrade_thread_cb, g_steal_pointer (&task)); ++} ++ ++static gboolean ++gs_plugin_dnf5_download_upgrade_finish (GsPlugin *plugin, ++ GAsyncResult *result, ++ GError **error) ++{ ++ return g_task_propagate_boolean (G_TASK (result), error); ++} ++ ++/* Run in @worker. */ ++static void ++gs_dnf5_trigger_upgrade_thread_cb (GTask *task, ++ gpointer source_object, ++ gpointer task_data, ++ GCancellable *cancellable) ++{ ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (source_object); ++ GsPluginTriggerUpgradeData *data = task_data; ++ g_autoptr(GError) local_error = NULL; ++ ++ assert_in_worker (self); ++ ++ gs_app_set_state (data->app, GS_APP_STATE_PENDING_INSTALL); ++ ++ if (gs_dnf5_system_upgrade_sync (self, gs_app_get_version (data->app), data->app, FALSE, cancellable, &local_error)) { ++ gs_app_set_state (data->app, GS_APP_STATE_UPDATABLE); ++ g_task_return_boolean (task, TRUE); ++ } else { ++ gs_app_set_state (data->app, GS_APP_STATE_AVAILABLE); ++ gs_dnf5_convert_error (&local_error); ++ gs_dnf5_report_error (self, local_error, (data->flags & GS_PLUGIN_TRIGGER_UPGRADE_FLAGS_INTERACTIVE) != 0); ++ g_task_return_error (task, g_steal_pointer (&local_error)); ++ } ++} ++ ++static void ++gs_plugin_dnf5_trigger_upgrade_async (GsPlugin *plugin, ++ GsApp *app, ++ GsPluginTriggerUpgradeFlags flags, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (plugin); ++ g_autoptr(GTask) task = NULL; ++ gboolean interactive = (flags & GS_PLUGIN_TRIGGER_UPGRADE_FLAGS_INTERACTIVE) != 0; ++ ++ task = gs_plugin_trigger_upgrade_data_new_task (plugin, app, flags, cancellable, callback, user_data); ++ g_task_set_source_tag (task, gs_plugin_dnf5_trigger_upgrade_async); ++ ++ /* only process this app if was created by this plugin */ ++ if (!gs_app_has_management_plugin (app, plugin)) { ++ g_task_return_boolean (task, TRUE); ++ return; ++ } ++ ++ /* check is distro-upgrade */ ++ if (gs_app_get_kind (app) != AS_COMPONENT_KIND_OPERATING_SYSTEM) { ++ g_task_return_boolean (task, TRUE); ++ return; ++ } ++ ++ gs_app_set_state (app, GS_APP_STATE_PENDING_INSTALL); ++ ++ gs_worker_thread_queue (self->worker, gs_dnf5_get_priority_for_interactivity (interactive), ++ gs_dnf5_trigger_upgrade_thread_cb, g_steal_pointer (&task)); ++} ++ ++static gboolean ++gs_plugin_dnf5_trigger_upgrade_finish (GsPlugin *plugin, ++ GAsyncResult *result, ++ GError **error) ++{ ++ return g_task_propagate_boolean (G_TASK (result), error); ++} ++ ++static void ++gs_plugin_dnf5_dispose (GObject *object) ++{ ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (object); ++ ++ if (self->rpm_transaction_watch_id != 0) { ++ g_bus_unwatch_name (self->rpm_transaction_watch_id); ++ self->rpm_transaction_watch_id = 0; ++ } ++ ++ g_clear_object (&self->worker); ++ g_clear_object (&self->connection); ++ g_clear_object (&self->rpm_transaction_proxy); ++ ++ g_mutex_lock (&self->session_data.mutex); ++ if (self->session_data.autoclose_timer) { ++ g_source_remove (self->session_data.autoclose_timer); ++ self->session_data.autoclose_timer = 0; ++ } ++ ++ if (self->session_data.proxy != NULL) { ++ gs_dnf5_close_session_real (self->session_data.proxy, self->session_data.object_path); ++ ++ g_clear_object (&self->session_data.proxy); ++ g_clear_pointer (&self->session_data.object_path, g_free); ++ } ++ g_mutex_unlock (&self->session_data.mutex); ++ ++ g_mutex_lock (&self->dependency_sizes_data.mutex); ++ g_clear_pointer (&self->dependency_sizes_data.apps, g_ptr_array_unref); ++ g_clear_object (&self->dependency_sizes_data.cancellable); ++ g_mutex_unlock (&self->dependency_sizes_data.mutex); ++ ++ G_OBJECT_CLASS (gs_plugin_dnf5_parent_class)->dispose (object); ++} ++ ++static void ++gs_plugin_dnf5_finalize (GObject *object) ++{ ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (object); ++ ++ g_mutex_clear (&self->session_data.mutex); ++ g_cond_clear (&self->session_data.cond); ++ g_mutex_clear (&self->dependency_sizes_data.mutex); ++ ++ G_OBJECT_CLASS (gs_plugin_dnf5_parent_class)->finalize (object); ++} ++ ++static void ++gs_plugin_dnf5_class_init (GsPluginDnf5Class *klass) ++{ ++ GObjectClass *object_class = G_OBJECT_CLASS (klass); ++ GsPluginClass *plugin_class = GS_PLUGIN_CLASS (klass); ++ ++ object_class->dispose = gs_plugin_dnf5_dispose; ++ object_class->finalize = gs_plugin_dnf5_finalize; ++ ++ plugin_class->setup_async = gs_plugin_dnf5_setup_async; ++ plugin_class->setup_finish = gs_plugin_dnf5_setup_finish; ++ plugin_class->shutdown_async = gs_plugin_dnf5_shutdown_async; ++ plugin_class->shutdown_finish = gs_plugin_dnf5_shutdown_finish; ++ plugin_class->list_apps_async = gs_plugin_dnf5_list_apps_async; ++ plugin_class->list_apps_finish = gs_plugin_dnf5_list_apps_finish; ++ plugin_class->refine_async = gs_plugin_dnf5_refine_async; ++ plugin_class->refine_finish = gs_plugin_dnf5_refine_finish; ++ plugin_class->refresh_metadata_async = gs_plugin_dnf5_refresh_metadata_async; ++ plugin_class->refresh_metadata_finish = gs_plugin_dnf5_refresh_metadata_finish; ++ plugin_class->update_apps_async = gs_plugin_dnf5_update_apps_async; ++ plugin_class->update_apps_finish = gs_plugin_dnf5_update_apps_finish; ++ plugin_class->enable_repository_async = gs_plugin_dnf5_enable_repository_async; ++ plugin_class->enable_repository_finish = gs_plugin_dnf5_enable_repository_finish; ++ plugin_class->disable_repository_async = gs_plugin_dnf5_disable_repository_async; ++ plugin_class->disable_repository_finish = gs_plugin_dnf5_disable_repository_finish; ++ plugin_class->install_apps_async = gs_plugin_dnf5_install_apps_async; ++ plugin_class->install_apps_finish = gs_plugin_dnf5_install_apps_finish; ++ plugin_class->uninstall_apps_async = gs_plugin_dnf5_uninstall_apps_async; ++ plugin_class->uninstall_apps_finish = gs_plugin_dnf5_uninstall_apps_finish; ++ plugin_class->launch_async = gs_plugin_dnf5_launch_async; ++ plugin_class->launch_finish = gs_plugin_dnf5_launch_finish; ++ plugin_class->file_to_app_async = gs_plugin_dnf5_file_to_app_async; ++ plugin_class->file_to_app_finish = gs_plugin_dnf5_file_to_app_finish; ++ plugin_class->download_upgrade_async = gs_plugin_dnf5_download_upgrade_async; ++ plugin_class->download_upgrade_finish = gs_plugin_dnf5_download_upgrade_finish; ++ plugin_class->trigger_upgrade_async = gs_plugin_dnf5_trigger_upgrade_async; ++ plugin_class->trigger_upgrade_finish = gs_plugin_dnf5_trigger_upgrade_finish; ++} ++ ++static void ++gs_plugin_dnf5_init (GsPluginDnf5 *self) ++{ ++ GsPlugin *plugin = GS_PLUGIN (self); ++ ++ g_mutex_init (&self->session_data.mutex); ++ g_cond_init (&self->session_data.cond); ++ g_mutex_init (&self->dependency_sizes_data.mutex); ++ ++ /* getting app properties from appstream is quicker */ ++ gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_RUN_AFTER, "appstream"); ++ ++ /* like appstream, we need the icon plugin to load cached icons into pixbufs */ ++ gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_RUN_BEFORE, "icons"); ++ ++ /* prioritize over packagekit */ ++ gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_CONFLICTS, "packagekit"); ++ ++ /* set name of MetaInfo file */ ++ gs_plugin_set_appstream_id (plugin, "org.gnome.Software.Plugin.Dnf5"); ++} ++ ++GType ++gs_plugin_query_type (void) ++{ ++ return GS_TYPE_PLUGIN_DNF5; ++} +diff --git a/plugins/dnf5/gs-plugin-dnf5.h b/plugins/dnf5/gs-plugin-dnf5.h +new file mode 100644 +index 000000000..319d5843c +--- /dev/null ++++ b/plugins/dnf5/gs-plugin-dnf5.h +@@ -0,0 +1,20 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- ++ * vi:set noexpandtab tabstop=8 shiftwidth=8: ++ * ++ * Copyright (C) 2024 Red Hat ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#pragma once ++ ++#include ++#include ++ ++G_BEGIN_DECLS ++ ++#define GS_TYPE_PLUGIN_DNF5 (gs_plugin_dnf5_get_type ()) ++ ++G_DECLARE_FINAL_TYPE (GsPluginDnf5, gs_plugin_dnf5, GS, PLUGIN_DNF5, GsPlugin) ++ ++G_END_DECLS +diff --git a/plugins/dnf5/meson.build b/plugins/dnf5/meson.build +new file mode 100644 +index 000000000..6059a9da1 +--- /dev/null ++++ b/plugins/dnf5/meson.build +@@ -0,0 +1,39 @@ ++cargs = ['-DG_LOG_DOMAIN="GsDnf5"'] ++ ++dnf5_generated = gnome.gdbus_codegen( ++ 'gs-dnf5-generated', ++ sources: [ 'org.rpm.dnf.v0.Advisory.xml', ++ 'org.rpm.dnf.v0.Base.xml', ++ 'org.rpm.dnf.v0.Goal.xml', ++ 'org.rpm.dnf.v0.Offline.xml', ++ 'org.rpm.dnf.v0.rpm.Repo.xml', ++ 'org.rpm.dnf.v0.rpm.Rpm.xml', ++ 'org.rpm.dnf.v0.SessionManager.xml' ++ ], ++ interface_prefix : 'org.rpm.dnf.v0', ++ namespace : 'GsDnf5' ++) ++ ++dnf5_generated += gnome.gdbus_codegen( ++ 'gs-dnf5-rpm-generated', ++ sources: [ 'org.rpm.Transaction.xml' ], ++ interface_prefix : 'org.rpm', ++ namespace : 'GsDnf5Rpm' ++) ++ ++shared_module( ++ 'gs_plugin_dnf5', ++ dnf5_generated, ++ sources : [ ++ 'gs-dnf5-progress-helper.c', ++ 'gs-plugin-dnf5.c' ++ ], ++ include_directories : [ ++ include_directories('../..'), ++ include_directories('../../lib'), ++ ], ++ install : true, ++ install_dir: plugin_dir, ++ c_args : cargs, ++ dependencies : [ plugin_libs ], ++) +diff --git a/plugins/dnf5/org.rpm.Transaction.xml b/plugins/dnf5/org.rpm.Transaction.xml +new file mode 100644 +index 000000000..7d0cbab48 +--- /dev/null ++++ b/plugins/dnf5/org.rpm.Transaction.xml +@@ -0,0 +1,26 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/plugins/dnf5/org.rpm.dnf.v0.Advisory.xml b/plugins/dnf5/org.rpm.dnf.v0.Advisory.xml +new file mode 100644 +index 000000000..6aecee9fa +--- /dev/null ++++ b/plugins/dnf5/org.rpm.dnf.v0.Advisory.xml +@@ -0,0 +1,74 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/plugins/dnf5/org.rpm.dnf.v0.Base.xml b/plugins/dnf5/org.rpm.dnf.v0.Base.xml +new file mode 100644 +index 000000000..dfdc1745a +--- /dev/null ++++ b/plugins/dnf5/org.rpm.dnf.v0.Base.xml +@@ -0,0 +1,153 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/plugins/dnf5/org.rpm.dnf.v0.Goal.xml b/plugins/dnf5/org.rpm.dnf.v0.Goal.xml +new file mode 100644 +index 000000000..f1ba08953 +--- /dev/null ++++ b/plugins/dnf5/org.rpm.dnf.v0.Goal.xml +@@ -0,0 +1,118 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/plugins/dnf5/org.rpm.dnf.v0.Offline.xml b/plugins/dnf5/org.rpm.dnf.v0.Offline.xml +new file mode 100644 +index 000000000..083b5b17c +--- /dev/null ++++ b/plugins/dnf5/org.rpm.dnf.v0.Offline.xml +@@ -0,0 +1,82 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/plugins/dnf5/org.rpm.dnf.v0.SessionManager.xml b/plugins/dnf5/org.rpm.dnf.v0.SessionManager.xml +new file mode 100644 +index 000000000..a0facd692 +--- /dev/null ++++ b/plugins/dnf5/org.rpm.dnf.v0.SessionManager.xml +@@ -0,0 +1,69 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/plugins/dnf5/org.rpm.dnf.v0.rpm.Repo.xml b/plugins/dnf5/org.rpm.dnf.v0.rpm.Repo.xml +new file mode 100644 +index 000000000..13c4cf1f8 +--- /dev/null ++++ b/plugins/dnf5/org.rpm.dnf.v0.rpm.Repo.xml +@@ -0,0 +1,85 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/plugins/dnf5/org.rpm.dnf.v0.rpm.Rpm.xml b/plugins/dnf5/org.rpm.dnf.v0.rpm.Rpm.xml +new file mode 100644 +index 000000000..5df68cd91 +--- /dev/null ++++ b/plugins/dnf5/org.rpm.dnf.v0.rpm.Rpm.xml +@@ -0,0 +1,468 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/plugins/meson.build b/plugins/meson.build +index a108e47e5..a131a5cd3 100644 +--- a/plugins/meson.build ++++ b/plugins/meson.build +@@ -16,6 +16,9 @@ subdir('fedora-pkgdb-collections') + if get_option('dkms') + subdir('dkms') + endif ++if get_option('dnf5') ++ subdir('dnf5') ++endif + if get_option('eos_updater') + subdir('eos-updater') + endif +diff --git a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c +index 669bd7fdb..d6ae9a268 100644 +--- a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c ++++ b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c +@@ -160,6 +160,7 @@ gs_plugin_rpm_ostree_init (GsPluginRpmOstree *self) + * more sense to use a custom plugin instead of using PackageKit. + */ + gs_plugin_add_rule (GS_PLUGIN (self), GS_PLUGIN_RULE_CONFLICTS, "packagekit"); ++ gs_plugin_add_rule (GS_PLUGIN (self), GS_PLUGIN_RULE_CONFLICTS, "dnf5"); + + /* need pkgname */ + gs_plugin_add_rule (GS_PLUGIN (self), GS_PLUGIN_RULE_RUN_AFTER, "appstream"); +diff --git a/po/POTFILES.in b/po/POTFILES.in +index 71aa486e2..d3e909dee 100644 +--- a/po/POTFILES.in ++++ b/po/POTFILES.in +@@ -112,6 +112,7 @@ lib/gs-utils.c + src/org.gnome.Software.desktop.in + plugins/dkms/gs-plugin-dkms.c + plugins/core/gs-plugin-generic-updates.c ++plugins/dnf5/gs-plugin-dnf5.c + plugins/eos-updater/gs-plugin-eos-updater.c + plugins/epiphany/gs-plugin-epiphany.c + plugins/epiphany/org.gnome.Software.Plugin.Epiphany.metainfo.xml.in diff --git a/gnome-software.spec b/gnome-software.spec index 763ed62..0e01617 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -17,6 +17,9 @@ # Disable DKMS/akmods support for RHEL builds %bcond dkms %[!0%{?rhel}] +%bcond packagekit 0 +%bcond dnf5 1 + # this is not a library version %define gs_plugin_version 22 @@ -26,13 +29,15 @@ Name: gnome-software Version: 48.1 -Release: 1%{?dist} +Release: 2%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later URL: https://apps.gnome.org/Software Source0: https://download.gnome.org/sources/gnome-software/48/%{name}-%{tarball_version}.tar.xz +Patch: 0001-dnf5-plugin.patch + # ostree and flatpak not on i686 for Fedora and RHEL 10 # https://github.com/containers/composefs/pull/229#issuecomment-1838735764 %if 0%{?fedora} || 0%{?rhel} >= 10 @@ -65,7 +70,9 @@ BuildRequires: pkgconfig(libsoup-3.0) BuildRequires: pkgconfig(malcontent-0) %endif BuildRequires: pkgconfig(ostree-1) +%if %{with packagekit} BuildRequires: pkgconfig(packagekit-glib2) >= %{packagekit_version} +%endif BuildRequires: pkgconfig(polkit-gobject-1) BuildRequires: pkgconfig(rpm) %if %{with rpmostree} @@ -79,6 +86,11 @@ Requires: appstream%{?_isa} >= %{appstream_version} %if %{with webapps} Requires: epiphany-runtime%{?_isa} %endif +%if %{with dnf5} +Requires: dnf5daemon-server%{?_isa} +Requires: libdnf5-plugin-appstream%{?_isa} +Requires: rpm-plugin-dbus-announce%{?_isa} +%endif Requires: flatpak%{?_isa} >= %{flatpak_version} Requires: flatpak-libs%{?_isa} >= %{flatpak_version} Requires: fwupd%{?_isa} >= %{fwupd_version} @@ -97,7 +109,9 @@ Requires: libadwaita >= %{libadwaita_version} Requires: librsvg2%{?_isa} Requires: libxmlb%{?_isa} >= %{libxmlb_version} +%if %{with packagekit} Recommends: PackageKit%{?_isa} >= %{packagekit_version} +%endif Recommends: %{name}-fedora-langpacks Obsoletes: gnome-software-snap < 3.33.1 @@ -149,8 +163,17 @@ This package includes the rpm-ostree backend. -Dmalcontent=false \ %endif -Dgudev=true \ +%if %{with packagekit} -Dpackagekit=true \ -Dpackagekit_autoremove=true \ +%else + -Dpackagekit=false \ +%endif +%if %{with dnf5} + -Ddnf5=true \ +%else + -Ddnf5=false \ +%endif -Dexternal_appstream=false \ %if %{with rpmostree} -Drpm_ostree=true \ @@ -232,6 +255,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %dir %{_libdir}/gnome-software/plugins-%{gs_plugin_version} %{_libdir}/gnome-software/libgnomesoftware.so.%{gs_plugin_version} %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_appstream.so +%if %{with dnf5} +%{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_dnf5.so +%endif %if %{with webapps} %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_epiphany.so %endif @@ -246,7 +272,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %endif %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_modalias.so %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_os-release.so +%if %{with packagekit} %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_packagekit.so +%endif %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_provenance-license.so %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_provenance.so %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_repos.so @@ -256,7 +284,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %dir %{_datadir}/swcatalog/xml %{_datadir}/swcatalog/xml/gnome-pwa-list-foss.xml %endif +%if %{with packagekit} %{_datadir}/dbus-1/services/org.freedesktop.PackageKit.service +%endif %{_datadir}/dbus-1/services/org.gnome.Software.service %{_datadir}/gnome-shell/search-providers/org.gnome.Software-search-provider.ini %{_datadir}/glib-2.0/schemas/org.gnome.software.gschema.xml @@ -288,6 +318,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Tue Apr 29 2025 Milan Crha - 48.1-2 +- Switch from PackageKit to DNF5 plugin + * Fri Apr 11 2025 Milan Crha - 48.1-1 - Update to 48.1 From b57929aa0d37a6d3bd613fb4091556644195ad58 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 2 Jun 2025 13:51:22 +0200 Subject: [PATCH 090/116] Require dnf5daemon-server-polkit for the dnf5 plugin It will be in pair with PackageKit, where the wheel users can install packages without being asked for the credentials. --- gnome-software.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/gnome-software.spec b/gnome-software.spec index 0e01617..e840e8d 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -88,6 +88,7 @@ Requires: epiphany-runtime%{?_isa} %endif %if %{with dnf5} Requires: dnf5daemon-server%{?_isa} +Requires: dnf5daemon-server-polkit Requires: libdnf5-plugin-appstream%{?_isa} Requires: rpm-plugin-dbus-announce%{?_isa} %endif From 315c97814f1b4f0a3bd5e5f1e66709f956ba1b5a Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 2 Jun 2025 13:53:45 +0200 Subject: [PATCH 091/116] Update to 48.2 --- gnome-software.spec | 7 +++++-- sources | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index e840e8d..f36f610 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -28,8 +28,8 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 48.1 -Release: 2%{?dist} +Version: 48.2 +Release: 1%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -319,6 +319,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Mon Jun 02 2025 Milan Crha - 48.2-1 +- Update to 48.2 + * Tue Apr 29 2025 Milan Crha - 48.1-2 - Switch from PackageKit to DNF5 plugin diff --git a/sources b/sources index 31b7ac3..da03639 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-48.1.tar.xz) = 7cb1e7a7527e65e6283916cecee55fa4e65d71e538ced65af488d28e94801755d2ab961d2f4603cec0f781893e298fee109df4a839ee99fc3de2cefb82f25a97 +SHA512 (gnome-software-48.2.tar.xz) = 3a03f475de56cb2ba534a0a7eaaaeb21677cf27a54db03bb84e3953dce796bfc437daf59b41155884260006c18562c50d7e01056aeb190a18449cbcbf2f5120c From bd322e2006e57dca80cc555b5d4acd85e3f0d4d7 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 23 Jun 2025 13:49:59 +0200 Subject: [PATCH 092/116] Switch %autosetup from gendiff to git backups It's easier to build patches on top of the current code when multiple files are involved. --- gnome-software.spec | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gnome-software.spec b/gnome-software.spec index f36f610..1c0a1a1 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -48,6 +48,7 @@ BuildRequires: docbook-style-xsl BuildRequires: desktop-file-utils BuildRequires: gcc BuildRequires: gettext +BuildRequires: git-core BuildRequires: gtk-doc BuildRequires: itstool BuildRequires: libxslt @@ -153,7 +154,7 @@ This package includes the rpm-ostree backend. %endif %prep -%autosetup -p1 -S gendiff -n %{name}-%{tarball_version} +%autosetup -p1 -S git -n %{name}-%{tarball_version} %build %meson \ From 9d8fd61e9a565b9e23073f1e7a0bc79d4c15de35 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 27 Jun 2025 09:10:50 +0200 Subject: [PATCH 093/116] Update to 49.alpha --- 0001-dnf5-plugin.patch | 112 +++-- gnome-software.spec | 1021 +--------------------------------------- sources | 2 +- 3 files changed, 76 insertions(+), 1059 deletions(-) diff --git a/0001-dnf5-plugin.patch b/0001-dnf5-plugin.patch index f7b5b67..b2e8117 100644 --- a/0001-dnf5-plugin.patch +++ b/0001-dnf5-plugin.patch @@ -1,11 +1,11 @@ -at commit 31a1ad73cc4fa28b0d352a7ac392bec76e9c10a4 -Date: Wed Apr 2 14:21:03 2025 +0200 +at commit f3042a5f73fc6b04e26ceca5a1a469879af30fd3 +Date: Fri Jun 20 11:20:33 2025 +0200 diff --git a/meson_options.txt b/meson_options.txt -index bc32ba561..523f572cd 100644 +index cd49cf529..27fa15e8b 100644 --- a/meson_options.txt +++ b/meson_options.txt -@@ -2,6 +2,7 @@ option('tests', type : 'boolean', value : true, description : 'enable tests') +@@ -3,6 +3,7 @@ option('installed_tests', type : 'boolean', value : false, description : 'enable option('man', type : 'boolean', value : true, description : 'enable man pages') option('packagekit', type : 'boolean', value : true, description : 'enable PackageKit support') option('packagekit_autoremove', type : 'boolean', value : false, description : 'autoremove packages in PackageKit') @@ -589,10 +589,10 @@ index 000000000..73d528d54 +G_END_DECLS diff --git a/plugins/dnf5/gs-plugin-dnf5.c b/plugins/dnf5/gs-plugin-dnf5.c new file mode 100644 -index 000000000..93f22dc4f +index 000000000..bae3bde28 --- /dev/null +++ b/plugins/dnf5/gs-plugin-dnf5.c -@@ -0,0 +1,3738 @@ +@@ -0,0 +1,3770 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * vi:set noexpandtab tabstop=8 shiftwidth=8: + * @@ -691,17 +691,22 @@ index 000000000..93f22dc4f + +static void +gs_dnf5_report_error (GsPluginDnf5 *self, ++ GsPluginEventCallback event_callback, ++ void *event_user_data, + const GError *error, + gboolean interactive) +{ + g_autoptr(GsPluginEvent) event = NULL; + ++ if (!event_callback) ++ return; ++ + event = gs_plugin_event_new ("error", error, + NULL); + if (interactive) + gs_plugin_event_add_flag (event, GS_PLUGIN_EVENT_FLAG_INTERACTIVE); + gs_plugin_event_add_flag (event, GS_PLUGIN_EVENT_FLAG_WARNING); -+ gs_plugin_report_event (GS_PLUGIN (self), event); ++ event_callback (GS_PLUGIN (self), event, event_user_data); +} + +/* The session reset is used to refresh information about the packages, @@ -2186,7 +2191,7 @@ index 000000000..93f22dc4f +{ + GsPluginDnf5 *self = GS_PLUGIN_DNF5 (source_object); + GsAppQueryTristate is_for_update = GS_APP_QUERY_TRISTATE_UNSET; -+ GsAppQueryTristate is_source = GS_APP_QUERY_TRISTATE_UNSET; ++ const AsComponentKind *component_kinds = NULL; + GsPluginListAppsData *data = task_data; + const gchar * const *provides_files = NULL; + const gchar *provides_tag = NULL; @@ -2202,17 +2207,17 @@ index 000000000..93f22dc4f + + if (data->query != NULL) { + is_for_update = gs_app_query_get_is_for_update (data->query); -+ is_source = gs_app_query_get_is_source (data->query); ++ component_kinds = gs_app_query_get_component_kinds (data->query); + provides_files = gs_app_query_get_provides_files (data->query); + provides_type = gs_app_query_get_provides (data->query, &provides_tag); + } + + if ((is_for_update == GS_APP_QUERY_TRISTATE_UNSET && -+ is_source == GS_APP_QUERY_TRISTATE_UNSET && ++ component_kinds == NULL && + provides_tag == NULL && + provides_files == NULL) || + is_for_update == GS_APP_QUERY_TRISTATE_FALSE || -+ is_source == GS_APP_QUERY_TRISTATE_FALSE || ++ (component_kinds != NULL && !gs_component_kind_array_contains (component_kinds, AS_COMPONENT_KIND_REPOSITORY)) || + gs_app_query_get_n_properties_set (data->query) != 1) { + g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "Unsupported query"); @@ -2359,7 +2364,7 @@ index 000000000..93f22dc4f + gs_dnf5_convert_error (&local_error); + g_prefix_error_literal (&local_error, "Failed to call Rpm::list: "); + } -+ } else if (is_source == GS_APP_QUERY_TRISTATE_TRUE) { ++ } else if (gs_component_kind_array_contains (component_kinds, AS_COMPONENT_KIND_REPOSITORY)) { + g_autoptr(GsDnf5RpmRepo) repo_proxy = NULL; + + repo_proxy = gs_dnf5_rpm_repo_proxy_new_sync (self->connection, @@ -2534,6 +2539,8 @@ index 000000000..93f22dc4f +gs_plugin_dnf5_list_apps_async (GsPlugin *plugin, + GsAppQuery *query, + GsPluginListAppsFlags flags, ++ GsPluginEventCallback event_callback, ++ void *event_user_data, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) @@ -2542,7 +2549,7 @@ index 000000000..93f22dc4f + gboolean interactive = (flags & GS_PLUGIN_LIST_APPS_FLAGS_INTERACTIVE) != 0; + g_autoptr(GTask) task = NULL; + -+ task = gs_plugin_list_apps_data_new_task (plugin, query, flags, ++ task = gs_plugin_list_apps_data_new_task (plugin, query, flags, event_callback, event_user_data, + cancellable, callback, user_data); + g_task_set_source_tag (task, gs_plugin_dnf5_list_apps_async); + @@ -2590,7 +2597,7 @@ index 000000000..93f22dc4f + if (str == NULL) + return TRUE; + /* the app itself is in the list too */ -+ if (g_strcmp0 (gs_app_get_source_default (main_app), str) == 0) ++ if (g_strcmp0 (gs_app_get_default_source (main_app), str) == 0) + return TRUE; + + /* always create a new app, no cached can be used here */ @@ -2676,7 +2683,7 @@ index 000000000..93f22dc4f + if (success) { + g_autoptr(GVariantBuilder) options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); + g_autoptr(GVariant) transaction = NULL; -+ const gchar *package_name = gs_app_get_source_default (app); ++ const gchar *package_name = gs_app_get_default_source (app); + const gchar *packages[2] = { NULL, NULL }; + + packages[0] = package_name; @@ -2827,14 +2834,14 @@ index 000000000..93f22dc4f + GsApp *app = gs_app_list_index (data->list, i); + if (!gs_app_has_quirk (app, GS_APP_QUIRK_IS_WILDCARD) && ( + gs_app_get_state (app) == GS_APP_STATE_UNKNOWN || -+ ((data->flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_SIZE_DATA) != 0 && ++ ((data->require_flags & GS_PLUGIN_REFINE_REQUIRE_FLAGS_SIZE_DATA) != 0 && + gs_app_list_length (gs_app_get_related (app)) == 0))) { -+ if (gs_app_get_source_default (app) != NULL && ++ if (gs_app_get_default_source (app) != NULL && + ((gs_app_has_management_plugin (app, NULL) && + gs_app_get_bundle_kind (app) == AS_BUNDLE_KIND_PACKAGE && + gs_app_get_scope (app) == AS_COMPONENT_SCOPE_SYSTEM) || + gs_app_has_management_plugin (app, plugin))) -+ g_hash_table_insert (apps, g_strdup (gs_app_get_source_default (app)), g_object_ref (app)); ++ g_hash_table_insert (apps, g_strdup (gs_app_get_default_source (app)), g_object_ref (app)); + } + } + @@ -2914,7 +2921,7 @@ index 000000000..93f22dc4f + success = gs_dnf5_foreach_item (self, result, gs_dnf5_refine_cb, apps, cancellable, &local_error); + + if (success && -+ (data->flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_SIZE_DATA) != 0) { ++ (data->require_flags & GS_PLUGIN_REFINE_REQUIRE_FLAGS_SIZE_DATA) != 0) { + /* do not panic when cannot get dependency sizes for the apps */ + if (!gs_dnf5_get_dependency_sizes_sync (self, apps, cancellable, &local_error)) { + g_debug ("Failed to get dependency sizes: %s", local_error->message); @@ -2940,16 +2947,20 @@ index 000000000..93f22dc4f +static void +gs_plugin_dnf5_refine_async (GsPlugin *plugin, + GsAppList *list, -+ GsPluginRefineFlags flags, ++ GsPluginRefineFlags job_flags, ++ GsPluginRefineRequireFlags require_flags, ++ GsPluginEventCallback event_callback, ++ void *event_user_data, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GsPluginDnf5 *self = GS_PLUGIN_DNF5 (plugin); -+ gboolean interactive = gs_plugin_has_flags (plugin, GS_PLUGIN_FLAGS_INTERACTIVE); ++ gboolean interactive = (job_flags & GS_PLUGIN_REFINE_FLAGS_INTERACTIVE) != 0; + g_autoptr(GTask) task = NULL; + -+ task = gs_plugin_refine_data_new_task (plugin, list, flags, ++ task = gs_plugin_refine_data_new_task (plugin, list, job_flags, require_flags, ++ event_callback, event_user_data, + cancellable, callback, user_data); + g_task_set_source_tag (task, gs_plugin_dnf5_refine_async); + @@ -3050,6 +3061,8 @@ index 000000000..93f22dc4f +gs_plugin_dnf5_refresh_metadata_async (GsPlugin *plugin, + guint64 cache_age_secs, + GsPluginRefreshMetadataFlags flags, ++ GsPluginEventCallback event_callback, ++ void *event_user_data, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) @@ -3095,6 +3108,8 @@ index 000000000..93f22dc4f + GsAppList *list, + gboolean is_install, + gboolean interactive, ++ GsPluginEventCallback event_callback, ++ void *event_user_data, + GCancellable *cancellable, + GError **error) +{ @@ -3131,7 +3146,7 @@ index 000000000..93f22dc4f + for (guint i = 0; i < gs_app_list_length (list); i++) { + GsApp *app = gs_app_list_index (list, i); + if (gs_app_has_management_plugin (app, plugin)) { -+ const gchar *source = gs_app_get_source_default (app); ++ const gchar *source = gs_app_get_default_source (app); + if (source != NULL) { + GFile *local_file = gs_app_get_local_file (app); + if (local_file != NULL) @@ -3147,7 +3162,7 @@ index 000000000..93f22dc4f + for (guint j = 0; j < gs_app_list_length (related); j++) { + GsApp *rel_app = gs_app_list_index (related, j); + if (gs_app_has_management_plugin (rel_app, plugin)) { -+ const gchar *source = gs_app_get_source_default (rel_app); ++ const gchar *source = gs_app_get_default_source (rel_app); + if (source != NULL) { + GFile *local_file = gs_app_get_local_file (rel_app); + if (local_file != NULL) @@ -3193,7 +3208,7 @@ index 000000000..93f22dc4f + for (guint j = 0; addons != NULL && j < gs_app_list_length (addons); j++) { + GsApp *addon = gs_app_list_index (addons, j); + if (gs_app_get_to_be_installed (addon)) { -+ const gchar *addon_source = gs_app_get_source_default (app); ++ const gchar *addon_source = gs_app_get_default_source (app); + if (addon_source != NULL) { + g_ptr_array_add (packages, g_strdup (addon_source)); + if (is_install) @@ -3282,7 +3297,7 @@ index 000000000..93f22dc4f + gs_dnf5_convert_error (error); + + if (error != NULL && *error != NULL) -+ gs_dnf5_report_error (self, *error, interactive); ++ gs_dnf5_report_error (self, event_callback, event_user_data, *error, interactive); + } + + for (guint i = 0; i < gs_app_list_length (used_apps); i++) { @@ -3341,6 +3356,7 @@ index 000000000..93f22dc4f + + success = gs_dnf5_install_update (plugin, data->apps, TRUE, + (data->flags & GS_PLUGIN_INSTALL_APPS_FLAGS_INTERACTIVE) != 0, ++ data->event_callback, data->event_user_data, + cancellable, &local_error); + + g_atomic_int_dec_and_test (&self->calling_rpm); @@ -3357,6 +3373,8 @@ index 000000000..93f22dc4f + GsPluginInstallAppsFlags flags, + GsPluginProgressCallback progress_callback, + gpointer progress_user_data, ++ GsPluginEventCallback event_callback, ++ void *event_user_data, + GsPluginAppNeedsUserActionCallback app_needs_user_action_callback, + gpointer app_needs_user_action_data, + GCancellable *cancellable, @@ -3368,6 +3386,7 @@ index 000000000..93f22dc4f + g_autoptr(GTask) task = NULL; + + task = gs_plugin_install_apps_data_new_task (plugin, apps, flags, progress_callback, progress_user_data, ++ event_callback, event_user_data, + app_needs_user_action_callback, app_needs_user_action_data, + cancellable, callback, user_data); + g_task_set_source_tag (task, gs_plugin_dnf5_install_apps_async); @@ -3418,7 +3437,7 @@ index 000000000..93f22dc4f + g_warn_if_reached (); + continue; + } -+ source = gs_app_get_source_default (app); ++ source = gs_app_get_default_source (app); + if (source == NULL) { + g_task_return_new_error (task, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_NOT_SUPPORTED, + "remove not available"); @@ -3435,7 +3454,7 @@ index 000000000..93f22dc4f + for (guint j = 0; addons != NULL && j < gs_app_list_length (addons); j++) { + GsApp *addon = gs_app_list_index (addons, j); + if (gs_app_get_state (addon) == GS_APP_STATE_INSTALLED) { -+ const gchar *addon_source = gs_app_get_source_default (addon); ++ const gchar *addon_source = gs_app_get_default_source (addon); + if (addon_source != NULL) { + g_ptr_array_add (packages, g_strdup (addon_source)); + g_ptr_array_add (touched_apps, g_object_ref (addon)); @@ -3499,7 +3518,8 @@ index 000000000..93f22dc4f + gs_dnf5_mark_session_needs_reset (self); + } else { + gs_dnf5_convert_error (&local_error); -+ gs_dnf5_report_error (self, local_error, (data->flags & GS_PLUGIN_UNINSTALL_APPS_FLAGS_INTERACTIVE) != 0); ++ gs_dnf5_report_error (self, data->event_callback, data->event_user_data, ++ local_error, (data->flags & GS_PLUGIN_UNINSTALL_APPS_FLAGS_INTERACTIVE) != 0); + } + + for (guint i = 0; i < touched_apps->len; i++) { @@ -3524,6 +3544,8 @@ index 000000000..93f22dc4f + GsPluginUninstallAppsFlags flags, + GsPluginProgressCallback progress_callback, + gpointer progress_user_data, ++ GsPluginEventCallback event_callback, ++ void *event_user_data, + GsPluginAppNeedsUserActionCallback app_needs_user_action_callback, + gpointer app_needs_user_action_data, + GCancellable *cancellable, @@ -3535,6 +3557,7 @@ index 000000000..93f22dc4f + g_autoptr(GTask) task = NULL; + + task = gs_plugin_uninstall_apps_data_new_task (plugin, apps, flags, progress_callback, progress_user_data, ++ event_callback, event_user_data, + app_needs_user_action_callback, app_needs_user_action_data, + cancellable, callback, user_data); + g_task_set_source_tag (task, gs_plugin_dnf5_uninstall_apps_async); @@ -3570,6 +3593,7 @@ index 000000000..93f22dc4f + + success = gs_dnf5_install_update (plugin, data->apps, FALSE, + (data->flags & GS_PLUGIN_UPDATE_APPS_FLAGS_INTERACTIVE) != 0, ++ data->event_callback, data->event_user_data, + cancellable, &local_error); + + g_atomic_int_dec_and_test (&self->calling_rpm); @@ -3586,6 +3610,8 @@ index 000000000..93f22dc4f + GsPluginUpdateAppsFlags flags, + GsPluginProgressCallback progress_callback, + gpointer progress_user_data, ++ GsPluginEventCallback event_callback, ++ void *event_user_data, + GsPluginAppNeedsUserActionCallback app_needs_user_action_callback, + gpointer app_needs_user_action_data, + GCancellable *cancellable, @@ -3597,6 +3623,7 @@ index 000000000..93f22dc4f + g_autoptr(GTask) task = NULL; + + task = gs_plugin_update_apps_data_new_task (plugin, apps, flags, progress_callback, progress_user_data, ++ event_callback, event_user_data, + app_needs_user_action_callback, app_needs_user_action_data, + cancellable, callback, user_data); + g_task_set_source_tag (task, gs_plugin_dnf5_update_apps_async); @@ -3708,6 +3735,8 @@ index 000000000..93f22dc4f +gs_plugin_dnf5_enable_repository_async (GsPlugin *plugin, + GsApp *repository, + GsPluginManageRepositoryFlags flags, ++ GsPluginEventCallback event_callback, ++ void *event_user_data, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) @@ -3716,7 +3745,7 @@ index 000000000..93f22dc4f + gboolean interactive = (flags & GS_PLUGIN_MANAGE_REPOSITORY_FLAGS_INTERACTIVE) != 0; + g_autoptr(GTask) task = NULL; + -+ task = gs_plugin_manage_repository_data_new_task (plugin, repository, flags, ++ task = gs_plugin_manage_repository_data_new_task (plugin, repository, flags, event_callback, event_user_data, + cancellable, callback, user_data); + g_task_set_source_tag (task, gs_plugin_dnf5_enable_repository_async); + @@ -3757,6 +3786,8 @@ index 000000000..93f22dc4f +gs_plugin_dnf5_disable_repository_async (GsPlugin *plugin, + GsApp *repository, + GsPluginManageRepositoryFlags flags, ++ GsPluginEventCallback event_callback, ++ void *event_user_data, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) @@ -3765,7 +3796,7 @@ index 000000000..93f22dc4f + gboolean interactive = (flags & GS_PLUGIN_MANAGE_REPOSITORY_FLAGS_INTERACTIVE) != 0; + g_autoptr(GTask) task = NULL; + -+ task = gs_plugin_manage_repository_data_new_task (plugin, repository, flags, ++ task = gs_plugin_manage_repository_data_new_task (plugin, repository, flags, event_callback, event_user_data, + cancellable, callback, user_data); + g_task_set_source_tag (task, gs_plugin_dnf5_disable_repository_async); + @@ -3949,6 +3980,8 @@ index 000000000..93f22dc4f +gs_plugin_dnf5_file_to_app_async (GsPlugin *plugin, + GFile *file, + GsPluginFileToAppFlags flags, ++ GsPluginEventCallback event_callback, ++ void *event_user_data, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) @@ -3957,7 +3990,7 @@ index 000000000..93f22dc4f + GsPluginDnf5 *self = GS_PLUGIN_DNF5 (plugin); + gboolean interactive = (flags & GS_PLUGIN_FILE_TO_APP_FLAGS_INTERACTIVE) != 0; + -+ task = gs_plugin_file_to_app_data_new_task (plugin, file, flags, cancellable, callback, user_data); ++ task = gs_plugin_file_to_app_data_new_task (plugin, file, flags, event_callback, event_user_data, cancellable, callback, user_data); + g_task_set_source_tag (task, gs_plugin_dnf5_file_to_app_async); + + /* Queue a job to get the apps. */ @@ -4106,7 +4139,8 @@ index 000000000..93f22dc4f + } else { + gs_app_set_state (data->app, GS_APP_STATE_AVAILABLE); + gs_dnf5_convert_error (&local_error); -+ gs_dnf5_report_error (self, local_error, (data->flags & GS_PLUGIN_DOWNLOAD_UPGRADE_FLAGS_INTERACTIVE) != 0); ++ gs_dnf5_report_error (self, data->event_callback, data->event_user_data, ++ local_error, (data->flags & GS_PLUGIN_DOWNLOAD_UPGRADE_FLAGS_INTERACTIVE) != 0); + g_task_return_error (task, g_steal_pointer (&local_error)); + } +} @@ -4115,6 +4149,8 @@ index 000000000..93f22dc4f +gs_plugin_dnf5_download_upgrade_async (GsPlugin *plugin, + GsApp *app, + GsPluginDownloadUpgradeFlags flags, ++ GsPluginEventCallback event_callback, ++ void *event_user_data, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) @@ -4123,7 +4159,7 @@ index 000000000..93f22dc4f + g_autoptr(GTask) task = NULL; + gboolean interactive = (flags & GS_PLUGIN_DOWNLOAD_UPGRADE_FLAGS_INTERACTIVE) != 0; + -+ task = gs_plugin_download_upgrade_data_new_task (plugin, app, flags, cancellable, callback, user_data); ++ task = gs_plugin_download_upgrade_data_new_task (plugin, app, flags, event_callback, event_user_data, cancellable, callback, user_data); + g_task_set_source_tag (task, gs_plugin_dnf5_download_upgrade_async); + + /* only process this app if was created by this plugin */ @@ -4171,7 +4207,6 @@ index 000000000..93f22dc4f + } else { + gs_app_set_state (data->app, GS_APP_STATE_AVAILABLE); + gs_dnf5_convert_error (&local_error); -+ gs_dnf5_report_error (self, local_error, (data->flags & GS_PLUGIN_TRIGGER_UPGRADE_FLAGS_INTERACTIVE) != 0); + g_task_return_error (task, g_steal_pointer (&local_error)); + } +} @@ -4321,9 +4356,6 @@ index 000000000..93f22dc4f + + /* prioritize over packagekit */ + gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_CONFLICTS, "packagekit"); -+ -+ /* set name of MetaInfo file */ -+ gs_plugin_set_appstream_id (plugin, "org.gnome.Software.Plugin.Dnf5"); +} + +GType @@ -5540,10 +5572,10 @@ index a108e47e5..a131a5cd3 100644 subdir('eos-updater') endif diff --git a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c -index 669bd7fdb..d6ae9a268 100644 +index 627a5143e..64451bccc 100644 --- a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c +++ b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c -@@ -160,6 +160,7 @@ gs_plugin_rpm_ostree_init (GsPluginRpmOstree *self) +@@ -168,6 +168,7 @@ gs_plugin_rpm_ostree_init (GsPluginRpmOstree *self) * more sense to use a custom plugin instead of using PackageKit. */ gs_plugin_add_rule (GS_PLUGIN (self), GS_PLUGIN_RULE_CONFLICTS, "packagekit"); diff --git a/gnome-software.spec b/gnome-software.spec index 1c0a1a1..5f6b255 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -28,13 +28,13 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 48.2 +Version: 49~alpha Release: 1%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later URL: https://apps.gnome.org/Software -Source0: https://download.gnome.org/sources/gnome-software/48/%{name}-%{tarball_version}.tar.xz +Source0: https://download.gnome.org/sources/gnome-software/49/%{name}-%{tarball_version}.tar.xz Patch: 0001-dnf5-plugin.patch @@ -320,1019 +320,4 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog -* Mon Jun 02 2025 Milan Crha - 48.2-1 -- Update to 48.2 - -* Tue Apr 29 2025 Milan Crha - 48.1-2 -- Switch from PackageKit to DNF5 plugin - -* Fri Apr 11 2025 Milan Crha - 48.1-1 -- Update to 48.1 - -* Fri Mar 14 2025 Milan Crha - 48.0-1 -- Update to 48.0 - -* Mon Mar 03 2025 Milan Crha - 48~rc-1 -- Update to 48.rc - -* Mon Feb 03 2025 Milan Crha - 48~beta-1 -- Update to 48.beta - -* Thu Jan 16 2025 Fedora Release Engineering - 48~alpha3-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild - -* Tue Jan 14 2025 Milan Crha - 48~alpha3-1 -- Update to 48.alpha3 - -* Tue Jan 07 2025 Milan Crha - 48~alpha2-1 -- Update to 48.alpha2 - -* Mon Dec 09 2024 Milan Crha - 47.2-3 -- Resolves: #2272232 (Crash under gs_appstream_gather_merge_data()) - -* Thu Dec 05 2024 Yaakov Selkowitz - 47.2-2 -- Rebuild for fwupd 2.0 - -* Mon Nov 25 2024 Milan Crha - 47.2-1 -- Update to 47.2 - -* Thu Oct 10 2024 Milan Crha - 47.1-1 -- Update to 47.1 - -* Fri Oct 04 2024 Richard Hughes - 47.0-3 -- Rebuild against fwupd 2.0.0 - -* Thu Sep 19 2024 Milan Crha - 47.0-2 -- Resolves: #2312882 (dkms: Fix callback user data in a reload() function) - -* Fri Sep 13 2024 Milan Crha - 47.0-1 -- Update to 47.0 - -* Fri Aug 30 2024 Milan Crha - 47~rc-1 -- Update to 47.rc - -* Fri Aug 02 2024 Milan Crha - 47~beta-1 -- Update to 47.beta -- Build with DKMS/akmods plugin in Fedora - -* Thu Jul 18 2024 Fedora Release Engineering - 47~alpha-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild - -* Fri Jun 28 2024 Milan Crha - 47~alpha-1 -- Update to 47.alpha - -* Fri May 24 2024 Milan Crha - 46.2-1 -- Update to 46.2 - -* Thu Apr 25 2024 Milan Crha - 46.1-1 -- Update to 46.1 - -* Fri Apr 12 2024 Adam Williamson - 46.0-2 -- Backport MR #1949 to fix upgrading - -* Mon Mar 18 2024 Milan Crha - 46.0-1 -- Update to 46.0 - -* Fri Mar 01 2024 Milan Crha - 46~rc-1 -- Update to 46.rc - -* Fri Feb 09 2024 Milan Crha - 46~beta-1 -- Update to 46.beta - -* Fri Jan 26 2024 Milan Crha - 46~alpha-4 -- Resolves: #2260294 (Split fedora-langpacks plugin into a subpackage) - -* Wed Jan 24 2024 Fedora Release Engineering - 46~alpha-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild - -* Fri Jan 19 2024 Fedora Release Engineering - 46~alpha-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild - -* Fri Jan 05 2024 Milan Crha - 46~alpha-1 -- Update to 46.alpha - -* Fri Dec 01 2023 Milan Crha - 45.2-1 -- Update to 45.2 - -* Tue Nov 07 2023 Neal Gompa - 45.1-3 -- Fix appstream_version macro for prerelease appstream 1.0 package - -* Tue Nov 07 2023 Milan Crha - 45.1-2 -- Add patch to build with appstream 1.0 - -* Fri Oct 20 2023 Milan Crha - 45.1-1 -- Update to 45.1 - -* Fri Sep 15 2023 Milan Crha - 45.0-1 -- Update to 45.0 - -* Fri Sep 01 2023 Milan Crha - 45~rc-1 -- Update to 45.rc - -* Mon Jul 31 2023 Milan Crha - 45~beta-1 -- Update to 45.beta - -* Wed Jul 19 2023 Fedora Release Engineering - 45~alpha-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild - -* Fri Jun 30 2023 Milan Crha - 45~alpha-1 -- Update to 45.alpha - -* Thu Jun 22 2023 Tomas Popela - 44.2-2 -- Disable parental control (through malcontent) and rpm-ostree support in RHEL - -* Fri May 26 2023 Milan Crha - 44.2-1 -- Update to 44.2 - -* Fri May 19 2023 Milan Crha - 44.1-2 -- Rebuild for RPM - -* Fri Apr 21 2023 Milan Crha - 44.1-1 -- Update to 44.1 - -* Sun Mar 26 2023 Yaakov Selkowitz - 44.0-3 -- Fix libsoup runtime dependency - -* Fri Mar 24 2023 Milan Crha - 44.0-2 -- Resolves: #2181367 (Prefer Fedora Flatpaks before RPM before other sources for apps) - -* Fri Mar 17 2023 Milan Crha - 44.0-1 -- Update to 44.0 - -* Fri Mar 03 2023 Milan Crha - 44~rc-1 -- Update to 44.rc - -* Thu Feb 23 2023 Adam Williamson - 44~beta-2 -- Backport MR #1635 to fix update notifications - -* Tue Feb 14 2023 Milan Crha - 44.beta-1 -- Update to 44.beta - -* Thu Feb 09 2023 Michael Catanzaro - 44~alpha-3 -- Switch to libsoup 3 - -* Thu Jan 19 2023 Fedora Release Engineering - 44~alpha-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild - -* Mon Jan 09 2023 Milan Crha - 44.alpha-1 -- Update to 44.alpha - -* Fri Dec 02 2022 Milan Crha - 43.2-1 -- Update to 43.2 - -* Tue Nov 08 2022 Milan Crha - 43.1-3 -- Also skip gnome-pwa-list-foss.xml when building without WebApps - -* Tue Nov 08 2022 Milan Crha - 43.1-2 -- Disable WebApps for RHEL builds - -* Mon Oct 24 2022 Milan Crha - 43.1-1 -- Update to 43.1 - -* Wed Oct 05 2022 Milan Crha - 43.0-3 -- Resolves: #2132292 (rpm-ostree plugin refuses to update) - -* Tue Sep 27 2022 Kalev Lember - 43.0-2 -- Rebuild to fix sysprof-capture symbols leaking into libraries consuming it - -* Fri Sep 16 2022 Milan Crha - 43.0-1 -- Update to 43.0 - -* Tue Sep 13 2022 Milan Crha - 43.rc-2 -- Resolves: #2124869 (Cannot install RPM package file) - -* Fri Sep 02 2022 Milan Crha - 43.rc-1 -- Update to 43.rc - -* Wed Aug 17 2022 Milan Crha - 43.beta-3 -- Resolves: #2119089 (No enough apps to show for the "Editor's Choice" section) - -* Mon Aug 15 2022 Milan Crha - 43.beta-2 -- Add patch for install-queue - -* Fri Aug 05 2022 Milan Crha - 43.beta-1 -- Update to 43.beta - -* Thu Jul 21 2022 Fedora Release Engineering - 43.alpha-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild - -* Thu Jul 07 2022 Adam Williamson - 43.alpha-2 -- Backport MR #1401 to fix issue #1816 and fedora-workstation #107 - -* Fri Jul 01 2022 Milan Crha - 43.alpha-1 -- Update to 43.alpha - -* Fri Jun 17 2022 Richard Hughes - 42.2-4 -- Add patch to make fwupd user requests work - -* Thu Jun 16 2022 David King - 42.2-3 -- Filter private libraries from Provides -- Use pkgconfig for BuildRequires -- Improve directory onwership - -* Mon Jun 13 2022 Milan Crha - 42.2-2 -- Add patch for crash under gs_flatpak_refine_app_unlocked() - -* Mon May 30 2022 Milan Crha - 42.2-1 -- Update to 42.2 -- Add patch to correct order of the setup of the GsShell - -* Wed Apr 27 2022 Milan Crha - 42.1-1 -- Update to 42.1 - -* Fri Mar 18 2022 Milan Crha - 42.0-1 -- Update to 42.0 - -* Thu Mar 10 2022 Milan Crha - 42.rc-2 -- Add upstream patches for gs-download-utils (i#1677 and i#1679) - -* Mon Mar 07 2022 Milan Crha - 42.rc-1 -- Update to 42.rc - -* Mon Feb 21 2022 Milan Crha - 42.beta-3 -- Resolves: #2056082 (Enable PackageKit autoremove option) - -* Wed Feb 16 2022 Milan Crha - 42.beta-2 -- Resolves: #2054939 (Crash on a PackageKit app install) -- Add a temporary workaround for gtk_widget_measure error flood on GsAppRow - -* Fri Feb 11 2022 Milan Crha - 42.beta-1 -- Update to 42.beta - -* Thu Jan 20 2022 Fedora Release Engineering - 42~alpha-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild - -* Fri Jan 07 2022 Milan Crha - 42.alpha-1 -- Update to 42.alpha - -* Fri Dec 03 2021 Milan Crha - 41.2-1 -- Update to 41.2 - -* Fri Oct 29 2021 Milan Crha - 41.1-1 -- Update to 41.1 - -* Tue Oct 19 2021 Milan Crha - 41.0-6 -- Resolves: #2012863 (gs-installed-page: Change section on application state change) - -* Mon Oct 11 2021 Milan Crha - 41.0-5 -- Add patch to mark compulsory only repos, not apps from it - -* Fri Oct 08 2021 Milan Crha - 41.0-4 -- 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) - -* Thu Oct 07 2021 Milan Crha - 41.0-3 -- Resolves: #2010740 (Refresh on repository setup change) - -* Mon Oct 04 2021 Milan Crha - 41.0-2 -- Resolves: #2009063 (Correct update notifications) - -* Mon Sep 20 2021 Milan Crha - 41.0-1 -- Update to 41.0 - -* Mon Sep 13 2021 Milan Crha - 41~rc-2 -- Resolves: #2003365 (packagekit: Ensure PkClient::interactive flag being set) - -* Wed Sep 08 2021 Milan Crha - 41~rc-1 -- Update to 41.rc - -* Wed Sep 01 2021 Milan Crha - 41~beta-3 -- Resolves: #1995817 (gs-updates-section: Check also dependencies' download size) - -* Tue Aug 24 2021 Kalev Lember - 41~beta-2 -- Enable parental controls support - -* Fri Aug 13 2021 Milan Crha - 41~beta-1 -- Update to 41.beta - -* Thu Jul 22 2021 Fedora Release Engineering - 41~alpha-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild - -* Wed Jul 21 2021 Milan Crha - 41~alpha-1 -- Update to 41.alpha - -* Mon Jul 12 2021 Milan Crha - 40.3-2 -- Add rpm-ostree patch to hide packages from the search results -- Add patch to implement what-provides search in the Flatpak plugin - -* Mon Jul 12 2021 Milan Crha - 40.3-1 -- Update to 40.3 - -* Wed Jun 23 2021 Milan Crha - 40.2-2 -- Add patch to automatically install application updates (i#1248) - -* Fri Jun 04 2021 Milan Crha - 40.2-1 -- Update to 40.2 - -* Mon May 03 2021 Milan Crha - 40.1-2 -- Add patch for crash under gs_details_page_refresh_all() (i#1227) - -* Mon May 03 2021 Milan Crha - 40.1-1 -- Update to 40.1 - -* Fri Mar 26 2021 Kalev Lember - 40.0-2 -- Rebuild to fix sysprof-capture symbols leaking into libraries consuming it - -* Mon Mar 22 2021 Kalev Lember - 40.0-1 -- Update to 40.0 - -* Thu Mar 18 2021 Adam Williamson - 40~rc-2 -- Backport a couple of bug fixes from upstream (icon display, crash bug) - -* Mon Mar 15 2021 Kalev Lember - 40~rc-1 -- Update to 40.rc - -* Wed Mar 10 2021 Adam Williamson - 40~beta-2 -- Backport MR #643 to fix update notifications on first run (#1930401) - -* Tue Feb 16 2021 Kalev Lember - 40~beta-1 -- Update to 40.beta - -* Mon Feb 08 2021 Richard Hughes - 3.38.1-1 -- New upstream version -- Fix package details not found for some packages -- Ignore harmless warnings when using unusual fwupd versions - -* Tue Jan 26 2021 Fedora Release Engineering - 3.38.0-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild - -* Mon Sep 14 2020 Kalev Lember - 3.38.0-2 -- Revert an optimization that broke packagekit updates - -* Fri Sep 11 2020 Kalev Lember - 3.38.0-1 -- Update to 3.38.0 - -* Tue Sep 01 2020 Kalev Lember - 3.37.92-1 -- Update to 3.37.92 - -* Tue Aug 18 2020 Richard Hughes - 3.36.1-4 -- Rebuild for the libxmlb API bump. - -* Sat Aug 01 2020 Fedora Release Engineering - 3.36.1-3 -- Second attempt - Rebuilt for - https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild - -* Mon Jul 27 2020 Fedora Release Engineering - 3.36.1-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild - -* Fri May 22 2020 Richard Hughes - 3.36.1-1 -- Update to 3.36.1 - -* Tue May 12 2020 Kalev Lember - 3.36.0-2 -- Backport various rpm-ostree backend fixes - -* Wed Mar 11 2020 Kalev Lember - 3.36.0-1 -- Update to 3.36.0 - -* Wed Mar 04 2020 Kalev Lember - 3.35.92-1 -- Update to 3.35.92 - -* Fri Feb 21 2020 Richard Hughes - 3.35.91-2 -- Backport a patch to fix a crash when looking at the application details. - -* Wed Feb 19 2020 Richard Hughes - 3.35.91-1 -- Update to 3.35.91. - -* Tue Jan 28 2020 Fedora Release Engineering - 3.35.2-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild - -* Mon Nov 25 2019 Richard Hughes - 3.35.2-1 -- Update to 3.35.2. - -* Fri Oct 18 2019 Kalev Lember - 3.34.1-6 -- Backport patches to fix a crash in gs_flatpak_get_installation (#1762689) - -* Mon Oct 14 2019 Kalev Lember - 3.34.1-5 -- Update renamed appstream ids for GNOME 3.34 - -* Fri Oct 11 2019 Richard Hughes - 3.34.1-4 -- Backport a simpler to correct the installed applications -- Resolves #1759193 - -* Fri Oct 11 2019 Richard Hughes - 3.34.1-3 -- Backport a better patch to correct the installed applications -- Resolves #1759193 - -* Thu Oct 10 2019 Richard Hughes - 3.34.1-2 -- Backport a patch to correct the applications shown in the installed list -- Resolves #1759193 - -* Mon Oct 07 2019 Kalev Lember - 3.34.1-1 -- Update to 3.34.1 - -* Wed Sep 25 2019 Kalev Lember - 3.34.0-2 -- Fix third party repo enabling not working (#1749566) - -* Mon Sep 09 2019 Kalev Lember - 3.34.0-1 -- Update to 3.34.0 - -* Thu Jul 25 2019 Fedora Release Engineering - 3.32.4-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild - -* Thu Jul 11 2019 Kalev Lember - 3.32.4-1 -- Update to 3.32.4 - -* Thu Jul 11 2019 Richard Hughes - 3.32.3-5 -- Disable the snap plugin. Canonical upstream are not going to be installing - gnome-software in the next LTS, prefering instead to ship a "Snap Store" - rather than GNOME Software. -- Enabling the snap plugin also enables the Snap Store which violated the same - rules which prevented us installing Flathub by default. -- The existing plugin is barely maintained and I don't want to be the one - responsible when it breaks. - -* Thu Jun 13 2019 Kalev Lember - 3.32.3-4 -- Rebuild for accidental libflatpak ABI break - -* Mon Jun 10 22:13:19 CET 2019 Igor Gnatenko - 3.32.3-3 -- Rebuild for RPM 4.15 - -* Mon Jun 10 15:42:01 CET 2019 Igor Gnatenko - 3.32.3-2 -- Rebuild for RPM 4.15 - -* Fri May 24 2019 Kalev Lember - 3.32.3-1 -- Update to 3.32.3 - -* Tue May 07 2019 Kalev Lember - 3.32.2-1 -- Update to 3.32.2 - -* Fri May 03 2019 Kalev Lember - 3.32.1-4 -- Update a patch to final upstream version - -* Tue Apr 30 2019 Kalev Lember - 3.32.1-3 -- Backport a number of rpm-ostree fixes - -* Tue Apr 16 2019 Adam Williamson - 3.32.1-2 -- Rebuild with Meson fix for #1699099 - -* Mon Apr 15 2019 Kalev Lember - 3.32.1-1 -- Update to 3.32.1 - -* Fri Apr 05 2019 Neal Gompa - 3.32.0-6 -- Require snapd instead of the obsolete snapd-login-service for snap subpackage - -* Wed Apr 03 2019 Kalev Lember - 3.32.0-5 -- Switch to system libdnf - -* Fri Mar 29 2019 Kalev Lember - 3.32.0-4 -- Rebuild for new rpm-ostree - -* Fri Mar 15 2019 Kalev Lember - 3.32.0-3 -- Add nm-connection-editor.desktop to Utilities folder (#1686851) - -* Tue Mar 12 2019 Kalev Lember - 3.32.0-2 -- Backport a patch to add shadows to app icons - -* Mon Mar 11 2019 Kalev Lember - 3.32.0-1 -- Update to 3.32.0 - -* Tue Mar 05 2019 Kalev Lember - 3.31.92-1 -- Update to 3.31.92 - -* Thu Feb 28 2019 Kalev Lember - 3.31.90-4 -- Change PackageKit requires to recommends - -* Wed Feb 27 2019 Kalev Lember - 3.31.90-3 -- Remove unneeded dpkg plugin - -* Mon Feb 25 2019 Kalev Lember - 3.31.90-2 -- Split rpm-ostree backend to its own subpackage - -* Sun Feb 24 2019 Kalev Lember - 3.31.90-1 -- Update to 3.31.90 -- Add "anaconda" repo to official repos list (#1679693) - -* Thu Jan 31 2019 Fedora Release Engineering - 3.31.2-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild - -* Wed Jan 16 2019 Kalev Lember - 3.31.2-1 -- Update to 3.31.2 - -* Fri Dec 14 2018 Kalev Lember - 3.31.1-2 -- Fix offline update notifications to show up (#1659231) - -* Tue Oct 09 2018 Kalev Lember - 3.31.1-1 -- Update to 3.31.1 - -* Fri Oct 05 2018 Kalev Lember - 3.30.2-1 -- Update to 3.30.2 - -* Wed Sep 26 2018 Kalev Lember - 3.30.1-2 -- Add modular repos to official repos list - -* Tue Sep 25 2018 Kalev Lember - 3.30.1-1 -- Update to 3.30.1 - -* Thu Sep 06 2018 Kalev Lember - 3.30.0-1 -- Update to 3.30.0 - -* Tue Aug 28 2018 Richard Hughes - 3.29.92-1 -- Update to 3.29.92 - -* Fri Jul 13 2018 Fedora Release Engineering - 3.29.1-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild - -* Wed May 09 2018 Kalev Lember - 3.29.1-1 -- Update to 3.29.1 - -* Mon Apr 09 2018 Kalev Lember - 3.28.1-1 -- Update to 3.28.1 - -* Thu Mar 29 2018 Kalev Lember - 3.28.0-5 -- Fix empty OS Updates showing up -- Make rpm-ostree update triggering work - -* Thu Mar 15 2018 Kalev Lember - 3.28.0-4 -- Fix opening results from gnome-shell search provider - -* Wed Mar 14 2018 Kalev Lember - 3.28.0-3 -- Fix crash on initial run with no network (#1554986) - -* Tue Mar 13 2018 Kalev Lember - 3.28.0-2 -- Backport an upstream patch to fix shell extensions app ID - -* Mon Mar 12 2018 Kalev Lember - 3.28.0-1 -- Update to 3.28.0 - -* Sun Mar 11 2018 Kalev Lember - 3.27.92-3 -- Rebuilt for gspell 1.8 - -* Wed Mar 07 2018 Kalev Lember - 3.27.92-2 -- Move org.gnome.Software.Featured.xml from -editor to main package - -* Mon Mar 05 2018 Kalev Lember - 3.27.92-1 -- Update to 3.27.92 - -* Sun Mar 04 2018 Neal Gompa - 3.27.90-4 -- Drop obsolete snapd-login-service requirement for snap plugin subpackage - -* Mon Feb 19 2018 Adam Williamson - 3.27.90-3 -- Backport fix for RHBZ #1546893 from upstream git - -* Mon Feb 19 2018 Kalev Lember - 3.27.90-2 -- Re-enable rpm-ostree plugin - -* Thu Feb 15 2018 Kalev Lember - 3.27.90-1 -- Update to 3.27.90 -- Temporarily disable the rpm-ostree plugin - -* Tue Feb 13 2018 Björn Esser - 3.27.4-4 -- Rebuild against newer gnome-desktop3 package - -* Thu Feb 08 2018 Kalev Lember - 3.27.4-3 -- Add fedora-workstation-repositories to nonfree-sources schema defaults - -* Wed Feb 07 2018 Fedora Release Engineering - 3.27.4-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild - -* Mon Jan 08 2018 Kalev Lember - 3.27.4-1 -- Update to 3.27.4 -- Drop unused --without packagekit option - -* Fri Jan 05 2018 Igor Gnatenko - 3.27.3-2 -- Remove obsolete scriptlets - -* Sat Dec 16 2017 Kalev Lember - 3.27.3-1 -- Update to 3.27.3 - -* Mon Nov 13 2017 Kalev Lember - 3.27.2-1 -- Update to 3.27.2 - -* Thu Nov 09 2017 Kalev Lember - 3.26.2-1 -- Update to 3.26.2 -- Re-enable fwupd support - -* Tue Oct 31 2017 Kalev Lember - 3.26.1-5 -- Enable the rpm-ostree plugin - -* Wed Oct 25 2017 Kalev Lember - 3.26.1-4 -- Fix "too many results returned" error after distro upgrades (#1496489) - -* Tue Oct 10 2017 Kalev Lember - 3.26.1-3 -- Backport a flatpakref installation fix - -* Mon Oct 09 2017 Richard Hughes - 3.26.1-2 -- Disable fwupd support until we get a 3.27.1 tarball - -* Sun Oct 08 2017 Kalev Lember - 3.26.1-1 -- Update to 3.26.1 - -* Mon Sep 11 2017 Kalev Lember - 3.26.0-1 -- Update to 3.26.0 - -* Sun Aug 27 2017 Kalev Lember - 3.25.91-1 -- Update to 3.25.91 - -* Tue Aug 15 2017 Kalev Lember - 3.25.90-1 -- Update to 3.25.90 - -* Fri Aug 11 2017 Igor Gnatenko - 3.25.4-6 -- Rebuilt after RPM update (№ 3) - -* Thu Aug 10 2017 Igor Gnatenko - 3.25.4-5 -- Rebuilt for RPM soname bump - -* Thu Aug 10 2017 Igor Gnatenko - 3.25.4-4 -- Rebuilt for RPM soname bump - -* Wed Aug 02 2017 Fedora Release Engineering - 3.25.4-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild - -* Wed Jul 26 2017 Fedora Release Engineering - 3.25.4-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild - -* Fri Jul 21 2017 Kalev Lember - 3.25.4-1 -- Update to 3.25.4 - -* Tue Jul 18 2017 Kalev Lember - 3.25.3-6 -- Drop a meson workaround now that meson is fixed - -* Wed Jun 28 2017 Neal Gompa - 3.25.3-5 -- Actually properly enable snap subpackage after removing conditional - -* Wed Jun 28 2017 Neal Gompa - 3.25.3-4 -- Remove unnecessary arch-specific conditional for snap subpackage - -* Tue Jun 27 2017 Neal Gompa - 3.25.3-3 -- Ensure snap subpackage is installed if snapd is installed - -* Fri Jun 23 2017 Richard Hughes - 3.24.3-2 -- Enable the snap subpackage - -* Fri Jun 23 2017 Kalev Lember - 3.25.3-1 -- Update to 3.25.3 -- Switch to the meson build system -- Add an -editor subpackage with new banner editor - -* Mon May 15 2017 Richard Hughes - 3.24.3-1 -- Update to 3.23.3 -- Fix a common crash when installing flatpakrepo files -- Ensure we show the banner when upgrades are available - -* Tue May 09 2017 Kalev Lember - 3.24.2-1 -- Update to 3.24.2 - -* Tue Apr 25 2017 Adam Williamson - 3.24.1-2 -- Backport crasher fix from upstream (RHBZ #1444669 / BGO #781217) - -* Tue Apr 11 2017 Kalev Lember - 3.24.1-1 -- Update to 3.24.1 - -* Tue Mar 21 2017 Kalev Lember - 3.24.0-1 -- Update to 3.24.0 - -* Thu Mar 16 2017 Kalev Lember - 3.23.92-1 -- Update to 3.23.92 - -* Mon Feb 27 2017 Richard Hughes - 3.23.91-1 -- Update to 3.23.91 - -* Mon Feb 13 2017 Richard Hughes - 3.23.90-1 -- Update to 3.23.90 - -* Fri Feb 10 2017 Fedora Release Engineering - 3.23.3-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild - -* Thu Dec 15 2016 Richard Hughes - 3.23.3-1 -- Update to 3.23.3 - -* Wed Nov 23 2016 Kalev Lember - 3.23.2-1 -- Update to 3.23.2 - -* Tue Nov 08 2016 Kalev Lember - 3.22.2-1 -- Update to 3.22.2 - -* Wed Oct 12 2016 Kalev Lember - 3.22.1-1 -- Update to 3.22.1 - -* Mon Sep 19 2016 Kalev Lember - 3.22.0-1 -- Update to 3.22.0 - -* Wed Sep 14 2016 Kalev Lember - 3.21.92-1 -- Update to 3.21.92 -- Don't set group tags - -* Thu Sep 01 2016 Kalev Lember - 3.21.91-1 -- Update to 3.21.91 - -* Wed Aug 17 2016 Kalev Lember - 3.21.90-2 -- Rebuilt for fixed libappstream-glib headers - -* Wed Aug 17 2016 Kalev Lember - 3.21.90-1 -- Update to 3.21.90 -- Tighten -devel subpackage dependencies - -* Thu Jul 28 2016 Richard Hughes - 3.21.4-2 -- Allow building without PackageKit for the atomic workstation. - -* Mon Jul 18 2016 Richard Hughes - 3.21.4-1 -- Update to 3.21.4 - -* Thu May 26 2016 Kalev Lember - 3.21.2-2 -- Build with flatpak support - -* Mon May 23 2016 Richard Hughes - 3.21.2-1 -- Update to 3.21.2 - -* Tue May 10 2016 Kalev Lember - 3.21.1-2 -- Require PackageKit 1.1.1 for system upgrade support - -* Mon Apr 25 2016 Richard Hughes - 3.21.1-1 -- Update to 3.21.1 - -* Mon Apr 25 2016 Richard Hughes - 3.20.2-1 -- Update to 3.20.1 -- Allow popular and featured apps to match any plugin -- Do not make the ODRS plugin depend on xdg-app -- Fix many of the os-upgrade issues and implement the latest mockups -- Make all the plugins more threadsafe -- Return all update descriptions newer than the installed version -- Show some non-fatal error messages if installing fails -- Use a background PackageKit transaction when downloading upgrades - -* Wed Apr 13 2016 Kalev Lember - 3.20.1-1 -- Update to 3.20.1 - -* Fri Apr 01 2016 Richard Hughes - 3.20.1-2 -- Set the list of official sources -- Compile with xdg-app support - -* Tue Mar 22 2016 Kalev Lember - 3.20.0-1 -- Update to 3.20.0 - -* Mon Mar 14 2016 Richard Hughes - 3.19.92-1 -- Update to 3.19.92 - -* Thu Mar 03 2016 Kalev Lember - 3.19.91-2 -- Set minimum required json-glib version - -* Mon Feb 29 2016 Richard Hughes - 3.19.91-1 -- Update to 3.19.91 - -* Mon Feb 15 2016 Richard Hughes - 3.19.90-1 -- Update to 3.19.90 - -* Wed Feb 03 2016 Fedora Release Engineering - 3.19.4-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild - -* Fri Jan 15 2016 Richard Hughes - 3.19.4-1 -- Update to 3.19.4 - -* Thu Dec 03 2015 Kalev Lember - 3.18.3-2 -- Require librsvg2 for the gdk-pixbuf svg loader - -* Thu Nov 05 2015 Richard Hughes - 3.18.3-1 -- Update to 3.18.3 -- Use the correct user agent string when downloading firmware -- Fix a crash in the limba plugin -- Fix installing web applications - -* Mon Oct 26 2015 Kalev Lember - 3.18.2-2 -- Fix apps reappearing as installed a few seconds after removal (#1275163) - -* Thu Oct 15 2015 Kalev Lember - 3.18.2-1 -- Update to 3.18.2 - -* Tue Oct 13 2015 Kalev Lember - 3.18.1-1 -- Update to 3.18.1 - -* Wed Oct 07 2015 Kalev Lember - 3.18.0-2 -- Backport two crasher fixes from upstream - -* Mon Sep 21 2015 Kalev Lember - 3.18.0-1 -- Update to 3.18.0 - -* Tue Sep 15 2015 Kalev Lember - 3.17.92-2 -- Update dependency versions - -* Tue Sep 15 2015 Richard Hughes - 3.17.92-1 -- Update to 3.17.92 - -* Thu Sep 10 2015 Richard Hughes - 3.17.91-2 -- Fix firmware updates - -* Thu Sep 03 2015 Kalev Lember - 3.17.91-1 -- Update to 3.17.91 - -* Wed Aug 19 2015 Kalev Lember - 3.17.90-1 -- Update to 3.17.90 - -* Wed Aug 12 2015 Richard Hughes - 3.17.3-1 -- Update to 3.17.3 - -* Wed Jul 22 2015 David King - 3.17.2-3 -- Bump for new gnome-desktop3 - -* Wed Jun 17 2015 Fedora Release Engineering - 3.17.2-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild - -* Fri Jun 05 2015 Kalev Lember - 3.17.2-1 -- Update to 3.17.2 - -* Mon May 25 2015 Kalev Lember - 3.17.1-1 -- Update to 3.17.1 - -* Fri May 15 2015 Kalev Lember - 3.16.2-2 -- Fix a crash under Wayland (#1221968) - -* Mon May 11 2015 Kalev Lember - 3.16.2-1 -- Update to 3.16.2 - -* Tue Apr 14 2015 Kalev Lember - 3.16.1-1 -- Update to 3.16.1 - -* Mon Mar 23 2015 Kalev Lember - 3.16.0-1 -- Update to 3.16.0 - -* Mon Mar 16 2015 Kalev Lember - 3.15.92-1 -- Update to 3.15.92 -- Use license macro for the COPYING file -- Add a patch to adapt to gnome-terminal desktop file rename - -* Mon Mar 02 2015 Kalev Lember - 3.15.91-1 -- Update to 3.15.91 - -* Sat Feb 21 2015 Kalev Lember - 3.15.90-3 -- Export DisplayName property on the packagekit session service - -* Thu Feb 19 2015 Kalev Lember - 3.15.90-2 -- Backport a crash fix - -* Tue Feb 17 2015 Richard Hughes - 3.15.90-1 -- Update to 3.15.90 - -* Mon Jan 19 2015 Richard Hughes - 3.15.4-1 -- Update to 3.15.4 - -* Tue Nov 25 2014 Kalev Lember - 3.15.2-1 -- Update to 3.15.2 - -* Thu Nov 13 2014 Richard Hughes - 3.14.2-3 -- Fix non-Fedora build - -* Tue Nov 11 2014 Richard Hughes - 3.14.2-2 -- Backport a patch to fix compilation - -* Mon Nov 10 2014 Kalev Lember - 3.14.2-1 -- Update to 3.14.2 - -* Sat Nov 08 2014 Kalev Lember - 3.14.1-3 -- Update the list of system apps - -* Sat Nov 01 2014 David King - 3.14.1-2 -- Rebuild for new libappstream-glib (#1156494) - -* Mon Oct 13 2014 Kalev Lember - 3.14.1-1 -- Update to 3.14.1 - -* Thu Oct 09 2014 Kalev Lember - 3.14.0-2 -- Depend on gnome-menus for app folder directory entries - -* Mon Sep 22 2014 Kalev Lember - 3.14.0-1 -- Update to 3.14.0 - -* Wed Sep 17 2014 Kalev Lember - 3.13.92-2 -- Set minimum required dependency versions (#1136343) - -* Tue Sep 16 2014 Kalev Lember - 3.13.92-1 -- Update to 3.13.92 -- Replace gnome-system-log with gnome-logs in the system apps list - -* Tue Sep 02 2014 Kalev Lember - 3.13.91-1 -- Update to 3.13.91 - -* Tue Aug 19 2014 Richard Hughes - 3.13.90-1 -- Update to 3.13.90 - -* Sat Aug 16 2014 Fedora Release Engineering - 3.13.5-0.2.git5c89189 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild - -* Mon Aug 11 2014 Kalev Lember - 3.13.5-0.1.git5c89189 -- Update to 3.13.5 git snapshot -- Ship HighContrast icons - -* Sun Aug 03 2014 Kalev Lember - 3.13.4-2 -- Replace Epiphany with Firefox in the system apps list - -* Wed Jul 23 2014 Kalev Lember - 3.13.4-1 -- Update to 3.13.4 - -* Wed Jun 25 2014 Kalev Lember - 3.13.3-1 -- Update to 3.13.3 - -* Thu Jun 12 2014 Richard Hughes - 3.13.3-0.2.git7491627 -- Depend on the newly-created appstream-data package and stop shipping - the metadata here. - -* Sat Jun 07 2014 Kalev Lember - 3.13.3-0.1.git7491627 -- Update to 3.13.3 git snapshot - -* Wed May 28 2014 Richard Hughes - 3.13.2-2 -- Rebuild with new metadata. - -* Wed May 28 2014 Kalev Lember - 3.13.2-1 -- Update to 3.13.2 - -* Thu May 15 2014 Kalev Lember - 3.13.1-4 -- Depend on gsettings-desktop-schemas - -* Mon May 12 2014 Richard Hughes - 3.13.1-3 -- Update the metadata and use appstream-util to install the metadata. - -* Wed May 07 2014 Kalev Lember - 3.13.1-2 -- Drop gnome-icon-theme dependency - -* Mon Apr 28 2014 Richard Hughes - 3.13.1-1 -- Update to 3.13.1 - -* Fri Apr 11 2014 Kalev Lember - 3.12.1-2 -- Rebuild with new metadata. - -* Fri Apr 11 2014 Richard Hughes - 3.12.1-1 -- Update to 3.12.1 - -* Mon Mar 24 2014 Richard Hughes - 3.12.0-1 -- Update to 3.12.0 - -* Thu Mar 20 2014 Richard Hughes - 3.11.92-1 -- Update to 3.11.92 - -* Tue Mar 18 2014 Richard Hughes - 3.11.91-2 -- Rebuild with new metadata. - -* Sat Mar 08 2014 Richard Hughes - 3.11.91-1 -- Update to 3.11.91 - -* Tue Feb 18 2014 Richard Hughes - 3.11.90-1 -- Update to 3.11.90 - -* Mon Feb 03 2014 Richard Hughes - 3.11.5-2 -- Require epiphany-runtime rather than the full application - -* Mon Feb 03 2014 Richard Hughes - 3.11.5-1 -- Update to 3.11.5 - -* Thu Jan 30 2014 Richard Hughes - 3.11.4-3 -- Rebuild for libpackagekit-glib soname bump - -* Wed Jan 22 2014 Richard Hughes - 3.11.4-2 -- Rebuild with metadata that has the correct screenshot url. - -* Thu Jan 16 2014 Richard Hughes - 3.11.4-1 -- Update to 3.11.4 - -* Tue Dec 17 2013 Richard Hughes - 3.11.3-1 -- Update to 3.11.3 - -* Tue Nov 19 2013 Richard Hughes - 3.11.2-1 -- Update to 3.11.2 - -* Tue Oct 29 2013 Richard Hughes - 3.11.1-1 -- Update to 3.11.1 -- Add a gnome shell search provider -- Add a module to submit the user rating to the fedora-tagger web service -- Add support for 'missing' codecs that we know exist but we can't install -- Add support for epiphany web applications -- Handle offline installation sensibly -- Save the user rating if the user clicks the rating stars -- Show a modal error message if install or remove actions failed -- Show a star rating on the application details page -- Show font screenshots -- Show more detailed version numbers when required -- Show screenshots to each application - -* Wed Sep 25 2013 Richard Hughes 3.10.0-1 -- New upstream release. -- New metadata for fedora, updates and updates-testing -- Add a plugin to query the PackageKit prepared-update file directly -- Do not clear the offline-update trigger if rebooting succeeded -- Do not load incompatible projects when parsing AppStream data -- Lots of updated translations -- Show the window right away when starting - -* Fri Sep 13 2013 Richard Hughes 3.9.3-1 -- New upstream release. -- Lots of new and fixed UI and updated metadata for Fedora 20 - -* Tue Sep 03 2013 Richard Hughes 3.9.2-1 -- New upstream release. -- Allow stock items in the AppStream XML -- Extract the AppStream URL and description from the XML -- Only present the window when the overview is complete -- Return the subcategories sorted by name - -* Mon Sep 02 2013 Richard Hughes 3.9.1-1 -- New upstream release which is a technical preview for the alpha. - -* Sun Sep 01 2013 Richard Hughes 0.1-3 -- Use buildroot not RPM_BUILD_ROOT -- Own all gnome-software directories -- Drop gtk-update-icon-cache requires and the mime database functionality - -* Thu Aug 29 2013 Richard Hughes 0.1-2 -- Add call to desktop-file-validate and fix other review comments. - -* Wed Aug 28 2013 Richard Hughes 0.1-1 -- First release for Fedora package review - +%autochangelog diff --git a/sources b/sources index da03639..dc17852 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-48.2.tar.xz) = 3a03f475de56cb2ba534a0a7eaaaeb21677cf27a54db03bb84e3953dce796bfc437daf59b41155884260006c18562c50d7e01056aeb190a18449cbcbf2f5120c +SHA512 (gnome-software-49.alpha.tar.xz) = 7616e9f3969b73651c502874ab20f78390b7284ba289451d68847e9afe47f306ef514f46fd633bc99440d98154329d2872237ffb73ae47222ab1d6273ae78b3d From b4aa6186d3ffea75de915d48f8bb4627398f2cff Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 27 Jun 2025 09:50:36 +0200 Subject: [PATCH 094/116] Bump plugin API version --- gnome-software.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gnome-software.spec b/gnome-software.spec index 5f6b255..664794e 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -21,7 +21,7 @@ %bcond dnf5 1 # this is not a library version -%define gs_plugin_version 22 +%define gs_plugin_version 23 %global tarball_version %%(echo %{version} | tr '~' '.') From 6f0144b990cf025954b7b741ae3a70beb1603f56 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 30 Jun 2025 14:48:06 +0200 Subject: [PATCH 095/116] dnf5: Install 'gnome-software-local-file-packagekit.desktop' also for dnf5 plugin --- 0001-dnf5-plugin.patch | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/0001-dnf5-plugin.patch b/0001-dnf5-plugin.patch index b2e8117..3277b35 100644 --- a/0001-dnf5-plugin.patch +++ b/0001-dnf5-plugin.patch @@ -1,5 +1,5 @@ -at commit f3042a5f73fc6b04e26ceca5a1a469879af30fd3 -Date: Fri Jun 20 11:20:33 2025 +0200 +at commit 523ea7ff97d4092faad730d9ddd2311d8de0fa22 +Date: Mon Jun 30 14:44:52 2025 +0200 diff --git a/meson_options.txt b/meson_options.txt index cd49cf529..27fa15e8b 100644 @@ -5595,3 +5595,16 @@ index 71aa486e2..d3e909dee 100644 plugins/eos-updater/gs-plugin-eos-updater.c plugins/epiphany/gs-plugin-epiphany.c plugins/epiphany/org.gnome.Software.Plugin.Epiphany.metainfo.xml.in +diff --git a/src/meson.build b/src/meson.build +index 99dfb409f..e91a73bac 100644 +--- a/src/meson.build ++++ b/src/meson.build +@@ -235,7 +235,7 @@ if get_option('fwupd') + ) + endif + +-if get_option('packagekit') or get_option('rpm_ostree') ++if get_option('packagekit') or get_option('rpm_ostree') or get_option('dnf5') + i18n.merge_file( + input: 'gnome-software-local-file-packagekit.desktop.in', + output: 'gnome-software-local-file-packagekit.desktop', From c924750e8af509c8256cd8163350bf323c9cd545 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 30 Jun 2025 15:42:41 +0200 Subject: [PATCH 096/116] dnf5: Update the dnf5 plugin patch to match the latest upstream main branch --- 0001-dnf5-plugin.patch | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/0001-dnf5-plugin.patch b/0001-dnf5-plugin.patch index 3277b35..70ad781 100644 --- a/0001-dnf5-plugin.patch +++ b/0001-dnf5-plugin.patch @@ -1,4 +1,4 @@ -at commit 523ea7ff97d4092faad730d9ddd2311d8de0fa22 +at commit 87d6d722ec47390682581162d5c14d9b26d4a65e Date: Mon Jun 30 14:44:52 2025 +0200 diff --git a/meson_options.txt b/meson_options.txt @@ -5596,15 +5596,15 @@ index 71aa486e2..d3e909dee 100644 plugins/epiphany/gs-plugin-epiphany.c plugins/epiphany/org.gnome.Software.Plugin.Epiphany.metainfo.xml.in diff --git a/src/meson.build b/src/meson.build -index 99dfb409f..e91a73bac 100644 +index 43e1b58e9..e8af8b058 100644 --- a/src/meson.build +++ b/src/meson.build -@@ -235,7 +235,7 @@ if get_option('fwupd') +@@ -245,7 +245,7 @@ if get_option('fwupd') ) endif -if get_option('packagekit') or get_option('rpm_ostree') +if get_option('packagekit') or get_option('rpm_ostree') or get_option('dnf5') i18n.merge_file( - input: 'gnome-software-local-file-packagekit.desktop.in', - output: 'gnome-software-local-file-packagekit.desktop', + input: + configure_file( From 91ecbf1717f7f6e0b68096998b9a79718cae3451 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 30 Jun 2025 15:57:08 +0200 Subject: [PATCH 097/116] Add script to update the dnf5-plugin patch To not have it saved on a single machine, easy to recover and run by anyone. --- .gitignore | 1 + dnf5-plugin/.gitignore | 1 + dnf5-plugin/update-patch.sh | 24 ++++++++++++++++++++++++ gnome-software.spec | 2 ++ 4 files changed, 28 insertions(+) create mode 100644 dnf5-plugin/.gitignore create mode 100755 dnf5-plugin/update-patch.sh diff --git a/.gitignore b/.gitignore index b4345b1..ba3b2b3 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /gnome-software-*.tar.xz +/gnome-software-*-build diff --git a/dnf5-plugin/.gitignore b/dnf5-plugin/.gitignore new file mode 100644 index 0000000..b86f2cd --- /dev/null +++ b/dnf5-plugin/.gitignore @@ -0,0 +1 @@ +checkout-gs-dnf5 diff --git a/dnf5-plugin/update-patch.sh b/dnf5-plugin/update-patch.sh new file mode 100755 index 0000000..bf03fdd --- /dev/null +++ b/dnf5-plugin/update-patch.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +if [ ! -d checkout-gs-dnf5 ]; then + git clone --branch wip/dnf5daemon https://gitlab.gnome.org/mcrha/gnome-software.git checkout-gs-dnf5 +fi + +PATCH_PATH=../0001-dnf5-plugin.patch +FIRST_COMMIT=f8b6ed17c592922c2e80667c5f122747f9c2d4ab + +cd checkout-gs-dnf5 && \ +echo "Updating gs-dnf5 git repository" && \ +git pull --rebase && \ +echo -n "at " >../${PATCH_PATH} && \ +git log HEAD | head -n 5 | grep -E "commit|Date" >>../${PATCH_PATH} && \ +echo "" >>../${PATCH_PATH} && \ +git diff ${FIRST_COMMIT}^ >>../${PATCH_PATH} && \ +cd - >/dev/null + +if [ "$?" = "0" ]; then + echo "Patch '${PATCH_PATH}' updated" +else + echo "Failed to update patch '${PATCH_PATH}'" + exit 1 +fi diff --git a/gnome-software.spec b/gnome-software.spec index 664794e..3894347 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -36,6 +36,8 @@ License: GPL-2.0-or-later URL: https://apps.gnome.org/Software Source0: https://download.gnome.org/sources/gnome-software/49/%{name}-%{tarball_version}.tar.xz +# to update the patch enter the ./dnf5-plugin/ directory and run from +# it the ./update-patch.sh script Patch: 0001-dnf5-plugin.patch # ostree and flatpak not on i686 for Fedora and RHEL 10 From cb80ea5cd1d87952fb27e0e3f7a4b69685ed8ae8 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 30 Jun 2025 17:15:57 +0200 Subject: [PATCH 098/116] dnf5-plugin: Update script to generate patch to not depend on exact commit It'll mean less changes, and less work, to keep it up to date with the repository changes. --- dnf5-plugin/update-patch.sh | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/dnf5-plugin/update-patch.sh b/dnf5-plugin/update-patch.sh index bf03fdd..481ffcf 100755 --- a/dnf5-plugin/update-patch.sh +++ b/dnf5-plugin/update-patch.sh @@ -1,24 +1,35 @@ #!/bin/bash if [ ! -d checkout-gs-dnf5 ]; then - git clone --branch wip/dnf5daemon https://gitlab.gnome.org/mcrha/gnome-software.git checkout-gs-dnf5 + git clone --branch main https://gitlab.gnome.org/mcrha/gnome-software.git checkout-gs-dnf5 && \ + cd checkout-gs-dnf5 && \ + git checkout -b wip/dnf5daemon origin/wip/dnf5daemon && \ + cd - >/dev/null + + if [ "$?" != "0" ]; then + echo "Failed to clone dnf5-plugin repository" 1>&2 + exit 1; + fi fi PATCH_PATH=../0001-dnf5-plugin.patch -FIRST_COMMIT=f8b6ed17c592922c2e80667c5f122747f9c2d4ab cd checkout-gs-dnf5 && \ -echo "Updating gs-dnf5 git repository" && \ +echo "Updating gs-dnf5 git 'main' repository" && \ +git checkout main && \ +git pull --rebase && \ +echo "Updating gs-dnf5 git 'dnf5-pugin' repository" && \ +git checkout wip/dnf5daemon && \ git pull --rebase && \ echo -n "at " >../${PATCH_PATH} && \ git log HEAD | head -n 5 | grep -E "commit|Date" >>../${PATCH_PATH} && \ echo "" >>../${PATCH_PATH} && \ -git diff ${FIRST_COMMIT}^ >>../${PATCH_PATH} && \ +git diff main >>../${PATCH_PATH} && \ cd - >/dev/null if [ "$?" = "0" ]; then echo "Patch '${PATCH_PATH}' updated" else - echo "Failed to update patch '${PATCH_PATH}'" + echo "Failed to update patch '${PATCH_PATH}'" 1>&2 exit 1 fi From 9baa1e6cb69167623a41174901b16ab14ded738a Mon Sep 17 00:00:00 2001 From: Yaakov Selkowitz Date: Fri, 27 Jun 2025 12:56:22 -0400 Subject: [PATCH 099/116] Fix files list for RHEL builds gnome-software-local-file-packagekit.desktop is installed only when one or more of these options are enabled. --- gnome-software.spec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gnome-software.spec b/gnome-software.spec index 3894347..f18c59b 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -235,7 +235,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_bindir}/gnome-software %{_datadir}/applications/gnome-software-local-file-flatpak.desktop %{_datadir}/applications/gnome-software-local-file-fwupd.desktop +%if %{with packagekit} || %{with rpmostree} || %{with dnf5} %{_datadir}/applications/gnome-software-local-file-packagekit.desktop +%endif %{_datadir}/applications/org.gnome.Software.desktop %{_datadir}/bash-completion/completions/gnome-software %{_mandir}/man1/gnome-software.1* From 47f4fc83f39e1d952ac8912d7360c781da4e2ee2 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 23 Jul 2025 22:48:57 +0000 Subject: [PATCH 100/116] Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild --- gnome-software.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gnome-software.spec b/gnome-software.spec index f18c59b..32061b0 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -29,7 +29,7 @@ Name: gnome-software Version: 49~alpha -Release: 1%{?dist} +Release: 2%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -324,4 +324,7 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog +* Wed Jul 23 2025 Fedora Release Engineering - 49~alpha-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + %autochangelog From 3a3519584163c2c69ead75a0f10e00112318d82e Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 25 Jul 2025 11:34:05 +0200 Subject: [PATCH 101/116] Resolves: #2377094 (Update dnf5 plugin with fixes for rhbz#2377094) --- 0001-dnf5-plugin.patch | 164 ++++++++++++++++++++++++++++++----------- gnome-software.spec | 5 +- 2 files changed, 120 insertions(+), 49 deletions(-) diff --git a/0001-dnf5-plugin.patch b/0001-dnf5-plugin.patch index 70ad781..c6cf3dc 100644 --- a/0001-dnf5-plugin.patch +++ b/0001-dnf5-plugin.patch @@ -1,5 +1,5 @@ -at commit 87d6d722ec47390682581162d5c14d9b26d4a65e -Date: Mon Jun 30 14:44:52 2025 +0200 +at commit f78a6ba2af27d06c77a052e7499422da22c2cd06 +Date: Fri Jul 25 11:23:46 2025 +0200 diff --git a/meson_options.txt b/meson_options.txt index cd49cf529..27fa15e8b 100644 @@ -15,10 +15,10 @@ index cd49cf529..27fa15e8b 100644 option('fwupd', type : 'boolean', value : true, description : 'enable fwupd support') diff --git a/plugins/dnf5/gs-dnf5-progress-helper.c b/plugins/dnf5/gs-dnf5-progress-helper.c new file mode 100644 -index 000000000..d720adc87 +index 000000000..cd8b861df --- /dev/null +++ b/plugins/dnf5/gs-dnf5-progress-helper.c -@@ -0,0 +1,532 @@ +@@ -0,0 +1,552 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * vi:set noexpandtab tabstop=8 shiftwidth=8: + * @@ -41,7 +41,8 @@ index 000000000..d720adc87 + + GsDnf5RpmRpm *rpm_proxy; /* (owned) */ + GsDnf5Base *base_proxy; /* (owned) */ -+ GsApp *app; /* (owned) */ ++ GsApp *app; /* (owned) (nullable) */ ++ GsAppList *list; /* (owned) (nullable) */ + gchar *session_object_path; /* (owned) */ + GHashTable *ongoing_downloads; /* (owned); gchar * (download_id) ~> DownloadInfo * */ + GsAppState recover_download_state; @@ -73,10 +74,20 @@ index 000000000..d720adc87 +G_DEFINE_TYPE (GsDnf5ProgressHelper, gs_dnf5_progress_helper, G_TYPE_OBJECT) + +static void ++gs_dnf5_helper_set_progress (GsDnf5ProgressHelper *self, ++ guint progress) ++{ ++ if (self->app != NULL) ++ gs_app_set_progress (self->app, progress); ++ if (self->list != NULL) ++ gs_app_list_override_progress (self->list, progress); ++} ++ ++static void +gs_dnf5_update_download_progress (GsDnf5ProgressHelper *self) +{ + if (self->to_download_total > 0) -+ gs_app_set_progress (self->app, 100 * self->downloaded_total / self->to_download_total); ++ gs_dnf5_helper_set_progress (self, 100 * self->downloaded_total / self->to_download_total); +} + +typedef struct { @@ -104,10 +115,12 @@ index 000000000..d720adc87 + return; + + if (g_hash_table_size (self->ongoing_downloads) == 0) { -+ self->recover_download_state = gs_app_get_state (self->app); ++ if (self->app != NULL) { ++ self->recover_download_state = gs_app_get_state (self->app); ++ gs_app_set_state (self->app, GS_APP_STATE_DOWNLOADING); ++ } + self->to_download_total = 0; + self->downloaded_total = 0; -+ gs_app_set_state (self->app, GS_APP_STATE_DOWNLOADING); + } + + download_info = g_new0 (DownloadInfo, 1); @@ -116,7 +129,8 @@ index 000000000..d720adc87 + g_hash_table_insert (self->ongoing_downloads, g_strdup (arg_download_id), download_info); + self->to_download_total += arg_total_to_download; + -+ gs_app_set_size_download (self->app, GS_SIZE_TYPE_VALID, self->to_download_total); ++ if (self->app != NULL) ++ gs_app_set_size_download (self->app, GS_SIZE_TYPE_VALID, self->to_download_total); + gs_dnf5_update_download_progress (self); +} + @@ -147,9 +161,11 @@ index 000000000..d720adc87 + + /* it's the last package to be downloaded */ + if (g_hash_table_size (self->ongoing_downloads) == 0) { -+ gs_app_set_state (self->app, self->recover_download_state); -+ gs_app_set_progress (self->app, GS_APP_PROGRESS_UNKNOWN); -+ gs_app_set_size_download (self->app, GS_SIZE_TYPE_UNKNOWN, 0); ++ gs_dnf5_helper_set_progress (self, GS_APP_PROGRESS_UNKNOWN); ++ if (self->app != NULL) { ++ gs_app_set_state (self->app, self->recover_download_state); ++ gs_app_set_size_download (self->app, GS_SIZE_TYPE_UNKNOWN, 0); ++ } + } else { + gs_dnf5_update_download_progress (self); + } @@ -194,7 +210,8 @@ index 000000000..d720adc87 + self->to_download_total -= download_info->total; + download_info->total = arg_total_to_download; + self->to_download_total += download_info->total; -+ gs_app_set_size_download (self->app, GS_SIZE_TYPE_VALID, self->to_download_total); ++ if (self->app != NULL) ++ gs_app_set_size_download (self->app, GS_SIZE_TYPE_VALID, self->to_download_total); + } + gs_dnf5_update_download_progress (self); + } @@ -208,7 +225,7 @@ index 000000000..d720adc87 +{ + if (g_strcmp0 (self->session_object_path, arg_session_object_path) != 0) + return; -+ gs_app_set_progress (self->app, 0); ++ gs_dnf5_helper_set_progress (self, 0); + g_debug ("%s: total:%" G_GUINT64_FORMAT, G_STRFUNC, arg_total); +} + @@ -221,7 +238,7 @@ index 000000000..d720adc87 + if (g_strcmp0 (self->session_object_path, arg_session_object_path) != 0) + return; + g_debug ("%s: success:%d", G_STRFUNC, arg_success); -+ gs_app_set_progress (self->app, 100); ++ gs_dnf5_helper_set_progress (self, 100); +} + +static void @@ -236,7 +253,7 @@ index 000000000..d720adc87 + return; + g_debug ("%s: nevra:'%s' progress:%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT, G_STRFUNC, arg_nevra, arg_processed, arg_total); + if (arg_total != 0) -+ gs_app_set_progress (self->app, arg_processed * 100 / arg_total); ++ gs_dnf5_helper_set_progress (self, arg_processed * 100 / arg_total); +} + +static void @@ -432,7 +449,7 @@ index 000000000..d720adc87 + + #undef clear_signal_handler + -+ gs_app_set_progress (self->app, GS_APP_PROGRESS_UNKNOWN); ++ gs_dnf5_helper_set_progress (self, GS_APP_PROGRESS_UNKNOWN); + + G_OBJECT_CLASS (gs_dnf5_progress_helper_parent_class)->dispose (object); +} @@ -445,6 +462,7 @@ index 000000000..d720adc87 + g_clear_object (&self->base_proxy); + g_clear_object (&self->rpm_proxy); + g_clear_object (&self->app); ++ g_clear_object (&self->list); + g_clear_pointer (&self->session_object_path, g_free); + g_clear_pointer (&self->ongoing_downloads, g_hash_table_destroy); + @@ -470,22 +488,24 @@ index 000000000..d720adc87 +gs_dnf5_progress_helper_new (GsDnf5Base *base_proxy, + GsDnf5RpmRpm *rpm_proxy, + GsApp *progress_app, ++ GsAppList *progress_list, + const gchar *session_object_path) +{ + GsDnf5ProgressHelper *self; + + g_return_val_if_fail (GS_DNF5_IS_BASE (base_proxy), NULL); + g_return_val_if_fail (GS_DNF5_IS_RPM_RPM (rpm_proxy), NULL); -+ g_return_val_if_fail (GS_IS_APP (progress_app), NULL); ++ g_return_val_if_fail (GS_IS_APP (progress_app) || GS_IS_APP_LIST (progress_list), NULL); + g_return_val_if_fail (session_object_path != NULL, NULL); + + self = g_object_new (GS_TYPE_DNF5_PROGRESS_HELPER, NULL); + self->base_proxy = g_object_ref (base_proxy); + self->rpm_proxy = g_object_ref (rpm_proxy); -+ self->app = g_object_ref (progress_app); ++ self->app = progress_app ? g_object_ref (progress_app) : NULL; ++ self->list = progress_list ? g_object_ref (progress_list) : NULL; + self->session_object_path = g_strdup (session_object_path); + -+ gs_app_set_progress (self->app, GS_APP_PROGRESS_UNKNOWN); ++ gs_dnf5_helper_set_progress (self, GS_APP_PROGRESS_UNKNOWN); + + self->download_add_new_id = + g_signal_connect_object (base_proxy, "download_add_new", @@ -553,10 +573,10 @@ index 000000000..d720adc87 +} diff --git a/plugins/dnf5/gs-dnf5-progress-helper.h b/plugins/dnf5/gs-dnf5-progress-helper.h new file mode 100644 -index 000000000..73d528d54 +index 000000000..5d522468c --- /dev/null +++ b/plugins/dnf5/gs-dnf5-progress-helper.h -@@ -0,0 +1,30 @@ +@@ -0,0 +1,31 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * vi:set noexpandtab tabstop=8 shiftwidth=8: + * @@ -584,15 +604,16 @@ index 000000000..73d528d54 + gs_dnf5_progress_helper_new (GsDnf5Base *base_proxy, + GsDnf5RpmRpm *rpm_proxy, + GsApp *progress_app, ++ GsAppList *progress_list, + const gchar *session_object_path); + +G_END_DECLS diff --git a/plugins/dnf5/gs-plugin-dnf5.c b/plugins/dnf5/gs-plugin-dnf5.c new file mode 100644 -index 000000000..bae3bde28 +index 000000000..fefad6961 --- /dev/null +++ b/plugins/dnf5/gs-plugin-dnf5.c -@@ -0,0 +1,3770 @@ +@@ -0,0 +1,3823 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * vi:set noexpandtab tabstop=8 shiftwidth=8: + * @@ -693,6 +714,7 @@ index 000000000..bae3bde28 +gs_dnf5_report_error (GsPluginDnf5 *self, + GsPluginEventCallback event_callback, + void *event_user_data, ++ GsApp *app, + const GError *error, + gboolean interactive) +{ @@ -702,6 +724,7 @@ index 000000000..bae3bde28 + return; + + event = gs_plugin_event_new ("error", error, ++ app ? "app" : NULL, app, + NULL); + if (interactive) + gs_plugin_event_add_flag (event, GS_PLUGIN_EVENT_FLAG_INTERACTIVE); @@ -1337,6 +1360,8 @@ index 000000000..bae3bde28 + GsAppState set_state; + GHashTable *nevra_to_app; /* (nullable): gchar *nevra ~> GsApp * */ + GHashTable *replaces; /* (nullable): GINT_TO_POINTER(pkg-id) ~> gchar *old_version */ ++ GHashTable *used_replaces; /* (nullable): GINT_TO_POINTER(pkg-id) ~> NULL */ ++ gboolean cover_unused_replaces; +} ReadPackageData; + +static gboolean @@ -1803,7 +1828,8 @@ index 000000000..bae3bde28 +typedef enum { + GS_DNF5_TRANSACTION_FLAG_NONE = 0, + GS_DNF5_TRANSACTION_FLAG_OFFLINE = 1 << 0, -+ GS_DNF5_TRANSACTION_FLAG_RESOLVE_ONLY = 1 << 1 ++ GS_DNF5_TRANSACTION_FLAG_RESOLVE_ONLY = 1 << 1, ++ GS_DNF5_TRANSACTION_FLAG_DISALLOW_ERASING = 1 << 2 /* negative flag, to not have it everywhere */ +} GsDnf5TransactionFlags; + +static gboolean @@ -1811,6 +1837,7 @@ index 000000000..bae3bde28 + const gchar *session_path, + GsDnf5RpmRpm *rpm_proxy, + GsApp *progress_app, ++ GsAppList *progress_list, + GsDnf5TransactionFlags flags, + GVariant **out_transaction, + GCancellable *cancellable, @@ -1870,8 +1897,11 @@ index 000000000..bae3bde28 + + options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); + -+ if (progress_app != NULL) -+ helper = gs_dnf5_progress_helper_new (base_proxy, rpm_proxy, progress_app, session_path); ++ g_variant_builder_add (options_builder, "{sv}", "allow_erasing", ++ g_variant_new_boolean ((flags & GS_DNF5_TRANSACTION_FLAG_DISALLOW_ERASING) == 0)); ++ ++ if (progress_app != NULL || progress_list != NULL) ++ helper = gs_dnf5_progress_helper_new (base_proxy, rpm_proxy, progress_app, progress_list, session_path); + + repo_key_import_data.self = self; + repo_key_import_data.session_path = session_path; @@ -2039,6 +2069,7 @@ index 000000000..bae3bde28 +typedef struct _UpdateReplacesData { + GsApp *app; + GHashTable *replaces; ++ GHashTable *used_replaces; +} UpdateReplacesData; + +static gboolean @@ -2051,8 +2082,10 @@ index 000000000..bae3bde28 + UpdateReplacesData *upd = user_data; + gint32 replaces_id = g_variant_get_int32 (item_array); + const gchar *old_version = g_hash_table_lookup (upd->replaces, GINT_TO_POINTER (replaces_id)); -+ if (old_version != NULL) ++ if (old_version != NULL) { + gs_app_set_version (upd->app, old_version); ++ g_hash_table_add (upd->used_replaces, GINT_TO_POINTER (replaces_id)); ++ } + + return TRUE; +} @@ -2073,13 +2106,27 @@ index 000000000..bae3bde28 + g_autoptr(GString) nevra = NULL; + GsApp *known_app; + -+ if (op_kind == OP_KIND_UNKNOWN || op_kind == OP_KIND_REPLACED) ++ if (op_kind == OP_KIND_UNKNOWN || (!rpd->cover_unused_replaces && op_kind == OP_KIND_REPLACED) || ++ (rpd->cover_unused_replaces && op_kind != OP_KIND_REPLACED)) + return TRUE; + + value = g_variant_get_child_value (item_array, 4); + dict = g_variant_dict_new (value); + g_clear_pointer (&value, g_variant_unref); + ++ if (rpd->cover_unused_replaces) { ++ value = g_variant_dict_lookup_value (dict, "id", G_VARIANT_TYPE_INT32); ++ if (value != NULL) { ++ gint32 id = g_variant_get_int32 (value); ++ if (g_hash_table_contains (rpd->used_replaces, GINT_TO_POINTER (id))) ++ return TRUE; ++ } else { ++ return TRUE; ++ } ++ ++ g_clear_pointer (&value, g_variant_unref); ++ } ++ + value = g_variant_dict_lookup_value (dict, "name", G_VARIANT_TYPE_STRING); + if (value == NULL) + return TRUE; @@ -2132,6 +2179,7 @@ index 000000000..bae3bde28 + + upd.app = upd_app; + upd.replaces = rpd->replaces; ++ upd.used_replaces = rpd->used_replaces; + + if (!gs_dnf5_foreach_item (self, value, gs_dnf5_gather_update_replaced_pkgs_cb, &upd, cancellable, error)) + return FALSE; @@ -2170,9 +2218,10 @@ index 000000000..bae3bde28 + gs_app_set_state (upd_app, GS_APP_STATE_UPDATABLE); + break; + case OP_KIND_REMOVE: -+ gs_app_set_state (upd_app, GS_APP_STATE_UNAVAILABLE); -+ break; + case OP_KIND_REPLACED: ++ gs_app_set_state (upd_app, GS_APP_STATE_UNAVAILABLE); ++ gs_app_set_size_download (upd_app, GS_SIZE_TYPE_VALID, 0); ++ break; + case OP_KIND_UNKNOWN: + default: + g_warn_if_reached (); @@ -2274,15 +2323,17 @@ index 000000000..bae3bde28 + if (success) { + g_autoptr(GHashTable) nevra_to_app = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + g_autoptr(GHashTable) replaces = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); ++ g_autoptr(GHashTable) used_replaces = g_hash_table_new (g_direct_hash, g_direct_equal); + ReadPackageData rpd = { 0, }; + rpd.list = list; + rpd.set_state = GS_APP_STATE_UPDATABLE; + rpd.nevra_to_app = nevra_to_app; + rpd.replaces = replaces; ++ rpd.used_replaces = used_replaces; + + success = gs_dnf5_foreach_item (self, result, gs_dnf5_read_package_cb, &rpd, cancellable, &local_error); + -+ if (success && g_hash_table_size (nevra_to_app) > 0) { ++ if (success) { + g_autoptr(GVariantBuilder) options_builder2 = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); + g_autoptr(GVariant) transaction = NULL; + const gchar * const packages[2] = { NULL, NULL }; @@ -2296,13 +2347,19 @@ index 000000000..bae3bde28 + cancellable, + &local_error); + success = success && -+ gs_dnf5_run_transaction (self, session_path, rpm_proxy, NULL, ++ gs_dnf5_run_transaction (self, session_path, rpm_proxy, NULL, NULL, + GS_DNF5_TRANSACTION_FLAG_RESOLVE_ONLY, + &transaction, cancellable, &local_error); + if (success && transaction != NULL) { + success = gs_dnf5_foreach_item (self, transaction, + gs_dnf5_gather_update_replaces_cb, &rpd, + cancellable, &local_error); ++ rpd.cover_unused_replaces = FALSE; ++ success = success && ++ gs_dnf5_foreach_item (self, transaction, ++ gs_dnf5_gather_updates_from_transaction_cb, &rpd, ++ cancellable, &local_error); ++ rpd.cover_unused_replaces = TRUE; + success = success && + gs_dnf5_foreach_item (self, transaction, + gs_dnf5_gather_updates_from_transaction_cb, &rpd, @@ -2697,7 +2754,7 @@ index 000000000..bae3bde28 + cancellable, + &local_error); + success = success && -+ gs_dnf5_run_transaction (self, session_path, rpm_proxy, NULL, ++ gs_dnf5_run_transaction (self, session_path, rpm_proxy, NULL, NULL, + GS_DNF5_TRANSACTION_FLAG_RESOLVE_ONLY, + &transaction, cancellable, &local_error); + if (success && transaction != NULL) @@ -3120,6 +3177,7 @@ index 000000000..bae3bde28 + g_autoptr(GsDnf5SessionManager) session_manager = NULL; + g_autoptr(GsDnf5RpmRpm) rpm_proxy = NULL; + g_autoptr(GsApp) progress_app = NULL; ++ GsAppList *progress_list = is_install ? NULL : list; + gboolean success; + + /* queue for install if installation needs the network */ @@ -3154,14 +3212,18 @@ index 000000000..bae3bde28 + else + g_ptr_array_add (packages, g_strdup (source)); + gs_app_list_add (used_apps, app); -+ if (progress_app == NULL) ++ if (progress_list == NULL && progress_app == NULL) + progress_app = g_object_ref (app); + } + } else if (gs_app_has_quirk (app, GS_APP_QUIRK_IS_PROXY)) { + GsAppList *related = gs_app_get_related (app); ++ gboolean is_os_update = gs_app_get_special_kind (app) == GS_APP_SPECIAL_KIND_OS_UPDATE; + for (guint j = 0; j < gs_app_list_length (related); j++) { + GsApp *rel_app = gs_app_list_index (related, j); -+ if (gs_app_has_management_plugin (rel_app, plugin)) { ++ /* add only updatable packages into the list when it's an OS Update, otherwise ++ dnf5 claims "Packages for argument '$pkgname' available, but not installed." */ ++ if (gs_app_has_management_plugin (rel_app, plugin) && (!is_install || !is_os_update || ++ gs_app_get_state (rel_app) == GS_APP_STATE_UPDATABLE)) { + const gchar *source = gs_app_get_default_source (rel_app); + if (source != NULL) { + GFile *local_file = gs_app_get_local_file (rel_app); @@ -3173,7 +3235,7 @@ index 000000000..bae3bde28 + } + } + } -+ if (progress_app == NULL) ++ if (progress_list == NULL && progress_app == NULL) + progress_app = g_object_ref (app); + } + } @@ -3244,13 +3306,16 @@ index 000000000..bae3bde28 + cancellable, + error); + } else if (success) { ++ /* ignore package list for update, it's an offline action, which should update ++ everything possible, not only a specific package */ ++ const gchar * const all_packages[2] = { NULL, NULL }; + success = gs_dnf5_rpm_rpm_call_upgrade_sync (rpm_proxy, -+ (const gchar * const *) packages->pdata, ++ all_packages, + g_variant_builder_end (options_builder), + cancellable, + error); + } -+ success = success && gs_dnf5_run_transaction (self, session_path, rpm_proxy, progress_app, ++ success = success && gs_dnf5_run_transaction (self, session_path, rpm_proxy, progress_app, progress_list, + is_install ? GS_DNF5_TRANSACTION_FLAG_NONE : GS_DNF5_TRANSACTION_FLAG_OFFLINE, + NULL, cancellable, error); + if (success && !is_install) { @@ -3296,8 +3361,13 @@ index 000000000..bae3bde28 + } else { + gs_dnf5_convert_error (error); + -+ if (error != NULL && *error != NULL) -+ gs_dnf5_report_error (self, event_callback, event_user_data, *error, interactive); ++ if (error != NULL && *error != NULL) { ++ GsApp *app = NULL; ++ if (gs_app_list_length (list) == 1) ++ app = gs_app_list_index (list, 0); ++ ++ gs_dnf5_report_error (self, event_callback, event_user_data, app, *error, interactive); ++ } + } + + for (guint i = 0; i < gs_app_list_length (used_apps); i++) { @@ -3505,7 +3575,7 @@ index 000000000..bae3bde28 + g_variant_builder_end (options_builder), + cancellable, + &local_error); -+ success = success && gs_dnf5_run_transaction (self, session_path, rpm_proxy, progress_app, GS_DNF5_TRANSACTION_FLAG_NONE, NULL, cancellable, &local_error); ++ success = success && gs_dnf5_run_transaction (self, session_path, rpm_proxy, progress_app, NULL, GS_DNF5_TRANSACTION_FLAG_NONE, NULL, cancellable, &local_error); + } else { + gs_dnf5_convert_error (&local_error); + g_prefix_error_literal (&local_error, "Failed to create Rpm proxy: "); @@ -3517,8 +3587,12 @@ index 000000000..bae3bde28 + if (success) { + gs_dnf5_mark_session_needs_reset (self); + } else { ++ GsApp *app = NULL; ++ if (gs_app_list_length (data->apps) == 1) ++ app = gs_app_list_index (data->apps, 0); ++ + gs_dnf5_convert_error (&local_error); -+ gs_dnf5_report_error (self, data->event_callback, data->event_user_data, ++ gs_dnf5_report_error (self, data->event_callback, data->event_user_data, app, + local_error, (data->flags & GS_PLUGIN_UNINSTALL_APPS_FLAGS_INTERACTIVE) != 0); + } + @@ -4088,7 +4162,7 @@ index 000000000..bae3bde28 + error); + + if (success) { -+ success = gs_dnf5_run_transaction (self, session_path, rpm_proxy, progress_app, GS_DNF5_TRANSACTION_FLAG_OFFLINE, NULL, cancellable, error); ++ success = gs_dnf5_run_transaction (self, session_path, rpm_proxy, progress_app, NULL, GS_DNF5_TRANSACTION_FLAG_OFFLINE, NULL, cancellable, error); + + if (success && !download_only) { + g_autofree gchar *op_error_msg = NULL; @@ -4139,7 +4213,7 @@ index 000000000..bae3bde28 + } else { + gs_app_set_state (data->app, GS_APP_STATE_AVAILABLE); + gs_dnf5_convert_error (&local_error); -+ gs_dnf5_report_error (self, data->event_callback, data->event_user_data, ++ gs_dnf5_report_error (self, data->event_callback, data->event_user_data, data->app, + local_error, (data->flags & GS_PLUGIN_DOWNLOAD_UPGRADE_FLAGS_INTERACTIVE) != 0); + g_task_return_error (task, g_steal_pointer (&local_error)); + } diff --git a/gnome-software.spec b/gnome-software.spec index 32061b0..abe7752 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -29,7 +29,7 @@ Name: gnome-software Version: 49~alpha -Release: 2%{?dist} +Release: 3%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -324,7 +324,4 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/gtk-doc/html/gnome-software/ %changelog -* Wed Jul 23 2025 Fedora Release Engineering - 49~alpha-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild - %autochangelog From 06b236a7381b97d04c1cb6fa5e829582bbb24dd2 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 1 Aug 2025 09:54:42 +0200 Subject: [PATCH 102/116] Update to 49.beta --- 0001-dnf5-plugin.patch | 4 ++-- gnome-software.spec | 9 ++++++--- sources | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/0001-dnf5-plugin.patch b/0001-dnf5-plugin.patch index c6cf3dc..c2353ab 100644 --- a/0001-dnf5-plugin.patch +++ b/0001-dnf5-plugin.patch @@ -1,4 +1,4 @@ -at commit f78a6ba2af27d06c77a052e7499422da22c2cd06 +at commit 238692b2cfb9cf3db85e1a0b2df369da97d7c639 Date: Fri Jul 25 11:23:46 2025 +0200 diff --git a/meson_options.txt b/meson_options.txt @@ -5670,7 +5670,7 @@ index 71aa486e2..d3e909dee 100644 plugins/epiphany/gs-plugin-epiphany.c plugins/epiphany/org.gnome.Software.Plugin.Epiphany.metainfo.xml.in diff --git a/src/meson.build b/src/meson.build -index 43e1b58e9..e8af8b058 100644 +index f8b918539..7df81d130 100644 --- a/src/meson.build +++ b/src/meson.build @@ -245,7 +245,7 @@ if get_option('fwupd') diff --git a/gnome-software.spec b/gnome-software.spec index abe7752..46397ad 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -28,8 +28,8 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 49~alpha -Release: 3%{?dist} +Version: 49~beta +Release: 1%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -83,6 +83,7 @@ BuildRequires: pkgconfig(rpm-ostree-1) %endif BuildRequires: pkgconfig(sysprof-capture-4) BuildRequires: pkgconfig(xmlb) >= %{libxmlb_version} +BuildRequires: systemd Requires: appstream-data Requires: appstream%{?_isa} >= %{appstream_version} @@ -284,7 +285,6 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_provenance-license.so %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_provenance.so %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_repos.so -%{_sysconfdir}/xdg/autostart/org.gnome.Software.desktop %if %{with webapps} %dir %{_datadir}/swcatalog %dir %{_datadir}/swcatalog/xml @@ -314,6 +314,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_rpm-ostree.so %endif +%{_datadir}/dbus-1/services/org.gnome.Software.service +%{_userunitdir}/gnome-software.service + %files devel %{_libdir}/pkgconfig/gnome-software.pc %dir %{_includedir}/gnome-software diff --git a/sources b/sources index dc17852..f212fbd 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-49.alpha.tar.xz) = 7616e9f3969b73651c502874ab20f78390b7284ba289451d68847e9afe47f306ef514f46fd633bc99440d98154329d2872237ffb73ae47222ab1d6273ae78b3d +SHA512 (gnome-software-49.beta.tar.xz) = 9cb6d67216193840b2661871ef43da5e726a284d1164781f13423ee8dd86359334f199efc29f4b3a0b3eddfa8a3811d7dd38cd412fa53aaebb2e1c35ddc1f9df From 7fb63f649d3ade06860bf6fce2e8a0537b482a73 Mon Sep 17 00:00:00 2001 From: Adam Williamson Date: Fri, 1 Aug 2025 12:08:46 -0700 Subject: [PATCH 103/116] Move the user service file to the main package In the 49-beta bump, this new file was inadvertently put into the rpm-ostree subpackage, it doesn't make any sense for it to be there. --- gnome-software.spec | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index 46397ad..198e7c9 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -29,7 +29,7 @@ Name: gnome-software Version: 49~beta -Release: 1%{?dist} +Release: 2%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -299,6 +299,7 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_datadir}/glib-2.0/schemas/org.gnome.software-fedora.gschema.override %{_libexecdir}/gnome-software-cmd %{_libexecdir}/gnome-software-restarter +%{_userunitdir}/gnome-software.service %if %{with dkms} %{_datadir}/polkit-1/actions/org.gnome.software.dkms-helper.policy @@ -314,9 +315,6 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %{_libdir}/gnome-software/plugins-%{gs_plugin_version}/libgs_plugin_rpm-ostree.so %endif -%{_datadir}/dbus-1/services/org.gnome.Software.service -%{_userunitdir}/gnome-software.service - %files devel %{_libdir}/pkgconfig/gnome-software.pc %dir %{_includedir}/gnome-software From e4f244856b78751a56f757d91d247602862429d0 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 11 Aug 2025 17:10:38 +0200 Subject: [PATCH 104/116] dnf5-pugin: Use 'interactive' option, where supported - dnf5-plugin: Add support to provide update history --- 0001-dnf5-plugin.patch | 940 +++++++++++++++++++++++++++++++++++++---- gnome-software.spec | 5 +- 2 files changed, 859 insertions(+), 86 deletions(-) diff --git a/0001-dnf5-plugin.patch b/0001-dnf5-plugin.patch index c2353ab..3e9a13f 100644 --- a/0001-dnf5-plugin.patch +++ b/0001-dnf5-plugin.patch @@ -1,5 +1,5 @@ -at commit 238692b2cfb9cf3db85e1a0b2df369da97d7c639 -Date: Fri Jul 25 11:23:46 2025 +0200 +at commit 8a1f0ca6564157dd688c84ffd25af9747c1e038e +Date: Mon Aug 11 17:07:06 2025 +0200 diff --git a/meson_options.txt b/meson_options.txt index cd49cf529..27fa15e8b 100644 @@ -610,10 +610,10 @@ index 000000000..5d522468c +G_END_DECLS diff --git a/plugins/dnf5/gs-plugin-dnf5.c b/plugins/dnf5/gs-plugin-dnf5.c new file mode 100644 -index 000000000..fefad6961 +index 000000000..88d7e25d8 --- /dev/null +++ b/plugins/dnf5/gs-plugin-dnf5.c -@@ -0,0 +1,3823 @@ +@@ -0,0 +1,4275 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * vi:set noexpandtab tabstop=8 shiftwidth=8: + * @@ -642,10 +642,15 @@ index 000000000..fefad6961 + +#include "gs-plugin-dnf5.h" + ++#include "../packagekit/gs-markdown.h" ++ +#define GS_DNF5_RELEASEVER_DEFAULT NULL +#define GS_DNF5_INTERFACE_RPM_DNF "org.rpm.dnf.v0" +#define GS_DNF5_OBJECT_PATH_RPM_DNF "/org/rpm/dnf/v0" + ++#define GS_DNF5_ADVISORIES_KEY "gs-dnf5::advisories" ++#define GS_DNF5_CHANGELOGS_KEY "gs-dnf5::changelogs" ++ +/* for how long a session can be left opened until it's auto-closed */ +#define GS_SESSION_LIFETIME_SECS (5 * 60) + @@ -1302,8 +1307,15 @@ index 000000000..fefad6961 + gs_app_set_state (app, state); +} + ++typedef enum { ++ GS_DNF5_READ_PACKAGE_FLAG_NONE = 0, ++ GS_DNF5_READ_PACKAGE_FLAG_CAN_CACHED = 1 << 0, ++ GS_DNF5_READ_PACKAGE_FLAG_CHANGELOGS = 1 << 1 ++} GsDnf5ReadPackageFlags; ++ +static void +gs_dnf5_update_app_changelogs (GsApp *app, ++ GsDnf5ReadPackageFlags flags, + GVariantDict *dict) +{ + GVariantIter iter; @@ -1351,43 +1363,33 @@ index 000000000..fefad6961 + g_variant_unref (child); + } + -+ if (changes != NULL) -+ gs_app_set_update_details_text (app, changes->str); ++ if (changes != NULL) { ++ if ((flags & GS_DNF5_READ_PACKAGE_FLAG_CHANGELOGS) != 0) ++ gs_app_set_update_details_text (app, changes->str); ++ else ++ gs_app_set_metadata (app, GS_DNF5_CHANGELOGS_KEY, changes->str); ++ } +} + -+typedef struct { -+ GsAppList *list; -+ GsAppState set_state; -+ GHashTable *nevra_to_app; /* (nullable): gchar *nevra ~> GsApp * */ -+ GHashTable *replaces; /* (nullable): GINT_TO_POINTER(pkg-id) ~> gchar *old_version */ -+ GHashTable *used_replaces; /* (nullable): GINT_TO_POINTER(pkg-id) ~> NULL */ -+ gboolean cover_unused_replaces; -+} ReadPackageData; -+ -+static gboolean -+gs_dnf5_read_package_cb (GsPluginDnf5 *self, -+ GVariant *package_array, -+ gpointer user_data, -+ GCancellable *cancellable, -+ GError **error) ++static GsApp * /* (transfer full) */ ++gs_dnf5_read_package_from_dict (GsPluginDnf5 *self, ++ GVariantDict *dict, ++ GsDnf5ReadPackageFlags flags, ++ GsAppState set_state) +{ -+ ReadPackageData *rpd = user_data; -+ GsAppList *list = rpd->list; -+ GHashTable *nevra_to_app = rpd->nevra_to_app; -+ g_autofree gchar *name = NULL; + g_autoptr(GsApp) app = NULL; -+ g_autoptr(GVariantDict) dict = NULL; + g_autoptr(GVariant) value = NULL; ++ g_autofree gchar *name = NULL; + -+ dict = g_variant_dict_new (package_array); -+ -+ value = g_variant_dict_lookup_value (dict, "name", G_VARIANT_TYPE_STRING); -+ if (value != NULL) { -+ const gchar *name_const = g_variant_get_string (value, NULL); -+ app = gs_plugin_cache_lookup (GS_PLUGIN (self), name_const); -+ if (app == NULL) -+ name = g_strdup (name_const); -+ g_clear_pointer (&value, g_variant_unref); ++ if ((flags & GS_DNF5_READ_PACKAGE_FLAG_CAN_CACHED) != 0) { ++ value = g_variant_dict_lookup_value (dict, "name", G_VARIANT_TYPE_STRING); ++ if (value != NULL) { ++ const gchar *name_const = g_variant_get_string (value, NULL); ++ app = gs_plugin_cache_lookup (GS_PLUGIN (self), name_const); ++ if (app == NULL) ++ name = g_strdup (name_const); ++ g_clear_pointer (&value, g_variant_unref); ++ } + } + + if (app == NULL) { @@ -1414,21 +1416,58 @@ index 000000000..fefad6961 + g_clear_pointer (&value, g_variant_unref); + } + -+ gs_plugin_cache_add (GS_PLUGIN (self), name, app); ++ value = g_variant_dict_lookup_value (dict, "buildtime", G_VARIANT_TYPE_UINT64); ++ if (value != NULL) { ++ gs_app_set_install_date (app, (gint64) g_variant_get_uint64 (value)); ++ g_clear_pointer (&value, g_variant_unref); ++ } ++ ++ if ((flags & GS_DNF5_READ_PACKAGE_FLAG_CAN_CACHED) != 0) ++ gs_plugin_cache_add (GS_PLUGIN (self), name, app); + } + -+ gs_dnf5_update_app_changelogs (app, dict); -+ gs_dnf5_update_app_state (app, rpd->set_state, dict); ++ gs_dnf5_update_app_changelogs (app, flags, dict); ++ gs_dnf5_update_app_state (app, set_state, dict); + -+ if (rpd->set_state == GS_APP_STATE_UPDATABLE) { ++ if (set_state == GS_APP_STATE_UPDATABLE) { + gs_dnf5_app_set_version (dict, app, gs_app_set_update_version); + gs_app_add_quirk (app, GS_APP_QUIRK_NEEDS_REBOOT); + } else { + gs_dnf5_app_set_version (dict, app, gs_app_set_version); + } + ++ return g_steal_pointer (&app); ++} ++ ++typedef struct { ++ GsAppList *list; ++ GsAppState set_state; ++ GHashTable *nevra_to_app; /* (nullable): gchar *nevra ~> GsApp * */ ++ GHashTable *replaces; /* (nullable): GINT_TO_POINTER(pkg-id) ~> gchar *old_version */ ++ GHashTable *used_replaces; /* (nullable): GINT_TO_POINTER(pkg-id) ~> NULL */ ++ gboolean cover_unused_replaces; ++ gint64 timestamp; ++} ReadPackageData; ++ ++static gboolean ++gs_dnf5_read_package_cb (GsPluginDnf5 *self, ++ GVariant *package_array, ++ gpointer user_data, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ ReadPackageData *rpd = user_data; ++ GsAppList *list = rpd->list; ++ GHashTable *nevra_to_app = rpd->nevra_to_app; ++ g_autoptr(GsApp) app = NULL; ++ g_autoptr(GVariantDict) dict = NULL; ++ ++ dict = g_variant_dict_new (package_array); ++ ++ app = gs_dnf5_read_package_from_dict (self, dict, GS_DNF5_READ_PACKAGE_FLAG_CAN_CACHED | GS_DNF5_READ_PACKAGE_FLAG_CHANGELOGS, rpd->set_state); ++ + if (nevra_to_app != NULL) { -+ g_clear_pointer (&value, g_variant_unref); ++ g_autoptr(GVariant) value = NULL; + value = g_variant_dict_lookup_value (dict, "nevra", G_VARIANT_TYPE_STRING); + if (value != NULL) { + const gchar *nevra_const = g_variant_get_string (value, NULL); @@ -1600,6 +1639,7 @@ index 000000000..fefad6961 + g_variant_builder_add (attrs_builder, "s", "url"); + g_variant_builder_add (attrs_builder, "s", "license"); + g_variant_builder_add (attrs_builder, "s", "description"); ++ g_variant_builder_add (attrs_builder, "s", "buildtime"); + g_variant_builder_add (attrs_builder, "s", "changelogs"); + + return g_variant_builder_end (attrs_builder); @@ -1633,6 +1673,7 @@ index 000000000..fefad6961 + gchar *key_id; + GsPluginDnf5 *self; /* (owned) */ + GWeakRef repo_proxy_weakref; /* GsDnf5RpmRepo */ ++ gboolean interactive; +} QuestionData; + +static void @@ -1658,11 +1699,22 @@ index 000000000..fefad6961 + + repo_proxy = g_weak_ref_get (&data->repo_proxy_weakref); + if (repo_proxy != NULL) { ++ g_autoptr(GVariantBuilder) options_builder = NULL; + gboolean confirmed; + + confirmed = gs_plugin_ask_untrusted (GS_PLUGIN (data->self), data->title, data->msg, data->details, data->accept_label); + -+ gs_dnf5_rpm_repo_call_confirm_key (repo_proxy, data->key_id, confirmed, NULL, gs_dnf5_confirm_key_response_cb, NULL); ++ options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ g_variant_builder_add (options_builder, "{sv}", "interactive", ++ g_variant_new_boolean (data->interactive)); ++ ++ gs_dnf5_rpm_repo_call_confirm_key_with_options (repo_proxy, ++ data->key_id, ++ confirmed, ++ g_variant_builder_end (options_builder), ++ NULL, ++ gs_dnf5_confirm_key_response_cb, ++ NULL); + } + + return G_SOURCE_REMOVE; @@ -1672,6 +1724,7 @@ index 000000000..fefad6961 + GsPluginDnf5 *self; /* (not owned) */ + const gchar *session_path; /* (not owned) */ + GsDnf5RpmRepo *repo_proxy; /* (not owned) */ ++ gboolean interactive; +} RepoKeyImportData; + +static void @@ -1746,6 +1799,7 @@ index 000000000..fefad6961 + data->accept_label = g_strdup (_("_Import Key")); + data->key_id = g_strdup (arg_key_id); + data->self = g_object_ref (repo_key_import_data->self); ++ data->interactive = repo_key_import_data->interactive; + g_weak_ref_init (&data->repo_proxy_weakref, repo_key_import_data->repo_proxy); + + g_idle_add_full (G_PRIORITY_HIGH_IDLE, gs_dnf5_ask_question_idle_cb, data, (GDestroyNotify) question_data_free); @@ -1829,7 +1883,8 @@ index 000000000..fefad6961 + GS_DNF5_TRANSACTION_FLAG_NONE = 0, + GS_DNF5_TRANSACTION_FLAG_OFFLINE = 1 << 0, + GS_DNF5_TRANSACTION_FLAG_RESOLVE_ONLY = 1 << 1, -+ GS_DNF5_TRANSACTION_FLAG_DISALLOW_ERASING = 1 << 2 /* negative flag, to not have it everywhere */ ++ GS_DNF5_TRANSACTION_FLAG_DISALLOW_ERASING = 1 << 2, /* negative flag, to not have it everywhere */ ++ GS_DNF5_TRANSACTION_FLAG_INTERACTIVE = 1 << 3 +} GsDnf5TransactionFlags; + +static gboolean @@ -1855,6 +1910,7 @@ index 000000000..fefad6961 + gulong repo_key_import_id; + gulong cancellable_id = 0; + guint result = 0; ++ gboolean interactive = (flags & GS_DNF5_TRANSACTION_FLAG_INTERACTIVE) != 0; + gboolean success; + + base_proxy = gs_dnf5_base_proxy_new_sync (self->connection, @@ -1906,6 +1962,7 @@ index 000000000..fefad6961 + repo_key_import_data.self = self; + repo_key_import_data.session_path = session_path; + repo_key_import_data.repo_proxy = repo_proxy; ++ repo_key_import_data.interactive = interactive; + repo_key_import_id = g_signal_connect (base_proxy, "repo_key_import_request", + G_CALLBACK (gs_dnf5_repo_key_import_request_cb), &repo_key_import_data); + @@ -1958,6 +2015,8 @@ index 000000000..fefad6961 + g_variant_builder_add (options_builder, "{sv}", "offline", + g_variant_new_boolean (TRUE)); + } ++ g_variant_builder_add (options_builder, "{sv}", "interactive", ++ g_variant_new_boolean (interactive)); + + run_cancellable = g_cancellable_new (); + if (cancellable != NULL) { @@ -2231,6 +2290,91 @@ index 000000000..fefad6961 + return TRUE; +} + ++static gboolean ++gs_dnf5_read_history_packages_cb (GsPluginDnf5 *self, ++ GVariant *array, ++ gpointer user_data, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ ReadPackageData *rpd = user_data; ++ g_autoptr(GsApp) app = NULL; ++ g_autoptr(GVariantDict) dict = NULL; ++ ++ dict = g_variant_dict_new (array); ++ ++ app = gs_dnf5_read_package_from_dict (self, dict, GS_DNF5_READ_PACKAGE_FLAG_NONE, rpd->set_state); ++ if (app != NULL) { ++ g_autoptr(GVariant) value = NULL; ++ value = g_variant_dict_lookup_value (dict, "original_evr", G_VARIANT_TYPE_STRING); ++ if (value != NULL) { ++ const gchar *str = g_variant_get_string (value, NULL); ++ if (str != NULL) { ++ const gchar *delim = strchr (str, ':'); ++ /* skip the epoch, if set, because it's skipped in the current version too */ ++ gs_app_set_version (app, delim ? delim + 1 : str); ++ } ++ } ++ ++ g_clear_pointer (&value, g_variant_unref); ++ value = g_variant_dict_lookup_value (dict, "advisories", G_VARIANT_TYPE_ARRAY); ++ if (value != NULL) { ++ gs_app_set_metadata_variant (app, GS_DNF5_ADVISORIES_KEY, value); ++ } ++ ++ /* do not know the exact change date/time, it uses the build time and the one from the settings as a fallback */ ++ if (!gs_app_get_install_date (app)) ++ gs_app_set_install_date (app, rpd->timestamp); ++ gs_app_list_add (rpd->list, app); ++ } ++ ++ return TRUE; ++} ++ ++static gboolean ++gs_dnf5_read_history_items_cb (GsPluginDnf5 *self, ++ GVariant *array, ++ gpointer user_data, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ struct _known_changes { ++ const gchar *type_of_change; ++ GsAppState set_state; ++ } known_changes[] = { ++ { "installed", GS_APP_STATE_UPDATABLE }, ++ { "removed", GS_APP_STATE_UNAVAILABLE }, ++ { "upgraded", GS_APP_STATE_UPDATABLE }, ++ { "downgraded", GS_APP_STATE_UPDATABLE } ++ }; ++ ReadPackageData *rpd = user_data; ++ g_autoptr(GVariant) value = NULL; ++ const gchar *type_of_change; ++ guint ii; ++ ++ value = g_variant_get_child_value (array, 0); ++ if (value == NULL) ++ return TRUE; ++ ++ type_of_change = g_variant_get_string (value, NULL); ++ if (!type_of_change) ++ return TRUE; ++ ++ for (ii = 0; ii < G_N_ELEMENTS (known_changes); ii++) { ++ if (g_strcmp0 (type_of_change, known_changes[ii].type_of_change) == 0) { ++ g_autoptr(GVariant) packages = NULL; ++ packages = g_variant_get_child_value (array, 1); ++ if (packages != NULL) { ++ rpd->set_state = known_changes[ii].set_state; ++ gs_dnf5_foreach_item (self, packages, gs_dnf5_read_history_packages_cb, rpd, cancellable, error); ++ } ++ break; ++ } ++ } ++ ++ return TRUE; ++} ++ +/* Run in @worker. */ +static void +gs_dnf5_list_apps_thread_cb (GTask *task, @@ -2240,6 +2384,7 @@ index 000000000..fefad6961 +{ + GsPluginDnf5 *self = GS_PLUGIN_DNF5 (source_object); + GsAppQueryTristate is_for_update = GS_APP_QUERY_TRISTATE_UNSET; ++ GsAppQueryTristate is_historical_update = GS_APP_QUERY_TRISTATE_UNSET; + const AsComponentKind *component_kinds = NULL; + GsPluginListAppsData *data = task_data; + const gchar * const *provides_files = NULL; @@ -2256,16 +2401,19 @@ index 000000000..fefad6961 + + if (data->query != NULL) { + is_for_update = gs_app_query_get_is_for_update (data->query); ++ is_historical_update = gs_app_query_get_is_historical_update (data->query); + component_kinds = gs_app_query_get_component_kinds (data->query); + provides_files = gs_app_query_get_provides_files (data->query); + provides_type = gs_app_query_get_provides (data->query, &provides_tag); + } + + if ((is_for_update == GS_APP_QUERY_TRISTATE_UNSET && ++ is_historical_update == GS_APP_QUERY_TRISTATE_UNSET && + component_kinds == NULL && + provides_tag == NULL && + provides_files == NULL) || + is_for_update == GS_APP_QUERY_TRISTATE_FALSE || ++ is_historical_update == GS_APP_QUERY_TRISTATE_FALSE || + (component_kinds != NULL && !gs_component_kind_array_contains (component_kinds, AS_COMPONENT_KIND_REPOSITORY)) || + gs_app_query_get_n_properties_set (data->query) != 1) { + g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, @@ -2421,6 +2569,57 @@ index 000000000..fefad6961 + gs_dnf5_convert_error (&local_error); + g_prefix_error_literal (&local_error, "Failed to call Rpm::list: "); + } ++ } else if (is_historical_update == GS_APP_QUERY_TRISTATE_TRUE) { ++ g_autoptr(GsDnf5History) history_proxy = NULL; ++ ++ history_proxy = gs_dnf5_history_proxy_new_sync (self->connection, ++ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, ++ GS_DNF5_INTERFACE_RPM_DNF, ++ session_path, ++ cancellable, ++ &local_error); ++ success = history_proxy != NULL; ++ if (!success) { ++ gs_dnf5_convert_error (&local_error); ++ g_prefix_error_literal (&local_error, "Failed to create History proxy: "); ++ } ++ ++ if (success) { ++ g_autoptr(GVariantBuilder) options_builder = NULL; ++ g_autoptr(GVariant) result = NULL; ++ g_autoptr(GSettings) settings; ++ gint64 timestamp; ++ ++ /* use the option the GUI part uses */ ++ settings = g_settings_new ("org.gnome.software"); ++ timestamp = g_settings_get_int64 (settings, "install-timestamp"); ++ ++ options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ g_variant_builder_add (options_builder, "{sv}", "since", ++ g_variant_new_int64 (timestamp)); ++ g_variant_builder_add (options_builder, "{sv}", "package_attrs", ++ gs_dnf5_dup_package_attrs ()); ++ ++ success = gs_dnf5_history_call_recent_changes_sync (history_proxy, ++ g_variant_builder_end (options_builder), ++ &result, ++ cancellable, ++ &local_error); ++ ++ if (success) { ++ ReadPackageData rpd = { 0, }; ++ ++ rpd.list = list; ++ rpd.set_state = GS_APP_STATE_UNKNOWN; ++ rpd.nevra_to_app = NULL; ++ rpd.timestamp = timestamp; ++ ++ success = gs_dnf5_foreach_item (self, result, gs_dnf5_read_history_items_cb, &rpd, cancellable, &local_error); ++ } else { ++ gs_dnf5_convert_error (&local_error); ++ g_prefix_error_literal (&local_error, "Failed to call recent_changes: "); ++ } ++ } + } else if (gs_component_kind_array_contains (component_kinds, AS_COMPONENT_KIND_REPOSITORY)) { + g_autoptr(GsDnf5RpmRepo) repo_proxy = NULL; + @@ -2867,6 +3066,87 @@ index 000000000..fefad6961 + return TRUE; +} + ++static gboolean ++gs_dnf5_add_advisories_cb (GsPluginDnf5 *self, ++ GVariant *value, ++ gpointer user_data, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ GHashTable *advisories = user_data; /* gchar *name ~> gchar *description */ ++ g_autofree gchar *str = NULL; ++ ++ str = g_variant_dup_string (value, NULL); ++ if (str != NULL && *str != '\0') ++ g_hash_table_insert (advisories, g_steal_pointer (&str), NULL); ++ ++ return TRUE; ++} ++ ++static gboolean ++gs_dnf5_gather_update_description_for_advisory_cb (GsPluginDnf5 *self, ++ GVariant *value, ++ gpointer user_data, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ GHashTable *advisories = user_data; /* gchar *name ~> gchar *description */ ++ g_autoptr(GVariantDict) dict = NULL; ++ g_autoptr(GVariant) name = NULL; ++ g_autoptr(GVariant) description = NULL; ++ const gchar *name_str, *description_str; ++ ++ dict = g_variant_dict_new (value); ++ ++ name = g_variant_dict_lookup_value (dict, "name", G_VARIANT_TYPE_STRING); ++ if (name == NULL) ++ return TRUE; ++ ++ description = g_variant_dict_lookup_value (dict, "description", G_VARIANT_TYPE_STRING); ++ if (description == NULL) ++ return TRUE; ++ ++ name_str = g_variant_get_string (name, NULL); ++ description_str = g_variant_get_string (description, NULL); ++ ++ if (name_str != NULL && description_str != NULL && *description_str != '\0') ++ g_hash_table_replace (advisories, g_strdup (name_str), g_strdup (description_str)); ++ ++ return TRUE; ++} ++ ++typedef struct _AdvisoryUpdateDescriptionData { ++ GHashTable *advisories; /* gchar *name ~> gchar *description */ ++ GString *description; ++} AdvisoryUpdateDescriptionData; ++ ++static gboolean ++gs_dnf5_refine_update_description_from_advisory_cb (GsPluginDnf5 *self, ++ GVariant *value, ++ gpointer user_data, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ AdvisoryUpdateDescriptionData *adv_data = user_data; ++ const gchar *name = NULL; ++ ++ name = g_variant_get_string (value, NULL); ++ if (name != NULL && *name != '\0') { ++ const gchar *description = g_hash_table_lookup (adv_data->advisories, name); ++ if (description != NULL && *description != '\0') { ++ if (adv_data->description == NULL) { ++ adv_data->description = g_string_new (description); ++ } else { ++ g_string_append (adv_data->description, "\n\n"); ++ g_string_append (adv_data->description, description); ++ } ++ } ++ } ++ ++ return TRUE; ++} ++ ++ +/* Run in @worker. */ +static void +gs_dnf5_refine_thread_cb (GTask *task, @@ -2891,6 +3171,7 @@ index 000000000..fefad6961 + GsApp *app = gs_app_list_index (data->list, i); + if (!gs_app_has_quirk (app, GS_APP_QUIRK_IS_WILDCARD) && ( + gs_app_get_state (app) == GS_APP_STATE_UNKNOWN || ++ (data->require_flags & GS_PLUGIN_REFINE_REQUIRE_FLAGS_UPDATE_DETAILS) != 0 || + ((data->require_flags & GS_PLUGIN_REFINE_REQUIRE_FLAGS_SIZE_DATA) != 0 && + gs_app_list_length (gs_app_get_related (app)) == 0))) { + if (gs_app_get_default_source (app) != NULL && @@ -2926,7 +3207,127 @@ index 000000000..fefad6961 + g_prefix_error_literal (&local_error, "Failed to create Rpm proxy: "); + } + -+ if (success) { ++ if (success && (data->require_flags & GS_PLUGIN_REFINE_REQUIRE_FLAGS_UPDATE_DETAILS) != 0) { ++ g_autoptr(GHashTable) advisories = NULL; /* gchar *name ~> gchar *description */ ++ GHashTableIter iter; ++ gpointer value = NULL; ++ ++ data->require_flags = data->require_flags & (~GS_PLUGIN_REFINE_REQUIRE_FLAGS_UPDATE_DETAILS); ++ ++ advisories = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); ++ ++ g_hash_table_iter_init (&iter, apps); ++ while (success && g_hash_table_iter_next (&iter, NULL, &value)) { ++ GsApp *app = value; ++ GVariant *advisories_array; ++ ++ advisories_array = gs_app_get_metadata_variant (app, GS_DNF5_ADVISORIES_KEY); ++ if (advisories_array != NULL) ++ success = gs_dnf5_foreach_item (self, advisories_array, gs_dnf5_add_advisories_cb, advisories, cancellable, &local_error); ++ } ++ ++ if (success && g_hash_table_size (advisories) > 0) { ++ g_autoptr(GsDnf5Advisory) advisory_proxy = NULL; ++ ++ advisory_proxy = gs_dnf5_advisory_proxy_new_sync (self->connection, ++ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, ++ GS_DNF5_INTERFACE_RPM_DNF, ++ session_path, ++ cancellable, ++ &local_error); ++ success = advisory_proxy != NULL; ++ ++ if (success) { ++ g_autoptr(GVariantBuilder) adv_options_builder = NULL; ++ g_autoptr(GVariantBuilder) attrs_builder = NULL; ++ g_autoptr(GVariantBuilder) names_builder = NULL; ++ g_autoptr(GVariant) adv_result = NULL; ++ gpointer key = NULL; ++ ++ attrs_builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); ++ g_variant_builder_add (attrs_builder, "s", "name"); ++ g_variant_builder_add (attrs_builder, "s", "description"); ++ ++ names_builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); ++ g_hash_table_iter_init (&iter, advisories); ++ while (g_hash_table_iter_next (&iter, &key, NULL)) { ++ const gchar *name = key; ++ g_variant_builder_add (names_builder, "s", name); ++ } ++ ++ adv_options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ g_variant_builder_add (adv_options_builder, "{sv}", "advisory_attrs", ++ g_variant_builder_end (attrs_builder)); ++ g_variant_builder_add (adv_options_builder, "{sv}", "names", ++ g_variant_builder_end (names_builder)); ++ g_variant_builder_add (adv_options_builder, "{sv}", "availability", ++ g_variant_new_string ("all")); ++ ++ success = gs_dnf5_advisory_call_list_sync (advisory_proxy, ++ g_variant_builder_end (adv_options_builder), ++ &adv_result, ++ cancellable, ++ &local_error); ++ if (success) { ++ success = gs_dnf5_foreach_item (self, adv_result, ++ gs_dnf5_gather_update_description_for_advisory_cb, advisories, ++ cancellable, &local_error); ++ if (success) { ++ g_hash_table_iter_init (&iter, apps); ++ while (success && g_hash_table_iter_next (&iter, NULL, &value)) { ++ GsApp *app = value; ++ GVariant *advisories_array; ++ ++ advisories_array = gs_app_get_metadata_variant (app, GS_DNF5_ADVISORIES_KEY); ++ if (advisories_array != NULL) { ++ AdvisoryUpdateDescriptionData adv_data = { NULL, }; ++ adv_data.advisories = advisories; ++ adv_data.description = NULL; ++ ++ success = gs_dnf5_foreach_item (self, advisories_array, ++ gs_dnf5_refine_update_description_from_advisory_cb, ++ &adv_data, cancellable, &local_error); ++ ++ if (adv_data.description) { ++ g_autoptr(GsMarkdown) markdown = gs_markdown_new (GS_MARKDOWN_OUTPUT_PANGO); ++ g_autofree gchar *markup = gs_markdown_parse (markdown, adv_data.description->str); ++ if (markup != NULL && *markup != '\0') ++ gs_app_set_update_details_markup (app, markup); ++ else ++ gs_app_set_update_details_text (app, adv_data.description->str); ++ g_string_free (adv_data.description, TRUE); ++ } ++ } ++ } ++ ++ if (!success) ++ g_debug ("Failed to refine update description from advisory: %s", local_error->message); ++ } else { ++ g_debug ("Failed to gather update description for advisory: %s", local_error->message); ++ } ++ } else { ++ g_debug ("Failed to call Advisory::list: %s", local_error->message); ++ } ++ } else { ++ g_debug ("Failed to create Advisory proxy: %s", local_error->message); ++ } ++ } ++ ++ /* fallback to changelogs where advisory was not known */ ++ g_hash_table_iter_init (&iter, apps); ++ while (success && g_hash_table_iter_next (&iter, NULL, &value)) { ++ GsApp *app = value; ++ if (!gs_app_get_update_details_markup (app)) { ++ const gchar *changelogs = gs_app_get_metadata_item (app, GS_DNF5_CHANGELOGS_KEY); ++ if (changelogs != NULL && *changelogs != '\0') { ++ gs_app_set_update_details_text (app, changelogs); ++ gs_app_set_metadata (app, GS_DNF5_CHANGELOGS_KEY, NULL); ++ } ++ } ++ } ++ } ++ ++ if (success && data->require_flags != 0) { + g_autoptr(GVariantBuilder) attrs_builder = NULL; + g_autoptr(GVariantBuilder) options_builder = NULL; + g_autoptr(GVariantBuilder) patterns_builder = NULL; @@ -3041,6 +3442,7 @@ index 000000000..fefad6961 + GCancellable *cancellable) +{ + GsPluginDnf5 *self = GS_PLUGIN_DNF5 (source_object); ++ GsPluginRefreshMetadataData *data = task_data; + g_autofree gchar *session_path = NULL; + g_autoptr(GsDnf5SessionManager) session_manager = NULL; + g_autoptr(GsDnf5Base) base_proxy = NULL; @@ -3068,16 +3470,23 @@ index 000000000..fefad6961 + g_prefix_error_literal (&local_error, "Failed to create Base proxy: "); + } + -+ if (success && GPOINTER_TO_INT (task_data) == 1) { ++ if (success && data->cache_age_secs < 60) { ++ g_autoptr(GVariantBuilder) options_builder = NULL; + g_autofree gchar *op_error_msg = NULL; + gboolean op_success = FALSE; + -+ success = gs_dnf5_base_call_clean_sync (base_proxy, -+ "expire-cache", -+ &op_success, -+ &op_error_msg, -+ cancellable, -+ &local_error); ++ options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ ++ g_variant_builder_add (options_builder, "{sv}", "interactive", ++ g_variant_new_boolean ((data->flags & GS_PLUGIN_REFRESH_METADATA_FLAGS_INTERACTIVE) != 0)); ++ ++ success = gs_dnf5_base_call_clean_with_options_sync (base_proxy, ++ "expire-cache", ++ g_variant_builder_end (options_builder), ++ &op_success, ++ &op_error_msg, ++ cancellable, ++ &local_error); + if (!success) + g_debug ("Failed to call expire-cache: %s", local_error->message); + else if (!op_success) @@ -3130,9 +3539,9 @@ index 000000000..fefad6961 + + task = g_task_new (self, cancellable, callback, user_data); + g_task_set_source_tag (task, gs_plugin_dnf5_refresh_metadata_async); -+ /* no need to save whole structure, the seconds are not used at all, -+ thus make it only a flag whether to invalidate the cache or not first */ -+ g_task_set_task_data (task, GINT_TO_POINTER (cache_age_secs < 60 ? 1 : 0), NULL); ++ g_task_set_task_data (task, ++ gs_plugin_refresh_metadata_data_new (cache_age_secs, flags, event_callback, event_user_data), ++ (GDestroyNotify) gs_plugin_refresh_metadata_data_free); + + gs_worker_thread_queue (self->worker, gs_dnf5_get_priority_for_interactivity (interactive), + gs_dnf5_refresh_metadata_thread_cb, g_steal_pointer (&task)); @@ -3289,10 +3698,13 @@ index 000000000..fefad6961 + success = rpm_proxy != NULL; + if (success) { + g_autoptr(GVariantBuilder) options_builder = NULL; ++ GsDnf5TransactionFlags flags = interactive ? GS_DNF5_TRANSACTION_FLAG_INTERACTIVE : GS_DNF5_TRANSACTION_FLAG_NONE; + + g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (rpm_proxy), G_MAXINT); + + options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ g_variant_builder_add (options_builder, "{sv}", "interactive", ++ g_variant_new_boolean (interactive)); + + /* NULL-terminate the array, to be like strv */ + g_ptr_array_add (packages, NULL); @@ -3316,7 +3728,7 @@ index 000000000..fefad6961 + error); + } + success = success && gs_dnf5_run_transaction (self, session_path, rpm_proxy, progress_app, progress_list, -+ is_install ? GS_DNF5_TRANSACTION_FLAG_NONE : GS_DNF5_TRANSACTION_FLAG_OFFLINE, ++ flags | (is_install ? 0 : GS_DNF5_TRANSACTION_FLAG_OFFLINE), + NULL, cancellable, error); + if (success && !is_install) { + /* ensure the update is finished with the 'reboot' action */ @@ -3333,7 +3745,19 @@ index 000000000..fefad6961 + g_autofree gchar *op_error_msg = NULL; + gboolean op_success = FALSE; + -+ success = gs_dnf5_offline_call_set_finish_action_sync (offline_proxy, "reboot", &op_success, &op_error_msg, cancellable, error); ++ g_clear_pointer (&options_builder, g_variant_builder_unref); ++ ++ options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ g_variant_builder_add (options_builder, "{sv}", "interactive", ++ g_variant_new_boolean (interactive)); ++ ++ success = gs_dnf5_offline_call_set_finish_action_with_options_sync (offline_proxy, ++ "reboot", ++ g_variant_builder_end (options_builder), ++ &op_success, ++ &op_error_msg, ++ cancellable, ++ error); + if (success && !op_success) { + success = FALSE; + if (op_error_msg != NULL) { @@ -3556,6 +3980,8 @@ index 000000000..fefad6961 + &local_error); + success = rpm_proxy != NULL; + if (success) { ++ GsDnf5TransactionFlags flags = (data->flags & GS_PLUGIN_UNINSTALL_APPS_FLAGS_INTERACTIVE) != 0 ? ++ GS_DNF5_TRANSACTION_FLAG_INTERACTIVE : GS_DNF5_TRANSACTION_FLAG_NONE; + g_autoptr(GVariantBuilder) options_builder = NULL; + + g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (rpm_proxy), G_MAXINT); @@ -3575,7 +4001,7 @@ index 000000000..fefad6961 + g_variant_builder_end (options_builder), + cancellable, + &local_error); -+ success = success && gs_dnf5_run_transaction (self, session_path, rpm_proxy, progress_app, NULL, GS_DNF5_TRANSACTION_FLAG_NONE, NULL, cancellable, &local_error); ++ success = success && gs_dnf5_run_transaction (self, session_path, rpm_proxy, progress_app, NULL, flags, NULL, cancellable, &local_error); + } else { + gs_dnf5_convert_error (&local_error); + g_prefix_error_literal (&local_error, "Failed to create Rpm proxy: "); @@ -3718,6 +4144,7 @@ index 000000000..fefad6961 +gs_dnf5_manage_repository_sync (GsPluginDnf5 *self, + GsApp *repository, + gboolean enable, ++ gboolean interactive, + GCancellable *cancellable, + GError **error) +{ @@ -3758,15 +4185,20 @@ index 000000000..fefad6961 + + if (success) { + const gchar *ids[2] = { NULL, NULL }; ++ g_autoptr(GVariantBuilder) options_builder = NULL; + + g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (repo_proxy), G_MAXINT); + + ids[0] = gs_app_get_id (repository); + ++ options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ g_variant_builder_add (options_builder, "{sv}", "interactive", ++ g_variant_new_boolean (interactive)); ++ + if (enable) -+ success = gs_dnf5_rpm_repo_call_enable_sync (repo_proxy, ids, cancellable, error); ++ success = gs_dnf5_rpm_repo_call_enable_with_options_sync (repo_proxy, ids, g_variant_builder_end (options_builder), cancellable, error); + else -+ success = gs_dnf5_rpm_repo_call_disable_sync (repo_proxy, ids, cancellable, error); ++ success = gs_dnf5_rpm_repo_call_disable_with_options_sync (repo_proxy, ids, g_variant_builder_end (options_builder), cancellable, error); + + if (success) { + if (enable) @@ -3797,7 +4229,9 @@ index 000000000..fefad6961 + + assert_in_worker (self); + -+ if (gs_dnf5_manage_repository_sync (self, data->repository, TRUE, cancellable, &local_error)) { ++ if (gs_dnf5_manage_repository_sync (self, data->repository, TRUE, ++ (data->flags & GS_PLUGIN_MANAGE_REPOSITORY_FLAGS_INTERACTIVE) != 0, ++ cancellable, &local_error)) { + g_task_return_boolean (task, TRUE); + } else { + gs_dnf5_convert_error (&local_error); @@ -3848,7 +4282,9 @@ index 000000000..fefad6961 + + assert_in_worker (self); + -+ if (gs_dnf5_manage_repository_sync (self, data->repository, FALSE, cancellable, &local_error)) { ++ if (gs_dnf5_manage_repository_sync (self, data->repository, FALSE, ++ (data->flags & GS_PLUGIN_MANAGE_REPOSITORY_FLAGS_INTERACTIVE) != 0, ++ cancellable, &local_error)) { + g_task_return_boolean (task, TRUE); + } else { + gs_dnf5_convert_error (&local_error); @@ -4085,6 +4521,7 @@ index 000000000..fefad6961 + const gchar *releasever, + GsApp *progress_app, + gboolean download_only, ++ gboolean interactive, + GCancellable *cancellable, + GError **error) +{ @@ -4152,6 +4589,8 @@ index 000000000..fefad6961 + g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (rpm_proxy), G_MAXINT); + + options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ g_variant_builder_add (options_builder, "{sv}", "interactive", ++ g_variant_new_boolean (interactive)); + + success = gs_dnf5_reset_transaction_sync (self, session_path, rpm_proxy, cancellable, error); + @@ -4162,14 +4601,23 @@ index 000000000..fefad6961 + error); + + if (success) { -+ success = gs_dnf5_run_transaction (self, session_path, rpm_proxy, progress_app, NULL, GS_DNF5_TRANSACTION_FLAG_OFFLINE, NULL, cancellable, error); ++ GsDnf5TransactionFlags flags = interactive ? GS_DNF5_TRANSACTION_FLAG_INTERACTIVE : GS_DNF5_TRANSACTION_FLAG_NONE; ++ ++ success = gs_dnf5_run_transaction (self, session_path, rpm_proxy, progress_app, NULL, flags | GS_DNF5_TRANSACTION_FLAG_OFFLINE, NULL, cancellable, error); + + if (success && !download_only) { + g_autofree gchar *op_error_msg = NULL; + gboolean op_success = FALSE; + ++ g_clear_pointer (&options_builder, g_variant_builder_unref); ++ ++ options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ g_variant_builder_add (options_builder, "{sv}", "interactive", ++ g_variant_new_boolean (interactive)); ++ + /* ensure the upgrade is finished with the 'reboot' action */ -+ success = gs_dnf5_offline_call_set_finish_action_sync (offline_proxy, "reboot", &op_success, &op_error_msg, cancellable, error); ++ success = gs_dnf5_offline_call_set_finish_action_with_options_sync (offline_proxy, "reboot", g_variant_builder_end (options_builder), ++ &op_success, &op_error_msg, cancellable, error); + if (success && !op_success) { + success = FALSE; + if (op_error_msg != NULL) { @@ -4207,7 +4655,9 @@ index 000000000..fefad6961 + + gs_app_set_state (data->app, GS_APP_STATE_DOWNLOADING); + -+ if (gs_dnf5_system_upgrade_sync (self, gs_app_get_version (data->app), data->app, TRUE, cancellable, &local_error)) { ++ if (gs_dnf5_system_upgrade_sync (self, gs_app_get_version (data->app), data->app, TRUE, ++ (data->flags & GS_PLUGIN_DOWNLOAD_UPGRADE_FLAGS_INTERACTIVE) != 0, ++ cancellable, &local_error)) { + gs_app_set_state (data->app, GS_APP_STATE_UPDATABLE); + g_task_return_boolean (task, TRUE); + } else { @@ -4275,7 +4725,9 @@ index 000000000..fefad6961 + + gs_app_set_state (data->app, GS_APP_STATE_PENDING_INSTALL); + -+ if (gs_dnf5_system_upgrade_sync (self, gs_app_get_version (data->app), data->app, FALSE, cancellable, &local_error)) { ++ if (gs_dnf5_system_upgrade_sync (self, gs_app_get_version (data->app), data->app, FALSE, ++ (data->flags & GS_PLUGIN_TRIGGER_UPGRADE_FLAGS_INTERACTIVE) != 0, ++ cancellable, &local_error)) { + gs_app_set_state (data->app, GS_APP_STATE_UPDATABLE); + g_task_return_boolean (task, TRUE); + } else { @@ -4465,17 +4917,19 @@ index 000000000..319d5843c +G_END_DECLS diff --git a/plugins/dnf5/meson.build b/plugins/dnf5/meson.build new file mode 100644 -index 000000000..6059a9da1 +index 000000000..12b2137e1 --- /dev/null +++ b/plugins/dnf5/meson.build -@@ -0,0 +1,39 @@ +@@ -0,0 +1,42 @@ +cargs = ['-DG_LOG_DOMAIN="GsDnf5"'] + +dnf5_generated = gnome.gdbus_codegen( + 'gs-dnf5-generated', + sources: [ 'org.rpm.dnf.v0.Advisory.xml', + 'org.rpm.dnf.v0.Base.xml', ++ 'org.rpm.dnf.v0.comps.Group.xml', + 'org.rpm.dnf.v0.Goal.xml', ++ 'org.rpm.dnf.v0.History.xml', + 'org.rpm.dnf.v0.Offline.xml', + 'org.rpm.dnf.v0.rpm.Repo.xml', + 'org.rpm.dnf.v0.rpm.Rpm.xml', @@ -4497,7 +4951,8 @@ index 000000000..6059a9da1 + dnf5_generated, + sources : [ + 'gs-dnf5-progress-helper.c', -+ 'gs-plugin-dnf5.c' ++ 'gs-plugin-dnf5.c', ++ '../packagekit/gs-markdown.c', + ], + include_directories : [ + include_directories('../..'), @@ -4622,10 +5077,10 @@ index 000000000..6aecee9fa + diff --git a/plugins/dnf5/org.rpm.dnf.v0.Base.xml b/plugins/dnf5/org.rpm.dnf.v0.Base.xml new file mode 100644 -index 000000000..dfdc1745a +index 000000000..e596e60b9 --- /dev/null +++ b/plugins/dnf5/org.rpm.dnf.v0.Base.xml -@@ -0,0 +1,153 @@ +@@ -0,0 +1,176 @@ + + @@ -4664,13 +5119,36 @@ index 000000000..dfdc1745a + + + ++ ++ ++ ++ ++ ++ ++ ++ + + @@ -4680,7 +5158,7 @@ index 000000000..dfdc1745a + + @@ -4883,7 +5365,7 @@ index 000000000..f1ba08953 + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ diff --git a/plugins/dnf5/org.rpm.dnf.v0.Offline.xml b/plugins/dnf5/org.rpm.dnf.v0.Offline.xml new file mode 100644 -index 000000000..083b5b17c +index 000000000..8d84c22aa --- /dev/null +++ b/plugins/dnf5/org.rpm.dnf.v0.Offline.xml -@@ -0,0 +1,82 @@ +@@ -0,0 +1,151 @@ + + @@ -4948,6 +5520,25 @@ index 000000000..083b5b17c + + + ++ ++ ++ ++ ++ ++ + + + + @@ -4962,13 +5555,58 @@ index 000000000..083b5b17c + + + ++ ++ ++ ++ ++ ++ + ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + @@ -4981,6 +5619,9 @@ index 000000000..083b5b17c + + Set the action that should be performed after the offline transaction is applied. If the `action` is "poweroff", the system will be powered off, otherwise it will be rebooted (which is default). + The call might fail in case there is no scheduled offline transaction, or the transaction was not scheduled using libdnf5. ++ ++ ++ This is equivalent to call "set_finish_action_with_options()" with empty options. + --> + + @@ -5066,12 +5707,79 @@ index 000000000..a0facd692 + + + +diff --git a/plugins/dnf5/org.rpm.dnf.v0.comps.Group.xml b/plugins/dnf5/org.rpm.dnf.v0.comps.Group.xml +new file mode 100644 +index 000000000..b12e0ac6d +--- /dev/null ++++ b/plugins/dnf5/org.rpm.dnf.v0.comps.Group.xml +@@ -0,0 +1,61 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ diff --git a/plugins/dnf5/org.rpm.dnf.v0.rpm.Repo.xml b/plugins/dnf5/org.rpm.dnf.v0.rpm.Repo.xml new file mode 100644 -index 000000000..13c4cf1f8 +index 000000000..50b2ba3bf --- /dev/null +++ b/plugins/dnf5/org.rpm.dnf.v0.rpm.Repo.xml -@@ -0,0 +1,85 @@ +@@ -0,0 +1,147 @@ + + @@ -5123,11 +5831,33 @@ index 000000000..13c4cf1f8 + + + ++ ++ ++ ++ ++ ++ ++ + + @@ -5135,20 +5865,60 @@ index 000000000..13c4cf1f8 + + + ++ ++ ++ ++ ++ ++ + + + + + ++ ++ ++ ++ ++ ++ + + @@ -5159,10 +5929,10 @@ index 000000000..13c4cf1f8 + diff --git a/plugins/dnf5/org.rpm.dnf.v0.rpm.Rpm.xml b/plugins/dnf5/org.rpm.dnf.v0.rpm.Rpm.xml new file mode 100644 -index 000000000..5df68cd91 +index 000000000..f24b14d39 --- /dev/null +++ b/plugins/dnf5/org.rpm.dnf.v0.rpm.Rpm.xml -@@ -0,0 +1,468 @@ +@@ -0,0 +1,470 @@ + + @@ -5388,6 +6158,8 @@ index 000000000..5df68cd91 + + - mode: string (one of "distrosync", "upgrade", default is "distrosync") + By default the system_upgrade behaves like `dnf distro-sync`, always installing packages from the new release, even if they are older than the currently installed version. If set to "upgrade", packages from the new release are not installed if they are older than what is currently installed (behave like `dnf upgrade`). ++ - interactive: boolean, default true ++ Set to "true", when the operation is done by a user, thus user interaction like password prompts can be done. + + Unknown options are ignored. + --> diff --git a/gnome-software.spec b/gnome-software.spec index 198e7c9..10c8d74 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -7,6 +7,7 @@ %global libadwaita_version 1.6.0 %global libxmlb_version 0.3.4 %global packagekit_version 1.2.5 +%global dnf5_version 5.2.16 # Disable WebApps for RHEL builds %bcond webapps %[!0%{?rhel}] @@ -29,7 +30,7 @@ Name: gnome-software Version: 49~beta -Release: 2%{?dist} +Release: 3%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -91,7 +92,7 @@ Requires: appstream%{?_isa} >= %{appstream_version} Requires: epiphany-runtime%{?_isa} %endif %if %{with dnf5} -Requires: dnf5daemon-server%{?_isa} +Requires: dnf5daemon-server%{?_isa} >= %{dnf5_version} Requires: dnf5daemon-server-polkit Requires: libdnf5-plugin-appstream%{?_isa} Requires: rpm-plugin-dbus-announce%{?_isa} From eaee792f9f386eb90797895cb9f6637e2b0ff6bc Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Wed, 13 Aug 2025 18:32:50 +0200 Subject: [PATCH 105/116] dnf5-plugin: Auto-accept new RPM keys --- 0001-dnf5-plugin.patch | 12 +++++++----- gnome-software.spec | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/0001-dnf5-plugin.patch b/0001-dnf5-plugin.patch index 3e9a13f..0ba8881 100644 --- a/0001-dnf5-plugin.patch +++ b/0001-dnf5-plugin.patch @@ -1,5 +1,5 @@ -at commit 8a1f0ca6564157dd688c84ffd25af9747c1e038e -Date: Mon Aug 11 17:07:06 2025 +0200 +at commit d7f516e25742e1c0631194df5829bf73668f7df5 +Date: Wed Aug 13 18:23:59 2025 +0200 diff --git a/meson_options.txt b/meson_options.txt index cd49cf529..27fa15e8b 100644 @@ -610,10 +610,10 @@ index 000000000..5d522468c +G_END_DECLS diff --git a/plugins/dnf5/gs-plugin-dnf5.c b/plugins/dnf5/gs-plugin-dnf5.c new file mode 100644 -index 000000000..88d7e25d8 +index 000000000..36d10163a --- /dev/null +++ b/plugins/dnf5/gs-plugin-dnf5.c -@@ -0,0 +1,4275 @@ +@@ -0,0 +1,4277 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * vi:set noexpandtab tabstop=8 shiftwidth=8: + * @@ -1702,7 +1702,9 @@ index 000000000..88d7e25d8 + g_autoptr(GVariantBuilder) options_builder = NULL; + gboolean confirmed; + -+ confirmed = gs_plugin_ask_untrusted (GS_PLUGIN (data->self), data->title, data->msg, data->details, data->accept_label); ++ /* auto-accept new keys, just as PacakgeKit plugin used to do */ ++ confirmed = TRUE; ++ /* confirmed = gs_plugin_ask_untrusted (GS_PLUGIN (data->self), data->title, data->msg, data->details, data->accept_label); */ + + options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (options_builder, "{sv}", "interactive", diff --git a/gnome-software.spec b/gnome-software.spec index 10c8d74..21466da 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -30,7 +30,7 @@ Name: gnome-software Version: 49~beta -Release: 3%{?dist} +Release: 4%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later From 446ce42aa8d01622a25810693ed527f115afddbe Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 25 Aug 2025 12:05:46 +0200 Subject: [PATCH 106/116] dnf5-plugin: Auto-accept new RPM keys only when installed from repos - dnf5-plugin: Download offline updates also by regular users --- 0001-dnf5-plugin.patch | 327 +++++++++++++++++++++++++++++++++++++++-- gnome-software.spec | 2 +- 2 files changed, 317 insertions(+), 12 deletions(-) diff --git a/0001-dnf5-plugin.patch b/0001-dnf5-plugin.patch index 0ba8881..088ad51 100644 --- a/0001-dnf5-plugin.patch +++ b/0001-dnf5-plugin.patch @@ -1,5 +1,5 @@ -at commit d7f516e25742e1c0631194df5829bf73668f7df5 -Date: Wed Aug 13 18:23:59 2025 +0200 +at commit 55ca6d4d49d5edd682b8ca15904ec556eb5d0874 +Date: Tue Aug 19 13:13:48 2025 +0200 diff --git a/meson_options.txt b/meson_options.txt index cd49cf529..27fa15e8b 100644 @@ -610,10 +610,10 @@ index 000000000..5d522468c +G_END_DECLS diff --git a/plugins/dnf5/gs-plugin-dnf5.c b/plugins/dnf5/gs-plugin-dnf5.c new file mode 100644 -index 000000000..36d10163a +index 000000000..c8d9ed83d --- /dev/null +++ b/plugins/dnf5/gs-plugin-dnf5.c -@@ -0,0 +1,4277 @@ +@@ -0,0 +1,4582 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * vi:set noexpandtab tabstop=8 shiftwidth=8: + * @@ -1671,9 +1671,13 @@ index 000000000..36d10163a + gchar *details; + gchar *accept_label; + gchar *key_id; ++ gchar *key_filename; ++ gchar *session_path; ++ GCancellable *cancellable; /* (owned) */ + GsPluginDnf5 *self; /* (owned) */ + GWeakRef repo_proxy_weakref; /* GsDnf5RpmRepo */ + gboolean interactive; ++ gboolean confirmed_by_repo; +} QuestionData; + +static void @@ -1685,6 +1689,9 @@ index 000000000..36d10163a + g_free (data->details); + g_free (data->accept_label); + g_free (data->key_id); ++ g_free (data->key_filename); ++ g_free (data->session_path); ++ g_clear_object (&data->cancellable); + g_clear_object (&data->self); + g_weak_ref_clear (&data->repo_proxy_weakref); + g_free (data); @@ -1703,8 +1710,9 @@ index 000000000..36d10163a + gboolean confirmed; + + /* auto-accept new keys, just as PacakgeKit plugin used to do */ -+ confirmed = TRUE; -+ /* confirmed = gs_plugin_ask_untrusted (GS_PLUGIN (data->self), data->title, data->msg, data->details, data->accept_label); */ ++ confirmed = data->confirmed_by_repo; ++ if (!confirmed) ++ confirmed = gs_plugin_ask_untrusted (GS_PLUGIN (data->self), data->title, data->msg, data->details, data->accept_label); + + options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (options_builder, "{sv}", "interactive", @@ -1714,7 +1722,7 @@ index 000000000..36d10163a + data->key_id, + confirmed, + g_variant_builder_end (options_builder), -+ NULL, ++ data->cancellable, + gs_dnf5_confirm_key_response_cb, + NULL); + } @@ -1722,10 +1730,184 @@ index 000000000..36d10163a + return G_SOURCE_REMOVE; +} + ++static gboolean ++gs_dnf5_read_package_repo_ids_cb (GsPluginDnf5 *self, ++ GVariant *package_array, ++ gpointer user_data, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ GPtrArray **out_repo_ids = user_data; ++ g_autoptr(GVariantDict) dict = NULL; ++ g_autoptr(GVariant) value = NULL; ++ ++ dict = g_variant_dict_new (package_array); ++ ++ value = g_variant_dict_lookup_value (dict, "from_repo_id", G_VARIANT_TYPE_STRING); ++ if (value != NULL) { ++ const gchar *repo_id_const = g_variant_get_string (value, NULL); ++ if (repo_id_const != NULL && *repo_id_const != '\0') { ++ if (*out_repo_ids == NULL) ++ *out_repo_ids = g_ptr_array_new_with_free_func (g_free); ++ g_ptr_array_add (*out_repo_ids, g_strdup (repo_id_const)); ++ } ++ } ++ ++ return TRUE; ++} ++ ++static gboolean ++gs_dnf5_read_repo_gpg_info_cb (GsPluginDnf5 *self, ++ GVariant *package_array, ++ gpointer user_data, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ guint *out_n_good = user_data; ++ g_autoptr(GVariantDict) dict = NULL; ++ g_autoptr(GVariant) id_value = NULL; ++ g_autoptr(GVariant) gpgcheck_value = NULL; ++ ++ dict = g_variant_dict_new (package_array); ++ ++ id_value = g_variant_dict_lookup_value (dict, "id", G_VARIANT_TYPE_STRING); ++ gpgcheck_value = g_variant_dict_lookup_value (dict, "gpgcheck", G_VARIANT_TYPE_BOOLEAN); ++ ++ if (id_value != NULL && gpgcheck_value != NULL) { ++ gboolean gpgcheck = g_variant_get_boolean (gpgcheck_value); ++ ++ if (gpgcheck) ++ *out_n_good = (*out_n_good) + 1; ++ } ++ ++ return TRUE; ++} ++ ++static gpointer ++gs_dnf5_check_key_source_thread (gpointer user_data) ++{ ++ QuestionData *data = user_data; ++ g_autoptr(GsDnf5RpmRpm) rpm_proxy = NULL; ++ g_autoptr(GPtrArray) repo_ids = NULL; ++ g_autoptr(GError) local_error = NULL; ++ gboolean success; ++ ++ rpm_proxy = gs_dnf5_rpm_rpm_proxy_new_sync (data->self->connection, ++ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, ++ GS_DNF5_INTERFACE_RPM_DNF, ++ data->session_path, ++ data->cancellable, ++ &local_error); ++ success = rpm_proxy != NULL; ++ if (!success) { ++ gs_dnf5_convert_error (&local_error); ++ g_prefix_error_literal (&local_error, "Failed to create Rpm proxy: "); ++ } ++ ++ /* try to get whether the key comes from any package */ ++ if (success) { ++ g_autoptr(GVariantBuilder) options_builder = NULL; ++ g_autoptr(GVariantBuilder) package_attrs_builder = NULL; ++ g_autoptr(GVariantBuilder) whatprovides_builder = NULL; ++ g_autoptr(GVariant) result = NULL; ++ ++ g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (rpm_proxy), G_MAXINT); ++ ++ package_attrs_builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); ++ g_variant_builder_add (package_attrs_builder, "s", "from_repo_id"); ++ ++ whatprovides_builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); ++ g_variant_builder_add (whatprovides_builder, "s", data->key_filename); ++ ++ options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ g_variant_builder_add (options_builder, "{sv}", "package_attrs", ++ g_variant_builder_end (package_attrs_builder)); ++ g_variant_builder_add (options_builder, "{sv}", "whatprovides", ++ g_variant_builder_end (whatprovides_builder)); ++ g_variant_builder_add (options_builder, "{sv}", "scope", ++ g_variant_new_string ("installed")); ++ ++ success = gs_dnf5_rpm_rpm_call_list_sync (rpm_proxy, ++ g_variant_builder_end (options_builder), ++ &result, ++ data->cancellable, ++ &local_error); ++ ++ if (success) { ++ success = gs_dnf5_foreach_item (data->self, result, gs_dnf5_read_package_repo_ids_cb, &repo_ids, data->cancellable, &local_error); ++ } else { ++ gs_dnf5_convert_error (&local_error); ++ g_prefix_error_literal (&local_error, "Failed to call rpm::list: "); ++ } ++ } ++ ++ if (success && repo_ids != NULL) { ++ g_autoptr(GVariantBuilder) patterns_builder = NULL; ++ guint n_verify = 0; ++ ++ for (guint i = 0; i < repo_ids->len; i++) { ++ const gchar *repo_id = g_ptr_array_index (repo_ids, i); ++ /* those are special repos, like `@commandline` */ ++ if (*repo_id != '@') { ++ if (patterns_builder == NULL) ++ patterns_builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); ++ g_variant_builder_add (patterns_builder, "s", repo_id); ++ n_verify++; ++ } ++ } ++ ++ if (patterns_builder != NULL) { ++ g_autoptr(GsDnf5RpmRepo) repo_proxy = NULL; ++ ++ repo_proxy = g_weak_ref_get (&data->repo_proxy_weakref); ++ if (repo_proxy != NULL) { ++ g_autoptr(GVariantBuilder) repo_attrs_builder = NULL; ++ g_autoptr(GVariantBuilder) options_builder = NULL; ++ g_autoptr(GVariant) result = NULL; ++ ++ repo_attrs_builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); ++ g_variant_builder_add (repo_attrs_builder, "s", "id"); ++ g_variant_builder_add (repo_attrs_builder, "s", "gpgcheck"); ++ ++ options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ g_variant_builder_add (options_builder, "{sv}", "patterns", ++ g_variant_builder_end (patterns_builder)); ++ g_variant_builder_add (options_builder, "{sv}", "repo_attrs", ++ g_variant_builder_end (repo_attrs_builder)); ++ ++ success = gs_dnf5_rpm_repo_call_list_sync (repo_proxy, ++ g_variant_builder_end (options_builder), ++ &result, ++ data->cancellable, ++ &local_error); ++ ++ if (success) { ++ guint n_good = 0; ++ ++ success = gs_dnf5_foreach_item (data->self, result, gs_dnf5_read_repo_gpg_info_cb, &n_good, data->cancellable, &local_error); ++ ++ data->confirmed_by_repo = success && n_verify == n_good; ++ } else { ++ gs_dnf5_convert_error (&local_error); ++ g_prefix_error_literal (&local_error, "Failed to call repo::list: "); ++ } ++ } else { ++ success = FALSE; ++ g_set_error_literal (&local_error, G_IO_ERROR, G_IO_ERROR_FAILED, "Repo proxy vanished"); ++ } ++ } ++ } ++ ++ g_idle_add_full (G_PRIORITY_HIGH_IDLE, gs_dnf5_ask_question_idle_cb, data, (GDestroyNotify) question_data_free); ++ ++ return NULL; ++} ++ +typedef struct { + GsPluginDnf5 *self; /* (not owned) */ + const gchar *session_path; /* (not owned) */ + GsDnf5RpmRepo *repo_proxy; /* (not owned) */ ++ GCancellable *cancellable; /* (not owned) */ + gboolean interactive; +} RepoKeyImportData; + @@ -1800,11 +1982,18 @@ index 000000000..36d10163a + data->details = g_string_free (details, FALSE); + data->accept_label = g_strdup (_("_Import Key")); + data->key_id = g_strdup (arg_key_id); ++ data->key_filename = g_steal_pointer (&key_filename); ++ data->session_path = g_strdup (repo_key_import_data->session_path); + data->self = g_object_ref (repo_key_import_data->self); + data->interactive = repo_key_import_data->interactive; ++ data->confirmed_by_repo = FALSE; ++ g_set_object (&data->cancellable, repo_key_import_data->cancellable); + g_weak_ref_init (&data->repo_proxy_weakref, repo_key_import_data->repo_proxy); + -+ g_idle_add_full (G_PRIORITY_HIGH_IDLE, gs_dnf5_ask_question_idle_cb, data, (GDestroyNotify) question_data_free); ++ if (data->key_filename != NULL) ++ g_thread_unref (g_thread_new ("gs-dnf5-check-key-source_thread", gs_dnf5_check_key_source_thread, data)); ++ else ++ g_idle_add_full (G_PRIORITY_HIGH_IDLE, gs_dnf5_ask_question_idle_cb, data, (GDestroyNotify) question_data_free); +} + +static void @@ -1886,7 +2075,8 @@ index 000000000..36d10163a + GS_DNF5_TRANSACTION_FLAG_OFFLINE = 1 << 0, + GS_DNF5_TRANSACTION_FLAG_RESOLVE_ONLY = 1 << 1, + GS_DNF5_TRANSACTION_FLAG_DISALLOW_ERASING = 1 << 2, /* negative flag, to not have it everywhere */ -+ GS_DNF5_TRANSACTION_FLAG_INTERACTIVE = 1 << 3 ++ GS_DNF5_TRANSACTION_FLAG_INTERACTIVE = 1 << 3, ++ GS_DNF5_TRANSACTION_FLAG_DOWNLOAD_ONLY = 1 << 4 +} GsDnf5TransactionFlags; + +static gboolean @@ -1965,6 +2155,7 @@ index 000000000..36d10163a + repo_key_import_data.session_path = session_path; + repo_key_import_data.repo_proxy = repo_proxy; + repo_key_import_data.interactive = interactive; ++ repo_key_import_data.cancellable = cancellable; + repo_key_import_id = g_signal_connect (base_proxy, "repo_key_import_request", + G_CALLBACK (gs_dnf5_repo_key_import_request_cb), &repo_key_import_data); + @@ -2017,6 +2208,10 @@ index 000000000..36d10163a + g_variant_builder_add (options_builder, "{sv}", "offline", + g_variant_new_boolean (TRUE)); + } ++ if ((flags & GS_DNF5_TRANSACTION_FLAG_DOWNLOAD_ONLY) != 0) { ++ g_variant_builder_add (options_builder, "{sv}", "downloadonly", ++ g_variant_new_boolean (TRUE)); ++ } + g_variant_builder_add (options_builder, "{sv}", "interactive", + g_variant_new_boolean (interactive)); + @@ -3576,6 +3771,7 @@ index 000000000..36d10163a + GsAppList *list, + gboolean is_install, + gboolean interactive, ++ gboolean can_apply, + GsPluginEventCallback event_callback, + void *event_user_data, + GCancellable *cancellable, @@ -3700,7 +3896,8 @@ index 000000000..36d10163a + success = rpm_proxy != NULL; + if (success) { + g_autoptr(GVariantBuilder) options_builder = NULL; -+ GsDnf5TransactionFlags flags = interactive ? GS_DNF5_TRANSACTION_FLAG_INTERACTIVE : GS_DNF5_TRANSACTION_FLAG_NONE; ++ GsDnf5TransactionFlags flags = (interactive ? GS_DNF5_TRANSACTION_FLAG_INTERACTIVE : GS_DNF5_TRANSACTION_FLAG_NONE) | ++ (!can_apply ? GS_DNF5_TRANSACTION_FLAG_DOWNLOAD_ONLY : GS_DNF5_TRANSACTION_FLAG_NONE); + + g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (rpm_proxy), G_MAXINT); + @@ -3732,7 +3929,7 @@ index 000000000..36d10163a + success = success && gs_dnf5_run_transaction (self, session_path, rpm_proxy, progress_app, progress_list, + flags | (is_install ? 0 : GS_DNF5_TRANSACTION_FLAG_OFFLINE), + NULL, cancellable, error); -+ if (success && !is_install) { ++ if (success && !is_install && can_apply) { + /* ensure the update is finished with the 'reboot' action */ + g_autoptr(GsDnf5Offline) offline_proxy = NULL; + @@ -3852,6 +4049,7 @@ index 000000000..36d10163a + + success = gs_dnf5_install_update (plugin, data->apps, TRUE, + (data->flags & GS_PLUGIN_INSTALL_APPS_FLAGS_INTERACTIVE) != 0, ++ (data->flags & GS_PLUGIN_INSTALL_APPS_FLAGS_NO_APPLY) == 0, + data->event_callback, data->event_user_data, + cancellable, &local_error); + @@ -4095,6 +4293,7 @@ index 000000000..36d10163a + + success = gs_dnf5_install_update (plugin, data->apps, FALSE, + (data->flags & GS_PLUGIN_UPDATE_APPS_FLAGS_INTERACTIVE) != 0, ++ (data->flags & GS_PLUGIN_UPDATE_APPS_FLAGS_NO_APPLY) == 0, + data->event_callback, data->event_user_data, + cancellable, &local_error); + @@ -4780,6 +4979,110 @@ index 000000000..36d10163a + return g_task_propagate_boolean (G_TASK (result), error); +} + ++/* Run in @worker. */ ++static void ++gs_dnf5_cancel_offline_update_thread_cb (GTask *task, ++ gpointer source_object, ++ gpointer task_data, ++ GCancellable *cancellable) ++{ ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (source_object); ++ GsPluginCancelOfflineUpdateData *data = task_data; ++ g_autofree gchar *session_path = NULL; ++ g_autoptr(GsAppList) list = NULL; ++ g_autoptr(GsDnf5SessionManager) session_manager = NULL; ++ g_autoptr(GsDnf5Offline) offline_proxy = NULL; ++ gboolean success; ++ g_autoptr(GError) local_error = NULL; ++ ++ assert_in_worker (self); ++ ++ session_path = gs_dnf5_open_session (self, GS_DNF5_RELEASEVER_DEFAULT, &session_manager, cancellable, &local_error); ++ if (session_path == NULL) { ++ gs_dnf5_convert_error (&local_error); ++ g_task_return_error (task, g_steal_pointer (&local_error)); ++ return; ++ } ++ ++ offline_proxy = gs_dnf5_offline_proxy_new_sync (self->connection, ++ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, ++ GS_DNF5_INTERFACE_RPM_DNF, ++ session_path, ++ cancellable, ++ &local_error); ++ success = offline_proxy != NULL; ++ if (!success) { ++ gs_dnf5_convert_error (&local_error); ++ g_prefix_error_literal (&local_error, "Failed to create Offline proxy: "); ++ } ++ ++ if (success) { ++ gboolean pending = FALSE; ++ g_autoptr(GVariant) transaction_status = NULL; ++ ++ if (gs_dnf5_offline_call_get_status_sync (offline_proxy, &pending, &transaction_status, cancellable, &local_error) && ++ pending && transaction_status != NULL) { ++ g_autoptr(GVariantBuilder) options_builder = NULL; ++ g_autofree gchar *op_error_msg = NULL; ++ gboolean op_success = FALSE; ++ ++ options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ g_variant_builder_add (options_builder, "{sv}", "interactive", ++ g_variant_new_boolean ((data->flags & GS_PLUGIN_CANCEL_OFFLINE_UPDATE_FLAGS_INTERACTIVE) != 0)); ++ ++ success = gs_dnf5_offline_call_cancel_with_options_sync (offline_proxy, g_variant_builder_end (options_builder), ++ &op_success, &op_error_msg, cancellable, &local_error); ++ if (!success) { ++ gs_dnf5_convert_error (&local_error); ++ g_prefix_error_literal (&local_error, "Failed to call OfflineProxy::cancel: "); ++ } else if (!op_success) { ++ success = FALSE; ++ if (op_error_msg != NULL) { ++ g_set_error_literal (&local_error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, op_error_msg); ++ g_prefix_error_literal (&local_error, "Failed to call OfflineProxy::cancel op: "); ++ } else { ++ g_set_error_literal (&local_error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "Failed to call OfflineProxy::cancel op"); ++ } ++ } ++ } ++ } ++ ++ gs_dnf5_close_session (self, session_manager, session_path); ++ ++ if (success) { ++ g_task_return_boolean (task, TRUE); ++ } else { ++ gs_dnf5_convert_error (&local_error); ++ g_task_return_error (task, g_steal_pointer (&local_error)); ++ } ++} ++ ++static void ++gs_plugin_dnf5_cancel_offline_update_async (GsPlugin *plugin, ++ GsPluginCancelOfflineUpdateFlags flags, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ GsPluginDnf5 *self = GS_PLUGIN_DNF5 (plugin); ++ g_autoptr(GTask) task = NULL; ++ gboolean interactive = (flags & GS_PLUGIN_CANCEL_OFFLINE_UPDATE_FLAGS_INTERACTIVE) != 0; ++ ++ task = gs_plugin_cancel_offline_update_data_new_task (plugin, flags, cancellable, callback, user_data); ++ g_task_set_source_tag (task, gs_plugin_dnf5_cancel_offline_update_async); ++ ++ gs_worker_thread_queue (self->worker, gs_dnf5_get_priority_for_interactivity (interactive), ++ gs_dnf5_cancel_offline_update_thread_cb, g_steal_pointer (&task)); ++} ++ ++static gboolean ++gs_plugin_dnf5_cancel_offline_update_finish (GsPlugin *plugin, ++ GAsyncResult *result, ++ GError **error) ++{ ++ return g_task_propagate_boolean (G_TASK (result), error); ++} ++ +static void +gs_plugin_dnf5_dispose (GObject *object) +{ @@ -4865,6 +5168,8 @@ index 000000000..36d10163a + plugin_class->download_upgrade_finish = gs_plugin_dnf5_download_upgrade_finish; + plugin_class->trigger_upgrade_async = gs_plugin_dnf5_trigger_upgrade_async; + plugin_class->trigger_upgrade_finish = gs_plugin_dnf5_trigger_upgrade_finish; ++ plugin_class->cancel_offline_update_async = gs_plugin_dnf5_cancel_offline_update_async; ++ plugin_class->cancel_offline_update_finish = gs_plugin_dnf5_cancel_offline_update_finish; +} + +static void diff --git a/gnome-software.spec b/gnome-software.spec index 21466da..2cce046 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -30,7 +30,7 @@ Name: gnome-software Version: 49~beta -Release: 4%{?dist} +Release: 5%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later From e95633c7038667767acefda20b67d7f50d928c98 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Tue, 26 Aug 2025 19:02:10 +0200 Subject: [PATCH 107/116] dnf5-plugin: Skip historical updates search when no last date is set --- 0001-dnf5-plugin.patch | 97 ++++++++++++++++++++++-------------------- gnome-software.spec | 2 +- 2 files changed, 53 insertions(+), 46 deletions(-) diff --git a/0001-dnf5-plugin.patch b/0001-dnf5-plugin.patch index 088ad51..43864c1 100644 --- a/0001-dnf5-plugin.patch +++ b/0001-dnf5-plugin.patch @@ -1,5 +1,5 @@ -at commit 55ca6d4d49d5edd682b8ca15904ec556eb5d0874 -Date: Tue Aug 19 13:13:48 2025 +0200 +at commit 73640bc9127fb2200189433f935445208bf0b472 +Date: Tue Aug 26 18:59:16 2025 +0200 diff --git a/meson_options.txt b/meson_options.txt index cd49cf529..27fa15e8b 100644 @@ -610,10 +610,10 @@ index 000000000..5d522468c +G_END_DECLS diff --git a/plugins/dnf5/gs-plugin-dnf5.c b/plugins/dnf5/gs-plugin-dnf5.c new file mode 100644 -index 000000000..c8d9ed83d +index 000000000..b9b698a81 --- /dev/null +++ b/plugins/dnf5/gs-plugin-dnf5.c -@@ -0,0 +1,4582 @@ +@@ -0,0 +1,4589 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * vi:set noexpandtab tabstop=8 shiftwidth=8: + * @@ -2767,55 +2767,62 @@ index 000000000..c8d9ed83d + g_prefix_error_literal (&local_error, "Failed to call Rpm::list: "); + } + } else if (is_historical_update == GS_APP_QUERY_TRISTATE_TRUE) { -+ g_autoptr(GsDnf5History) history_proxy = NULL; ++ g_autoptr(GSettings) settings = NULL; ++ gint64 timestamp; ++ gboolean interactive = (data->flags & GS_PLUGIN_LIST_APPS_FLAGS_INTERACTIVE) != 0; + -+ history_proxy = gs_dnf5_history_proxy_new_sync (self->connection, -+ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, -+ GS_DNF5_INTERFACE_RPM_DNF, -+ session_path, -+ cancellable, -+ &local_error); -+ success = history_proxy != NULL; -+ if (!success) { -+ gs_dnf5_convert_error (&local_error); -+ g_prefix_error_literal (&local_error, "Failed to create History proxy: "); -+ } ++ /* use the option the GUI part uses */ ++ settings = g_settings_new ("org.gnome.software"); ++ timestamp = g_settings_get_int64 (settings, "install-timestamp"); + -+ if (success) { -+ g_autoptr(GVariantBuilder) options_builder = NULL; -+ g_autoptr(GVariant) result = NULL; -+ g_autoptr(GSettings) settings; -+ gint64 timestamp; ++ if (timestamp > 0 || interactive) { ++ g_autoptr(GsDnf5History) history_proxy = NULL; + -+ /* use the option the GUI part uses */ -+ settings = g_settings_new ("org.gnome.software"); -+ timestamp = g_settings_get_int64 (settings, "install-timestamp"); -+ -+ options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); -+ g_variant_builder_add (options_builder, "{sv}", "since", -+ g_variant_new_int64 (timestamp)); -+ g_variant_builder_add (options_builder, "{sv}", "package_attrs", -+ gs_dnf5_dup_package_attrs ()); -+ -+ success = gs_dnf5_history_call_recent_changes_sync (history_proxy, -+ g_variant_builder_end (options_builder), -+ &result, -+ cancellable, -+ &local_error); ++ history_proxy = gs_dnf5_history_proxy_new_sync (self->connection, ++ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, ++ GS_DNF5_INTERFACE_RPM_DNF, ++ session_path, ++ cancellable, ++ &local_error); ++ success = history_proxy != NULL; ++ if (!success) { ++ gs_dnf5_convert_error (&local_error); ++ g_prefix_error_literal (&local_error, "Failed to create History proxy: "); ++ } + + if (success) { -+ ReadPackageData rpd = { 0, }; ++ g_autoptr(GVariantBuilder) options_builder = NULL; ++ g_autoptr(GVariant) result = NULL; + -+ rpd.list = list; -+ rpd.set_state = GS_APP_STATE_UNKNOWN; -+ rpd.nevra_to_app = NULL; -+ rpd.timestamp = timestamp; ++ options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); ++ g_variant_builder_add (options_builder, "{sv}", "since", ++ g_variant_new_int64 (timestamp)); ++ g_variant_builder_add (options_builder, "{sv}", "package_attrs", ++ gs_dnf5_dup_package_attrs ()); + -+ success = gs_dnf5_foreach_item (self, result, gs_dnf5_read_history_items_cb, &rpd, cancellable, &local_error); -+ } else { -+ gs_dnf5_convert_error (&local_error); -+ g_prefix_error_literal (&local_error, "Failed to call recent_changes: "); ++ success = gs_dnf5_history_call_recent_changes_sync (history_proxy, ++ g_variant_builder_end (options_builder), ++ &result, ++ cancellable, ++ &local_error); ++ ++ if (success) { ++ ReadPackageData rpd = { 0, }; ++ ++ rpd.list = list; ++ rpd.set_state = GS_APP_STATE_UNKNOWN; ++ rpd.nevra_to_app = NULL; ++ rpd.timestamp = timestamp; ++ ++ success = gs_dnf5_foreach_item (self, result, gs_dnf5_read_history_items_cb, &rpd, cancellable, &local_error); ++ } else { ++ gs_dnf5_convert_error (&local_error); ++ g_prefix_error_literal (&local_error, "Failed to call recent_changes: "); ++ } + } ++ } else { ++ /* initialize the value to today */ ++ g_settings_set (settings, "install-timestamp", "x", g_get_real_time () / G_USEC_PER_SEC); + } + } else if (gs_component_kind_array_contains (component_kinds, AS_COMPONENT_KIND_REPOSITORY)) { + g_autoptr(GsDnf5RpmRepo) repo_proxy = NULL; diff --git a/gnome-software.spec b/gnome-software.spec index 2cce046..ad7833b 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -30,7 +30,7 @@ Name: gnome-software Version: 49~beta -Release: 5%{?dist} +Release: 6%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later From 4a71393113c82fe2afd330153fd30851504aa0da Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 29 Aug 2025 09:11:51 +0200 Subject: [PATCH 108/116] Update to 49.rc --- gnome-software.spec | 4 ++-- sources | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index ad7833b..c6f4ac8 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -29,8 +29,8 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 49~beta -Release: 6%{?dist} +Version: 49~rc +Release: 1%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later diff --git a/sources b/sources index f212fbd..c3ec757 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-49.beta.tar.xz) = 9cb6d67216193840b2661871ef43da5e726a284d1164781f13423ee8dd86359334f199efc29f4b3a0b3eddfa8a3811d7dd38cd412fa53aaebb2e1c35ddc1f9df +SHA512 (gnome-software-49.rc.tar.xz) = cecebbff1163f0179c5699ecc8325e2c4f68c811ec7633e6cf32e18ad2f03592b55daa16b9b5497a117cbfbf63f3d9162dd8e8191e6a6213d35261fa1bad15a5 From 90da5737b3044a752d2f4d7ebc5513123b46113d Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 1 Sep 2025 18:28:21 +0200 Subject: [PATCH 109/116] Resolves: #2392057 (dnf5-pugin: No update notifications shown) --- 0001-dnf5-plugin.patch | 18 +++++++++--------- gnome-software.spec | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/0001-dnf5-plugin.patch b/0001-dnf5-plugin.patch index 43864c1..3b4b355 100644 --- a/0001-dnf5-plugin.patch +++ b/0001-dnf5-plugin.patch @@ -1,5 +1,5 @@ -at commit 73640bc9127fb2200189433f935445208bf0b472 -Date: Tue Aug 26 18:59:16 2025 +0200 +at commit 786bab5f1928920251ee9e93d51953ff9dd9faa4 +Date: Mon Sep 1 18:23:09 2025 +0200 diff --git a/meson_options.txt b/meson_options.txt index cd49cf529..27fa15e8b 100644 @@ -610,7 +610,7 @@ index 000000000..5d522468c +G_END_DECLS diff --git a/plugins/dnf5/gs-plugin-dnf5.c b/plugins/dnf5/gs-plugin-dnf5.c new file mode 100644 -index 000000000..b9b698a81 +index 000000000..82f3e19a8 --- /dev/null +++ b/plugins/dnf5/gs-plugin-dnf5.c @@ -0,0 +1,4589 @@ @@ -2769,13 +2769,12 @@ index 000000000..b9b698a81 + } else if (is_historical_update == GS_APP_QUERY_TRISTATE_TRUE) { + g_autoptr(GSettings) settings = NULL; + gint64 timestamp; -+ gboolean interactive = (data->flags & GS_PLUGIN_LIST_APPS_FLAGS_INTERACTIVE) != 0; + + /* use the option the GUI part uses */ + settings = g_settings_new ("org.gnome.software"); -+ timestamp = g_settings_get_int64 (settings, "install-timestamp"); ++ timestamp = (gint64) g_settings_get_uint64 (settings, "packagekit-historical-updates-timestamp"); + -+ if (timestamp > 0 || interactive) { ++ if (timestamp > 0) { + g_autoptr(GsDnf5History) history_proxy = NULL; + + history_proxy = gs_dnf5_history_proxy_new_sync (self->connection, @@ -2820,9 +2819,6 @@ index 000000000..b9b698a81 + g_prefix_error_literal (&local_error, "Failed to call recent_changes: "); + } + } -+ } else { -+ /* initialize the value to today */ -+ g_settings_set (settings, "install-timestamp", "x", g_get_real_time () / G_USEC_PER_SEC); + } + } else if (gs_component_kind_array_contains (component_kinds, AS_COMPONENT_KIND_REPOSITORY)) { + g_autoptr(GsDnf5RpmRepo) repo_proxy = NULL; @@ -3973,6 +3969,10 @@ index 000000000..b9b698a81 + } else if (!success) { + gs_dnf5_convert_error (error); + g_prefix_error_literal (error, "Failed to set finish action: "); ++ } else { ++ g_autoptr(GSettings) settings = g_settings_new ("org.gnome.software"); ++ /* to check anything installed/updated after today */ ++ g_settings_set (settings, "packagekit-historical-updates-timestamp", "t", g_get_real_time () / G_USEC_PER_SEC); + } + } else { + gs_dnf5_convert_error (error); diff --git a/gnome-software.spec b/gnome-software.spec index c6f4ac8..09c8546 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -30,7 +30,7 @@ Name: gnome-software Version: 49~rc -Release: 1%{?dist} +Release: 2%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later From ac8dbc92e832cb6c72963e90cd49f7d92a6b05ee Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 12 Sep 2025 10:01:34 +0200 Subject: [PATCH 110/116] Update to 49.0 --- gnome-software.spec | 8 ++++---- sources | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index 09c8546..34328cf 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -29,17 +29,19 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 49~rc -Release: 2%{?dist} +Version: 49.0 +Release: 1%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later URL: https://apps.gnome.org/Software Source0: https://download.gnome.org/sources/gnome-software/49/%{name}-%{tarball_version}.tar.xz +%if %{with dnf5} # to update the patch enter the ./dnf5-plugin/ directory and run from # it the ./update-patch.sh script Patch: 0001-dnf5-plugin.patch +%endif # ostree and flatpak not on i686 for Fedora and RHEL 10 # https://github.com/containers/composefs/pull/229#issuecomment-1838735764 @@ -177,8 +179,6 @@ This package includes the rpm-ostree backend. %endif %if %{with dnf5} -Ddnf5=true \ -%else - -Ddnf5=false \ %endif -Dexternal_appstream=false \ %if %{with rpmostree} diff --git a/sources b/sources index c3ec757..469fb06 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-49.rc.tar.xz) = cecebbff1163f0179c5699ecc8325e2c4f68c811ec7633e6cf32e18ad2f03592b55daa16b9b5497a117cbfbf63f3d9162dd8e8191e6a6213d35261fa1bad15a5 +SHA512 (gnome-software-49.0.tar.xz) = 7c63b0bd59e6ebe7ef526b438c6d0b234897edacfa72ab4846358ffa9e3d63ced2945f52a4d3111307e349b846be80cb4039b4cec25f7bc5ceba135d0a4fe343 From 2c29600426d9ef7d1ef04b90d8b3af73ba1c07c1 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 19 Sep 2025 13:25:37 +0200 Subject: [PATCH 111/116] Resolves: #2395811 (Packages not found for "what-provides" searches) --- ...ackages-not-found-for-what-provides-.patch | 28 +++++++++++++++++++ gnome-software.spec | 4 ++- 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 0002-gs-extras-page-Packages-not-found-for-what-provides-.patch diff --git a/0002-gs-extras-page-Packages-not-found-for-what-provides-.patch b/0002-gs-extras-page-Packages-not-found-for-what-provides-.patch new file mode 100644 index 0000000..5d14caf --- /dev/null +++ b/0002-gs-extras-page-Packages-not-found-for-what-provides-.patch @@ -0,0 +1,28 @@ +From 272cdf10b69a84f773ce203a4d1fa9e7be9cd225 Mon Sep 17 00:00:00 2001 +Date: Fri, 19 Sep 2025 12:52:43 +0200 +Subject: [PATCH] gs-extras-page: Packages not found for "what-provides" + searches + +This is a regression after commit 22926c20b3f062082f689379b0d7b2946c35c958, +accidentally removed "allow-packages" flag for the app listing for one branch. + +Reported downstream at: https://bugzilla.redhat.com/show_bug.cgi?id=2395811 +--- + src/gs-extras-page.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/gs-extras-page.c b/src/gs-extras-page.c +index 9d16c0eb9..0d8d786c1 100644 +--- a/src/gs-extras-page.c ++++ b/src/gs-extras-page.c +@@ -853,6 +853,7 @@ gs_extras_page_load (GsExtrasPage *self, GPtrArray *array_search_data) + + query = gs_app_query_new ("provides-tag", search_data->search, + "provides-type", search_data->search_provides_type, ++ "refine-flags", GS_PLUGIN_REFINE_FLAGS_ALLOW_PACKAGES, + "refine-require-flags", require_flags, + "license-type", gs_page_get_query_license_type (GS_PAGE (self)), + "developer-verified-type", gs_page_get_query_developer_verified_type (GS_PAGE (self)), +-- +2.49.0 + diff --git a/gnome-software.spec b/gnome-software.spec index 34328cf..91e0bd4 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -30,7 +30,7 @@ Name: gnome-software Version: 49.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -43,6 +43,8 @@ Source0: https://download.gnome.org/sources/gnome-software/49/%{name}-%{tarbal Patch: 0001-dnf5-plugin.patch %endif +Patch: 0002-gs-extras-page-Packages-not-found-for-what-provides-.patch + # ostree and flatpak not on i686 for Fedora and RHEL 10 # https://github.com/containers/composefs/pull/229#issuecomment-1838735764 %if 0%{?fedora} || 0%{?rhel} >= 10 From 3364ed6d8c4f5b3536689bb260aac812ad3c6134 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 10 Oct 2025 08:47:16 +0200 Subject: [PATCH 112/116] Update to 49.1 --- ...ackages-not-found-for-what-provides-.patch | 28 ------------------- gnome-software.spec | 8 ++---- sources | 2 +- 3 files changed, 4 insertions(+), 34 deletions(-) delete mode 100644 0002-gs-extras-page-Packages-not-found-for-what-provides-.patch diff --git a/0002-gs-extras-page-Packages-not-found-for-what-provides-.patch b/0002-gs-extras-page-Packages-not-found-for-what-provides-.patch deleted file mode 100644 index 5d14caf..0000000 --- a/0002-gs-extras-page-Packages-not-found-for-what-provides-.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 272cdf10b69a84f773ce203a4d1fa9e7be9cd225 Mon Sep 17 00:00:00 2001 -Date: Fri, 19 Sep 2025 12:52:43 +0200 -Subject: [PATCH] gs-extras-page: Packages not found for "what-provides" - searches - -This is a regression after commit 22926c20b3f062082f689379b0d7b2946c35c958, -accidentally removed "allow-packages" flag for the app listing for one branch. - -Reported downstream at: https://bugzilla.redhat.com/show_bug.cgi?id=2395811 ---- - src/gs-extras-page.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/gs-extras-page.c b/src/gs-extras-page.c -index 9d16c0eb9..0d8d786c1 100644 ---- a/src/gs-extras-page.c -+++ b/src/gs-extras-page.c -@@ -853,6 +853,7 @@ gs_extras_page_load (GsExtrasPage *self, GPtrArray *array_search_data) - - query = gs_app_query_new ("provides-tag", search_data->search, - "provides-type", search_data->search_provides_type, -+ "refine-flags", GS_PLUGIN_REFINE_FLAGS_ALLOW_PACKAGES, - "refine-require-flags", require_flags, - "license-type", gs_page_get_query_license_type (GS_PAGE (self)), - "developer-verified-type", gs_page_get_query_developer_verified_type (GS_PAGE (self)), --- -2.49.0 - diff --git a/gnome-software.spec b/gnome-software.spec index 91e0bd4..e62923e 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -29,8 +29,8 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 49.0 -Release: 2%{?dist} +Version: 49.1 +Release: 1%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -43,8 +43,6 @@ Source0: https://download.gnome.org/sources/gnome-software/49/%{name}-%{tarbal Patch: 0001-dnf5-plugin.patch %endif -Patch: 0002-gs-extras-page-Packages-not-found-for-what-provides-.patch - # ostree and flatpak not on i686 for Fedora and RHEL 10 # https://github.com/containers/composefs/pull/229#issuecomment-1838735764 %if 0%{?fedora} || 0%{?rhel} >= 10 @@ -162,7 +160,7 @@ This package includes the rpm-ostree backend. %endif %prep -%autosetup -p1 -S git -n %{name}-%{tarball_version} +%autosetup -p1 -S gendiff -n %{name}-%{tarball_version} %build %meson \ diff --git a/sources b/sources index 469fb06..f738461 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-49.0.tar.xz) = 7c63b0bd59e6ebe7ef526b438c6d0b234897edacfa72ab4846358ffa9e3d63ced2945f52a4d3111307e349b846be80cb4039b4cec25f7bc5ceba135d0a4fe343 +SHA512 (gnome-software-49.1.tar.xz) = 3475ea7d7062679192d4317a6ae278601acd5316d20eb6db9512407058e3b39bf6804443a272016d206cd97d12c8c9fdd883db96297e6b5866d80300ff48503a From 93f854207d7f0b44f2019701a3c1a2b854319f8f Mon Sep 17 00:00:00 2001 From: Yanko Kaneti Date: Fri, 10 Oct 2025 10:04:05 +0300 Subject: [PATCH 113/116] Add NEWS to docs --- gnome-software.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gnome-software.spec b/gnome-software.spec index e62923e..78d502f 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -232,7 +232,7 @@ FOE desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %files -f %{name}.lang -%doc AUTHORS README.md +%doc AUTHORS NEWS README.md %license COPYING %{_bindir}/gnome-software %{_datadir}/applications/gnome-software-local-file-flatpak.desktop From 2a31982d3e20fec1a199d87dbb4013d39de293a9 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 21 Nov 2025 11:10:15 +0100 Subject: [PATCH 114/116] Update to 49.2 --- gnome-software.spec | 2 +- sources | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gnome-software.spec b/gnome-software.spec index 78d502f..3552763 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -29,7 +29,7 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 49.1 +Version: 49.2 Release: 1%{?dist} Summary: A software center for GNOME diff --git a/sources b/sources index f738461..0e06aac 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-49.1.tar.xz) = 3475ea7d7062679192d4317a6ae278601acd5316d20eb6db9512407058e3b39bf6804443a272016d206cd97d12c8c9fdd883db96297e6b5866d80300ff48503a +SHA512 (gnome-software-49.2.tar.xz) = 9ce33e2046b776f2a56c96d17eec85817e04bada9af9590125530c84bcc529f278bcba0c0ccdabcb459f92b326e0837cd63a9e316551ec313ac2f8720bf69835 From 095b81906e30c01f354627060e7229af28eafb36 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 24 Nov 2025 16:20:33 +0100 Subject: [PATCH 115/116] Add patch for bug #2416542 (Crash under gs_flatpak_refine_wildcard()) --- ...ash-under-gs_flatpak_refine_wildcard.patch | 155 ++++++++++++++++++ gnome-software.spec | 5 +- 2 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 0002-rhbug2416542-crash-under-gs_flatpak_refine_wildcard.patch diff --git a/0002-rhbug2416542-crash-under-gs_flatpak_refine_wildcard.patch b/0002-rhbug2416542-crash-under-gs_flatpak_refine_wildcard.patch new file mode 100644 index 0000000..0150264 --- /dev/null +++ b/0002-rhbug2416542-crash-under-gs_flatpak_refine_wildcard.patch @@ -0,0 +1,155 @@ +diff --git a/plugins/flatpak/gs-flatpak.c b/plugins/flatpak/gs-flatpak.c +index b409475c7..a40ab54fb 100644 +--- a/plugins/flatpak/gs-flatpak.c ++++ b/plugins/flatpak/gs-flatpak.c +@@ -3748,16 +3748,19 @@ gboolean + gs_flatpak_refine_wildcard (GsFlatpak *self, GsApp *app, + GsAppList *list, GsPluginRefineRequireFlags require_flags, + gboolean interactive, ++ XbSilo **inout_silo, ++ gchar **inout_silo_filename, ++ GHashTable **inout_installed_by_desktopid, + GHashTable **inout_components_by_id, + GHashTable **inout_components_by_bundle, + GCancellable *cancellable, GError **error) + { + const gchar *id; + GPtrArray* components = NULL; ++ XbSilo *silo; ++ GHashTable *silo_installed_by_desktopid; ++ const gchar *silo_filename; + g_autoptr(GError) error_local = NULL; +- g_autoptr(XbSilo) silo = NULL; +- g_autoptr(GHashTable) silo_installed_by_desktopid = NULL; +- g_autofree gchar *silo_filename = NULL; + + GS_PROFILER_BEGIN_SCOPED (FlatpakRefineWildcard, "Flatpak (refine wildcard)", NULL); + +@@ -3766,10 +3769,15 @@ gs_flatpak_refine_wildcard (GsFlatpak *self, GsApp *app, + if (id == NULL) + return TRUE; + +- silo = gs_flatpak_ref_silo (self, interactive, &silo_filename, &silo_installed_by_desktopid, cancellable, error); +- if (silo == NULL) ++ if (*inout_silo == NULL) ++ *inout_silo = gs_flatpak_ref_silo (self, interactive, inout_silo_filename, inout_installed_by_desktopid, cancellable, error); ++ if (*inout_silo == NULL) + return FALSE; + ++ silo = *inout_silo; ++ silo_filename = *inout_silo_filename; ++ silo_installed_by_desktopid = *inout_installed_by_desktopid; ++ + GS_PROFILER_BEGIN_SCOPED (FlatpakRefineWildcardQuerySilo, "Flatpak (query silo)", NULL); + + if (*inout_components_by_id != NULL) { +diff --git a/plugins/flatpak/gs-flatpak.h b/plugins/flatpak/gs-flatpak.h +index 66ff59967..34e1416b5 100644 +--- a/plugins/flatpak/gs-flatpak.h ++++ b/plugins/flatpak/gs-flatpak.h +@@ -11,6 +11,7 @@ + + #include + #include ++#include + + G_BEGIN_DECLS + +@@ -108,6 +109,9 @@ gboolean gs_flatpak_refine_wildcard (GsFlatpak *self, + GsAppList *list, + GsPluginRefineRequireFlags require_flags, + gboolean interactive, ++ XbSilo **inout_silo, ++ gchar **inout_silo_filename, ++ GHashTable **inout_installed_by_desktopid, + GHashTable **inout_components_by_id, + GHashTable **inout_components_by_bundle, + GCancellable *cancellable, +diff --git a/plugins/flatpak/gs-plugin-flatpak.c b/plugins/flatpak/gs-plugin-flatpak.c +index 3d0503d46..f5d4a1d67 100644 +--- a/plugins/flatpak/gs-plugin-flatpak.c ++++ b/plugins/flatpak/gs-plugin-flatpak.c +@@ -667,12 +667,29 @@ gs_plugin_flatpak_refine_app (GsPluginFlatpak *self, + return gs_flatpak_refine_app (flatpak, app, require_flags, interactive, FALSE, event_callback, event_user_data, cancellable, error); + } + ++typedef struct { ++ XbSilo *silo; ++ gchar *silo_filename; ++ GHashTable *installed_by_desktopid; ++ GHashTable *components_by_id; ++ GHashTable *components_by_bundle; ++} RefineInstallationData; ++ + static void +-unref_nonnull_hash_table (gpointer ptr) ++refine_installation_data_free (gpointer ptr) + { +- GHashTable *hash_table = ptr; +- if (hash_table != NULL) +- g_hash_table_unref (hash_table); ++ RefineInstallationData *data = ptr; ++ ++ if (data == NULL) ++ return; ++ ++ g_clear_pointer (&data->silo_filename, g_free); ++ g_clear_pointer (&data->installed_by_desktopid, g_hash_table_unref); ++ g_clear_pointer (&data->components_by_id, g_hash_table_unref); ++ g_clear_pointer (&data->components_by_bundle, g_hash_table_unref); ++ /* free the silo as the last, just in case, because the data from it is in the above hash tables */ ++ g_clear_object (&data->silo); ++ g_free (data); + } + + static gboolean +@@ -761,8 +778,7 @@ refine_thread_cb (GTask *task, + gboolean interactive = (data->job_flags & GS_PLUGIN_REFINE_FLAGS_INTERACTIVE) != 0; + GsPluginEventCallback event_callback = data->event_callback; + void *event_user_data = data->event_user_data; +- g_autoptr(GPtrArray) array_components_by_id = NULL; /* (element-type GHashTable) */ +- g_autoptr(GPtrArray) array_components_by_bundle = NULL; /* (element-type GHashTable) */ ++ g_autoptr(GPtrArray) installation_data = NULL; /* (element-type RefineInstallationData) */ + g_autoptr(GsAppList) app_list = NULL; + g_autoptr(GError) local_error = NULL; + +@@ -783,10 +799,9 @@ refine_thread_cb (GTask *task, + * (e.g. inserting an app in the list on every call results in + * an infinite loop) */ + app_list = gs_app_list_copy (list); +- array_components_by_id = g_ptr_array_new_full (self->installations->len, unref_nonnull_hash_table); +- g_ptr_array_set_size (array_components_by_id, self->installations->len); +- array_components_by_bundle = g_ptr_array_new_full (self->installations->len, unref_nonnull_hash_table); +- g_ptr_array_set_size (array_components_by_bundle, self->installations->len); ++ ++ installation_data = g_ptr_array_new_full (self->installations->len, refine_installation_data_free); ++ g_ptr_array_set_size (installation_data, self->installations->len); + + for (guint j = 0; j < gs_app_list_length (app_list); j++) { + GsApp *app = gs_app_list_index (app_list, j); +@@ -796,16 +811,20 @@ refine_thread_cb (GTask *task, + + for (guint i = 0; i < self->installations->len; i++) { + GsFlatpak *flatpak = g_ptr_array_index (self->installations, i); +- GHashTable *components_by_id = array_components_by_id->pdata[i]; +- GHashTable *components_by_bundle = array_components_by_bundle->pdata[i]; ++ RefineInstallationData *inst_data = g_ptr_array_index (installation_data, i); ++ ++ if (inst_data == NULL) { ++ inst_data = g_new0 (RefineInstallationData, 1); ++ installation_data->pdata[i] = inst_data; ++ } + +- if (!gs_flatpak_refine_wildcard (flatpak, app, list, require_flags, interactive, &components_by_id, &components_by_bundle, ++ if (!gs_flatpak_refine_wildcard (flatpak, app, list, require_flags, interactive, &inst_data->silo, ++ &inst_data->silo_filename, &inst_data->installed_by_desktopid, ++ &inst_data->components_by_id, &inst_data->components_by_bundle, + cancellable, &local_error)) { + g_task_return_error (task, g_steal_pointer (&local_error)); + return; + } +- array_components_by_id->pdata[i] = components_by_id; +- array_components_by_bundle->pdata[i] = components_by_bundle; + } + } + diff --git a/gnome-software.spec b/gnome-software.spec index 3552763..6830ae0 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -30,7 +30,7 @@ Name: gnome-software Version: 49.2 -Release: 1%{?dist} +Release: 2%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later @@ -43,6 +43,9 @@ Source0: https://download.gnome.org/sources/gnome-software/49/%{name}-%{tarbal Patch: 0001-dnf5-plugin.patch %endif +# https://bugzilla.redhat.com/show_bug.cgi?id=2416542 +Patch: 0002-rhbug2416542-crash-under-gs_flatpak_refine_wildcard.patch + # ostree and flatpak not on i686 for Fedora and RHEL 10 # https://github.com/containers/composefs/pull/229#issuecomment-1838735764 %if 0%{?fedora} || 0%{?rhel} >= 10 From a10b3cf10fff31405ee2087b87c1a7d8d139fd29 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 12 Jan 2026 17:23:11 +0100 Subject: [PATCH 116/116] Update to 49.3 --- ...ash-under-gs_flatpak_refine_wildcard.patch | 531 ++++++++++++++++++ gnome-software.spec | 4 +- sources | 2 +- 3 files changed, 534 insertions(+), 3 deletions(-) diff --git a/0002-rhbug2416542-crash-under-gs_flatpak_refine_wildcard.patch b/0002-rhbug2416542-crash-under-gs_flatpak_refine_wildcard.patch index 0150264..33140df 100644 --- a/0002-rhbug2416542-crash-under-gs_flatpak_refine_wildcard.patch +++ b/0002-rhbug2416542-crash-under-gs_flatpak_refine_wildcard.patch @@ -1,3 +1,26 @@ +From 0c79d9fb08a348a45a18f15427c945a63b44982e Mon Sep 17 00:00:00 2001 +Date: Mon, 24 Nov 2025 16:06:51 +0100 +Subject: [PATCH 1/3] flatpak: Fix XbSilo lifetime in + gs_flatpak_refine_wildcard() + +The function uses pre-cached data in the hash tables, consisting of XbNode-s +from an XbSilo. The nodes are referenced, but the silos the node belongs to +is not referenced (by the XbNode). + +This change keeps the XbSilo alive as long as it's needed for the nodes +in the pre-cached data. It also does not call gs_flatpak_ref_silo() multiple +times for the same GsFlatpak instance, which could invalidate the XbNode-s +in the pre-cached data when a change in the silo or in the installation +had been received while the function was still processing the apps. + +Related downstream bug https://bugzilla.redhat.com/show_bug.cgi?id=2416542 +Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/2900 +--- + plugins/flatpak/gs-flatpak.c | 18 ++++++++--- + plugins/flatpak/gs-flatpak.h | 4 +++ + plugins/flatpak/gs-plugin-flatpak.c | 49 ++++++++++++++++++++--------- + 3 files changed, 51 insertions(+), 20 deletions(-) + diff --git a/plugins/flatpak/gs-flatpak.c b/plugins/flatpak/gs-flatpak.c index b409475c7..a40ab54fb 100644 --- a/plugins/flatpak/gs-flatpak.c @@ -153,3 +176,511 @@ index 3d0503d46..f5d4a1d67 100644 } } +-- +GitLab + + +From 546c6ee17b5959d2a696a6cb346a1f8b94aba303 Mon Sep 17 00:00:00 2001 +Date: Wed, 7 Jan 2026 18:37:52 +0100 +Subject: [PATCH 2/3] flatpak: Simplify wildcard app lookup function + +By flipping the order of traversing app and installation the code +can be simplified to not have too many in/out arguments. + +Suggested by Philip Withnall +--- + plugins/flatpak/gs-flatpak.c | 251 ++++++++++++++-------------- + plugins/flatpak/gs-flatpak.h | 9 +- + plugins/flatpak/gs-plugin-flatpak.c | 61 +------ + 3 files changed, 130 insertions(+), 191 deletions(-) + +diff --git a/plugins/flatpak/gs-flatpak.c b/plugins/flatpak/gs-flatpak.c +index a40ab54fb..782b0bb48 100644 +--- a/plugins/flatpak/gs-flatpak.c ++++ b/plugins/flatpak/gs-flatpak.c +@@ -3745,167 +3745,158 @@ gs_flatpak_refine_app (GsFlatpak *self, + } + + gboolean +-gs_flatpak_refine_wildcard (GsFlatpak *self, GsApp *app, +- GsAppList *list, GsPluginRefineRequireFlags require_flags, +- gboolean interactive, +- XbSilo **inout_silo, +- gchar **inout_silo_filename, +- GHashTable **inout_installed_by_desktopid, +- GHashTable **inout_components_by_id, +- GHashTable **inout_components_by_bundle, +- GCancellable *cancellable, GError **error) ++gs_flatpak_refine_wildcards (GsFlatpak *self, ++ GPtrArray *wildcard_apps, ++ GsAppList *list, ++ GsPluginRefineRequireFlags require_flags, ++ gboolean interactive, ++ GCancellable *cancellable, ++ GError **error) + { +- const gchar *id; +- GPtrArray* components = NULL; +- XbSilo *silo; +- GHashTable *silo_installed_by_desktopid; +- const gchar *silo_filename; + g_autoptr(GError) error_local = NULL; ++ g_autoptr(XbSilo) silo = NULL; ++ g_autoptr(GHashTable) silo_installed_by_desktopid = NULL; ++ g_autoptr(GHashTable) components_by_id = NULL; ++ g_autoptr(GHashTable) components_by_bundle = NULL; ++ g_autoptr(GPtrArray) components_with_id = NULL; ++ g_autoptr(GPtrArray) bundles = NULL; ++ g_autofree gchar *silo_filename = NULL; + + GS_PROFILER_BEGIN_SCOPED (FlatpakRefineWildcard, "Flatpak (refine wildcard)", NULL); + +- /* not enough info to find */ +- id = gs_app_get_id (app); +- if (id == NULL) +- return TRUE; +- +- if (*inout_silo == NULL) +- *inout_silo = gs_flatpak_ref_silo (self, interactive, inout_silo_filename, inout_installed_by_desktopid, cancellable, error); +- if (*inout_silo == NULL) ++ silo = gs_flatpak_ref_silo (self, interactive, &silo_filename, &silo_installed_by_desktopid, cancellable, error); ++ if (silo == NULL) + return FALSE; + +- silo = *inout_silo; +- silo_filename = *inout_silo_filename; +- silo_installed_by_desktopid = *inout_installed_by_desktopid; +- + GS_PROFILER_BEGIN_SCOPED (FlatpakRefineWildcardQuerySilo, "Flatpak (query silo)", NULL); + +- if (*inout_components_by_id != NULL) { +- components = g_hash_table_lookup (*inout_components_by_id, gs_app_get_id (app)); +- } else { +- g_autoptr(GPtrArray) components_with_id = NULL; +- *inout_components_by_id = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_ptr_array_unref); +- components_with_id = xb_silo_query (silo, "components/component/id", 0, &error_local); +- if (components_with_id == NULL) { +- if (g_error_matches (error_local, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) +- return TRUE; +- g_propagate_error (error, g_steal_pointer (&error_local)); +- return FALSE; ++ components_by_id = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_ptr_array_unref); ++ components_with_id = xb_silo_query (silo, "components/component/id", 0, &error_local); ++ if (components_with_id == NULL) { ++ if (g_error_matches (error_local, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) ++ return TRUE; ++ g_propagate_error (error, g_steal_pointer (&error_local)); ++ return FALSE; ++ } ++ ++ for (guint i = 0; i < components_with_id->len; i++) { ++ XbNode *node = g_ptr_array_index (components_with_id, i); ++ XbNode *comp_node = xb_node_get_parent (node); ++ const gchar *comp_id = xb_node_get_text (node); ++ GPtrArray *comps = g_hash_table_lookup (components_by_id, comp_id); ++ if (comps == NULL) { ++ comps = g_ptr_array_new_with_free_func (g_object_unref); ++ g_hash_table_insert (components_by_id, g_strdup (comp_id), comps); + } +- for (guint i = 0; i < components_with_id->len; i++) { +- XbNode *node = g_ptr_array_index (components_with_id, i); +- XbNode *comp_node = xb_node_get_parent (node); +- const gchar *comp_id = xb_node_get_text (node); +- GPtrArray *comps = g_hash_table_lookup (*inout_components_by_id, comp_id); +- if (comps == NULL) { +- comps = g_ptr_array_new_with_free_func (g_object_unref); +- g_hash_table_insert (*inout_components_by_id, g_strdup (comp_id), comps); ++ g_ptr_array_add (comps, comp_node); ++ } ++ ++ components_by_bundle = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); ++ bundles = xb_silo_query (silo, "/components/component/bundle[@type='flatpak']", 0, NULL); ++ for (guint b = 0; bundles != NULL && b < bundles->len; b++) { ++ XbNode *bundle_node = g_ptr_array_index (bundles, b); ++ g_autoptr(XbNode) component_node = xb_node_get_parent (bundle_node); ++ g_autoptr(XbNode) components_node = xb_node_get_parent (component_node); ++ const gchar *origin = xb_node_get_attr (components_node, "origin"); ++ if (origin != NULL) { ++ const gchar *bundle = xb_node_get_text (bundle_node); ++ if (bundle != NULL) { ++ g_autofree gchar *key = g_strconcat (origin, "\n", bundle, NULL); ++ g_hash_table_insert (components_by_bundle, g_steal_pointer (&key), g_steal_pointer (&component_node)); + } +- g_ptr_array_add (comps, comp_node); +- if (components == NULL && g_strcmp0 (id, comp_id) == 0) +- components = comps; + } + } + + GS_PROFILER_END_SCOPED (FlatpakRefineWildcardQuerySilo); + +- if (components == NULL) +- return TRUE; +- + gs_flatpak_ensure_remote_title (self, interactive, cancellable); + +- if (*inout_components_by_bundle == NULL) { +- g_autoptr(GPtrArray) bundles = NULL; +- +- *inout_components_by_bundle = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); +- bundles = xb_silo_query (silo, "/components/component/bundle[@type='flatpak']", 0, NULL); +- for (guint b = 0; bundles != NULL && b < bundles->len; b++) { +- XbNode *bundle_node = g_ptr_array_index (bundles, b); +- g_autoptr(XbNode) component_node = xb_node_get_parent (bundle_node); +- g_autoptr(XbNode) components_node = xb_node_get_parent (component_node); +- const gchar *origin = xb_node_get_attr (components_node, "origin"); +- if (origin != NULL) { +- const gchar *bundle = xb_node_get_text (bundle_node); +- if (bundle != NULL) { +- g_autofree gchar *key = g_strconcat (origin, "\n", bundle, NULL); +- g_hash_table_insert (*inout_components_by_bundle, g_steal_pointer (&key), g_steal_pointer (&component_node)); +- } +- } +- } +- } ++ for (guint j = 0; j < wildcard_apps->len; j++) { ++ GsApp *app = g_ptr_array_index (wildcard_apps, j); ++ GPtrArray *components = NULL; ++ const gchar *id; + ++ /* not enough info to find */ ++ id = gs_app_get_id (app); ++ if (id == NULL) ++ continue; + +- GS_PROFILER_BEGIN_SCOPED (FlatpakRefineWildcardGenerateApps, "Flatpak (create app)", NULL); +- for (guint i = 0; i < components->len; i++) { +- XbNode *component = g_ptr_array_index (components, i); +- g_autoptr(GsApp) new = NULL; ++ components = g_hash_table_lookup (components_by_id, id); ++ if (components == NULL) ++ continue; + +- GS_PROFILER_BEGIN_SCOPED (FlatpakRefineWildcardCreateAppstreamApp, "Flatpak (create Appstream app)", NULL); +- new = gs_appstream_create_app (self->plugin, silo, component, silo_filename ? silo_filename : "", +- self->scope, error); +- GS_PROFILER_END_SCOPED (FlatpakRefineWildcardCreateAppstreamApp); ++ GS_PROFILER_BEGIN_SCOPED (FlatpakRefineWildcardGenerateApps, "Flatpak (create app)", NULL); ++ for (guint i = 0; i < components->len; i++) { ++ XbNode *component = g_ptr_array_index (components, i); ++ g_autoptr(GsApp) new = NULL; + +- if (new == NULL) +- return FALSE; ++ GS_PROFILER_BEGIN_SCOPED (FlatpakRefineWildcardCreateAppstreamApp, "Flatpak (create Appstream app)", NULL); ++ new = gs_appstream_create_app (self->plugin, silo, component, silo_filename ? silo_filename : "", ++ self->scope, error); ++ GS_PROFILER_END_SCOPED (FlatpakRefineWildcardCreateAppstreamApp); + +- gs_flatpak_claim_app (self, new); +- +- /* The appstream plugin did not find the component in the plugin's cache, +- thus read the required info from the 'bundle' element. */ +- if (gs_flatpak_app_get_ref_name (new) == NULL || +- gs_flatpak_app_get_ref_arch (new) == NULL) { +- const gchar *xref_str = NULL; +- g_autoptr(XbNode) child = NULL; +- g_autoptr(XbNode) next = NULL; +- for (child = xb_node_get_child (component); child != NULL && xref_str == NULL; +- g_object_unref (child), child = g_steal_pointer (&next)) { +- next = xb_node_get_next (child); +- if (g_strcmp0 (xb_node_get_element (child), "bundle") == 0 && +- g_strcmp0 (xb_node_get_attr (child, "type"), "flatpak") == 0) { +- xref_str = xb_node_get_text (child); +- break; ++ if (new == NULL) ++ return FALSE; ++ ++ gs_flatpak_claim_app (self, new); ++ ++ /* The appstream plugin did not find the component in the plugin's cache, ++ thus read the required info from the 'bundle' element. */ ++ if (gs_flatpak_app_get_ref_name (new) == NULL || ++ gs_flatpak_app_get_ref_arch (new) == NULL) { ++ const gchar *xref_str = NULL; ++ g_autoptr(XbNode) child = NULL; ++ g_autoptr(XbNode) next = NULL; ++ for (child = xb_node_get_child (component); child != NULL && xref_str == NULL; ++ g_object_unref (child), child = g_steal_pointer (&next)) { ++ next = xb_node_get_next (child); ++ if (g_strcmp0 (xb_node_get_element (child), "bundle") == 0 && ++ g_strcmp0 (xb_node_get_attr (child, "type"), "flatpak") == 0) { ++ xref_str = xb_node_get_text (child); ++ break; ++ } + } +- } +- if (xref_str != NULL) { +- g_auto(GStrv) split = NULL; +- +- /* get the kind/name/arch/branch */ +- split = g_strsplit (xref_str, "/", -1); +- if (g_strv_length (split) == 4) { +- const gchar *comp_type = xb_node_get_attr (component, "type"); +- AsComponentKind kind = as_component_kind_from_string (comp_type); +- if (kind != AS_COMPONENT_KIND_UNKNOWN) +- gs_app_set_kind (new, kind); +- else if (g_ascii_strcasecmp (split[0], "app") == 0) +- gs_app_set_kind (new, AS_COMPONENT_KIND_DESKTOP_APP); +- else if (g_ascii_strcasecmp (split[0], "runtime") == 0) +- gs_flatpak_set_runtime_kind_from_id (new); +- gs_flatpak_app_set_ref_name (new, split[1]); +- gs_flatpak_app_set_ref_arch (new, split[2]); +- gs_app_set_branch (new, split[3]); +- gs_app_set_metadata (new, "GnomeSoftware::packagename-value", xref_str); ++ if (xref_str != NULL) { ++ g_auto(GStrv) split = NULL; ++ ++ /* get the kind/name/arch/branch */ ++ split = g_strsplit (xref_str, "/", -1); ++ if (g_strv_length (split) == 4) { ++ const gchar *comp_type = xb_node_get_attr (component, "type"); ++ AsComponentKind kind = as_component_kind_from_string (comp_type); ++ if (kind != AS_COMPONENT_KIND_UNKNOWN) ++ gs_app_set_kind (new, kind); ++ else if (g_ascii_strcasecmp (split[0], "app") == 0) ++ gs_app_set_kind (new, AS_COMPONENT_KIND_DESKTOP_APP); ++ else if (g_ascii_strcasecmp (split[0], "runtime") == 0) ++ gs_flatpak_set_runtime_kind_from_id (new); ++ gs_flatpak_app_set_ref_name (new, split[1]); ++ gs_flatpak_app_set_ref_arch (new, split[2]); ++ gs_app_set_branch (new, split[3]); ++ gs_app_set_metadata (new, "GnomeSoftware::packagename-value", xref_str); ++ } + } + } +- } + +- if (gs_flatpak_app_get_ref_name (new) == NULL || +- gs_flatpak_app_get_ref_arch (new) == NULL) { +- g_debug ("Failed to get ref info for '%s' from wildcard '%s', skipping it...", gs_app_get_id (new), id); +- } else { +- GS_PROFILER_BEGIN_SCOPED (FlatpakRefineWildcardRefineNewApp, "Flatpak (refine new app)", NULL); +- if (!gs_flatpak_refine_app_internal (self, new, require_flags, interactive, FALSE, *inout_components_by_bundle, +- silo, silo_filename, silo_installed_by_desktopid, cancellable, error)) +- return FALSE; +- GS_PROFILER_END_SCOPED (FlatpakRefineWildcardRefineNewApp); ++ if (gs_flatpak_app_get_ref_name (new) == NULL || ++ gs_flatpak_app_get_ref_arch (new) == NULL) { ++ g_debug ("Failed to get ref info for '%s' from wildcard '%s', skipping it...", gs_app_get_id (new), id); ++ } else { ++ GS_PROFILER_BEGIN_SCOPED (FlatpakRefineWildcardRefineNewApp, "Flatpak (refine new app)", NULL); ++ if (!gs_flatpak_refine_app_internal (self, new, require_flags, interactive, FALSE, components_by_bundle, ++ silo, silo_filename, silo_installed_by_desktopid, cancellable, error)) ++ return FALSE; ++ GS_PROFILER_END_SCOPED (FlatpakRefineWildcardRefineNewApp); + +- GS_PROFILER_BEGIN_SCOPED (FlatpakRefineWildcardSubsumeMetadata, "Flatpak (subsume metadata)", NULL); +- gs_app_subsume_metadata (new, app); +- GS_PROFILER_END_SCOPED (FlatpakRefineWildcardSubsumeMetadata); ++ GS_PROFILER_BEGIN_SCOPED (FlatpakRefineWildcardSubsumeMetadata, "Flatpak (subsume metadata)", NULL); ++ gs_app_subsume_metadata (new, app); ++ GS_PROFILER_END_SCOPED (FlatpakRefineWildcardSubsumeMetadata); + +- gs_app_list_add (list, new); ++ gs_app_list_add (list, new); ++ } + } ++ GS_PROFILER_END_SCOPED (FlatpakRefineWildcardGenerateApps); + } +- GS_PROFILER_END_SCOPED (FlatpakRefineWildcardGenerateApps); + + GS_PROFILER_END_SCOPED (FlatpakRefineWildcard); + +diff --git a/plugins/flatpak/gs-flatpak.h b/plugins/flatpak/gs-flatpak.h +index 34e1416b5..1f7d35a8f 100644 +--- a/plugins/flatpak/gs-flatpak.h ++++ b/plugins/flatpak/gs-flatpak.h +@@ -104,16 +104,11 @@ gboolean gs_flatpak_refine_app_state (GsFlatpak *self, + void *event_user_data, + GCancellable *cancellable, + GError **error); +-gboolean gs_flatpak_refine_wildcard (GsFlatpak *self, +- GsApp *app, ++gboolean gs_flatpak_refine_wildcards (GsFlatpak *self, ++ GPtrArray *wildcard_apps, + GsAppList *list, + GsPluginRefineRequireFlags require_flags, + gboolean interactive, +- XbSilo **inout_silo, +- gchar **inout_silo_filename, +- GHashTable **inout_installed_by_desktopid, +- GHashTable **inout_components_by_id, +- GHashTable **inout_components_by_bundle, + GCancellable *cancellable, + GError **error); + gboolean gs_flatpak_launch (GsFlatpak *self, +diff --git a/plugins/flatpak/gs-plugin-flatpak.c b/plugins/flatpak/gs-plugin-flatpak.c +index f5d4a1d67..c06b1fb5f 100644 +--- a/plugins/flatpak/gs-plugin-flatpak.c ++++ b/plugins/flatpak/gs-plugin-flatpak.c +@@ -667,31 +667,6 @@ gs_plugin_flatpak_refine_app (GsPluginFlatpak *self, + return gs_flatpak_refine_app (flatpak, app, require_flags, interactive, FALSE, event_callback, event_user_data, cancellable, error); + } + +-typedef struct { +- XbSilo *silo; +- gchar *silo_filename; +- GHashTable *installed_by_desktopid; +- GHashTable *components_by_id; +- GHashTable *components_by_bundle; +-} RefineInstallationData; +- +-static void +-refine_installation_data_free (gpointer ptr) +-{ +- RefineInstallationData *data = ptr; +- +- if (data == NULL) +- return; +- +- g_clear_pointer (&data->silo_filename, g_free); +- g_clear_pointer (&data->installed_by_desktopid, g_hash_table_unref); +- g_clear_pointer (&data->components_by_id, g_hash_table_unref); +- g_clear_pointer (&data->components_by_bundle, g_hash_table_unref); +- /* free the silo as the last, just in case, because the data from it is in the above hash tables */ +- g_clear_object (&data->silo); +- g_free (data); +-} +- + static gboolean + refine_app (GsPluginFlatpak *self, + GsApp *app, +@@ -778,8 +753,7 @@ refine_thread_cb (GTask *task, + gboolean interactive = (data->job_flags & GS_PLUGIN_REFINE_FLAGS_INTERACTIVE) != 0; + GsPluginEventCallback event_callback = data->event_callback; + void *event_user_data = data->event_user_data; +- g_autoptr(GPtrArray) installation_data = NULL; /* (element-type RefineInstallationData) */ +- g_autoptr(GsAppList) app_list = NULL; ++ g_autoptr(GPtrArray) wildcard_apps = g_ptr_array_new_with_free_func (g_object_unref); /* (element-type GsApp) (owned) */ + g_autoptr(GError) local_error = NULL; + + assert_in_worker (self); +@@ -790,38 +764,17 @@ refine_thread_cb (GTask *task, + g_task_return_error (task, g_steal_pointer (&local_error)); + return; + } +- } +- +- /* Refine wildcards. +- * +- * Use a copy of the list for the loop because a function called +- * on the plugin may affect the list which can lead to problems +- * (e.g. inserting an app in the list on every call results in +- * an infinite loop) */ +- app_list = gs_app_list_copy (list); +- +- installation_data = g_ptr_array_new_full (self->installations->len, refine_installation_data_free); +- g_ptr_array_set_size (installation_data, self->installations->len); +- +- for (guint j = 0; j < gs_app_list_length (app_list); j++) { +- GsApp *app = gs_app_list_index (app_list, j); + +- if (!gs_app_has_quirk (app, GS_APP_QUIRK_IS_WILDCARD)) +- continue; ++ if (gs_app_has_quirk (app, GS_APP_QUIRK_IS_WILDCARD) && gs_app_get_id (app) != NULL) ++ g_ptr_array_add (wildcard_apps, g_object_ref (app)); ++ } + ++ /* Refine wildcards. */ ++ if (wildcard_apps->len > 0) { + for (guint i = 0; i < self->installations->len; i++) { + GsFlatpak *flatpak = g_ptr_array_index (self->installations, i); +- RefineInstallationData *inst_data = g_ptr_array_index (installation_data, i); +- +- if (inst_data == NULL) { +- inst_data = g_new0 (RefineInstallationData, 1); +- installation_data->pdata[i] = inst_data; +- } + +- if (!gs_flatpak_refine_wildcard (flatpak, app, list, require_flags, interactive, &inst_data->silo, +- &inst_data->silo_filename, &inst_data->installed_by_desktopid, +- &inst_data->components_by_id, &inst_data->components_by_bundle, +- cancellable, &local_error)) { ++ if (!gs_flatpak_refine_wildcards (flatpak, wildcard_apps, list, require_flags, interactive, cancellable, &local_error)) { + g_task_return_error (task, g_steal_pointer (&local_error)); + return; + } +-- +GitLab + + +From 8472d717356a801e6c0171156738ea48480fa695 Mon Sep 17 00:00:00 2001 +Date: Wed, 7 Jan 2026 18:45:47 +0100 +Subject: [PATCH 3/3] flatpak: Hold silo lock when refining wildcard apps + +The refine can take a long time, thus hold the silo lock to not have +it invalidated from another thread. Object reference is not enough +for the XbSilo, it breaks as soon as the underlying file changes. +--- + plugins/flatpak/gs-flatpak.c | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) + +diff --git a/plugins/flatpak/gs-flatpak.c b/plugins/flatpak/gs-flatpak.c +index 782b0bb48..c5437125d 100644 +--- a/plugins/flatpak/gs-flatpak.c ++++ b/plugins/flatpak/gs-flatpak.c +@@ -59,7 +59,7 @@ struct _GsFlatpak { + AsComponentScope scope; + GsPlugin *plugin; + XbSilo *silo; +- GMutex silo_lock; ++ GRecMutex silo_lock; + gchar *silo_filename; + GHashTable *silo_installed_by_desktopid; + gint silo_change_stamp; +@@ -1187,11 +1187,11 @@ gs_flatpak_ref_silo (GsFlatpak *self, + g_autoptr(GFile) file = NULL; + g_autoptr(GPtrArray) xremotes = NULL; + g_autoptr(GPtrArray) desktop_paths = NULL; +- g_autoptr(GMutexLocker) locker = NULL; ++ g_autoptr(GRecMutexLocker) locker = NULL; + g_autoptr(XbBuilder) builder = NULL; + g_autoptr(GMainContext) old_thread_default = NULL; + +- locker = g_mutex_locker_new (&self->silo_lock); ++ locker = g_rec_mutex_locker_new (&self->silo_lock); + /* everything is okay */ + if (self->silo != NULL && xb_silo_is_valid (self->silo) && + g_atomic_int_get (&self->silo_change_stamp_current) == g_atomic_int_get (&self->silo_change_stamp)) { +@@ -3754,6 +3754,7 @@ gs_flatpak_refine_wildcards (GsFlatpak *self, + GError **error) + { + g_autoptr(GError) error_local = NULL; ++ g_autoptr(GRecMutexLocker) silo_locker = NULL; + g_autoptr(XbSilo) silo = NULL; + g_autoptr(GHashTable) silo_installed_by_desktopid = NULL; + g_autoptr(GHashTable) components_by_id = NULL; +@@ -3764,6 +3765,11 @@ gs_flatpak_refine_wildcards (GsFlatpak *self, + + GS_PROFILER_BEGIN_SCOPED (FlatpakRefineWildcard, "Flatpak (refine wildcard)", NULL); + ++ /* the refine can take a long time, thus hold the silo lock to not have ++ it invalidated from another thread; object reference is not enough ++ for the XbSilo, it breaks as soon as the underlying file changes */ ++ silo_locker = g_rec_mutex_locker_new (&self->silo_lock); ++ + silo = gs_flatpak_ref_silo (self, interactive, &silo_filename, &silo_installed_by_desktopid, cancellable, error); + if (silo == NULL) + return FALSE; +@@ -4810,7 +4816,7 @@ gs_flatpak_finalize (GObject *object) + g_object_unref (self->plugin); + g_hash_table_unref (self->broken_remotes); + g_mutex_clear (&self->broken_remotes_mutex); +- g_mutex_clear (&self->silo_lock); ++ g_rec_mutex_clear (&self->silo_lock); + g_hash_table_unref (self->app_silos); + g_mutex_clear (&self->app_silos_mutex); + g_clear_pointer (&self->remote_title, g_hash_table_unref); +@@ -4831,7 +4837,7 @@ gs_flatpak_init (GsFlatpak *self) + { + /* XbSilo needs external locking as we destroy the silo and build a new + * one when something changes */ +- g_mutex_init (&self->silo_lock); ++ g_rec_mutex_init (&self->silo_lock); + + g_mutex_init (&self->installed_refs_mutex); + self->installed_refs = NULL; +-- +GitLab + diff --git a/gnome-software.spec b/gnome-software.spec index 6830ae0..c080ede 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -29,8 +29,8 @@ %global __provides_exclude_from ^%{_libdir}/%{name}/plugins-%{gs_plugin_version}/.*\\.so.*$ Name: gnome-software -Version: 49.2 -Release: 2%{?dist} +Version: 49.3 +Release: 1%{?dist} Summary: A software center for GNOME License: GPL-2.0-or-later diff --git a/sources b/sources index 0e06aac..c24e704 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-software-49.2.tar.xz) = 9ce33e2046b776f2a56c96d17eec85817e04bada9af9590125530c84bcc529f278bcba0c0ccdabcb459f92b326e0837cd63a9e316551ec313ac2f8720bf69835 +SHA512 (gnome-software-49.3.tar.xz) = 0414ea55ad3b83bcd50514985e3d2026207801c040934805bb26d162e88f0619a9d70aa6ba324a29acfab02573490b928c83594b54f57ec2a8ad00e6c127f657