diff --git a/src/bz-application.c b/src/bz-application.c index f4632196..b0b75e9d 100644 --- a/src/bz-application.c +++ b/src/bz-application.c @@ -218,7 +218,7 @@ static DexFuture * watch_backend_notifs_then_loop_cb (DexFuture *future, GWeakRef *wr); -static void +static BzEntryGroup * fiber_replace_entry (BzApplication *self, BzEntry *entry); @@ -1119,10 +1119,11 @@ init_fiber (GWeakRef *wr) entries, (GCompareDataFunc) cmp_entry, NULL); for (guint i = 0; i < entries->len; i++) { - BzEntry *entry = NULL; + BzEntry *entry = NULL; + g_autoptr (BzEntryGroup) group = NULL; entry = g_ptr_array_index (entries, i); - fiber_replace_entry (self, entry); + group = fiber_replace_entry (self, entry); } gtk_filter_changed (GTK_FILTER (self->group_filter), GTK_FILTER_CHANGE_LESS_STRICT); @@ -1310,23 +1311,17 @@ respond_to_flatpak_fiber (RespondToFlatpakData *data) break; case BZ_BACKEND_NOTIFICATION_KIND_REPLACE_ENTRY: { - BzEntry *entry = NULL; + BzEntry *entry = NULL; + g_autoptr (BzEntryGroup) group = NULL; entry = bz_backend_notification_get_entry (notif); - fiber_replace_entry (self, entry); + group = fiber_replace_entry (self, entry); g_ptr_array_add (build_futures, bz_entry_cache_manager_add (self->cache, entry)); - if (bz_entry_is_of_kinds (entry, BZ_ENTRY_KIND_APPLICATION)) + if (group != NULL) { - const char *id = NULL; - BzEntryGroup *group = NULL; - update_filters = TRUE; - - id = bz_entry_get_id (entry); - group = g_hash_table_lookup (self->ids_to_groups, id); - if (group != NULL) - g_ptr_array_add (build_notify_groups, g_object_ref (group)); + g_ptr_array_add (build_notify_groups, g_object_ref (group)); } self->n_notifications_incoming--; @@ -1626,6 +1621,7 @@ open_flatpakref_fiber (OpenFlatpakrefData *data) g_autoptr (BzApplication) self = NULL; GFile *file = data->file; g_autoptr (GError) local_error = NULL; + gboolean result = FALSE; g_autoptr (DexFuture) future = NULL; GtkWindow *window = NULL; const GValue *value = NULL; @@ -1647,14 +1643,36 @@ open_flatpakref_fiber (OpenFlatpakrefData *data) { BzEntry *entry = NULL; - entry = g_value_get_object (value); - bz_window_show_entry (BZ_WINDOW (window), entry); + entry = g_value_get_object (value); + result = dex_await (bz_entry_cache_manager_add (self->cache, entry), &local_error); + if (result) + { + g_autoptr (BzEntryGroup) group = NULL; + + group = fiber_replace_entry (self, entry); + if (group != NULL) + bz_window_show_group (BZ_WINDOW (window), group); + else + /* TODO: handle standalone addons & runtimes in dedicated UI */ + bz_show_error_for_widget ( + GTK_WIDGET (window), + "Non-Application Bundle", + "This flatpak ref is a standalone addon/runtime"); + } + else + bz_show_error_for_widget ( + GTK_WIDGET (window), + _ ("Failed to open package"), + local_error->message); } else open_generic_id (self, g_value_get_string (value)); } else - bz_show_error_for_widget (GTK_WIDGET (window), _ ("Failed to open .flatpakref"), local_error->message); + bz_show_error_for_widget ( + GTK_WIDGET (window), + _ ("Failed to open package"), + local_error->message); return dex_future_new_true (); } @@ -1845,7 +1863,7 @@ watch_backend_notifs_then_loop_cb (DexFuture *future, return g_steal_pointer (&ret_future); } -static void +static BzEntryGroup * fiber_replace_entry (BzApplication *self, BzEntry *entry) { @@ -1856,6 +1874,7 @@ fiber_replace_entry (BzApplication *self, gboolean installed = FALSE; const char *flatpak_id = NULL; const char *version = NULL; + g_autoptr (BzEntryGroup) group = NULL; id = bz_entry_get_id (entry); unique_id = bz_entry_get_unique_id (entry); @@ -1863,7 +1882,7 @@ fiber_replace_entry (BzApplication *self, if (id == NULL || unique_id == NULL || unique_id_checksum == NULL) - return; + return NULL; user = bz_flatpak_entry_is_user (BZ_FLATPAK_ENTRY (entry)); installed = g_hash_table_contains (self->installed_set, unique_id); @@ -1904,12 +1923,12 @@ fiber_replace_entry (BzApplication *self, if (bz_entry_is_of_kinds (entry, BZ_ENTRY_KIND_APPLICATION)) { - BzEntryGroup *group = NULL; - gboolean ignore_eol = FALSE; - const char *runtime_name = NULL; - BzEntry *eol_runtime = NULL; + BzEntryGroup *existing_group = NULL; + gboolean ignore_eol = FALSE; + const char *runtime_name = NULL; + BzEntry *eol_runtime = NULL; - group = g_hash_table_lookup (self->ids_to_groups, id); + existing_group = g_hash_table_lookup (self->ids_to_groups, id); if (self->ignore_eol_set != NULL) ignore_eol = g_hash_table_contains (self->ignore_eol_set, id); @@ -1917,13 +1936,15 @@ fiber_replace_entry (BzApplication *self, if (!ignore_eol && runtime_name != NULL) eol_runtime = g_hash_table_lookup (self->eol_runtimes, runtime_name); - if (group != NULL) + if (existing_group != NULL) { - bz_entry_group_add (group, entry, eol_runtime, ignore_eol); - if (installed && !g_list_store_find (self->installed_apps, group, NULL)) + bz_entry_group_add (existing_group, entry, eol_runtime, ignore_eol); + if (installed && !g_list_store_find (self->installed_apps, existing_group, NULL)) g_list_store_insert_sorted ( - self->installed_apps, group, + self->installed_apps, existing_group, (GCompareDataFunc) cmp_group, NULL); + + group = g_object_ref (existing_group); } else { @@ -1940,6 +1961,8 @@ fiber_replace_entry (BzApplication *self, g_list_store_insert_sorted ( self->installed_apps, new_group, (GCompareDataFunc) cmp_group, NULL); + + group = g_object_ref (new_group); } } @@ -1996,6 +2019,8 @@ fiber_replace_entry (BzApplication *self, "does not seem to extend anything", unique_id); } + + return g_steal_pointer (&group); } static void diff --git a/src/bz-entry-group.c b/src/bz-entry-group.c index d9df0f21..4af6e8a3 100644 --- a/src/bz-entry-group.c +++ b/src/bz-entry-group.c @@ -509,86 +509,6 @@ bz_entry_group_new (BzApplicationMapFactory *factory) return group; } -BzEntryGroup * -bz_entry_group_new_for_single_entry (BzEntry *entry) -{ - BzEntryGroup *group = NULL; - const char *id = NULL; - const char *unique_id = NULL; - const char *title = NULL; - const char *developer = NULL; - const char *description = NULL; - GIcon *mini_icon = NULL; - const char *search_tokens = NULL; - gboolean is_floss = FALSE; - const char *light_accent_color = NULL; - const char *dark_accent_color = NULL; - gboolean is_flathub = FALSE; - gboolean is_verified = FALSE; - const char *eol = NULL; - guint64 installed_size = 0; - const char *donation_url = NULL; - GListModel *entry_categories = NULL; - DexFuture *future = NULL; - - g_return_val_if_fail (BZ_IS_ENTRY (entry), NULL); - - group = g_object_new (BZ_TYPE_ENTRY_GROUP, NULL); - - id = bz_entry_get_id (entry); - unique_id = bz_entry_get_unique_id (entry); - title = bz_entry_get_title (entry); - developer = bz_entry_get_developer (entry); - description = bz_entry_get_description (entry); - mini_icon = bz_entry_get_mini_icon (entry); - search_tokens = bz_entry_get_search_tokens (entry); - is_floss = bz_entry_get_is_foss (entry); - light_accent_color = bz_entry_get_light_accent_color (entry); - dark_accent_color = bz_entry_get_dark_accent_color (entry); - is_flathub = bz_entry_get_is_flathub (entry); - is_verified = bz_entry_is_verified (entry); - eol = bz_entry_get_eol (entry); - installed_size = bz_entry_get_installed_size (entry); - donation_url = bz_entry_get_donation_url (entry); - entry_categories = bz_entry_get_categories (entry); - - if (id != NULL) - group->id = g_strdup (id); - if (title != NULL) - group->title = g_strdup (title); - if (developer != NULL) - group->developer = g_strdup (developer); - if (description != NULL) - group->description = g_strdup (description); - if (mini_icon != NULL) - group->mini_icon = g_object_ref (mini_icon); - if (search_tokens != NULL) - group->search_tokens = g_strdup (search_tokens); - group->is_floss = is_floss; - if (light_accent_color != NULL) - group->light_accent_color = g_strdup (light_accent_color); - if (dark_accent_color != NULL) - group->dark_accent_color = g_strdup (dark_accent_color); - group->is_flathub = is_flathub; - group->is_verified = is_verified; - if (eol != NULL) - group->eol = g_strdup (eol); - group->installed_size = installed_size; - if (donation_url != NULL) - group->donation_url = g_strdup (donation_url); - if (entry_categories != NULL) - group->categories = g_object_ref (entry_categories); - - if (unique_id != NULL) - gtk_string_list_append (group->unique_ids, unique_id); - - future = dex_future_new_for_object (entry); - group->standalone_ui_entry = bz_result_new (future); - dex_unref (future); - - return group; -} - GMutexLocker * bz_entry_group_lock (BzEntryGroup *self) { diff --git a/src/bz-entry-group.h b/src/bz-entry-group.h index 88a5133d..dd6b6f2a 100644 --- a/src/bz-entry-group.h +++ b/src/bz-entry-group.h @@ -32,9 +32,6 @@ G_DECLARE_FINAL_TYPE (BzEntryGroup, bz_entry_group, BZ, ENTRY_GROUP, GObject) BzEntryGroup * bz_entry_group_new (BzApplicationMapFactory *factory); -BzEntryGroup * -bz_entry_group_new_for_single_entry (BzEntry *entry); - /* Only necessary if reading props from another thread, writing is always prohibited */ GMutexLocker * diff --git a/src/bz-flatpak-entry.c b/src/bz-flatpak-entry.c index bd155198..5aefcf32 100644 --- a/src/bz-flatpak-entry.c +++ b/src/bz-flatpak-entry.c @@ -41,8 +41,8 @@ struct _BzFlatpakEntry BzEntry parent_instance; gboolean user; - gboolean is_bundle; gboolean is_installed_ref; + char *bundle_uri; char *flatpak_name; char *flatpak_id; char *flatpak_version; @@ -71,7 +71,7 @@ enum PROP_USER, PROP_FLATPAK_NAME, - PROP_IS_BUNDLE, + PROP_BUNDLE_URI, PROP_FLATPAK_ID, PROP_FLATPAK_VERSION, PROP_APPLICATION_NAME, @@ -124,8 +124,8 @@ bz_flatpak_entry_get_property (GObject *object, case PROP_APPLICATION_NAME: g_value_set_string (value, self->application_name); break; - case PROP_IS_BUNDLE: - g_value_set_boolean (value, self->is_bundle); + case PROP_BUNDLE_URI: + g_value_set_string (value, self->bundle_uri); break; case PROP_APPLICATION_RUNTIME: g_value_set_string (value, self->application_runtime); @@ -162,7 +162,7 @@ bz_flatpak_entry_set_property (GObject *object, case PROP_FLATPAK_ID: case PROP_FLATPAK_VERSION: case PROP_APPLICATION_NAME: - case PROP_IS_BUNDLE: + case PROP_BUNDLE_URI: case PROP_APPLICATION_RUNTIME: case PROP_APPLICATION_COMMAND: case PROP_RUNTIME_NAME: @@ -212,11 +212,10 @@ bz_flatpak_entry_class_init (BzFlatpakEntryClass *klass) NULL, NULL, NULL, G_PARAM_READABLE); - props[PROP_IS_BUNDLE] = - g_param_spec_boolean ( - "is-bundle", - NULL, NULL, - FALSE, + props[PROP_BUNDLE_URI] = + g_param_spec_string ( + "bundle-uri", + NULL, NULL, NULL, G_PARAM_READABLE); props[PROP_APPLICATION_RUNTIME] = @@ -266,6 +265,8 @@ bz_flatpak_entry_real_serialize (BzSerializable *serializable, g_variant_builder_add (builder, "{sv}", "user", g_variant_new_boolean (self->user)); g_variant_builder_add (builder, "{sv}", "is-installed-ref", g_variant_new_boolean (self->is_installed_ref)); + if (self->bundle_uri != NULL) + g_variant_builder_add (builder, "{sv}", "bundle-uri", g_variant_new_string (self->bundle_uri)); if (self->flatpak_name != NULL) g_variant_builder_add (builder, "{sv}", "flatpak-name", g_variant_new_string (self->flatpak_name)); if (self->flatpak_id != NULL) @@ -309,6 +310,8 @@ bz_flatpak_entry_real_deserialize (BzSerializable *serializable, self->user = g_variant_get_boolean (value); else if (g_strcmp0 (key, "is-installed-ref") == 0) self->is_installed_ref = g_variant_get_boolean (value); + else if (g_strcmp0 (key, "bundle-uri") == 0) + self->bundle_uri = g_variant_dup_string (value, NULL); else if (g_strcmp0 (key, "flatpak-name") == 0) self->flatpak_name = g_variant_dup_string (value, NULL); else if (g_strcmp0 (key, "flatpak-id") == 0) @@ -400,7 +403,6 @@ bz_flatpak_entry_new_for_ref (FlatpakRef *ref, self = g_object_new (BZ_TYPE_FLATPAK_ENTRY, NULL); self->user = user; - self->is_bundle = FLATPAK_IS_BUNDLE_REF (ref); self->is_installed_ref = FLATPAK_IS_INSTALLED_REF (ref); self->ref = g_object_ref (ref); @@ -505,8 +507,17 @@ bz_flatpak_entry_new_for_ref (FlatpakRef *ref, else if (FLATPAK_IS_BUNDLE_REF (ref)) { g_autoptr (GFileInfo) file_info = NULL; + g_autoptr (GFile) bundle_file = NULL; - GFile *bundle_file = flatpak_bundle_ref_get_file (FLATPAK_BUNDLE_REF (ref)); + bundle_file = flatpak_bundle_ref_get_file (FLATPAK_BUNDLE_REF (ref)); + self->bundle_uri = g_file_get_uri (bundle_file); + if (self->bundle_uri == NULL) + { + g_autofree char *path = NULL; + + path = g_file_get_path (bundle_file); + self->bundle_uri = g_strdup_printf ("file://%s", path); + } file_info = g_file_query_info (bundle_file, G_FILE_ATTRIBUTE_STANDARD_SIZE, @@ -754,11 +765,11 @@ bz_flatpak_entry_get_addon_extension_of_ref (BzFlatpakEntry *self) return self->addon_extension_of_ref; } -gboolean -bz_flatpak_entry_is_bundle (BzFlatpakEntry *self) +const char * +bz_flatpak_entry_get_bundle_uri (BzFlatpakEntry *self) { g_return_val_if_fail (BZ_IS_FLATPAK_ENTRY (self), FALSE); - return self->is_bundle; + return self->bundle_uri; } gboolean @@ -816,6 +827,7 @@ bz_flatpak_entry_launch (BzFlatpakEntry *self, static void clear_entry (BzFlatpakEntry *self) { + g_clear_pointer (&self->bundle_uri, g_free); g_clear_pointer (&self->flatpak_name, g_free); g_clear_pointer (&self->flatpak_id, g_free); g_clear_pointer (&self->flatpak_version, g_free); diff --git a/src/bz-flatpak-entry.h b/src/bz-flatpak-entry.h index 5c85e1c2..a11cc488 100644 --- a/src/bz-flatpak-entry.h +++ b/src/bz-flatpak-entry.h @@ -57,8 +57,8 @@ bz_flatpak_entry_get_runtime_name (BzFlatpakEntry *self); BzResult * bz_flatpak_entry_dup_runtime_result (BzFlatpakEntry *self); -gboolean -bz_flatpak_entry_is_bundle (BzFlatpakEntry *self); +const char * +bz_flatpak_entry_get_bundle_uri (BzFlatpakEntry *self); gboolean bz_flatpak_entry_is_installed_ref (BzFlatpakEntry *self); diff --git a/src/bz-flatpak-instance.c b/src/bz-flatpak-instance.c index 24d4ce22..59b54b35 100644 --- a/src/bz-flatpak-instance.c +++ b/src/bz-flatpak-instance.c @@ -958,7 +958,7 @@ load_local_ref_fiber (LoadLocalRefData *data) return dex_future_new_take_string (g_steal_pointer (&name)); } else - /* This is a bundle ref */ + /* Otherwise, this is a bundle ref */ { g_autoptr (FlatpakBundleRef) bref = NULL; g_autoptr (BzFlatpakEntry) entry = NULL; @@ -1813,13 +1813,15 @@ transaction_fiber (TransactionData *data) BzFlatpakEntry *entry = NULL; FlatpakRef *ref = NULL; gboolean is_user = FALSE; + const char *bundle_uri = NULL; g_autofree char *ref_fmt = NULL; g_autoptr (FlatpakTransaction) transaction = NULL; - entry = g_ptr_array_index (installations, i); - ref = bz_flatpak_entry_get_ref (entry); - is_user = bz_flatpak_entry_is_user (BZ_FLATPAK_ENTRY (entry)); - ref_fmt = flatpak_ref_format_ref (ref); + entry = g_ptr_array_index (installations, i); + ref = bz_flatpak_entry_get_ref (entry); + is_user = bz_flatpak_entry_is_user (BZ_FLATPAK_ENTRY (entry)); + bundle_uri = bz_flatpak_entry_get_bundle_uri (entry); + ref_fmt = flatpak_ref_format_ref (ref); if ((is_user && self->user == NULL) || (!is_user && self->system == NULL)) @@ -1848,12 +1850,24 @@ transaction_fiber (TransactionData *data) local_error->message); } - result = flatpak_transaction_add_install ( - transaction, - bz_entry_get_remote_repo_name (BZ_ENTRY (entry)), - ref_fmt, - NULL, - &local_error); + if (bundle_uri != NULL) + { + g_autoptr (GFile) file = NULL; + + file = g_file_new_for_uri (bundle_uri); + result = flatpak_transaction_add_install_bundle ( + transaction, + file, + NULL, + &local_error); + } + else + result = flatpak_transaction_add_install ( + transaction, + bz_entry_get_remote_repo_name (BZ_ENTRY (entry)), + ref_fmt, + NULL, + &local_error); if (!result) { dex_channel_close_send (channel); diff --git a/src/bz-full-view.blp b/src/bz-full-view.blp index 2812b6c7..a3fb06d4 100644 --- a/src/bz-full-view.blp +++ b/src/bz-full-view.blp @@ -126,11 +126,6 @@ template $BzFullView: Adw.Bin { margin-bottom: 15; spacing: 20; - Adw.Banner { - title: _("Installing .flatpak bundles is not yet supported"); - revealed: bind template.ui-entry as <$BzResult>.object as <$BzFlatpakEntry>.is-bundle as ; - } - Adw.Clamp { maximum-size: 860; tightening-threshold: 1000; diff --git a/src/bz-window.c b/src/bz-window.c index ad04032a..e5cc7e64 100644 --- a/src/bz-window.c +++ b/src/bz-window.c @@ -883,26 +883,6 @@ bz_window_search (BzWindow *self, search (self, text); } -void -bz_window_show_entry (BzWindow *self, - BzEntry *entry) -{ - g_autoptr (BzEntryGroup) group = NULL; - AdwNavigationPage *view_page = NULL; - - g_return_if_fail (BZ_IS_WINDOW (self)); - g_return_if_fail (BZ_IS_ENTRY (entry)); - - group = bz_entry_group_new_for_single_entry (entry); - bz_full_view_set_entry_group (self->full_view, group); - - view_page = adw_navigation_view_find_page (self->navigation_view, "view"); - if (view_page != NULL) - adw_navigation_view_pop_to_page (self->navigation_view, view_page); - else - adw_navigation_view_push_by_tag (self->navigation_view, "view"); -} - void bz_window_show_group (BzWindow *self, BzEntryGroup *group) diff --git a/src/bz-window.h b/src/bz-window.h index 7f58d6b4..c0fa0bd4 100644 --- a/src/bz-window.h +++ b/src/bz-window.h @@ -39,10 +39,6 @@ bz_window_search (BzWindow *self, void bz_window_push_update_dialog (BzWindow *self); -void -bz_window_show_entry (BzWindow *self, - BzEntry *entry); - void bz_window_show_group (BzWindow *self, BzEntryGroup *group);