summaryrefslogtreecommitdiff
path: root/src/nautilus-mime-actions.c
diff options
context:
space:
mode:
authorCarlos Soriano <csoriano@redhat.com>2018-05-18 17:04:04 +0200
committerErnestas Kulik <ernestas.kulik@gmail.com>2018-05-21 06:29:14 +0000
commitac886102c23c8eae4759a240193473e1b00f7352 (patch)
treeb9ea997ae55a2ec3357482e0448a72e03f482629 /src/nautilus-mime-actions.c
parentce61f4848d6b06b9f4206d2af24de3143c67c7e9 (diff)
downloadnautilus-ac886102c23c8eae4759a240193473e1b00f7352.tar.gz
general: Revert to allow running binaries and scripts
Recently we removed the ability to launch binaries and scripts in commit 3a22ed5b8e3bb. A few cases appeared that we need to support, specially for enterprise and content creators. Specifically, cases similar to https://gitlab.gnome.org/GNOME/nautilus/issues/434 This also shows that is hard to predict cases like these, as some complex setups might be needed for specific workflows. This commits allow to run binaries and scripts as before, and further investigation in these cases need to be done if we ever want to tweak the workflow of running binaries. More discussion about improving binaries/script handling is being proposed and discussed in https://gitlab.gnome.org/GNOME/nautilus/issues/443
Diffstat (limited to 'src/nautilus-mime-actions.c')
-rw-r--r--src/nautilus-mime-actions.c255
1 files changed, 248 insertions, 7 deletions
diff --git a/src/nautilus-mime-actions.c b/src/nautilus-mime-actions.c
index 494d6dab2..55b5df82f 100644
--- a/src/nautilus-mime-actions.c
+++ b/src/nautilus-mime-actions.c
@@ -48,6 +48,8 @@
typedef enum
{
ACTIVATION_ACTION_ASK,
+ ACTIVATION_ACTION_LAUNCH,
+ ACTIVATION_ACTION_LAUNCH_IN_TERMINAL,
ACTIVATION_ACTION_OPEN_IN_VIEW,
ACTIVATION_ACTION_OPEN_IN_APPLICATION,
ACTIVATION_ACTION_EXTRACT,
@@ -75,6 +77,7 @@ typedef struct
gboolean timed_wait_active;
NautilusFileListHandle *files_handle;
gboolean tried_mounting;
+ char *activation_directory;
gboolean user_confirmation;
} ActivateParameters;
@@ -219,6 +222,10 @@ struct
/* Number of seconds until cancel dialog shows up */
#define DELAY_UNTIL_CANCEL_MSECS 5000
+#define RESPONSE_RUN 1000
+#define RESPONSE_DISPLAY 1001
+#define RESPONSE_RUN_IN_TERMINAL 1002
+
#define SILENT_WINDOW_OPEN_LIMIT 5
#define SILENT_OPEN_LIMIT 5
@@ -590,6 +597,115 @@ out:
}
static ActivationAction
+get_executable_text_file_action (GtkWindow *parent_window,
+ NautilusFile *file)
+{
+ GtkDialog *dialog;
+ char *file_name;
+ char *prompt;
+ char *detail;
+ int preferences_value;
+ int response;
+
+ g_assert (nautilus_file_contains_text (file));
+
+ preferences_value = g_settings_get_enum (nautilus_preferences,
+ NAUTILUS_PREFERENCES_EXECUTABLE_TEXT_ACTIVATION);
+ switch (preferences_value)
+ {
+ case NAUTILUS_EXECUTABLE_TEXT_LAUNCH:
+ {
+ return ACTIVATION_ACTION_LAUNCH;
+ }
+
+ case NAUTILUS_EXECUTABLE_TEXT_DISPLAY:
+ {
+ return ACTIVATION_ACTION_OPEN_IN_APPLICATION;
+ }
+
+ case NAUTILUS_EXECUTABLE_TEXT_ASK:
+ {
+ }
+ break;
+
+ default:
+ /* Complain non-fatally, since preference data can't be trusted */
+ g_warning ("Unknown value %d for NAUTILUS_PREFERENCES_EXECUTABLE_TEXT_ACTIVATION",
+ preferences_value);
+ }
+
+
+ file_name = nautilus_file_get_display_name (file);
+ prompt = g_strdup_printf (_("Do you want to run ā€œ%sā€, or display its contents?"),
+ file_name);
+ detail = g_strdup_printf (_("ā€œ%sā€ is an executable text file."),
+ file_name);
+ g_free (file_name);
+
+ dialog = eel_create_question_dialog (prompt,
+ detail,
+ _("Run in _Terminal"), RESPONSE_RUN_IN_TERMINAL,
+ _("_Display"), RESPONSE_DISPLAY,
+ parent_window);
+ gtk_dialog_add_button (dialog, _("_Cancel"), GTK_RESPONSE_CANCEL);
+ gtk_dialog_add_button (dialog, _("_Run"), RESPONSE_RUN);
+ gtk_dialog_set_default_response (dialog, GTK_RESPONSE_CANCEL);
+ gtk_widget_show (GTK_WIDGET (dialog));
+
+ g_free (prompt);
+ g_free (detail);
+
+ response = gtk_dialog_run (dialog);
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+
+ switch (response)
+ {
+ case RESPONSE_RUN:
+ {
+ return ACTIVATION_ACTION_LAUNCH;
+ }
+
+ case RESPONSE_RUN_IN_TERMINAL:
+ {
+ return ACTIVATION_ACTION_LAUNCH_IN_TERMINAL;
+ }
+
+ case RESPONSE_DISPLAY:
+ {
+ return ACTIVATION_ACTION_OPEN_IN_APPLICATION;
+ }
+
+ default:
+ return ACTIVATION_ACTION_DO_NOTHING;
+ }
+}
+
+static ActivationAction
+get_default_executable_text_file_action (void)
+{
+ int preferences_value;
+
+ preferences_value = g_settings_get_enum (nautilus_preferences,
+ NAUTILUS_PREFERENCES_EXECUTABLE_TEXT_ACTIVATION);
+ switch (preferences_value)
+ {
+ case NAUTILUS_EXECUTABLE_TEXT_LAUNCH:
+ {
+ return ACTIVATION_ACTION_LAUNCH;
+ }
+
+ case NAUTILUS_EXECUTABLE_TEXT_DISPLAY:
+ {
+ return ACTIVATION_ACTION_OPEN_IN_APPLICATION;
+ }
+
+ case NAUTILUS_EXECUTABLE_TEXT_ASK:
+ default:
+ return ACTIVATION_ACTION_ASK;
+ }
+}
+
+static ActivationAction
get_activation_action (NautilusFile *file)
{
ActivationAction action;
@@ -615,13 +731,35 @@ get_activation_action (NautilusFile *file)
activation_uri = nautilus_file_get_uri (file);
}
- if (nautilus_file_opens_in_view (file))
+ action = ACTIVATION_ACTION_DO_NOTHING;
+ if (nautilus_file_is_launchable (file))
{
- action = ACTIVATION_ACTION_OPEN_IN_VIEW;
+ char *executable_path;
+
+ action = ACTIVATION_ACTION_LAUNCH;
+
+ executable_path = g_filename_from_uri (activation_uri, NULL, NULL);
+ if (!executable_path)
+ {
+ action = ACTIVATION_ACTION_DO_NOTHING;
+ }
+ else if (nautilus_file_contains_text (file))
+ {
+ action = get_default_executable_text_file_action ();
+ }
+ g_free (executable_path);
}
- else
+
+ if (action == ACTIVATION_ACTION_DO_NOTHING)
{
- action = ACTIVATION_ACTION_OPEN_IN_APPLICATION;
+ if (nautilus_file_opens_in_view (file))
+ {
+ action = ACTIVATION_ACTION_OPEN_IN_VIEW;
+ }
+ else
+ {
+ action = ACTIVATION_ACTION_OPEN_IN_APPLICATION;
+ }
}
g_free (activation_uri);
@@ -635,6 +773,16 @@ nautilus_mime_file_extracts (NautilusFile *file)
}
gboolean
+nautilus_mime_file_launches (NautilusFile *file)
+{
+ ActivationAction activation_action;
+
+ activation_action = get_activation_action (file);
+
+ return (activation_action == ACTIVATION_ACTION_LAUNCH);
+}
+
+gboolean
nautilus_mime_file_opens_in_external_app (NautilusFile *file)
{
ActivationAction activation_action;
@@ -689,6 +837,7 @@ activation_parameters_free (ActivateParameters *parameters)
nautilus_file_list_free (parameters->mountables);
nautilus_file_list_free (parameters->start_mountables);
nautilus_file_list_free (parameters->not_mounted);
+ g_free (parameters->activation_directory);
g_free (parameters->timed_wait_prompt);
g_assert (parameters->files_handle == NULL);
g_free (parameters);
@@ -816,6 +965,7 @@ typedef struct
NautilusFile *file;
GList *files;
NautilusWindowOpenFlags flags;
+ char *activation_directory;
gboolean user_confirmation;
char *uri;
GDBusProxy *proxy;
@@ -841,6 +991,7 @@ activate_parameters_install_free (ActivateParametersInstall *parameters_install)
nautilus_file_unref (parameters_install->file);
nautilus_file_list_free (parameters_install->files);
+ g_free (parameters_install->activation_directory);
g_free (parameters_install->uri);
g_free (parameters_install);
}
@@ -1044,6 +1195,7 @@ search_for_application_dbus_call_notify_cb (GDBusProxy *proxy,
nautilus_mime_activate_files (parameters_install->parent_window,
parameters_install->slot,
parameters_install->files,
+ parameters_install->activation_directory,
parameters_install->flags,
parameters_install->user_confirmation);
@@ -1192,6 +1344,7 @@ application_unhandled_uri (ActivateParameters *parameters,
parameters_install->parent_window = parameters->parent_window;
g_object_add_weak_pointer (G_OBJECT (parameters_install->parent_window), (gpointer *) &parameters_install->parent_window);
}
+ parameters_install->activation_directory = g_strdup (parameters->activation_directory);
parameters_install->file = file;
parameters_install->files = get_file_list_for_launch_locations (parameters->locations);
parameters_install->flags = parameters->flags;
@@ -1298,12 +1451,17 @@ activate_files (ActivateParameters *parameters)
NautilusWindowOpenFlags flags;
int count;
g_autofree char *old_working_dir = NULL;
+ GdkScreen *screen;
gboolean closed_window;
+ g_autoptr (GQueue) launch_files = NULL;
+ g_autoptr (GQueue) launch_in_terminal_files = NULL;
g_autoptr (GQueue) open_in_app_uris = NULL;
g_autoptr (GQueue) open_in_view_files = NULL;
GList *l;
ActivationAction action;
+ launch_files = g_queue_new ();
+ launch_in_terminal_files = g_queue_new ();
open_in_view_files = g_queue_new ();
open_in_app_uris = g_queue_new ();
@@ -1320,8 +1478,30 @@ activate_files (ActivateParameters *parameters)
}
action = get_activation_action (file);
+ if (action == ACTIVATION_ACTION_ASK)
+ {
+ /* Special case for executable text files, since it might be
+ * dangerous & unexpected to launch these.
+ */
+ pause_activation_timed_cancel (parameters);
+ action = get_executable_text_file_action (parameters->parent_window, file);
+ unpause_activation_timed_cancel (parameters);
+ }
+
switch (action)
{
+ case ACTIVATION_ACTION_LAUNCH:
+ {
+ g_queue_push_tail (launch_files, file);
+ }
+ break;
+
+ case ACTIVATION_ACTION_LAUNCH_IN_TERMINAL:
+ {
+ g_queue_push_tail (launch_in_terminal_files, file);
+ }
+ break;
+
case ACTIVATION_ACTION_OPEN_IN_VIEW:
{
g_queue_push_tail (open_in_view_files, file);
@@ -1346,7 +1526,7 @@ activate_files (ActivateParameters *parameters)
}
break;
- default:
+ case ACTIVATION_ACTION_ASK:
{
g_assert_not_reached ();
}
@@ -1354,6 +1534,54 @@ activate_files (ActivateParameters *parameters)
}
}
+ if (parameters->activation_directory &&
+ (!g_queue_is_empty (launch_files) ||
+ !g_queue_is_empty (launch_in_terminal_files)))
+ {
+ old_working_dir = g_get_current_dir ();
+ g_chdir (parameters->activation_directory);
+ }
+
+ screen = gtk_widget_get_screen (GTK_WIDGET (parameters->parent_window));
+ for (l = g_queue_peek_head_link (launch_files); l != NULL; l = l->next)
+ {
+ g_autofree char *uri = NULL;
+ g_autofree char *executable_path = NULL;
+ g_autofree char *quoted_path = NULL;
+
+ file = NAUTILUS_FILE (l->data);
+
+ uri = nautilus_file_get_activation_uri (file);
+ executable_path = g_filename_from_uri (uri, NULL, NULL);
+ quoted_path = g_shell_quote (executable_path);
+
+ DEBUG ("Launching file path %s", quoted_path);
+
+ nautilus_launch_application_from_command (screen, quoted_path, FALSE, NULL);
+ }
+
+ for (l = g_queue_peek_head_link (launch_in_terminal_files); l != NULL; l = l->next)
+ {
+ g_autofree char *uri = NULL;
+ g_autofree char *executable_path = NULL;
+ g_autofree char *quoted_path = NULL;
+
+ file = NAUTILUS_FILE (l->data);
+
+ uri = nautilus_file_get_activation_uri (file);
+ executable_path = g_filename_from_uri (uri, NULL, NULL);
+ quoted_path = g_shell_quote (executable_path);
+
+ DEBUG ("Launching in terminal file quoted path %s", quoted_path);
+
+ nautilus_launch_application_from_command (screen, quoted_path, TRUE, NULL);
+ }
+
+ if (old_working_dir != NULL)
+ {
+ g_chdir (old_working_dir);
+ }
+
count = g_queue_get_length (open_in_view_files);
flags = parameters->flags;
@@ -1522,7 +1750,8 @@ activation_mount_not_mounted_callback (GObject *source_object,
file);
if (loc)
{
- parameters->locations = g_list_remove (parameters->locations, loc);
+ parameters->locations =
+ g_list_remove (parameters->locations, loc);
launch_location_free (loc);
}
}
@@ -1941,10 +2170,20 @@ activation_start_mountables (ActivateParameters *parameters)
}
}
+/**
+ * nautilus_mime_activate_files:
+ *
+ * Activate a list of files. Each one might launch with an application or
+ * with a component. This is normally called only by subclasses.
+ * @view: FMDirectoryView in question.
+ * @files: A GList of NautilusFiles to activate.
+ *
+ **/
void
nautilus_mime_activate_files (GtkWindow *parent_window,
NautilusWindowSlot *slot,
GList *files,
+ const char *launch_directory,
NautilusWindowOpenFlags flags,
gboolean user_confirmation)
{
@@ -1971,6 +2210,7 @@ nautilus_mime_activate_files (GtkWindow *parent_window,
g_object_add_weak_pointer (G_OBJECT (parameters->parent_window), (gpointer *) &parameters->parent_window);
}
parameters->cancellable = g_cancellable_new ();
+ parameters->activation_directory = g_strdup (launch_directory);
parameters->locations = launch_locations_from_file_list (files);
parameters->flags = flags;
parameters->user_confirmation = user_confirmation;
@@ -2040,6 +2280,7 @@ void
nautilus_mime_activate_file (GtkWindow *parent_window,
NautilusWindowSlot *slot,
NautilusFile *file,
+ const char *launch_directory,
NautilusWindowOpenFlags flags)
{
GList *files;
@@ -2047,7 +2288,7 @@ nautilus_mime_activate_file (GtkWindow *parent_window,
g_return_if_fail (NAUTILUS_IS_FILE (file));
files = g_list_prepend (NULL, file);
- nautilus_mime_activate_files (parent_window, slot, files, flags, FALSE);
+ nautilus_mime_activate_files (parent_window, slot, files, launch_directory, flags, FALSE);
g_list_free (files);
}