diff options
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.patch | 359 |
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 |