diff --git a/src/bz-application.c b/src/bz-application.c index 824cfa96..b6c0545d 100644 --- a/src/bz-application.c +++ b/src/bz-application.c @@ -189,6 +189,11 @@ static void open_metainfo_take (BzApplication *self, GFile *file); +static void +open_location_take (BzApplication *self, + const char *name_for_suffix_check, + GFile *file); + static DexFuture * backend_sync_finally (DexFuture *future, BzWeakRef *wr); @@ -673,6 +678,28 @@ bz_application_show_app_id_action (GSimpleAction *action, } } +static void +bz_application_open_location_action (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) +{ + BzApplication *self = user_data; + const char *uri = NULL; + g_autoptr (GFile) file = NULL; + g_autofree char *basename = NULL; + + g_assert (BZ_IS_APPLICATION (self)); + + uri = g_variant_get_string (parameter, NULL); + if (uri == NULL || *uri == '\0') + return; + + file = g_file_new_for_uri (uri); + basename = g_file_get_basename (file); + + open_location_take (self, basename, g_object_ref (file)); +} + static void bz_application_sync_remotes_action (GSimpleAction *action, GVariant *parameter, @@ -848,6 +875,7 @@ static const GActionEntry app_actions[] = { { "donate", bz_application_donate_action, NULL }, { "bazaar-inspector", bz_application_bazaar_inspector_action, NULL }, { "toggle-debug-mode", bz_application_toggle_debug_mode_action, NULL }, + { "open-location", bz_application_open_location_action, "s" }, }; static void @@ -3790,6 +3818,19 @@ open_metainfo_take (BzApplication *self, g_object_unref (file); } +static void +open_location_take (BzApplication *self, + const char *name_for_suffix_check, + GFile *file) +{ + if (name_for_suffix_check != NULL && + (g_str_has_suffix (name_for_suffix_check, ".metainfo.xml") || + g_str_has_suffix (name_for_suffix_check, ".appdata.xml"))) + open_metainfo_take (self, file); + else + open_flatpakref_take (self, file); +} + static void command_line_open_location (BzApplication *self, GApplicationCommandLine *cmdline, @@ -3818,11 +3859,7 @@ command_line_open_location (BzApplication *self, : g_file_new_for_path (location); } - if (g_str_has_suffix (location, ".metainfo.xml") || - g_str_has_suffix (location, ".appdata.xml")) - open_metainfo_take (self, g_steal_pointer (&file)); - else - open_flatpakref_take (self, g_steal_pointer (&file)); + open_location_take (self, location, g_steal_pointer (&file)); } static void diff --git a/src/bz-window.blp b/src/bz-window.blp index 2b4397e6..6740db77 100644 --- a/src/bz-window.blp +++ b/src/bz-window.blp @@ -32,6 +32,13 @@ template $BzWindow: Adw.ApplicationWindow { } } + DropTarget drop_target { + actions: copy; + + accept => $drop_accept_cb(template); + drop => $drop_cb(template); + } + content: Gtk.Overlay window_overlay { child: Adw.ToolbarView { content: Adw.BreakpointBin split_breakpoint_bin { diff --git a/src/bz-window.c b/src/bz-window.c index d1c8a796..83858926 100644 --- a/src/bz-window.c +++ b/src/bz-window.c @@ -67,6 +67,7 @@ struct _BzWindow AdwViewStack *main_view_stack; GtkStack *main_stack; GtkOverlay *window_overlay; + GtkDropTarget *drop_target; }; G_DEFINE_FINAL_TYPE (BzWindow, bz_window, ADW_TYPE_APPLICATION_WINDOW) @@ -394,6 +395,34 @@ format_title (gpointer object, return g_strdup_printf (_ ("Bazaar — %s"), title); } +static gboolean +drop_accept_cb (BzWindow *self, + GdkDrop *drop, + GtkDropTarget *target) +{ + return !bz_state_info_get_busy (self->state) && + self->screenshot_page == NULL && + adw_application_window_get_visible_dialog (ADW_APPLICATION_WINDOW (self)) == NULL; +} + +static gboolean +drop_cb (BzWindow *self, + const GValue *value, + double x, + double y, + GtkDropTarget *target) +{ + GFile *file = NULL; + g_autofree char *uri = NULL; + + file = G_FILE (g_value_get_object (value)); + uri = g_file_get_uri (file); + + gtk_widget_activate_action (GTK_WIDGET (self), "app.open-location", "s", uri); + + return TRUE; +} + static BzEntryGroup * resolve_group_from_parameter (BzWindow *self, GVariant *parameter, @@ -786,6 +815,7 @@ bz_window_class_init (BzWindowClass *klass) gtk_widget_class_bind_template_child (widget_class, BzWindow, main_view_stack); gtk_widget_class_bind_template_child (widget_class, BzWindow, main_stack); gtk_widget_class_bind_template_child (widget_class, BzWindow, window_overlay); + gtk_widget_class_bind_template_child (widget_class, BzWindow, drop_target); gtk_widget_class_bind_template_callback (widget_class, list_length); gtk_widget_class_bind_template_callback (widget_class, update_cb); gtk_widget_class_bind_template_callback (widget_class, page_toggled_cb); @@ -797,6 +827,8 @@ bz_window_class_init (BzWindowClass *klass) gtk_widget_class_bind_template_callback (widget_class, open_search_cb); gtk_widget_class_bind_template_callback (widget_class, format_progress); gtk_widget_class_bind_template_callback (widget_class, format_title); + gtk_widget_class_bind_template_callback (widget_class, drop_accept_cb); + gtk_widget_class_bind_template_callback (widget_class, drop_cb); gtk_widget_class_install_action (widget_class, "escape", NULL, action_escape); gtk_widget_class_install_action (widget_class, "window.user-data", NULL, action_user_data); @@ -874,6 +906,7 @@ bz_window_init (BzWindow *self) G_CALLBACK (key_pressed), self); gtk_widget_add_controller (GTK_WIDGET (self), self->key_controller); + gtk_drop_target_set_gtypes (self->drop_target, (GType[]) { G_TYPE_FILE }, 1); } static void