Logging user actions



Hi,

Now that customers are actually using SLED 10 from Novell, the
distribution that prevents cavities and

Oh, wait.  This was not supposed to be an advertisement.

I meant to say that customers are of course sending in bug reports for
Nautilus, with crashes that are really hard to reproduce.  And they of
course never quite know what they did to trigger the crash.

I've started writing a little logging mechanism for Nautilus, based on
the ideas in this nice and short paper:
	http://visibleworkings.com/trace/Documentation/ring-buffer.pdf

[The patch is attached]

The idea is that you log stuff (like user actions) to a ring buffer.
The user then has a way to dump the log to a file when he notices
something wrong, or the log can also be dumped automatically when the
program detects an error.

So, I have started instrumenting Nautilus with several logging points: 

- windows are created
- a window changes location
- a window changes its view
- a file gets activated
- etc.

The idea is to have better info about how to reproduce bugs.  While
right now I'm only logging user actions, this is extensible to logging
internal actions as well.

* Why not just use g_log() or g_debug() and friends?  Several reasons.
These would pollute ~/.xsession-errors too much when we get extensive
logging; the paper explains why a ring buffer is better.  Implementing a
ring buffer on top of g_log() and friends is perfectly possible, but
amounts to exactly the same amount of work as simply using a different
system.

* Why a ring buffer?  Read the paper.

Next week I'll start getting logs from people who have gotten these
hard-to-reproduce crashers.  This will let me know what extra logging
points I need.

And in the medium-term future, I intend to use this logged info to
analyze how users browse their file systems.  We may be able to extract
nice usability data out of it.

Do people find this useful?

  Federico
2006-09-22  Federico Mena Quintero  <federico novell com>

	* libnautilus-private/nautilus-debug-log.[ch]: New files with a
	simple logging infrastructure based on a ring buffer.

	* libnautilus-private/Makefile.am
	(libnautilus_private_la_SOURCES): Added nautilus-debug-log.[ch].

	* src/nautilus-main.c (main): Make SIGUSR1 dump the debug log to
	~/nautilus-debug-log.txt.

	* src/file-manager/fm-directory-view.c
	(fm_directory_view_activate_files): Log the action of activating a
	file.
	(open_location): Likewise.
	(fm_directory_view_launch_application): Likewise, for launching an
	application.
	(action_new_launcher_callback): Likewise, for creating a launcher.
	(activate_callback): Log the various actions that can happen here.

	* src/file-manager/fm-tree-view.c (got_activation_uri_callback):
	Log the various activations/launches that can happen.

	* src/nautilus-places-sidebar.c (row_activated_callback): Log the
	action of the user activating something in the Places sidebar.

	* src/nautilus-navigation-window.c
	(path_bar_location_changed_callback): Log the action when a button
	in the path bar is clicked.

	* src/nautilus-window-manage-views.c
	(nautilus_navigation_window_back_or_forward): Log the action when
	the user goes back or forward in the history of paths.
	(nautilus_window_open_location_full): Log the action of changing
	the location in a window.
	(nautilus_window_set_content_view): Log the action of thanging the
	view of a window.
	(end_location_change): Log when the window finishes loading.

	* src/file-manager/fm-list-view.c (row_expanded_callback): Log the
	action of expanding a row to load a subdirectory.
	(row_collapsed_callback): Likewise, for collapsing a row.

	* src/file-manager/fm-error-reporting.c (fm_rename_file): Log the
	action of renaming a file.

	* src/nautilus-application.c
	(nautilus_application_present_spatial_window_with_selection): Log
	when new or existing spatial windows get presented.
	(nautilus_application_create_navigation_window): Log when a
	navigation window gets created.

--- /dev/null	2006-06-16 08:07:58.000000000 -0500
+++ nautilus-debug/libnautilus-private/nautilus-debug-log.h	2006-09-22 14:57:57.000000000 -0500
@@ -0,0 +1,48 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
+
+   nautilus-debug-log.h: Ring buffer for logging debug messages
+ 
+   Copyright (C) 2006 Novell, Inc.
+  
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+  
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+  
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, write to the
+   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+  
+   Author: Federico Mena-Quintero <federico novell com>
+*/
+
+#ifndef NAUTILUS_DEBUG_LOG_H
+#define NAUTILUS_DEBUG_LOG_H
+
+#include <glib.h>
+
+#define NAUTILUS_DEBUG_LOG_DOMAIN_USER "USER"
+
+void nautilus_debug_log (gboolean is_milestone, const char *domain, const char *format, ...);
+void nautilus_debug_logv (gboolean is_milestone, const char *domain, const char *format, va_list args);
+
+void nautilus_debug_log_enable_domains (const char **domains, int n_domains);
+void nautilus_debug_log_disable_domains (const char **domains, int n_domains);
+
+gboolean nautilus_debug_log_is_domain_enabled (const char *domain);
+
+gboolean nautilus_debug_log_dump (const char *filename, GError **error);
+
+void nautilus_debug_log_set_max_lines (int num_lines);
+int nautilus_debug_log_get_max_lines (void);
+
+/* For testing only */
+void nautilus_debug_log_clear (void);
+
+#endif /* NAUTILUS_DEBUG_LOG_H */
--- /dev/null	2006-06-16 08:07:58.000000000 -0500
+++ nautilus-debug/libnautilus-private/nautilus-debug-log.c	2006-09-22 14:57:57.000000000 -0500
@@ -0,0 +1,391 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
+
+   nautilus-debug-log.c: Ring buffer for logging debug messages
+ 
+   Copyright (C) 2006 Novell, Inc.
+  
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+  
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+  
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, write to the
+   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+  
+   Author: Federico Mena-Quintero <federico novell com>
+*/
+#include <config.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <sys/time.h>
+#include "nautilus-debug-log.h"
+
+#define DEFAULT_RING_BUFFER_NUM_LINES 1000
+
+static GStaticMutex log_mutex = G_STATIC_MUTEX_INIT;
+
+static GHashTable *domains_hash;
+static char **ring_buffer;
+static int ring_buffer_next_index;
+static int ring_buffer_num_lines;
+static int ring_buffer_max_lines = DEFAULT_RING_BUFFER_NUM_LINES;
+
+static void
+lock (void)
+{
+	g_static_mutex_lock (&log_mutex);
+}
+
+static void
+unlock (void)
+{
+	g_static_mutex_unlock (&log_mutex);
+}
+
+void
+nautilus_debug_log (gboolean is_milestone, const char *domain, const char *format, ...)
+{
+	va_list args;
+
+	va_start (args, format);
+	nautilus_debug_logv (is_milestone, domain, format, args);
+	va_end (args);
+}
+
+static gboolean
+is_domain_enabled (const char *domain)
+{
+	/* User actions are always logged */
+	if (strcmp (domain, NAUTILUS_DEBUG_LOG_DOMAIN_USER) == 0)
+		return TRUE;
+
+	if (!domains_hash)
+		return FALSE;
+
+	return (g_hash_table_lookup (domains_hash, domain) != NULL);
+}
+
+static void
+ensure_ring (void)
+{
+	if (ring_buffer)
+		return;
+
+	ring_buffer = g_new0 (char *, ring_buffer_max_lines);
+	ring_buffer_next_index = 0;
+	ring_buffer_num_lines = 0;
+}
+
+static void
+add_to_ring (char *str)
+{
+	ensure_ring ();
+
+	g_assert (str != NULL);
+
+	if (ring_buffer_num_lines == ring_buffer_max_lines) {
+		/* We have an overlap, and the ring_buffer_next_index points to
+		 * the "first" item.  Free it to make room for the new item.
+		 */
+
+		g_assert (ring_buffer[ring_buffer_next_index] != NULL);
+		g_free (ring_buffer[ring_buffer_next_index]);
+	} else
+		ring_buffer_num_lines++;
+
+	g_assert (ring_buffer_num_lines <= ring_buffer_max_lines);
+
+	ring_buffer[ring_buffer_next_index] = str;
+
+	ring_buffer_next_index++;
+	if (ring_buffer_next_index == ring_buffer_max_lines) {
+		ring_buffer_next_index = 0;
+		g_assert (ring_buffer_num_lines == ring_buffer_max_lines);
+	}
+}
+
+void
+nautilus_debug_logv (gboolean is_milestone, const char *domain, const char *format, va_list args)
+{
+	char *str;
+	char *debug_str;
+	struct timeval tv;
+	struct tm tm;
+
+	lock ();
+
+	if (!(is_milestone || is_domain_enabled (domain)))
+		goto out;
+
+	str = g_strdup_vprintf (format, args);
+	gettimeofday (&tv, NULL);
+
+	tm = *localtime (&tv.tv_sec);
+
+	debug_str = g_strdup_printf ("%p %04d/%02d/%02d %02d:%02d:%02d.%04d (%s): %s",
+				     g_thread_self (),
+				     tm.tm_year + 1900,
+				     tm.tm_mon + 1,
+				     tm.tm_mday,
+				     tm.tm_hour,
+				     tm.tm_min,
+				     tm.tm_sec,
+				     (int) (tv.tv_usec / 100),
+				     domain,
+				     str);
+	g_free (str);
+
+	add_to_ring (debug_str);
+
+	/* FIXME: deal with milestones */
+
+ out:
+	unlock ();
+}
+
+void
+nautilus_debug_log_enable_domains (const char **domains, int n_domains)
+{
+	int i;
+
+	g_assert (domains != NULL);
+	g_assert (n_domains >= 0);
+
+	lock ();
+
+	if (!domains_hash)
+		domains_hash = g_hash_table_new (g_str_hash, g_str_equal);
+
+	for (i = 0; i < n_domains; i++) {
+		g_assert (domains[i] != NULL);
+
+		if (strcmp (domains[i], NAUTILUS_DEBUG_LOG_DOMAIN_USER) == 0)
+			continue; /* user actions are always enabled */
+
+		if (g_hash_table_lookup (domains_hash, domains[i]) == NULL) {
+			char *domain;
+
+			domain = g_strdup (domains[i]);
+			g_hash_table_insert (domains_hash, domain, domain);
+		}
+	}
+
+	unlock ();
+}
+
+void
+nautilus_debug_log_disable_domains (const char **domains, int n_domains)
+{
+	int i;
+
+	g_assert (domains != NULL);
+	g_assert (n_domains >= 0);
+
+	lock ();
+
+	if (domains_hash) {
+		for (i = 0; i < n_domains; i++) {
+			char *domain;
+
+			g_assert (domains[i] != NULL);
+
+			if (strcmp (domains[i], NAUTILUS_DEBUG_LOG_DOMAIN_USER) == 0)
+				continue; /* user actions are always enabled */
+
+			domain = g_hash_table_lookup (domains_hash, domains[i]);
+			if (domain) {
+				g_hash_table_remove (domains_hash, domain);
+				g_free (domain);
+			}
+		}
+	} /* else, there is nothing to disable */
+
+	unlock ();
+}
+
+gboolean
+nautilus_debug_log_is_domain_enabled (const char *domain)
+{
+	gboolean retval;
+
+	g_assert (domain != NULL);
+
+	lock ();
+	retval = is_domain_enabled (domain);
+	unlock ();
+
+	return retval;
+}
+
+gboolean
+nautilus_debug_log_dump (const char *filename, GError **error)
+{
+	FILE *file;
+	gboolean success;
+	int start_index;
+	int i;
+
+	g_assert (error == NULL || *error == NULL);
+
+	lock ();
+
+	success = TRUE;
+
+	file = fopen (filename, "w");
+	if (!file) {
+		int saved_errno;
+
+		saved_errno = errno;
+		g_set_error (error,
+			     G_FILE_ERROR,
+			     g_file_error_from_errno (saved_errno),
+			     "could not open log file %s", filename);
+		success = FALSE;
+		goto out;
+	}
+
+	if (ring_buffer_num_lines == ring_buffer_max_lines)
+		start_index = ring_buffer_next_index;
+	else
+		start_index = 0;
+
+	for (i = 0; i < ring_buffer_num_lines; i++) {
+		int idx;
+
+		idx = (start_index + i) % ring_buffer_max_lines;
+
+		if (fputs (ring_buffer[idx], file) == EOF
+		    || fputc ('\n', file) == EOF) {
+			int saved_errno;
+
+			saved_errno = errno;
+			g_set_error (error,
+				     G_FILE_ERROR,
+				     g_file_error_from_errno (saved_errno),
+				     "error when writing to log file %s", filename);
+
+			success = FALSE;
+			goto do_close;
+		}
+	}
+
+ do_close:
+
+	if (fclose (file) != 0) {
+		int saved_errno;
+
+		saved_errno = errno;
+
+		if (error && *error) {
+			g_error_free (*error);
+			*error = NULL;
+		}
+
+		g_set_error (error,
+			     G_FILE_ERROR,
+			     g_file_error_from_errno (saved_errno),
+			     "error when closing log file %s", filename);
+		success = FALSE;
+	}
+
+ out:
+
+	unlock ();
+	return success;
+}
+
+void
+nautilus_debug_log_set_max_lines (int num_lines)
+{
+	char **new_buffer;
+	int lines_to_copy;
+
+	g_assert (num_lines > 0);
+
+	lock ();
+
+	if (num_lines == ring_buffer_max_lines)
+		goto out;
+
+	new_buffer = g_new0 (char *, num_lines);
+
+	lines_to_copy = MIN (num_lines, ring_buffer_num_lines);
+
+	if (ring_buffer) {
+		int start_index;
+		int i;
+
+		if (ring_buffer_num_lines == ring_buffer_max_lines)
+			start_index = (ring_buffer_next_index + ring_buffer_max_lines - lines_to_copy) % ring_buffer_max_lines;
+		else
+			start_index = ring_buffer_num_lines - lines_to_copy;
+
+		g_assert (start_index >= 0 && start_index < ring_buffer_max_lines);
+
+		for (i = 0; i < lines_to_copy; i++) {
+			int idx;
+
+			idx = (start_index + i) % ring_buffer_max_lines;
+
+			new_buffer[i] = ring_buffer[idx];
+			ring_buffer[idx] = NULL;
+		}
+
+		for (i = 0; i < ring_buffer_max_lines; i++)
+			g_free (ring_buffer[i]);
+
+		g_free (ring_buffer);
+	}
+
+	ring_buffer = new_buffer;
+	ring_buffer_next_index = lines_to_copy;
+	ring_buffer_num_lines = lines_to_copy;
+	ring_buffer_max_lines = num_lines;
+
+ out:
+
+	unlock ();
+}
+
+int
+nautilus_debug_log_get_max_lines (void)
+{
+	int retval;
+
+	lock ();
+	retval = ring_buffer_max_lines;
+	unlock ();
+
+	return retval;
+}
+
+void
+nautilus_debug_log_clear (void)
+{
+	int i;
+
+	lock ();
+
+	if (!ring_buffer)
+		goto out;
+
+	for (i = 0; i < ring_buffer_max_lines; i++) {
+		g_free (ring_buffer[i]);
+		ring_buffer[i] = NULL;
+	}
+
+	ring_buffer_next_index = 0;
+	ring_buffer_num_lines = 0;
+
+ out:
+	unlock ();
+}
--- nautilus-orig/libnautilus-private/Makefile.am	2006-09-22 20:14:18.000000000 -0500
+++ nautilus-debug/libnautilus-private/Makefile.am	2006-09-22 14:57:57.000000000 -0500
@@ -63,6 +63,8 @@ libnautilus_private_la_SOURCES = \
 	nautilus-column-utilities.h \
 	nautilus-customization-data.c \
 	nautilus-customization-data.h \
+	nautilus-debug-log.c \
+	nautilus-debug-log.h \
 	nautilus-default-file-icon.c \
 	nautilus-default-file-icon.h \
 	nautilus-desktop-directory-file.c \
--- nautilus-orig/src/nautilus-main.c	2006-09-22 20:14:20.000000000 -0500
+++ nautilus-debug/src/nautilus-main.c	2006-09-22 14:57:57.000000000 -0500
@@ -37,6 +37,7 @@
 #include <bonobo-activation/bonobo-activation.h>
 #include <bonobo/bonobo-main.h>
 #include <dlfcn.h>
+#include <signal.h>
 #include <eel/eel-debug.h>
 #include <eel/eel-glib-extensions.h>
 #include <eel/eel-self-checks.h>
@@ -49,6 +50,7 @@
 #include <libgnome/gnome-init.h>
 #include <libgnomeui/gnome-ui-init.h>
 #include <libgnomevfs/gnome-vfs-init.h>
+#include <libnautilus-private/nautilus-debug-log.h>
 #include <libnautilus-private/nautilus-directory-metafile.h>
 #include <libnautilus-private/nautilus-global-preferences.h>
 #include <libnautilus-private/nautilus-lib-self-check-functions.h>
@@ -215,6 +217,27 @@ slowly_and_stupidly_obtain_timestamp (Di
 	return event.xproperty.time;
 }
 
+static gboolean
+dump_debug_log_idle_cb (gpointer data)
+{
+	char *filename;
+
+	nautilus_debug_log (TRUE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+			    "user requested dump of debug log");
+
+	filename = g_build_filename (g_get_home_dir (), "nautilus-debug-log.txt", NULL);
+	nautilus_debug_log_dump (filename, NULL); /* NULL GError */
+	g_free (filename);
+
+	return FALSE;
+}
+
+static void
+sigusr1_handler (int sig)
+{
+	g_idle_add (dump_debug_log_idle_cb, NULL);
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -234,6 +257,7 @@ main (int argc, char *argv[])
 	GnomeProgram *program;
 	GValue context_as_value = { 0 };
 	int i;
+	struct sigaction sa;
 
 	struct poptOption options[] = {
 #ifndef NAUTILUS_OMIT_SELF_CHECK
@@ -255,6 +279,10 @@ main (int argc, char *argv[])
 		{ NULL, '\0', 0, NULL, 0, NULL, NULL }
 	};
 
+	memset (&sa, 0, sizeof (sa));
+	sa.sa_handler = sigusr1_handler;
+	sigaction (SIGUSR1, &sa, NULL);
+
 	i = 0;
 #ifndef NAUTILUS_OMIT_SELF_CHECK
 	options[i++].arg = &perform_self_check;
--- nautilus-orig/src/file-manager/fm-directory-view.c	2006-09-22 20:14:20.000000000 -0500
+++ nautilus-debug/src/file-manager/fm-directory-view.c	2006-09-22 18:04:45.000000000 -0500
@@ -75,6 +75,7 @@
 #include <libnautilus-private/nautilus-recent.h>
 #include <libnautilus-extension/nautilus-menu-provider.h>
 #include <libnautilus-private/nautilus-clipboard-monitor.h>
+#include <libnautilus-private/nautilus-debug-log.h>
 #include <libnautilus-private/nautilus-desktop-icon-file.h>
 #include <libnautilus-private/nautilus-desktop-directory.h>
 #include <libnautilus-private/nautilus-directory-background.h>
@@ -664,11 +665,14 @@ fm_directory_view_launch_application (Gn
 	g_assert (NAUTILUS_IS_FILE (file));
 	g_assert (FM_IS_DIRECTORY_VIEW (directory_view));
 
+	uri = nautilus_file_get_uri (file);
+
 	nautilus_launch_application
 			(application, file, 
 			 fm_directory_view_get_containing_window (directory_view));
 
-	uri = nautilus_file_get_uri (file);
+	nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+			    "directory_view_launch_application: %s", uri);
 
 	/* Only add real gnome-vfs uris to recent. Not things like
 	   trash:// and x-nautilus-desktop:// */
@@ -725,7 +729,9 @@ open_location (FMDirectoryView *director
 		monitor_file_for_open_with (directory_view, NULL);
 	}
 	nautilus_file_unref (file);
-	
+
+	nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+			    "directory view open_location: %s", new_uri);
 	nautilus_window_info_open_location (directory_view->details->window,
 					    new_uri, mode, flags, NULL);
 }
@@ -1157,6 +1163,8 @@ action_new_launcher_callback (GtkAction 
 
 	parent_uri = fm_directory_view_get_backing_uri (view);
 
+	nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+			    "directory view create new launcher in: %s", parent_uri);
 	nautilus_launch_application_from_command (gtk_widget_get_screen (GTK_WIDGET (view)),
 						  "gnome-desktop-item-edit", 
 						  "gnome-desktop-item-edit --create-new",
@@ -4844,6 +4852,8 @@ run_script_callback (GtkAction *action, 
 
 	name = nautilus_file_get_name (launch_parameters->file);
 	/* FIXME: handle errors with dialog? Or leave up to each script? */
+	nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+			    "directory view run_script_callback, name=\"%s\", command=\"%s\"", name, command);
 	nautilus_launch_application_from_command (screen, name, command, NULL, FALSE);
 	g_free (name);
 	g_free (command);
@@ -7324,6 +7334,8 @@ activate_callback (NautilusFile *file, g
 	switch (action) {
 	case ACTIVATION_ACTION_LAUNCH_DESKTOP_FILE :
 		file_uri = nautilus_file_get_uri (file);
+		nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+				    "directory view activate_callback launch_desktop_file: %s", file_uri);
 		nautilus_launch_desktop_file (
 				screen, file_uri, NULL,
 				fm_directory_view_get_containing_window (view));
@@ -7331,6 +7343,8 @@ activate_callback (NautilusFile *file, g
 		break;
 	case ACTIVATION_ACTION_LAUNCH_APPLICATION_FROM_COMMAND :
 		uri += strlen (NAUTILUS_COMMAND_SPECIFIER);
+		nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+				    "directory view activate_callback launch_application_from_command: %s", uri);
 		nautilus_launch_application_from_command (screen, NULL, uri, NULL, FALSE);
 		break;
 	case ACTIVATION_ACTION_LAUNCH :
@@ -7340,6 +7354,10 @@ activate_callback (NautilusFile *file, g
 		executable_path = gnome_vfs_get_local_path_from_uri (uri);
 		quoted_path = g_shell_quote (executable_path);
 		name = nautilus_file_get_name (file);
+		nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+				    "directory view activate_callback launch_application_from_command name=\"%s\", "
+				    "quoted_path=\"%s\"",
+				    name, quoted_path);
 		nautilus_launch_application_from_command 
 			(screen, name, quoted_path, NULL,
 			 (action == ACTIVATION_ACTION_LAUNCH_IN_TERMINAL) /* use terminal */ );
@@ -7352,9 +7370,14 @@ activate_callback (NautilusFile *file, g
 		
 		break;
 	case ACTIVATION_ACTION_OPEN_IN_VIEW :
+		/* no need to log here; we already do it in open_location() */
 		open_location (view, uri, parameters->mode, parameters->flags);
 		break;
 	case ACTIVATION_ACTION_OPEN_IN_APPLICATION :
+		file_uri = nautilus_file_get_uri (file);
+		nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+				    "directory view launch_show_file: %s", file_uri);
+
 		nautilus_launch_show_file
 			(file, fm_directory_view_get_containing_window (view));
 		
@@ -7367,10 +7390,10 @@ activate_callback (NautilusFile *file, g
 		/* We should not add trash and directory uris.*/
 		if ((!nautilus_file_is_in_trash (file)) && 
 		    (!nautilus_file_is_directory (file))) {
-			file_uri = nautilus_file_get_uri (file);
 			egg_recent_model_add (nautilus_recent_get_model (), file_uri);
-			g_free (file_uri);
 		}
+
+		g_free (file_uri);
 		break;
 	case ACTIVATION_ACTION_DO_NOTHING :
 		break;
@@ -7619,6 +7642,22 @@ fm_directory_view_activate_files (FMDire
 
 	g_return_if_fail (FM_IS_DIRECTORY_VIEW (view));
 
+	{
+		GList *l;
+
+		for (l = files; l; l = l->next) {
+			NautilusFile *file;
+			char *uri;
+
+			file = NAUTILUS_FILE (l->data);
+			uri = nautilus_file_get_uri (file);
+			nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+					    "fm_directory_view_activate_files: %s",
+					    uri);
+			g_free (uri);
+		}
+	}
+
 	/* If there's a single file to activate, check user's preference whether
 	 * to open it in this window or a new window. If there is more than one
 	 * file to activate, open each one in a new window. Don't try to choose
--- nautilus-orig/src/file-manager/fm-tree-view.c	2006-09-22 20:14:20.000000000 -0500
+++ nautilus-debug/src/file-manager/fm-tree-view.c	2006-09-22 14:57:57.000000000 -0500
@@ -60,6 +60,7 @@
 #include <libgnomevfs/gnome-vfs-utils.h>
 #include <libgnomevfs/gnome-vfs-volume-monitor.h>
 #include <libnautilus-private/nautilus-clipboard-monitor.h>
+#include <libnautilus-private/nautilus-debug-log.h>
 #include <libnautilus-private/nautilus-file-attributes.h>
 #include <libnautilus-private/nautilus-file-operations.h>
 #include <libnautilus-private/nautilus-global-preferences.h>
@@ -345,12 +346,16 @@ got_activation_uri_callback (NautilusFil
 	    && eel_str_has_prefix (uri, NAUTILUS_COMMAND_SPECIFIER)) {
 
 		uri += strlen (NAUTILUS_COMMAND_SPECIFIER);
+		nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+				    "tree view launch_application_from_command: %s", uri);
 		nautilus_launch_application_from_command (screen, NULL, uri, NULL, FALSE);
 
 	} else if (uri != NULL
 	    	   && eel_str_has_prefix (uri, NAUTILUS_DESKTOP_COMMAND_SPECIFIER)) {
 		   
 		file_uri = nautilus_file_get_uri (file);
+		nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+				    "tree view launch_desktop_file: %s", file_uri);
 		nautilus_launch_desktop_file (screen, file_uri, NULL, NULL);
 		g_free (file_uri);
 		
@@ -363,6 +368,8 @@ got_activation_uri_callback (NautilusFil
 
 		/* Non-local executables don't get launched. They act like non-executables. */
 		if (file_uri == NULL) {
+			nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+					    "tree view window_info_open_location: %s", uri);
 			nautilus_window_info_open_location
 				(view->details->window, 
 				 uri, 
@@ -370,6 +377,8 @@ got_activation_uri_callback (NautilusFil
 				 0,
 				 NULL);
 		} else {
+			nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+					    "tree view launch_application_from_command: %s", file_uri);
 			nautilus_launch_application_from_command (screen, NULL, file_uri, NULL, FALSE);
 			g_free (file_uri);
 		}
@@ -381,6 +390,8 @@ got_activation_uri_callback (NautilusFil
 				g_free (view->details->selection_location);
 			}
 			view->details->selection_location = g_strdup (uri);
+			nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+					    "tree view window_info_open_location: %s", uri);
 			nautilus_window_info_open_location
 				(view->details->window, 
 				 uri,
--- nautilus-orig/src/nautilus-places-sidebar.c	2006-09-22 20:14:20.000000000 -0500
+++ nautilus-debug/src/nautilus-places-sidebar.c	2006-09-22 14:57:57.000000000 -0500
@@ -43,6 +43,7 @@
 #include <libgnome/gnome-macros.h>
 #include <libgnome/gnome-i18n.h>
 #include <libnautilus-private/nautilus-bookmark.h>
+#include <libnautilus-private/nautilus-debug-log.h>
 #include <libnautilus-private/nautilus-global-preferences.h>
 #include <libnautilus-private/nautilus-sidebar-provider.h>
 #include <libnautilus-private/nautilus-module.h>
@@ -406,6 +407,8 @@ row_activated_callback (GtkTreeView *tre
 		(model, &iter, PLACES_SIDEBAR_COLUMN_URI, &uri, -1);
 	
 	if (uri != NULL) {
+		nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+				    "activate from places sidebar: %s", uri);
 		/* Navigate to the clicked location. */
 		nautilus_window_info_open_location
 			(sidebar->window, 
@@ -416,6 +419,13 @@ row_activated_callback (GtkTreeView *tre
 		gtk_tree_model_get 
 			(model, &iter, PLACES_SIDEBAR_COLUMN_DRIVE, &drive, -1);
 		if (drive != NULL) {
+			char *path;
+
+			path = gnome_vfs_drive_get_device_path (drive);
+			nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+					    "activate drive from places sidebar: %s", path);
+			g_free (path);
+
 			gnome_vfs_drive_mount (drive, mount_volume_callback, sidebar);
 			gnome_vfs_drive_unref (drive);
 		}
--- nautilus-orig/src/nautilus-navigation-window.c	2006-09-22 20:14:20.000000000 -0500
+++ nautilus-debug/src/nautilus-navigation-window.c	2006-09-22 18:13:00.000000000 -0500
@@ -67,6 +67,7 @@
 #include <libgnomeui/gnome-window-icon.h>
 #include <libgnomevfs/gnome-vfs-uri.h>
 #include <libgnomevfs/gnome-vfs-utils.h>
+#include <libnautilus-private/nautilus-debug-log.h>
 #include <libnautilus-private/nautilus-file-utilities.h>
 #include <libnautilus-private/nautilus-file-attributes.h>
 #include <libnautilus-private/nautilus-global-preferences.h>
@@ -394,6 +395,9 @@ path_bar_location_changed_callback (GtkW
 
 	g_assert (NAUTILUS_IS_NAVIGATION_WINDOW (window));
 
+	nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+			    "path bar clicked: %s", uri);
+
 	/* check whether we already visited the target location */
 	i = bookmark_list_get_uri_index (window->back_list, uri);
 	if (i >= 0) {
--- nautilus-orig/src/nautilus-window-manage-views.c	2006-09-22 20:14:19.000000000 -0500
+++ nautilus-debug/src/nautilus-window-manage-views.c	2006-09-22 20:22:30.000000000 -0500
@@ -53,6 +53,7 @@
 #include <libgnomevfs/gnome-vfs-async-ops.h>
 #include <libgnomevfs/gnome-vfs-uri.h>
 #include <libgnomevfs/gnome-vfs-utils.h>
+#include <libnautilus-private/nautilus-debug-log.h>
 #include <libnautilus-private/nautilus-file-attributes.h>
 #include <libnautilus-private/nautilus-file-utilities.h>
 #include <libnautilus-private/nautilus-file.h>
@@ -447,6 +448,9 @@ nautilus_window_open_location_full (Naut
         
         target_window = NULL;
 
+	nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+			    "window open location: %s", location);
+
 	switch (mode) {
         case NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE :
 		if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ALWAYS_USE_BROWSER)) {
@@ -1232,6 +1236,13 @@ nautilus_window_report_load_complete (Na
 static void
 end_location_change (NautilusWindow *window)
 {
+	char *location;
+
+	location = nautilus_window_get_location (window);
+	nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+				"finished loading window %s", location);
+	g_free (location);
+
         nautilus_window_allow_stop (window, FALSE);
 
         /* Now we can free pending_scroll_to, since the load_complete
@@ -1497,11 +1508,18 @@ nautilus_window_set_content_view (Nautil
                                   const char *id)
 {
 	NautilusFile *file;
+	char *location;
 	
 	g_return_if_fail (NAUTILUS_IS_WINDOW (window));
         g_return_if_fail (window->details->location != NULL);
 	g_return_if_fail (id != NULL);
 
+	location = nautilus_window_get_location (window);
+	nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+			    "change view of window=\"%s\" to \"%s\"",
+			    location, id);
+	g_free (location);
+
         if (nautilus_window_content_view_matches_iid (window, id)) {
         	return;
         }
@@ -1681,6 +1699,10 @@ nautilus_navigation_window_back_or_forwa
         bookmark = g_list_nth_data (list, distance);
 	uri = nautilus_bookmark_get_uri (bookmark);
         scroll_pos = nautilus_bookmark_get_scroll_pos (bookmark);
+
+	nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+			    "nautilus_navigation_window_back_or_forward: %s", uri);
+
 	begin_location_change
 		(NAUTILUS_WINDOW (window),
 		 uri, NULL,
--- nautilus-orig/src/file-manager/fm-list-view.c	2005-11-14 08:46:57.000000000 -0600
+++ nautilus-debug/src/file-manager/fm-list-view.c	2006-09-22 18:29:21.000000000 -0500
@@ -55,6 +55,7 @@
 #include <libnautilus-extension/nautilus-column-provider.h>
 #include <libnautilus-private/nautilus-column-chooser.h>
 #include <libnautilus-private/nautilus-column-utilities.h>
+#include <libnautilus-private/nautilus-debug-log.h>
 #include <libnautilus-private/nautilus-directory-background.h>
 #include <libnautilus-private/nautilus-dnd.h>
 #include <libnautilus-private/nautilus-file-dnd.h>
@@ -895,6 +896,13 @@ row_expanded_callback (GtkTreeView *tree
 	view = FM_LIST_VIEW (callback_data);
 
 	if (fm_list_model_load_subdirectory (view->details->model, path, &directory)) {
+		char *uri;
+
+		uri = nautilus_directory_get_uri (directory);
+		nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+				    "list view row expanded: %s", uri);
+		g_free (uri);
+
 		fm_directory_view_add_subdirectory (FM_DIRECTORY_VIEW (view), directory);
 		
 		if (nautilus_directory_are_all_files_seen (directory)) {
@@ -951,6 +959,7 @@ row_collapsed_callback (GtkTreeView *tre
  	FMListView *view;
  	NautilusFile *file;
 	struct UnloadDelayData *unload_data;
+	char *uri;
 	
 	view = FM_LIST_VIEW (callback_data);
 		
@@ -958,6 +967,11 @@ row_collapsed_callback (GtkTreeView *tre
 			    iter, 
 			    FM_LIST_MODEL_FILE_COLUMN, &file,
 			    -1);
+
+	uri = nautilus_file_get_uri (file);
+	nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+			    "list view row collapsed: %s", uri);
+	g_free (uri);
 	
 	unload_data = g_new (struct UnloadDelayData, 1);
 	unload_data->view = view;
--- nautilus-orig/src/file-manager/fm-error-reporting.c	2006-09-22 20:14:20.000000000 -0500
+++ nautilus-debug/src/file-manager/fm-error-reporting.c	2006-09-22 18:39:49.000000000 -0500
@@ -29,6 +29,7 @@
 #include <string.h>
 #include <libgnome/gnome-i18n.h>
 #include <libgnomevfs/gnome-vfs-result.h>
+#include <libnautilus-private/nautilus-debug-log.h>
 #include <libnautilus-private/nautilus-file.h>
 #include <eel/eel-string.h>
 #include <eel/eel-stock-dialogs.h>
@@ -304,6 +305,7 @@ fm_rename_file (NautilusFile *file,
 		const char *new_name)
 {
 	char *old_name, *wait_message;
+	char *uri;
 
 	g_return_if_fail (NAUTILUS_IS_FILE (file));
 	g_return_if_fail (new_name != NULL);
@@ -328,6 +330,12 @@ fm_rename_file (NautilusFile *file,
 				   NULL); /* FIXME bugzilla.gnome.org 42395: Parent this? */
 	g_free (wait_message);
 
+	uri = nautilus_file_get_uri (file);
+	nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+			    "rename file old=\"%s\", new=\"%s\"",
+			    uri, new_name);
+	g_free (uri);
+
 	/* Start the rename. */
 	nautilus_file_rename (file, new_name,
 			      rename_callback, NULL);
--- nautilus-orig/src/nautilus-application.c	2006-09-22 20:14:20.000000000 -0500
+++ nautilus-debug/src/nautilus-application.c	2006-09-22 19:59:04.000000000 -0500
@@ -75,6 +75,7 @@
 #include <libgnomevfs/gnome-vfs-ops.h>
 #include <libgnomevfs/gnome-vfs-utils.h>
 #include <libgnomevfs/gnome-vfs-volume-monitor.h>
+#include <libnautilus-private/nautilus-debug-log.h>
 #include <libnautilus-private/nautilus-file-utilities.h>
 #include <libnautilus-private/nautilus-global-preferences.h>
 #include <libnautilus-private/nautilus-icon-factory.h>
@@ -1139,6 +1140,9 @@ nautilus_application_present_spatial_win
 			if (new_selection) {
 				nautilus_view_set_selection (existing_window->content_view, new_selection);
 			}
+
+			nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+					    "present EXISTING spatial window: %s", location);
 			return existing_window;
 		}
 	}
@@ -1176,6 +1180,9 @@ nautilus_application_present_spatial_win
 			   spatial_window_destroyed_callback, NULL);
 	
 	nautilus_window_go_to_with_selection (window, location, new_selection);
+
+	nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+			    "present NEW spatial window: %s", location);
 	
 	return window;
 }
@@ -1195,6 +1202,9 @@ nautilus_application_create_navigation_w
 				  startup_id);
 #endif
 
+	nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+			    "create new navigation window");
+
 	return window;
 }
 


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