diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index 23acfab..9115885 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -23,6 +23,7 @@
 
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <sys/stat.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <unistd.h>
@@ -140,6 +141,149 @@ G_DEFINE_TYPE (GsdXrandrManager, gsd_xrandr_manager, G_TYPE_OBJECT)
 
 static gpointer manager_object = NULL;
 
+static FILE *log_file;
+
+static void
+log_open (void)
+{
+        char *toggle_filename;
+        char *log_filename;
+        struct stat st;
+
+        if (log_file)
+                return;
+
+        toggle_filename = g_build_filename (g_get_home_dir (), "gsd-debug-randr", NULL);
+        log_filename = g_build_filename (g_get_home_dir (), "gsd-debug-randr.log", NULL);
+
+        if (stat (toggle_filename, &st) != 0)
+                goto out;
+
+        log_file = fopen (log_filename, "a");
+
+        if (log_file && ftell (log_file) == 0)
+                fprintf (log_file, "To keep this log from being created, please rm ~/gsd-debug-randr\n");
+
+out:
+        g_free (toggle_filename);
+        g_free (log_filename);
+}
+
+static void
+log_close (void)
+{
+        if (log_file) {
+                fclose (log_file);
+                log_file = NULL;
+        }
+}
+
+static void
+log_msg (const char *format, ...)
+{
+        if (log_file) {
+                va_list args;
+
+                va_start (args, format);
+                vfprintf (log_file, format, args);
+                va_end (args);
+        }
+}
+
+static void
+log_output (GnomeOutputInfo *output)
+{
+        log_msg ("        %s: ", output->name ? output->name : "unknown");
+
+        if (output->connected) {
+                if (output->on) {
+                        log_msg ("%dx%d@%d +%d+%d",
+                                 output->width,
+                                 output->height,
+                                 output->rate,
+                                 output->x,
+                                 output->y);
+                } else
+                        log_msg ("off");
+        } else
+                log_msg ("disconnected");
+
+        if (output->display_name)
+                log_msg (" (%s)", output->display_name);
+
+        if (output->primary)
+                log_msg (" (primary output)");
+
+        log_msg ("\n");
+}
+
+static void
+log_configuration (GnomeRRConfig *config)
+{
+        int i;
+
+        log_msg ("        cloned: %s\n", config->clone ? "yes" : "no");
+
+        for (i = 0; config->outputs[i] != NULL; i++)
+                log_output (config->outputs[i]);
+
+        if (i == 0)
+                log_msg ("        no outputs!\n");
+}
+
+static char
+timestamp_relationship (guint32 a, guint32 b)
+{
+        if (a < b)
+                return '<';
+        else if (a > b)
+                return '>';
+        else
+                return '=';
+}
+
+static void
+log_screen (GnomeRRScreen *screen)
+{
+        GnomeRRConfig *config;
+        int min_w, min_h, max_w, max_h;
+        guint32 change_timestamp, config_timestamp;
+
+        if (!log_file)
+                return;
+
+        config = gnome_rr_config_new_current (screen);
+
+        gnome_rr_screen_get_ranges (screen, &min_w, &max_w, &min_h, &max_h);
+        gnome_rr_screen_get_timestamps (screen, &change_timestamp, &config_timestamp);
+
+        log_msg ("        Screen min(%d, %d), max(%d, %d), change=%u %c config=%u\n",
+                 min_w, min_h,
+                 max_w, max_h,
+                 change_timestamp,
+                 timestamp_relationship (change_timestamp, config_timestamp),
+                 config_timestamp);
+
+        log_configuration (config);
+        gnome_rr_config_free (config);
+}
+
+static void
+log_configurations (GnomeRRConfig **configs)
+{
+        int i;
+
+        if (!configs) {
+                log_msg ("    No configurations\n");
+                return;
+        }
+
+        for (i = 0; configs[i]; i++) {
+                log_msg ("    Configuration %d\n", i);
+                log_configuration (configs[i]);
+        }
+}
+
 static void
 show_timestamps_dialog (GsdXrandrManager *manager, const char *msg)
 {
@@ -354,6 +498,8 @@ apply_configuration_and_display_error (GsdXrandrManager *manager, GnomeRRConfig
         error = NULL;
         success = gnome_rr_config_apply_with_time (config, priv->rw_screen, timestamp, &error);
         if (!success) {
+                log_msg ("Could not switch to the following configuration (timestamp %u): %s\n", timestamp, error->message);
+                log_configuration (config);
                 error_message (manager, _("Could not switch the monitor configuration"), error, NULL);
                 g_error_free (error);
         }
@@ -1107,6 +1253,9 @@ handle_fn_f7 (GsdXrandrManager *mgr, guint32 timestamp)
 
         gdk_error_trap_push (); /* avoid BadMatch error */
 
+        log_open ();
+        log_msg ("Handling XF86Display hotkey - timestamp %u\n", timestamp);
+
         error = NULL;
         if (!gnome_rr_screen_refresh (screen, &error) && error) {
                 char *str;
@@ -1114,12 +1263,16 @@ handle_fn_f7 (GsdXrandrManager *mgr, guint32 timestamp)
                 str = g_strdup_printf (_("Could not refresh the screen information: %s"), error->message);
                 g_error_free (error);
 
+                log_msg ("%s\n", str);
                 error_message (mgr, str, NULL, _("Trying to switch the monitor configuration anyway."));
                 g_free (str);
         }
 
-        if (!priv->fn_f7_configs)
+        if (!priv->fn_f7_configs) {
+                log_msg ("Generating stock configurations:\n");
                 generate_fn_f7_configs (mgr);
+                log_configurations (priv->fn_f7_configs);
+        }
 
         current = gnome_rr_config_new_current (screen);
 
@@ -1130,12 +1283,15 @@ handle_fn_f7 (GsdXrandrManager *mgr, guint32 timestamp)
                      * configurations
                      */
                     generate_fn_f7_configs (mgr);
+                    log_msg ("Regenerated stock configurations:\n");
+                    log_configurations (priv->fn_f7_configs);
             }
 
         gnome_rr_config_free (current);
 
         if (priv->fn_f7_configs) {
                 guint32 server_timestamp;
+                gboolean success;
 
                 mgr->priv->current_fn_f7_config++;
 
@@ -1164,12 +1320,19 @@ handle_fn_f7 (GsdXrandrManager *mgr, guint32 timestamp)
                 if (timestamp < server_timestamp)
                         timestamp = server_timestamp;
 
-                apply_configuration_and_display_error (mgr, priv->fn_f7_configs[mgr->priv->current_fn_f7_config], timestamp);
+                success = apply_configuration_and_display_error (mgr, priv->fn_f7_configs[mgr->priv->current_fn_f7_config], timestamp);
+
+                if (success) {
+                        log_msg ("Successfully switched to configuration (timestamp %u):\n", timestamp);
+                        log_configuration (priv->fn_f7_configs[mgr->priv->current_fn_f7_config]);
+                }
         }
         else {
                 g_debug ("no configurations generated");
         }
 
+        log_close ();
+
         gdk_flush ();
         gdk_error_trap_pop ();
 
@@ -1490,6 +1653,12 @@ on_randr_event (GnomeRRScreen *screen, gpointer data)
 
         gnome_rr_screen_get_timestamps (screen, &change_timestamp, &config_timestamp);
 
+        log_open ();
+        log_msg ("Got RANDR event with timestamps change=%u %c config=%u\n",
+                 change_timestamp,
+                 timestamp_relationship (change_timestamp, config_timestamp),
+                 config_timestamp);
+
         if (change_timestamp >= config_timestamp) {
                 /* The event is due to an explicit configuration change.
                  *
@@ -1498,7 +1667,8 @@ on_randr_event (GnomeRRScreen *screen, gpointer data)
                  * If the change was done by some other X client, we don't need
                  * to do anything, either; the screen is already configured.
                  */
-                show_timestamps_dialog (manager, "ignoring since change > config");
+                show_timestamps_dialog (manager, "ignoring since change >= config");
+                log_msg ("  Ignoring event since change >= config\n");
         } else {
                 /* Here, config_timestamp > change_timestamp.  This means that
                  * the screen got reconfigured because of hotplug/unplug; the X
@@ -1510,7 +1680,7 @@ on_randr_event (GnomeRRScreen *screen, gpointer data)
                 GError *error;
                 gboolean success;
 
-                show_timestamps_dialog (manager, "need to deal with reconfiguration, as config >= change");
+                show_timestamps_dialog (manager, "need to deal with reconfiguration, as config > change");
 
                 intended_filename = gnome_rr_config_get_intended_filename ();
 
@@ -1540,11 +1710,16 @@ on_randr_event (GnomeRRScreen *screen, gpointer data)
                         if (config_timestamp != priv->last_config_timestamp) {
                                 priv->last_config_timestamp = config_timestamp;
                                 auto_configure_outputs (manager, config_timestamp);
-                        }
-                }
+                                log_msg ("  Automatically configured outputs to deal with event\n");
+                        } else
+                                log_msg ("  Ignored event as old and new config timestamps are the same\n");
+                } else
+                        log_msg ("Applied stored configuration to deal with event\n");
         }
 
         refresh_tray_icon_menu_if_active (manager, MAX (change_timestamp, config_timestamp));
+
+        log_close ();
 }
 
 static void
@@ -2194,11 +2369,22 @@ gsd_xrandr_manager_start (GsdXrandrManager *manager,
         g_debug ("Starting xrandr manager");
         gnome_settings_profile_start (NULL);
 
+        log_open ();
+        log_msg ("------------------------------------------------------------\nSTARTING XRANDR PLUGIN\n");
+
         manager->priv->rw_screen = gnome_rr_screen_new (
                 gdk_screen_get_default (), on_randr_event, manager, error);
 
-        if (manager->priv->rw_screen == NULL)
+        if (manager->priv->rw_screen == NULL) {
+                log_msg ("Could not initialize the RANDR plugin%s%s\n",
+                         (error && *error) ? ": " : "",
+                         (error && *error) ? (*error)->message : "");
+                log_close ();
                 return FALSE;
+        }
+
+        log_msg ("State of screen at startup:\n");
+        log_screen (manager->priv->rw_screen);
 
         manager->priv->running = TRUE;
         manager->priv->client = gconf_client_get_default ();
@@ -2243,12 +2429,17 @@ gsd_xrandr_manager_start (GsdXrandrManager *manager,
         if (user_configuration_is_newer_than_xorg (manager))
                 apply_stored_configuration_at_startup (manager, GDK_CURRENT_TIME); /* we don't have a real timestamp at startup anyway */
 
+        log_msg ("State of screen after initial configuration:\n");
+        log_screen (manager->priv->rw_screen);
+
         gdk_window_add_filter (gdk_get_default_root_window(),
                                (GdkFilterFunc)event_filter,
                                manager);
 
         start_or_stop_icon (manager);
 
+        log_close ();
+
         gnome_settings_profile_end (NULL);
 
         return TRUE;
@@ -2308,6 +2499,10 @@ gsd_xrandr_manager_stop (GsdXrandrManager *manager)
                 manager->priv->dbus_connection = NULL;
         }
 
+        log_open ();
+        log_msg ("STOPPING XRANDR PLUGIN\n------------------------------------------------------------\n");
+        log_close ();
+
         status_icon_stop (manager);
 }
 
