summaryrefslogtreecommitdiffstats
path: root/debian/patches/mime-actions-Open-files-as-groups-if-not-sandboxed.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/mime-actions-Open-files-as-groups-if-not-sandboxed.patch')
-rw-r--r--debian/patches/mime-actions-Open-files-as-groups-if-not-sandboxed.patch359
1 files changed, 359 insertions, 0 deletions
diff --git a/debian/patches/mime-actions-Open-files-as-groups-if-not-sandboxed.patch b/debian/patches/mime-actions-Open-files-as-groups-if-not-sandboxed.patch
new file mode 100644
index 0000000..f9c6337
--- /dev/null
+++ b/debian/patches/mime-actions-Open-files-as-groups-if-not-sandboxed.patch
@@ -0,0 +1,359 @@
+From: =?utf-8?q?Ant=C3=B3nio_Fernandes?= <antoniof@gnome.org>
+Date: Wed, 30 Dec 2020 15:54:59 +0000
+Subject: mime-actions: Open files as groups if not sandboxed
+
+While sandboxed, we open files using the OpenURI portal, and we don't
+know which app is the default handler app for each file. As such, we
+have given up group-launching files with the same default handler when
+adapting nautilus to being sandboxed.[0]
+
+But this resulted in a feature regression in the non-sandboxed case,
+which is still the common case in production.
+
+Reinstate the code for the old behaviour[1], but keep the current
+behaviour when running in inside a flatpak sandbox.
+
+Bug: https://gitlab.gnome.org/GNOME/nautilus/-/issues/117
+
+[0] f5206a6daf0991d91e885a28bb66795a8ae12a41
+[1] based on revert patch with revert conflicts resolved by hadess
+
+Origin: upstream, 40.rc, commit:080f83385ff79a8be54ee31e7a45422138226f1f
+---
+ src/nautilus-mime-actions.c | 238 +++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 215 insertions(+), 23 deletions(-)
+
+diff --git a/src/nautilus-mime-actions.c b/src/nautilus-mime-actions.c
+index 26468c5..cbff2fa 100644
+--- a/src/nautilus-mime-actions.c
++++ b/src/nautilus-mime-actions.c
+@@ -61,6 +61,12 @@ typedef struct
+ char *uri;
+ } LaunchLocation;
+
++typedef struct
++{
++ GAppInfo *application;
++ GList *uris;
++} ApplicationLaunchParameters;
++
+ typedef struct
+ {
+ NautilusWindowSlot *slot;
+@@ -85,7 +91,7 @@ typedef struct
+ ActivateParameters *activation_params;
+ GQueue *uris;
+ GQueue *unhandled_uris;
+-} ApplicationLaunchParameters;
++} ApplicationLaunchAsyncParameters;
+
+ /* Microsoft mime types at https://blogs.msdn.microsoft.com/vsofficedeveloper/2008/05/08/office-2007-file-format-mime-types-for-http-content-streaming-2/ */
+ struct
+@@ -345,19 +351,27 @@ launch_locations_from_file_list (GList *list)
+ }
+
+ static ApplicationLaunchParameters *
+-application_launch_parameters_new (ActivateParameters *activation_params,
+- GQueue *uris)
++application_launch_parameters_new (GAppInfo *application,
++ GList *uris)
+ {
+ ApplicationLaunchParameters *result;
+
+ result = g_new0 (ApplicationLaunchParameters, 1);
+- result->activation_params = activation_params;
+- result->uris = uris;
+- result->unhandled_uris = g_queue_new ();
++ result->application = g_object_ref (application);
++ result->uris = g_list_copy_deep (uris, (GCopyFunc) g_strdup, NULL);
+
+ return result;
+ }
+
++static void
++application_launch_parameters_free (ApplicationLaunchParameters *parameters)
++{
++ g_object_unref (parameters->application);
++ g_list_free_full (parameters->uris, g_free);
++
++ g_free (parameters);
++}
++
+ static gboolean
+ nautilus_mime_actions_check_if_required_attributes_ready (NautilusFile *file)
+ {
+@@ -792,6 +806,114 @@ nautilus_mime_file_opens_in_external_app (NautilusFile *file)
+ return (activation_action == ACTIVATION_ACTION_OPEN_IN_APPLICATION);
+ }
+
++
++static unsigned int
++mime_application_hash (GAppInfo *app)
++{
++ const char *id;
++
++ id = g_app_info_get_id (app);
++
++ if (id == NULL)
++ {
++ return GPOINTER_TO_UINT (app);
++ }
++
++ return g_str_hash (id);
++}
++
++static void
++list_to_parameters_foreach (GAppInfo *application,
++ GList *uris,
++ GList **ret)
++{
++ ApplicationLaunchParameters *parameters;
++
++ uris = g_list_reverse (uris);
++
++ parameters = application_launch_parameters_new
++ (application, uris);
++ *ret = g_list_prepend (*ret, parameters);
++}
++
++
++/**
++ * make_activation_parameters
++ *
++ * Construct a list of ApplicationLaunchParameters from a list of NautilusFiles,
++ * where files that have the same default application are put into the same
++ * launch parameter, and others are put into the unhandled_files list.
++ *
++ * @files: Files to use for construction.
++ * @unhandled_files: Files without any default application will be put here.
++ *
++ * Return value: Newly allocated list of ApplicationLaunchParameters.
++ **/
++static GList *
++make_activation_parameters (GList *uris,
++ GList **unhandled_uris)
++{
++ GList *ret, *l, *app_uris;
++ NautilusFile *file;
++ GAppInfo *app, *old_app;
++ GHashTable *app_table;
++ char *uri;
++
++ ret = NULL;
++ *unhandled_uris = NULL;
++
++ app_table = g_hash_table_new_full
++ ((GHashFunc) mime_application_hash,
++ (GEqualFunc) g_app_info_equal,
++ (GDestroyNotify) g_object_unref,
++ (GDestroyNotify) g_list_free);
++
++ for (l = uris; l != NULL; l = l->next)
++ {
++ uri = l->data;
++ file = nautilus_file_get_by_uri (uri);
++
++ app = nautilus_mime_get_default_application_for_file (file);
++ if (app != NULL)
++ {
++ app_uris = NULL;
++
++ if (g_hash_table_lookup_extended (app_table, app,
++ (gpointer *) &old_app,
++ (gpointer *) &app_uris))
++ {
++ g_hash_table_steal (app_table, old_app);
++
++ app_uris = g_list_prepend (app_uris, uri);
++
++ g_object_unref (app);
++ app = old_app;
++ }
++ else
++ {
++ app_uris = g_list_prepend (NULL, uri);
++ }
++
++ g_hash_table_insert (app_table, app, app_uris);
++ }
++ else
++ {
++ *unhandled_uris = g_list_prepend (*unhandled_uris, uri);
++ }
++ nautilus_file_unref (file);
++ }
++
++ g_hash_table_foreach (app_table,
++ (GHFunc) list_to_parameters_foreach,
++ &ret);
++
++ g_hash_table_destroy (app_table);
++
++ *unhandled_uris = g_list_reverse (*unhandled_uris);
++
++ return g_list_reverse (ret);
++}
++
+ static gboolean
+ file_was_cancelled (NautilusFile *file)
+ {
+@@ -844,7 +966,7 @@ activation_parameters_free (ActivateParameters *parameters)
+ }
+
+ static void
+-application_launch_parameters_free (ApplicationLaunchParameters *parameters)
++application_launch_async_parameters_free (ApplicationLaunchAsyncParameters *parameters)
+ {
+ g_queue_free (parameters->unhandled_uris);
+ g_queue_free (parameters->uris);
+@@ -1370,11 +1492,11 @@ out:
+ }
+
+ static void
+-on_launch_default_for_uri (GObject *source_object,
+- GAsyncResult *res,
+- gpointer user_data)
++launch_default_for_uris_callback (GObject *source_object,
++ GAsyncResult *res,
++ gpointer user_data)
+ {
+- ApplicationLaunchParameters *params;
++ ApplicationLaunchAsyncParameters *params;
+ ActivateParameters *activation_params;
+ char *uri;
+ gboolean sandboxed;
+@@ -1396,7 +1518,7 @@ on_launch_default_for_uri (GObject *source_object,
+ nautilus_launch_default_for_uri_async (g_queue_peek_head (params->uris),
+ activation_params->parent_window,
+ activation_params->cancellable,
+- on_launch_default_for_uri,
++ launch_default_for_uris_callback,
+ params);
+ }
+ else
+@@ -1406,7 +1528,7 @@ on_launch_default_for_uri (GObject *source_object,
+ application_unhandled_uri (activation_params, uri);
+ }
+
+- application_launch_parameters_free (params);
++ application_launch_async_parameters_free (params);
+ }
+ }
+
+@@ -1415,9 +1537,16 @@ activate_files (ActivateParameters *parameters)
+ {
+ NautilusFile *file;
+ NautilusWindowOpenFlags flags;
++ g_autoptr (GList) open_in_app_parameters = NULL;
++ g_autoptr (GList) unhandled_open_in_app_uris = NULL;
++ ApplicationLaunchParameters *one_parameters;
+ int count;
+ g_autofree char *old_working_dir = NULL;
+ GdkScreen *screen;
++ gint num_apps;
++ gint num_unhandled;
++ gint num_files;
++ gboolean open_files;
+ g_autoptr (GQueue) launch_files = NULL;
+ g_autoptr (GQueue) launch_in_terminal_files = NULL;
+ g_autoptr (GQueue) open_in_app_uris = NULL;
+@@ -1612,26 +1741,89 @@ activate_files (ActivateParameters *parameters)
+ }
+ }
+
+- if (g_queue_is_empty (open_in_app_uris))
+- {
+- activation_parameters_free (parameters);
+- }
+- else
++ if (!g_queue_is_empty (open_in_app_uris) &&
++ g_file_test ("/.flatpak-info", G_FILE_TEST_EXISTS))
+ {
+ const char *uri;
+- ApplicationLaunchParameters *params;
++ ApplicationLaunchAsyncParameters *async_params;
+
+ uri = g_queue_peek_head (open_in_app_uris);
+- params = application_launch_parameters_new (parameters,
+- g_queue_copy (open_in_app_uris));
++
++ async_params = g_new0 (ApplicationLaunchAsyncParameters, 1);
++ async_params->activation_params = parameters;
++ async_params->uris = g_steal_pointer (&open_in_app_uris);
+
+ gtk_recent_manager_add_item (gtk_recent_manager_get_default (), uri);
+ nautilus_launch_default_for_uri_async (uri,
+ parameters->parent_window,
+ parameters->cancellable,
+- on_launch_default_for_uri,
+- params);
++ launch_default_for_uris_callback,
++ async_params);
++ return;
++ }
++
++ if (open_in_app_uris != NULL)
++ {
++ open_in_app_parameters = make_activation_parameters (g_queue_peek_head_link (open_in_app_uris),
++ &unhandled_open_in_app_uris);
+ }
++
++ num_apps = g_list_length (open_in_app_parameters);
++ num_unhandled = g_list_length (unhandled_open_in_app_uris);
++ num_files = g_queue_get_length (open_in_app_uris);
++ open_files = TRUE;
++
++ if (g_queue_is_empty (open_in_app_uris) &&
++ (!parameters->user_confirmation ||
++ num_files + num_unhandled > SILENT_OPEN_LIMIT) &&
++ num_apps > 1)
++ {
++ GtkDialog *dialog;
++ char *prompt;
++ g_autofree char *detail = NULL;
++ int response;
++
++ pause_activation_timed_cancel (parameters);
++
++ prompt = _("Are you sure you want to open all files?");
++ detail = g_strdup_printf (ngettext ("This will open %d separate application.",
++ "This will open %d separate applications.", num_apps), num_apps);
++ dialog = eel_show_yes_no_dialog (prompt, detail,
++ _("_OK"), _("_Cancel"),
++ parameters->parent_window);
++ response = gtk_dialog_run (dialog);
++ gtk_widget_destroy (GTK_WIDGET (dialog));
++
++ unpause_activation_timed_cancel (parameters);
++
++ if (response != GTK_RESPONSE_YES)
++ {
++ open_files = FALSE;
++ }
++ }
++
++ if (open_files)
++ {
++ for (l = open_in_app_parameters; l != NULL; l = l->next)
++ {
++ one_parameters = l->data;
++
++ nautilus_launch_application_by_uri (one_parameters->application,
++ one_parameters->uris,
++ parameters->parent_window);
++ application_launch_parameters_free (one_parameters);
++ }
++
++ for (l = unhandled_open_in_app_uris; l != NULL; l = l->next)
++ {
++ char *uri = l->data;
++
++ /* this does not block */
++ application_unhandled_uri (parameters, uri);
++ }
++ }
++
++ activation_parameters_free (parameters);
+ }
+
+ static void