From 49439a8f0bf0c45fcff38c695d716d6331d94ff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20Fern=C3=A1ndez=20D=C3=ADaz?= <42654671+oscfdezdz@users.noreply.github.com> Date: Wed, 22 Jan 2025 17:39:38 +0100 Subject: [PATCH 1/2] manager: Stop using g_dbus_proxy_call_sync Use shell_extensions_call_install_remote_extension/finish instead. --- src/exm-window.c | 4 ++- src/local/exm-manager.c | 44 ++++++++--------------------- src/local/exm-manager.h | 61 +++++++++++++++++++++++++++++------------ 3 files changed, 57 insertions(+), 52 deletions(-) diff --git a/src/exm-window.c b/src/exm-window.c index 9c46df37..d2267258 100644 --- a/src/exm-window.c +++ b/src/exm-window.c @@ -159,10 +159,12 @@ on_install_done (GObject *source, gpointer user_data G_GNUC_UNUSED) { GError *error = NULL; - if (!exm_manager_install_finish (EXM_MANAGER (source), res, &error) && error) + + if (!exm_manager_install_finish (source, res, &error) && error) { // TODO: Properly log this g_critical ("%s\n", error->message); + g_clear_error (&error); } } diff --git a/src/local/exm-manager.c b/src/local/exm-manager.c index 23ff77ea..50374c2d 100644 --- a/src/local/exm-manager.c +++ b/src/local/exm-manager.c @@ -21,7 +21,6 @@ #include "exm-manager.h" -#include "exm-extension.h" #include "shell-dbus-interface.h" #include "../exm-types.h" @@ -353,29 +352,6 @@ exm_manager_is_installed_uuid (ExmManager *self, return FALSE; } -static void -do_install_thread (GTask *task, - ExmManager *self, - const char *uuid, - GCancellable *cancellable) -{ - GError *error = NULL; - - g_dbus_proxy_call_sync (G_DBUS_PROXY (self->proxy), - "InstallRemoteExtension", - g_variant_new ("(s)", uuid, NULL), - G_DBUS_CALL_FLAGS_NONE, - -1, cancellable, &error); - - if (error != NULL) - { - g_task_return_error (task, error); - return; - } - - g_task_return_boolean (task, TRUE); -} - void exm_manager_install_async (ExmManager *self, const gchar *uuid, @@ -383,22 +359,24 @@ exm_manager_install_async (ExmManager *self, GAsyncReadyCallback callback, gpointer user_data) { - GTask *task; - - task = g_task_new (self, cancellable, callback, user_data); - g_task_set_task_data (task, g_strdup (uuid), (GDestroyNotify) g_free); - g_task_run_in_thread (task, (GTaskThreadFunc)do_install_thread); - g_object_unref (task); + shell_extensions_call_install_remote_extension (self->proxy, + uuid, + cancellable, + callback, + user_data); } gboolean -exm_manager_install_finish (ExmManager *self, +exm_manager_install_finish (GObject *self, GAsyncResult *result, GError **error) { - g_return_val_if_fail (g_task_is_valid (result, self), FALSE); + g_return_val_if_fail (SHELL_IS_EXTENSIONS (self), FALSE); - return g_task_propagate_boolean (G_TASK (result), error); + return shell_extensions_call_install_remote_extension_finish (SHELL_EXTENSIONS (self), + NULL, + result, + error); } static int diff --git a/src/local/exm-manager.h b/src/local/exm-manager.h index 8d978939..390c6cd7 100644 --- a/src/local/exm-manager.h +++ b/src/local/exm-manager.h @@ -1,3 +1,24 @@ +/* + * exm-manager.h + * + * Copyright 2022-2025 Matthew Jakeman + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + #pragma once #include @@ -11,23 +32,27 @@ G_BEGIN_DECLS G_DECLARE_FINAL_TYPE (ExmManager, exm_manager, EXM, MANAGER, GObject) -ExmManager *exm_manager_new (void); -void exm_manager_enable_extension (ExmManager *manager, ExmExtension *extension); -void exm_manager_disable_extension (ExmManager *manager, ExmExtension *extension); -void exm_manager_remove_extension (ExmManager *self, ExmExtension *extension); -void exm_manager_open_prefs (ExmManager *self, ExmExtension *extension); -void exm_manager_check_for_updates (ExmManager *self); -gboolean exm_manager_is_installed_uuid (ExmManager *self, const gchar *uuid); -ExmExtension *exm_manager_get_by_uuid (ExmManager *self, const gchar *uuid); - -void exm_manager_install_async (ExmManager *self, - const gchar *uuid, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); - -gboolean exm_manager_install_finish (ExmManager *self, - GAsyncResult *result, - GError **error); +ExmManager *exm_manager_new (void); +void exm_manager_enable_extension (ExmManager *manager, + ExmExtension *extension); +void exm_manager_disable_extension (ExmManager *manager, + ExmExtension *extension); +void exm_manager_remove_extension (ExmManager *self, + ExmExtension *extension); +void exm_manager_open_prefs (ExmManager *self, + ExmExtension *extension); +void exm_manager_check_for_updates (ExmManager *self); +gboolean exm_manager_is_installed_uuid (ExmManager *self, + const gchar *uuid); +ExmExtension *exm_manager_get_by_uuid (ExmManager *self, + const gchar *uuid); +void exm_manager_install_async (ExmManager *self, + const gchar *uuid, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean exm_manager_install_finish (GObject *self, + GAsyncResult *result, + GError **error); G_END_DECLS From 0e14966a56a62861926560d739fec07573905244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20Fern=C3=A1ndez=20D=C3=ADaz?= <42654671+oscfdezdz@users.noreply.github.com> Date: Thu, 23 Jan 2025 17:24:40 +0100 Subject: [PATCH 2/2] install-button: Disable during installation Introduces a new installing state that is set before activating `ext.install` action. To deal with cancellations, a new `install-status` signal is added to ExmManager which is emitted whenever it happens andreverts the button state to the last one it had, either default or unsupported. ExmSearchRow drops `is-installed` and `is-supported` properties in favor of a new `manager` property to connect to ExmManager's `install-status signal. --- src/exm-browse-page.c | 12 +----- src/exm-detail-view.c | 43 +++++++++++++++---- src/exm-install-button.c | 4 ++ src/exm-search-row.c | 90 +++++++++++++++++++++++----------------- src/exm-search-row.h | 29 +++++++++++-- src/exm-types.h | 22 ++++++++++ src/exm-window.c | 79 +++++++++++++++++++++++++---------- src/local/exm-manager.c | 28 +++++++++++-- 8 files changed, 223 insertions(+), 84 deletions(-) diff --git a/src/exm-browse-page.c b/src/exm-browse-page.c index fcd6623a..ad9d6395 100644 --- a/src/exm-browse-page.c +++ b/src/exm-browse-page.c @@ -41,7 +41,6 @@ struct _ExmBrowsePage GtkStringList *suggestions; GListModel *search_results_model; - gchar *shell_version; int current_page; int max_pages; @@ -135,17 +134,9 @@ search_widget_factory (ExmSearchResult *result, ExmBrowsePage *self) { ExmSearchRow *row; - gchar *uuid; - gboolean is_installed; - gboolean is_supported; GValue value = G_VALUE_INIT; - g_object_get (result, "uuid", &uuid, NULL); - - is_installed = exm_manager_is_installed_uuid (self->manager, uuid); - is_supported = exm_search_result_supports_shell_version (result, self->shell_version); - - row = exm_search_row_new (result, is_installed, is_supported); + row = exm_search_row_new (self->manager, result); g_value_init (&value, G_TYPE_BOOLEAN); g_value_set_boolean (&value, TRUE); @@ -355,7 +346,6 @@ on_bind_manager (ExmBrowsePage *self) &shell_version, NULL); - self->shell_version = shell_version; g_object_set (self->search, "shell-version", shell_version, NULL); refresh_search (self); diff --git a/src/exm-detail-view.c b/src/exm-detail-view.c index add3638f..a0c12ea4 100644 --- a/src/exm-detail-view.c +++ b/src/exm-detail-view.c @@ -83,7 +83,8 @@ struct _ExmDetailView AdwActionRow *link_extensions; gchar *uri_extensions; int pk; - guint signal_id; + guint comments_signal_id; + guint install_signal_id; }; G_DEFINE_FINAL_TYPE (ExmDetailView, exm_detail_view, ADW_TYPE_NAVIGATION_PAGE) @@ -281,6 +282,14 @@ show_more_comments (GtkButton *button G_GNUC_UNUSED, adw_dialog_present (ADW_DIALOG (dlg), GTK_WIDGET (toplevel)); } +static void +on_install_status (ExmManager *manager G_GNUC_UNUSED, + ExmInstallButtonState state, + ExmDetailView *self) +{ + g_object_set (self->ext_install, "state", state, NULL); +} + static void install_remote (GtkButton *button, ExmDetailView *self) @@ -291,6 +300,12 @@ install_remote (GtkButton *button, g_object_get (self->ext_install, "state", &state, NULL); warn = (state == EXM_INSTALL_BUTTON_STATE_UNSUPPORTED); + + g_object_set (self->ext_install, "state", EXM_INSTALL_BUTTON_STATE_INSTALLING, NULL); + + // Move focus to previous widget to avoid losing it after the button becomes insensitive + gtk_widget_grab_focus (GTK_WIDGET (self->ext_author)); + gtk_widget_activate_action (GTK_WIDGET (button), "ext.install", "(sb)", self->uuid, warn); @@ -510,13 +525,13 @@ on_data_loaded (GObject *source, self->pk = pk; - if (self->signal_id > 0) - g_signal_handler_disconnect (self->show_more_btn, self->signal_id); + if (self->comments_signal_id > 0) + g_signal_handler_disconnect (self->show_more_btn, self->comments_signal_id); - self->signal_id = g_signal_connect (self->show_more_btn, - "clicked", - G_CALLBACK (show_more_comments), - self); + self->comments_signal_id = g_signal_connect (self->show_more_btn, + "clicked", + G_CALLBACK (show_more_comments), + self); queue_resolve_comments (self, pk, self->resolver_cancel); @@ -567,9 +582,13 @@ open_link (ExmDetailView *self, toplevel = GTK_WIDGET (gtk_widget_get_root (GTK_WIDGET (self))); if (strcmp (action_name, "detail.open-extensions") == 0) + { uri = gtk_uri_launcher_new (self->uri_extensions); + } else if (strcmp (action_name, "detail.open-homepage") == 0) + { uri = gtk_uri_launcher_new (self->uri_homepage); + } else if (strcmp (action_name, "detail.open-donation") == 0) { guint val; @@ -577,7 +596,9 @@ open_link (ExmDetailView *self, uri = gtk_uri_launcher_new (self->uri_donations[val]); } else + { g_critical ("open_link() invalid action: %s", action_name); + } gtk_uri_launcher_launch (uri, GTK_WINDOW (toplevel), NULL, NULL, NULL); } @@ -591,6 +612,14 @@ on_bind_manager (ExmDetailView *self) "extensions", &ext_model, NULL); + if (self->install_signal_id > 0) + g_signal_handler_disconnect (self->ext_install, self->install_signal_id); + + self->install_signal_id = g_signal_connect (self->manager, + "install-status", + G_CALLBACK (on_install_status), + self); + g_signal_connect_swapped (ext_model, "items-changed", G_CALLBACK (exm_detail_view_update), diff --git a/src/exm-install-button.c b/src/exm-install-button.c index fa503d8e..c6e21932 100644 --- a/src/exm-install-button.c +++ b/src/exm-install-button.c @@ -128,6 +128,10 @@ update_state (ExmInstallButton *button) gtk_widget_set_sensitive (GTK_WIDGET (button), TRUE); gtk_widget_add_css_class (GTK_WIDGET (button), "suggested-action"); break; + case EXM_INSTALL_BUTTON_STATE_INSTALLING: + gtk_label_set_label (button->label, _("Installing")); + gtk_widget_set_sensitive (GTK_WIDGET (button), FALSE); + break; case EXM_INSTALL_BUTTON_STATE_INSTALLED: gtk_label_set_label (button->label, C_("State", "Installed")); gtk_widget_set_sensitive (GTK_WIDGET (button), FALSE); diff --git a/src/exm-search-row.c b/src/exm-search-row.c index 881cb9dc..7e7b2d9a 100644 --- a/src/exm-search-row.c +++ b/src/exm-search-row.c @@ -31,23 +31,22 @@ struct _ExmSearchRow { GtkListBoxRow parent_instance; + ExmManager *manager; ExmSearchResult *search_result; - gboolean is_installed; - gboolean is_supported; gboolean compact; gchar *uuid; GtkLabel *description_label; ExmInstallButton *install_btn; + guint signal_id; }; G_DEFINE_FINAL_TYPE (ExmSearchRow, exm_search_row, GTK_TYPE_LIST_BOX_ROW) enum { PROP_0, + PROP_MANAGER, PROP_SEARCH_RESULT, - PROP_IS_INSTALLED, - PROP_IS_SUPPORTED, PROP_COMPACT, N_PROPS }; @@ -55,14 +54,12 @@ enum { static GParamSpec *properties [N_PROPS]; ExmSearchRow * -exm_search_row_new (ExmSearchResult *search_result, - gboolean is_installed, - gboolean is_supported) +exm_search_row_new (ExmManager *manager, + ExmSearchResult *search_result) { return g_object_new (EXM_TYPE_SEARCH_ROW, + "manager", manager, "search-result", search_result, - "is-installed", is_installed, - "is-supported", is_supported, NULL); } @@ -76,15 +73,12 @@ exm_search_row_get_property (GObject *object, switch (prop_id) { + case PROP_MANAGER: + g_value_set_object (value, self->manager); + break; case PROP_SEARCH_RESULT: g_value_set_object (value, self->search_result); break; - case PROP_IS_INSTALLED: - g_value_set_boolean (value, self->is_installed); - break; - case PROP_IS_SUPPORTED: - g_value_set_boolean (value, self->is_supported); - break; case PROP_COMPACT: g_value_set_boolean (value, self->compact); break; @@ -103,6 +97,9 @@ exm_search_row_set_property (GObject *object, switch (prop_id) { + case PROP_MANAGER: + self->manager = g_value_get_object (value); + break; case PROP_SEARCH_RESULT: self->search_result = g_value_get_object (value); if (self->search_result) @@ -113,12 +110,6 @@ exm_search_row_set_property (GObject *object, NULL); } break; - case PROP_IS_INSTALLED: - self->is_installed = g_value_get_boolean (value); - break; - case PROP_IS_SUPPORTED: - self->is_supported = g_value_get_boolean (value); - break; case PROP_COMPACT: self->compact = g_value_get_boolean (value); break; @@ -127,6 +118,17 @@ exm_search_row_set_property (GObject *object, } } +static void +on_install_status (ExmManager *manager G_GNUC_UNUSED, + ExmInstallButtonState state, + ExmSearchRow *self) +{ + g_object_set (self->install_btn, "state", state, NULL); + + if (self->signal_id > 0) + g_signal_handler_disconnect (self->manager, self->signal_id); +} + static void install_remote (GtkButton *button, ExmSearchRow *self) @@ -136,7 +138,18 @@ install_remote (GtkButton *button, g_object_get (self->install_btn, "state", &state, NULL); + self->signal_id = g_signal_connect_object (self->manager, + "install-status", + G_CALLBACK (on_install_status), + self, + G_CONNECT_DEFAULT); + warn = (state == EXM_INSTALL_BUTTON_STATE_UNSUPPORTED); + + g_object_set (self->install_btn, "state", EXM_INSTALL_BUTTON_STATE_INSTALLING, NULL); + + gtk_widget_grab_focus (GTK_WIDGET (self)); + gtk_widget_activate_action (GTK_WIDGET (button), "ext.install", "(sb)", self->uuid, warn); @@ -148,6 +161,8 @@ exm_search_row_constructed (GObject *object) ExmSearchRow *self = EXM_SEARCH_ROW (object); ExmInstallButtonState install_state; + gboolean is_installed; + gboolean is_supported; gchar *uuid, *description; g_object_get (self->search_result, @@ -155,11 +170,19 @@ exm_search_row_constructed (GObject *object) "description", &description, NULL); + gchar *shell_version; + g_object_get (self->manager, + "shell-version", + &shell_version, + NULL); + gtk_actionable_set_action_target (GTK_ACTIONABLE (self), "s", uuid); + is_installed = exm_manager_is_installed_uuid (self->manager, uuid); + is_supported = exm_search_result_supports_shell_version (self->search_result, shell_version); - install_state = self->is_installed + install_state = is_installed ? EXM_INSTALL_BUTTON_STATE_INSTALLED - : (self->is_supported + : (is_supported ? EXM_INSTALL_BUTTON_STATE_DEFAULT : EXM_INSTALL_BUTTON_STATE_UNSUPPORTED); @@ -190,6 +213,13 @@ exm_search_row_class_init (ExmSearchRowClass *klass) object_class->set_property = exm_search_row_set_property; object_class->constructed = exm_search_row_constructed; + properties [PROP_MANAGER] + = g_param_spec_object ("manager", + "Manager", + "Manager", + EXM_TYPE_MANAGER, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY); + properties [PROP_SEARCH_RESULT] = g_param_spec_object ("search-result", "Search Result", @@ -197,20 +227,6 @@ exm_search_row_class_init (ExmSearchRowClass *klass) EXM_TYPE_SEARCH_RESULT, G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY); - properties [PROP_IS_INSTALLED] = - g_param_spec_boolean ("is-installed", - "Is Installed", - "Is Installed", - FALSE, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY); - - properties [PROP_IS_SUPPORTED] = - g_param_spec_boolean ("is-supported", - "Is Supported", - "Is Supported", - FALSE, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY); - properties [PROP_COMPACT] = g_param_spec_boolean ("compact", "Compact", diff --git a/src/exm-search-row.h b/src/exm-search-row.h index 70234054..f76afba8 100644 --- a/src/exm-search-row.h +++ b/src/exm-search-row.h @@ -1,7 +1,29 @@ +/* + * exm-search-row.h + * + * Copyright 2022-2025 Matthew Jakeman + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + #pragma once -#include +#include +#include "local/exm-manager.h" #include "web/model/exm-search-result.h" G_BEGIN_DECLS @@ -10,8 +32,7 @@ G_BEGIN_DECLS G_DECLARE_FINAL_TYPE (ExmSearchRow, exm_search_row, EXM, SEARCH_ROW, GtkListBoxRow) -ExmSearchRow *exm_search_row_new (ExmSearchResult *search_result, - gboolean is_installed, - gboolean is_supported); +ExmSearchRow *exm_search_row_new (ExmManager *manager, + ExmSearchResult *search_result); G_END_DECLS diff --git a/src/exm-types.h b/src/exm-types.h index f1a339bd..57447593 100644 --- a/src/exm-types.h +++ b/src/exm-types.h @@ -1,3 +1,24 @@ +/* + * exm-types.h + * + * Copyright 2022-2025 Matthew Jakeman + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + #pragma once // Should really be in the `local/` subdirectory but meson's mkenums @@ -25,6 +46,7 @@ typedef enum typedef enum { EXM_INSTALL_BUTTON_STATE_DEFAULT, + EXM_INSTALL_BUTTON_STATE_INSTALLING, EXM_INSTALL_BUTTON_STATE_INSTALLED, EXM_INSTALL_BUTTON_STATE_UNSUPPORTED } ExmInstallButtonState; diff --git a/src/exm-window.c b/src/exm-window.c index d2267258..a9bb862a 100644 --- a/src/exm-window.c +++ b/src/exm-window.c @@ -27,6 +27,7 @@ #include "exm-error-dialog.h" #include "exm-installed-page.h" #include "exm-screenshot-view.h" +#include "exm-types.h" #include "exm-upgrade-assistant.h" #include "local/exm-extension.h" #include "local/exm-manager.h" @@ -121,10 +122,8 @@ extension_remove_dialog_response (AdwAlertDialog *dialog, { const char *response = adw_alert_dialog_choose_finish (dialog, result); - if (strcmp(response, "yes") == 0) - { + if (g_str_equal (response, "yes")) exm_manager_remove_extension (data->manager, data->extension); - } g_clear_pointer (&data->manager, g_object_unref); g_clear_pointer (&data->extension, g_object_unref); @@ -153,26 +152,59 @@ extension_remove (GtkWidget *widget, (GAsyncReadyCallback) extension_remove_dialog_response, data); } +typedef struct +{ + ExmManager *manager; + gchar *uuid; +} UnsupportedDialogData; + static void -on_install_done (GObject *source, - GAsyncResult *res, - gpointer user_data G_GNUC_UNUSED) +on_install_done (GObject *source, + GAsyncResult *res, + gpointer user_data) { + ExmWindow *self = NULL; + UnsupportedDialogData *data = NULL; + ExmManager *manager = NULL; + ExmInstallButtonState state; GError *error = NULL; - if (!exm_manager_install_finish (source, res, &error) && error) + if (G_IS_OBJECT (user_data)) + { + self = (ExmWindow *)user_data; + manager = self->manager; + state = EXM_INSTALL_BUTTON_STATE_DEFAULT; + } + else + { + data = (UnsupportedDialogData *)user_data; + manager = data->manager; + state = EXM_INSTALL_BUTTON_STATE_UNSUPPORTED; + } + + if (!exm_manager_install_finish (source, res, &error)) { // TODO: Properly log this - g_critical ("%s\n", error->message); - g_clear_error (&error); + if (error) + { + g_critical ("%s\n", error->message); + g_clear_error (&error); + } + + g_signal_emit_by_name (manager, "install-status", state); + } + else + { + g_signal_emit_by_name (manager, "install-status", EXM_INSTALL_BUTTON_STATE_INSTALLED); } -} -typedef struct -{ - ExmManager *manager; - gchar *uuid; -} UnsupportedDialogData; + if (data) + { + g_clear_pointer (&data->manager, g_object_unref); + g_clear_pointer (&data->uuid, g_free); + g_free (data); + } +} static void extension_unsupported_dialog_response (AdwAlertDialog *dialog, @@ -181,16 +213,20 @@ extension_unsupported_dialog_response (AdwAlertDialog *dialog, { const char *response = adw_alert_dialog_choose_finish (dialog, result); - if (strcmp(response, "install") == 0) + if (g_str_equal (response, "install")) { exm_manager_install_async (data->manager, data->uuid, NULL, (GAsyncReadyCallback) on_install_done, - NULL); + data); } + else + { + g_signal_emit_by_name (data->manager, "install-status", EXM_INSTALL_BUTTON_STATE_UNSUPPORTED); - g_clear_pointer (&data->manager, g_object_unref); - g_clear_pointer (&data->uuid, g_free); - g_free (data); + g_clear_pointer (&data->manager, g_object_unref); + g_clear_pointer (&data->uuid, g_free); + g_free (data); + } } static void @@ -210,6 +246,7 @@ extension_install (GtkWidget *widget, UnsupportedDialogData *data = g_new0 (UnsupportedDialogData, 1); data->manager = g_object_ref (self->manager); data->uuid = g_strdup (uuid); + g_free (uuid); adw_alert_dialog_choose (self->unsupported_dialog, widget, NULL, (GAsyncReadyCallback) extension_unsupported_dialog_response, data); @@ -328,7 +365,7 @@ search_online (GtkWidget *widget, search_entry = exm_browse_page_get_search_entry (self->browse_page); search_text = gtk_editable_get_text (GTK_EDITABLE (gtk_search_bar_get_child (self->search_bar))); adw_view_stack_set_visible_child_name (self->view_stack, "browse"); - gtk_editable_set_text (GTK_EDITABLE (search_entry) , search_text); + gtk_editable_set_text (GTK_EDITABLE (search_entry), search_text); gtk_toggle_button_set_active (self->search_button, FALSE); } diff --git a/src/local/exm-manager.c b/src/local/exm-manager.c index 50374c2d..4111e899 100644 --- a/src/local/exm-manager.c +++ b/src/local/exm-manager.c @@ -55,6 +55,7 @@ enum { SIGNAL_0, SIGNAL_UPDATES_AVAILABLE, SIGNAL_ERROR_OCCURRED, + SIGNAL_INSTALL_STATUS, N_SIGNALS }; @@ -371,12 +372,23 @@ exm_manager_install_finish (GObject *self, GAsyncResult *result, GError **error) { + gchar *out_result = NULL; + gboolean success; + g_return_val_if_fail (SHELL_IS_EXTENSIONS (self), FALSE); - return shell_extensions_call_install_remote_extension_finish (SHELL_EXTENSIONS (self), - NULL, - result, - error); + success = shell_extensions_call_install_remote_extension_finish (SHELL_EXTENSIONS (self), + &out_result, + result, + error); + + if (g_str_equal (out_result, "cancelled")) + { + success = FALSE; + g_free (out_result); + } + + return success; } static int @@ -501,6 +513,14 @@ exm_manager_class_init (ExmManagerClass *klass) 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_STRING); + + signals [SIGNAL_INSTALL_STATUS] + = g_signal_new ("install-status", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST|G_SIGNAL_NO_RECURSE|G_SIGNAL_NO_HOOKS, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 1, + EXM_TYPE_INSTALL_BUTTON_STATE); } static void