nautilus-open-terminal r218 - trunk/src



Author: cneumair
Date: Mon Mar  9 12:34:43 2009
New Revision: 218
URL: http://svn.gnome.org/viewvc/nautilus-open-terminal?rev=218&view=rev

Log:
src/nautilus-open-terminal.c:
   * Support to open remote locations in local (~/.gvfs) terminal
   * Never cwd() to the destination path before running the terminal, but run cd inside the terminal.
     Fixes unmounting when opening a terminal on an extra medium (CDs, external HDs, ...), cd'ing away inside the
     terminal and trying to unmount the medium.
   * Do not run the terminal command ourselves, but use eel_gnome_open_terminal_on_screen().


Modified:
   trunk/src/nautilus-open-terminal.c

Modified: trunk/src/nautilus-open-terminal.c
==============================================================================
--- trunk/src/nautilus-open-terminal.c	(original)
+++ trunk/src/nautilus-open-terminal.c	Mon Mar  9 12:34:43 2009
@@ -31,12 +31,11 @@
 
 #include <glib/gi18n-lib.h>
 #include <gio/gio.h>
-#include <gtk/gtkicontheme.h>
-#include <gtk/gtkwidget.h>
-#include <gtk/gtkmain.h>
-#include <gconf/gconf-client.h>
+#include <gtk/gtk.h>
+#include <gconf/gconf.h>
 #include <libgnome/gnome-desktop-item.h>
-#include <libgnomevfs/gnome-vfs-utils.h>
+#include <libgnomevfs/gnome-vfs.h>
+#include <eel/eel.h>
 
 #include <errno.h>
 #include <fcntl.h>
@@ -90,44 +89,6 @@
 	return ret;
 }
 
-char *
-lookup_in_data_dir (const char *basename,
-                    const char *data_dir)
-{
-	char *path;
-
-	path = g_build_filename (data_dir, basename, NULL);
-	if (!g_file_test (path, G_FILE_TEST_EXISTS)) {
-		g_free (path);
-		return NULL;
-	}
-
-	return path;
-}
-
-static char *
-lookup_in_data_dirs (const char *basename)
-{
-	const char * const *system_data_dirs;
-	const char          *user_data_dir;
-	char                *retval;
-	int                  i;
-
-	user_data_dir    = g_get_user_data_dir ();
-	system_data_dirs = g_get_system_data_dirs ();
-
-	if ((retval = lookup_in_data_dir (basename, user_data_dir))) {
-		return retval;
-	}
-
-	for (i = 0; system_data_dirs[i]; i++) {
-		if ((retval = lookup_in_data_dir (basename, system_data_dirs[i])))
-			return retval;
-	}
-
-	return NULL;
-}
-
 static GConfClient *gconf_client = NULL;
 
 static inline gboolean
@@ -154,35 +115,21 @@
 				      NULL);
 }
 
-static inline void
-append_command_info (char **terminal_exec,
-		     const char *command)
-{
-	char *quoted_command;
-
-	quoted_command = g_shell_quote (command);
-
-	*terminal_exec = g_realloc (*terminal_exec, strlen (*terminal_exec) + strlen (quoted_command) + 4 + 1);
-	strcpy (*terminal_exec + strlen (*terminal_exec), " -e ");
-	strcpy (*terminal_exec + strlen (*terminal_exec), quoted_command);
-
-	g_free (quoted_command);
-}
-
-static void
-append_sftp_info (char **terminal_exec,
-		  const char *uri)
+static char *
+get_remote_ssh_command (const char *uri,
+			const char *command_to_run)
 {
 	GnomeVFSURI *vfs_uri;
 	const char *host_name, *path, *user_name;
-	char *cmd, *user_host, *unescaped_path;
+	char *command, *user_host, *unescaped_path;
 	guint host_port;
 
-	g_assert (terminal_exec != NULL);
 	g_assert (uri != NULL);
 	g_assert (strncmp (uri, "sftp", strlen ("sftp")) == 0 ||
 		  strncmp (uri, "ssh", strlen ("ssh")) == 0);
 
+	gnome_vfs_init ();
+
 	vfs_uri = gnome_vfs_uri_new (uri);
 	g_assert (vfs_uri != NULL);
 
@@ -203,13 +150,17 @@
 		user_host = g_strdup (host_name);
 	}
 
-	cmd = g_strdup_printf ("ssh %s -p %d -t \"cd \'%s\' && $SHELL -l\"", user_host, host_port, unescaped_path);
-	append_command_info (terminal_exec, cmd);
-	g_free (cmd);
+	if (command_to_run != NULL) {
+		command = g_strdup_printf ("ssh %s -p %d -t \"cd \'%s\' && %s\"", user_host, host_port, unescaped_path, command_to_run);
+	} else {
+		command = g_strdup_printf ("ssh %s -p %d -t \"cd \'%s\' && $SHELL -l\"", user_host, host_port, unescaped_path);
+	}
 
 	g_free (user_host);
 	g_free (unescaped_path);
 	gnome_vfs_uri_unref (vfs_uri);
+
+	return command;
 }
 
 static inline char *
@@ -225,77 +176,46 @@
 	return path;
 }
 
-static void
-open_terminal (NautilusMenuItem *item,
-	       NautilusFileInfo *file_info,
-	       const char *command)
+static char *
+get_terminal_command_for_file_info (NautilusFileInfo *file_info,
+				    const char *command_to_run,
+				    gboolean remote_terminal)
 {
-	gchar *display_str;
-	const gchar *old_display_str;
-	gchar *uri;
-	gchar **argv, *terminal_exec;
-	gchar *working_directory;
-	gchar *dfile;
-	GnomeDesktopItem *ditem;
-	GdkScreen *screen;
-
-	terminal_exec = gconf_client_get_string (gconf_client,
-						 "/desktop/gnome/applications/terminal/"
-						 "exec",
-						 NULL);
-
-	if (terminal_exec == NULL || strlen (terminal_exec) == 0) {
-		g_free (terminal_exec);
-		terminal_exec = g_strdup ("gnome-terminal");
-	}
+	char *uri, *path;
+	char *command;
 
 	uri = nautilus_file_info_get_activation_uri (file_info);
 
+	path = NULL;
+	command = NULL;
+
 	switch (get_terminal_file_info (uri)) {
 		case FILE_INFO_LOCAL:
 			if (uri != NULL) {
-				working_directory = g_filename_from_uri (uri, NULL, NULL);
-			} else {
-				working_directory = g_strdup (g_get_home_dir ());
-			}
-
-			if (command != NULL) {
-				append_command_info (&terminal_exec, command);
+				path = g_filename_from_uri (uri, NULL, NULL);
 			}
-
 			break;
 
 		case FILE_INFO_DESKTOP:
 			if (desktop_is_home_dir () || desktop_opens_home_dir ()) {
-				working_directory = g_strdup (g_get_home_dir ());
+				path = g_strdup (g_get_home_dir ());
 			} else {
-				working_directory =  g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP));
-			}
-
-			if (command != NULL) {
-				append_command_info (&terminal_exec, command);
+				path = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP));
 			}
+			g_free (path);
 			break;
 
 		case FILE_INFO_SFTP:
-			if (command == NULL) {
-				/* open remote shell in remote terminal */
-				working_directory = NULL;
-				append_sftp_info (&terminal_exec, uri);
-			} else {
-				/* this will map back sftp://... to ~/.gvfs.
-				 * we could also translate the URI to a FISH
-				 * URI, but we use our the GVFS FUSE code.
-				 */
-				working_directory = get_gvfs_path_for_uri (uri);
-				append_command_info (&terminal_exec, command);
+			if (remote_terminal && uri != NULL) {
+				command = get_remote_ssh_command (uri, command_to_run);
+				break;
 			}
-			break;
 
+			/* fall through */
 		case FILE_INFO_OTHER:
-			working_directory = get_gvfs_path_for_uri (uri);
-			if (command != NULL) {
-				append_command_info (&terminal_exec, command);
+			if (uri != NULL) {
+				/* map back remote URI to local path */
+				path = get_gvfs_path_for_uri (uri);
 			}
 			break;
 
@@ -303,201 +223,162 @@
 			g_assert_not_reached ();
 	}
 
-	g_free (uri);
-
-	if (g_str_has_prefix (terminal_exec, "gnome-terminal")) {
-		dfile = lookup_in_data_dirs ("applications/gnome-terminal.desktop");
-	} else {
-		dfile = NULL;
-	}
-
-	g_shell_parse_argv (terminal_exec, NULL, &argv, NULL);
-
-	display_str = NULL;
-	old_display_str = g_getenv ("DISPLAY");
-
-	screen = g_object_get_data (G_OBJECT (item), "NautilusOpenTerminal::screen");
-	if (screen != NULL) {
-		display_str = gdk_screen_make_display_name (screen);
-		g_setenv ("DISPLAY", display_str, TRUE);
+	if (command == NULL && path != NULL) {
+		if (command_to_run != NULL) {
+			command = g_strdup_printf ("cd '%s' && %s", path, command_to_run);
+		} else {
+			command = g_strdup_printf ("cd '%s' && $SHELL -l", path);
+		}
 	}
 
-	if (dfile != NULL) {
-		int orig_cwd = -1;
-
-		do {
-			orig_cwd = open (".", O_RDONLY);
-		} while (orig_cwd == -1 && errno == EINTR);
-
-		if (orig_cwd == -1) {
-			g_message ("NautilusOpenTerminal: Failed to open current Nautilus working directory.");
-		} else if (working_directory != NULL) {
-
-			if (chdir (working_directory) == -1) {
-				int ret;
-
-				g_message ("NautilusOpenTerminal: Failed to change Nautilus working directory to \"%s\".",
-					   working_directory);
-
-				do {
-					ret = close (orig_cwd);
-				} while (ret == -1 && errno == EINTR);
-
-				if (ret == -1) {
-					g_message ("NautilusOpenTerminal: Failed to close() current Nautilus working directory.");
-				}
+	g_free (path);
+	g_free (uri);
 
-				orig_cwd = -1;
-			}
-		}
+	return command;
+}
 
-		ditem = gnome_desktop_item_new_from_file (dfile, 0, NULL);
 
-		gnome_desktop_item_set_string (ditem, "Exec", terminal_exec);
-		if (gtk_get_current_event_time () > 0) {
-			gnome_desktop_item_set_launch_time (ditem, gtk_get_current_event_time ());
-		}
-		gnome_desktop_item_launch (ditem, NULL, GNOME_DESKTOP_ITEM_LAUNCH_USE_CURRENT_DIR, NULL);
-		gnome_desktop_item_unref (ditem);
-		g_free (dfile);
-
-		if (orig_cwd != -1) {
-			int ret;
-
-			ret = fchdir (orig_cwd);
-			if (ret == -1) {
-				g_message ("NautilusOpenTerminal: Failed to change back Nautilus working directory to original location after changing it to \"%s\".",
-					   working_directory);
-			}
+static void
+open_terminal (NautilusMenuItem *item,
+	       NautilusFileInfo *file_info)
+{
+	char *terminal_command, *command_to_run;
+	GdkScreen *screen;
+	gboolean remote_terminal;
 
-			do {
-				ret = close (orig_cwd);
-			} while (ret == -1 && errno == EINTR);
+	screen = g_object_get_data (G_OBJECT (item), "NautilusOpenTerminal::screen");
+	command_to_run = g_object_get_data (G_OBJECT (item), "NautilusOpenTerminal::command-to-run");
+	remote_terminal = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (item), "NautilusOpenTerminal::remote-terminal"));
 
-			if (ret == -1) {
-				g_message ("NautilusOpenTerminal: Failed to close Nautilus working directory.");
-			}
-		}
-	} else {	
-		g_spawn_async (working_directory,
-			       argv,
-			       NULL,
-			       G_SPAWN_SEARCH_PATH,
-			       NULL,
-			       NULL,
-			       NULL,
-			       NULL);
-	}
-
-	g_setenv ("DISPLAY", old_display_str, TRUE);
-
-	g_strfreev (argv);
-	g_free (terminal_exec);
-	g_free (working_directory);
-	g_free (display_str);
+	terminal_command = get_terminal_command_for_file_info (file_info, command_to_run, remote_terminal);
+	if (terminal_command != NULL) {
+		eel_gnome_open_terminal_on_screen (terminal_command, screen);
+	}
+	g_free (terminal_command);
 }
 
 static void
 open_terminal_callback (NautilusMenuItem *item,
 			NautilusFileInfo *file_info)
 {
-	open_terminal (item, file_info, NULL);
-}
-
-static void
-open_mc_callback (NautilusMenuItem *item,
-		  NautilusFileInfo *file_info)
-{
-	GFile *file;
-	char *uri, *working_directory;
-
-	open_terminal (item, file_info, "mc");
+	open_terminal (item, file_info);
 }
 
 static NautilusMenuItem *
-open_terminal_menu_item_new (TerminalFileInfo  terminal_file_info,
+open_terminal_menu_item_new (NautilusFileInfo *file_info,
+			     TerminalFileInfo  terminal_file_info,
 			     GdkScreen        *screen,
+			     const char       *command_to_run,
+			     gboolean          remote_terminal,
 			     gboolean          is_file_item)
 {
 	NautilusMenuItem *ret;
+	char *action_name;
 	const char *name;
 	const char *tooltip;
 
-	switch (terminal_file_info) {
-		case FILE_INFO_LOCAL:
-		case FILE_INFO_SFTP:
-		case FILE_INFO_OTHER:
-			name = _("Open in _Terminal");
-			if (is_file_item) {
-				tooltip = _("Open the currently selected folder in a terminal");
-			} else {
-				tooltip = _("Open the currently open folder in a terminal");
-			}
-			break;
+	if (command_to_run == NULL) {
+		switch (terminal_file_info) {
+			case FILE_INFO_SFTP:
+				if (remote_terminal) {
+					name = _("Open in _Remote Terminal");
+				} else {
+					name = _("Open in _Local Terminal");
+				}
 
-		case FILE_INFO_DESKTOP:
-			if (desktop_opens_home_dir ()) {
-				name = _("Open _Terminal");
-				tooltip = _("Open a terminal");
-			} else {
-				name = _("Open in _Terminal");
-				tooltip = _("Open the currently open folder in a terminal");
-			}
-			break;
+				if (is_file_item) {
+					tooltip = _("Open the currently selected folder in a terminal");
+				} else {
+					tooltip = _("Open the currently open folder in a terminal");
+				}
+				break;
 
-		default:
-			g_assert_not_reached ();
-	}
+			case FILE_INFO_LOCAL:
+			case FILE_INFO_OTHER:
+				name = _("Open in _Terminal");
 
-	ret = nautilus_menu_item_new ("NautilusOpenTerminal::open_terminal",
-				      name, tooltip, "gnome-terminal");
-	g_object_set_data (G_OBJECT (ret),
-			   "NautilusOpenTerminal::screen",
-			   screen);
+				if (is_file_item) {
+					tooltip = _("Open the currently selected folder in a terminal");
+				} else {
+					tooltip = _("Open the currently open folder in a terminal");
+				}
+				break;
 
-	return ret;
-}
+			case FILE_INFO_DESKTOP:
+				if (desktop_opens_home_dir ()) {
+					name = _("Open _Terminal");
+					tooltip = _("Open a terminal");
+				} else {
+					name = _("Open in _Terminal");
+					tooltip = _("Open the currently open folder in a terminal");
+				}
+				break;
 
-static NautilusMenuItem *
-open_mc_menu_item_new (TerminalFileInfo  terminal_file_info,
-		       GdkScreen        *screen,
-		       gboolean          is_file_item)
-{
-	NautilusMenuItem *ret;
-	const char *name;
-	const char *tooltip;
+			default:
+				g_assert_not_reached ();
+		}
+	} else if (!strcmp (command_to_run, "mc")) {
+		switch (terminal_file_info) {
+			case FILE_INFO_LOCAL:
+			case FILE_INFO_SFTP:
+			case FILE_INFO_OTHER:
+				name = _("Open in _Midnight Commander");
+				if (is_file_item) {
+					tooltip = _("Open the currently selected folder in the terminal file manager Midnight Commander");
+				} else {
+					tooltip = _("Open the currently open folder in the terminal file manager Midnight Commander");
+				}
+				break;
 
-	switch (terminal_file_info) {
-		case FILE_INFO_LOCAL:
-		case FILE_INFO_SFTP:
-		case FILE_INFO_OTHER:
-			name = _("Open in _Midnight Commander");
-			if (is_file_item) {
-				tooltip = _("Open the currently selected folder in the terminal file manager Midnight Commander");
-			} else {
-				tooltip = _("Open the currently open folder in the terminal file manager Midnight Commander");
-			}
-			break;
+			case FILE_INFO_DESKTOP:
+				if (desktop_opens_home_dir ()) {
+					name = _("Open _Midnight Commander");
+					tooltip = _("Open the terminal file manager Midnight Commander");
+				} else {
+					name = _("Open in _Midnight Commander");
+					tooltip = _("Open the currently open folder in the terminal file manager Midnight Commander");
+				}
+				break;
 
-		case FILE_INFO_DESKTOP:
-			if (desktop_opens_home_dir ()) {
-				name = _("Open _Midnight Commander");
-				tooltip = _("Open the terminal file manager Midnight Commander");
-			} else {
-				name = _("Open in _Midnight Commander");
-				tooltip = _("Open the currently open folder in the terminal file manager Midnight Commander");
-			}
-			break;
+			default:
+				g_assert_not_reached ();
+		}
+	} else {
+		g_assert_not_reached ();
+	}
 
-		default:
-			g_assert_not_reached ();
+	if (command_to_run != NULL) {
+		action_name = g_strdup_printf (remote_terminal ?
+					       "NautilusOpenTerminal::open_remote_terminal_%s" :
+					       "NautilusOpenTerminal::open_terminal_%s",
+					       command_to_run);
+	} else {
+		action_name = g_strdup (remote_terminal ? 
+					"NautilusOpenTerminal::open_remote_terminal" :
+					"NautilusOpenTerminal::open_terminal");
 	}
+	ret = nautilus_menu_item_new (action_name, name, tooltip, "gnome-terminal");
+	g_free (action_name);
 
-	ret = nautilus_menu_item_new ("NautilusOpenTerminal::open_mc",
-				      name, tooltip, NULL);
 	g_object_set_data (G_OBJECT (ret),
 			   "NautilusOpenTerminal::screen",
 			   screen);
+	g_object_set_data_full (G_OBJECT (ret), "NautilusOpenTerminal::command-to-run",
+				g_strdup (command_to_run),
+				(GDestroyNotify) g_free);
+	g_object_set_data (G_OBJECT (ret), "NautilusOpenTerminal::remote-terminal",
+			   GUINT_TO_POINTER (remote_terminal));
+
+
+	g_object_set_data_full (G_OBJECT (ret), "file-info",
+				g_object_ref (file_info),
+				(GDestroyNotify) g_object_unref);
+
+
+	g_signal_connect (ret, "activate",
+			  G_CALLBACK (open_terminal_callback),
+			  file_info);
+
 
 	return ret;
 }
@@ -530,24 +411,19 @@
 	terminal_file_info = get_terminal_file_info (uri);
 	g_free (uri);
 
-	item = open_terminal_menu_item_new (terminal_file_info, gtk_widget_get_screen (window), FALSE);
-	g_object_set_data_full (G_OBJECT (item), "file-info",
-				g_object_ref (file_info),
-				(GDestroyNotify) g_object_unref);
-	g_signal_connect (item, "activate",
-			  G_CALLBACK (open_terminal_callback),
-			  file_info);
+	item = open_terminal_menu_item_new (file_info, terminal_file_info, gtk_widget_get_screen (window),
+					    NULL, terminal_file_info == FILE_INFO_SFTP, FALSE);
 	items = g_list_append (items, item);
 
+	if (terminal_file_info == FILE_INFO_SFTP) {
+		item = open_terminal_menu_item_new (file_info, terminal_file_info, gtk_widget_get_screen (window),
+						    NULL, FALSE, FALSE);
+		items = g_list_append (items, item);
+	}
+
 	if (display_mc_item () &&
 	    g_find_program_in_path ("mc")) {
-		item = open_mc_menu_item_new (terminal_file_info, gtk_widget_get_screen (window), FALSE);
-		g_object_set_data_full (G_OBJECT (item), "file-info",
-					g_object_ref (file_info),
-					(GDestroyNotify) g_object_unref);
-		g_signal_connect (item, "activate",
-				  G_CALLBACK (open_mc_callback),
-				  file_info);
+		item = open_terminal_menu_item_new (file_info, terminal_file_info, gtk_widget_get_screen (window), "mc", FALSE, FALSE);
 		items = g_list_append (items, item);
 	}
 
@@ -585,24 +461,18 @@
 		case FILE_INFO_LOCAL:
 		case FILE_INFO_SFTP:
 		case FILE_INFO_OTHER:
-			item = open_terminal_menu_item_new (terminal_file_info, gtk_widget_get_screen (window), TRUE);
-			g_object_set_data_full (G_OBJECT (item), "file-info",
-						g_object_ref (files->data),
-						(GDestroyNotify) g_object_unref);
-			g_signal_connect (item, "activate",
-					  G_CALLBACK (open_terminal_callback),
-					  files->data);
+			item = open_terminal_menu_item_new (files->data, terminal_file_info, gtk_widget_get_screen (window),
+							    NULL, terminal_file_info == FILE_INFO_SFTP, TRUE);
 			items = g_list_append (items, item);
 
+			if (terminal_file_info == FILE_INFO_SFTP) {
+				item = open_terminal_menu_item_new (files->data, terminal_file_info, gtk_widget_get_screen (window), NULL, FALSE, TRUE);
+				items = g_list_append (items, item);
+			}
+
 			if (display_mc_item () &&
 			    g_find_program_in_path ("mc")) {
-				item = open_mc_menu_item_new (terminal_file_info, gtk_widget_get_screen (window), FALSE);
-				g_object_set_data_full (G_OBJECT (item), "file-info",
-							g_object_ref (files->data),
-							(GDestroyNotify) g_object_unref);
-				g_signal_connect (item, "activate",
-						  G_CALLBACK (open_mc_callback),
-						  files->data);
+				item = open_terminal_menu_item_new (files->data, terminal_file_info, gtk_widget_get_screen (window), "mc", TRUE, FALSE);
 				items = g_list_append (items, item);
 			}
 			break;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]