File gnome-settings-daemon-bnc381139-handle-hotplug-and-unsuspend.diff of Package gnome-settings-daemon

From b7862456f67b1e92a4d388ef2f50fe57b214c2de Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Tue, 5 May 2009 17:39:31 -0500
Subject: [PATCH 01/29] Comments on how to handle hotplug notifications

Signed-off-by: Federico Mena Quintero <federico@novell.com>
---
 plugins/xrandr/gsd-xrandr-manager.c |   33 +++++++++++++++++++++++++++++++++
 1 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index fbede4c..6e05e70 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -991,6 +991,39 @@ on_randr_event (GnomeRRScreen *screen, gpointer data)
         if (!manager->priv->running)
                 return;
 
+        /* Scenarios:
+         *
+         * 1. Monitor gets plugged.
+         *
+         *    - Can we detect if it is a projector?  We want "mirror" in that case.  If it's a monitor,
+         *      we probably want "extend desktop" like MacOS does by default.
+         *
+         * 2. Monitor gets unplugged.
+         *
+         *    - We don't get notification.  User presses XF86Display hotkey - we should come back with
+         *      a visible monitor.  Does this actually happen?
+         *
+         * 3. Machine gets unsuspended.
+         *
+         * Requirements:
+         *
+         * - Always have a visible monitor.
+         *
+         * - Have an easy way to turn on/off monitors.
+         *
+         * - Minimal reconfiguration; maximal DTRT when one plugs/unplugs.
+         */
+
+        /* See if the current configuration matches any saved one; if so, use the
+         * saved one.
+         *
+         * Otherwise, do what "xrandr --auto" does - basically, turn on connected outputs
+         * and turn off disconnected ones.
+         *
+         * Or get a diff between the old/new configurations, and do the
+         * interactive "you plugged a monitor; what do I do?" dance.
+         */
+
         /* FIXME: Set up any new screens here */
 }
 
-- 
1.6.0.2


From e51e1fdfc3e3af3f5d1738db4492da886d22337c Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Tue, 5 May 2009 18:17:24 -0500
Subject: [PATCH 02/29] Show a dialog when we get a RANDR event

Signed-off-by: Federico Mena Quintero <federico@novell.com>
---
 plugins/xrandr/gsd-xrandr-manager.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index 6e05e70..8874826 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -987,10 +987,15 @@ static void
 on_randr_event (GnomeRRScreen *screen, gpointer data)
 {
         GsdXrandrManager *manager = GSD_XRANDR_MANAGER (data);
+        GtkWidget *dialog;
 
         if (!manager->priv->running)
                 return;
 
+        dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, "Got RANDR event");
+        gtk_dialog_run (GTK_DIALOG (dialog));
+        gtk_widget_destroy (dialog);
+
         /* Scenarios:
          *
          * 1. Monitor gets plugged.
-- 
1.6.0.2


From 237ac7a0c9ee2071dea42a4afbd3e3da4f279d00 Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Wed, 27 May 2009 14:59:49 -0500
Subject: [PATCH 03/29] Pass GDK_CURRENT_TIME for now to gnome_rr_config_apply*_with_time()

Signed-off-by: Federico Mena Quintero <federico@novell.com>
---
 plugins/xrandr/gsd-xrandr-manager.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index 8874826..2475e8f 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -254,7 +254,7 @@ apply_configuration_from_filename (GsdXrandrManager *manager, const char *filena
         gboolean success;
 
         my_error = NULL;
-        success = gnome_rr_config_apply_from_filename (priv->rw_screen, filename, &my_error);
+        success = gnome_rr_config_apply_from_filename_with_time (priv->rw_screen, filename, GDK_CURRENT_TIME, &my_error); /* FMQ: pass a timestamp */
         if (success)
                 return TRUE;
 
@@ -948,7 +948,7 @@ handle_fn_f7 (GsdXrandrManager *mgr)
                 g_debug ("applying");
 
                 error = NULL;
-                if (!gnome_rr_config_apply (priv->fn_f7_configs[mgr->priv->current_fn_f7_config], screen, &error)) {
+                if (!gnome_rr_config_apply_with_time (priv->fn_f7_configs[mgr->priv->current_fn_f7_config], screen, GDK_CURRENT_TIME, &error)) { /* FMQ: pass a real timestamp */
                         error_message (mgr, _("Could not switch the monitor configuration"), error, NULL);
                         g_error_free (error);
                 }
-- 
1.6.0.2


From d09f8d64bf5674ac7b0d99b3460a82d3ddc39680 Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Mon, 1 Jun 2009 11:30:14 -0500
Subject: [PATCH 04/29] Pass a real timestamp when handling the XF86Display hotkey

---
 plugins/xrandr/gsd-xrandr-manager.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index 2475e8f..25ac158 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -887,7 +887,7 @@ error_message (GsdXrandrManager *mgr, const char *primary_text, GError *error_to
 }
 
 static void
-handle_fn_f7 (GsdXrandrManager *mgr)
+handle_fn_f7 (GsdXrandrManager *mgr, guint32 timestamp)
 {
         GsdXrandrManagerPrivate *priv = mgr->priv;
         GnomeRRScreen *screen = priv->rw_screen;
@@ -948,7 +948,7 @@ handle_fn_f7 (GsdXrandrManager *mgr)
                 g_debug ("applying");
 
                 error = NULL;
-                if (!gnome_rr_config_apply_with_time (priv->fn_f7_configs[mgr->priv->current_fn_f7_config], screen, GDK_CURRENT_TIME, &error)) { /* FMQ: pass a real timestamp */
+                if (!gnome_rr_config_apply_with_time (priv->fn_f7_configs[mgr->priv->current_fn_f7_config], screen, timestamp, &error)) {
                         error_message (mgr, _("Could not switch the monitor configuration"), error, NULL);
                         g_error_free (error);
                 }
@@ -974,8 +974,8 @@ event_filter (GdkXEvent           *xevent,
         if (xev->xany.type != KeyPress && xev->xany.type != KeyRelease)
                 return GDK_FILTER_CONTINUE;
 
-        if (xev->xkey.keycode == manager->priv->keycode && xev->xany.type == KeyPress) {
-                handle_fn_f7 (manager);
+        if (xev->xany.type == KeyPress && xev->xkey.keycode == manager->priv->keycode) {
+                handle_fn_f7 (manager, xev->xkey.time);
 
                 return GDK_FILTER_CONTINUE;
         }
-- 
1.6.0.2


From 6bae3022ad73dff71b7dcb63f5318f0428542990 Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Wed, 27 May 2009 15:05:57 -0500
Subject: [PATCH 05/29] Allow passing a timestamp to the central apply_configuration_from_filename()

Signed-off-by: Federico Mena Quintero <federico@novell.com>
---
 plugins/xrandr/gsd-xrandr-manager.c |   19 ++++++++-----------
 1 files changed, 8 insertions(+), 11 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index 25ac158..0aafd29 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -243,18 +243,18 @@ handle_tablet_rotation (GsdXrandrManager *manager)
         rotate_tablet (manager, rotation);
 }
 
-/* Filters out GNOME_RR_ERROR_NO_MATCHING_CONFIG from
- * gnome_rr_config_apply_from_filename(), since that is not usually an error.
+/* Optionally filters out GNOME_RR_ERROR_NO_MATCHING_CONFIG from
+ * gnome_rr_config_apply_from_filename_with_time(), since that is not usually an error.
  */
 static gboolean
-apply_configuration_from_filename (GsdXrandrManager *manager, const char *filename, GError **error)
+apply_configuration_from_filename (GsdXrandrManager *manager, const char *filename, guint32 timestamp, GError **error)
 {
         struct GsdXrandrManagerPrivate *priv = manager->priv;
         GError *my_error;
         gboolean success;
 
         my_error = NULL;
-        success = gnome_rr_config_apply_from_filename_with_time (priv->rw_screen, filename, GDK_CURRENT_TIME, &my_error); /* FMQ: pass a timestamp */
+        success = gnome_rr_config_apply_from_filename_with_time (priv->rw_screen, filename, timestamp, &my_error);
         if (success)
                 return TRUE;
 
@@ -299,7 +299,7 @@ restore_backup_configuration (GsdXrandrManager *manager, const char *backup_file
                 GError *error;
 
                 error = NULL;
-                if (!apply_stored_configuration_and_rotate_tablet (manager, intended_filename, &error)) {
+                if (!apply_configuration_from_filename (manager, intended_filename, GDK_CURRENT_TIME, &error)) { /* FMQ: pass a real timestamp */
                         error_message (manager, _("Could not restore the display's configuration"), error, NULL);
 
                         if (error)
@@ -438,10 +438,7 @@ try_to_apply_intended_configuration (GsdXrandrManager *manager, GdkWindow *paren
         backup_filename = gnome_rr_config_get_backup_filename ();
         intended_filename = gnome_rr_config_get_intended_filename ();
 
-        /* FIXME: we should pass the timestamp to the XRR* functions, but the
-         * GnomeRR wrapper API doesn't take timestamps yet.
-         */
-        result = apply_stored_configuration_and_rotate_tablet (manager, intended_filename, error);
+        result = apply_configuration_from_filename (manager, intended_filename, GDK_CURRENT_TIME, error); /* FMQ: pass a real timestamp */
         if (!result) {
                 error_message (manager, _("The selected configuration for displays could not be applied"), error ? *error : NULL, NULL);
                 restore_backup_configuration_without_messages (backup_filename, intended_filename);
@@ -1572,7 +1569,7 @@ apply_intended_configuration (GsdXrandrManager *manager, const char *intended_fi
         GError *my_error;
 
         my_error = NULL;
-        if (!apply_stored_configuration_and_rotate_tablet (manager, intended_filename, &my_error)) {
+        if (!apply_configuration_from_filename (manager, intended_filename, GDK_CURRENT_TIME, &my_error)) { /* FMQ: pass a timestamp */
                 if (my_error) {
                         if (!g_error_matches (my_error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
                                 error_message (manager, _("Could not apply the stored configuration for monitors"), my_error, NULL);
@@ -1601,7 +1598,7 @@ apply_stored_configuration_at_startup (GsdXrandrManager *manager)
 
         my_error = NULL;
 
-        success = apply_stored_configuration_and_rotate_tablet (manager, backup_filename, &my_error);
+        success = apply_configuration_from_filename (manager, backup_filename, GDK_CURRENT_TIME, &my_error); /* FMQ: pass a timestamp */
         if (success) {
                 /* The backup configuration existed, and could be applied
                  * successfully, so we must restore it on top of the
-- 
1.6.0.2


From 0197bc2cf6b81fe39a858d16e04f02e6e970ca10 Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Wed, 27 May 2009 17:51:09 -0500
Subject: [PATCH 06/29] Pass better timestamps when applying the intended configuration

For the compatibility API we simply use GDK_CURRENT_TIME;
for RANDR changes generated from the tray icon's popup menu,
we use an actual timestamp from GTK+.

Signed-off-by: Federico Mena Quintero <federico@novell.com>
---
 plugins/xrandr/gsd-xrandr-manager.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index 0aafd29..294049d 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -438,7 +438,7 @@ try_to_apply_intended_configuration (GsdXrandrManager *manager, GdkWindow *paren
         backup_filename = gnome_rr_config_get_backup_filename ();
         intended_filename = gnome_rr_config_get_intended_filename ();
 
-        result = apply_configuration_from_filename (manager, intended_filename, GDK_CURRENT_TIME, error); /* FMQ: pass a real timestamp */
+        result = apply_configuration_from_filename (manager, intended_filename, timestamp, error);
         if (!result) {
                 error_message (manager, _("The selected configuration for displays could not be applied"), error ? *error : NULL, NULL);
                 restore_backup_configuration_without_messages (backup_filename, intended_filename);
@@ -464,7 +464,7 @@ static gboolean
 gsd_xrandr_manager_apply_configuration (GsdXrandrManager *manager,
                                         GError          **error)
 {
-        return try_to_apply_intended_configuration (manager, NULL, 0, error);
+        return try_to_apply_intended_configuration (manager, NULL, GDK_CURRENT_TIME, error);
 }
 
 /* DBus method for org.gnome.SettingsDaemon.XRANDR_2 ApplyConfiguration; see gsd-xrandr-manager.xml for the interface definition */
@@ -1341,7 +1341,7 @@ output_rotation_item_activate_cb (GtkCheckMenuItem *item, gpointer data)
                 return;
         }
 
-        try_to_apply_intended_configuration (manager, NULL, 0, NULL); /* NULL-GError */
+        try_to_apply_intended_configuration (manager, NULL, gtk_get_current_event_time (), NULL); /* NULL-GError */
 }
 
 static void
-- 
1.6.0.2


From e9cc3acee20bc5cbc914868aafd8a48c86bbd27d Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Wed, 27 May 2009 18:08:49 -0500
Subject: [PATCH 07/29] Obtain the RANDR timestamps at the higest possible caller, and pass them down the chain of functions

Signed-off-by: Federico Mena Quintero <federico@novell.com>
---
 plugins/xrandr/gsd-xrandr-manager.c |   20 ++++++++++----------
 1 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index 294049d..621d075 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -291,7 +291,7 @@ restore_backup_configuration_without_messages (const char *backup_filename, cons
 }
 
 static void
-restore_backup_configuration (GsdXrandrManager *manager, const char *backup_filename, const char *intended_filename)
+restore_backup_configuration (GsdXrandrManager *manager, const char *backup_filename, const char *intended_filename, guint32 timestamp)
 {
         int saved_errno;
 
@@ -299,7 +299,7 @@ restore_backup_configuration (GsdXrandrManager *manager, const char *backup_file
                 GError *error;
 
                 error = NULL;
-                if (!apply_configuration_from_filename (manager, intended_filename, GDK_CURRENT_TIME, &error)) { /* FMQ: pass a real timestamp */
+                if (!apply_configuration_from_filename (manager, intended_filename, timestamp, &error)) {
                         error_message (manager, _("Could not restore the display's configuration"), error, NULL);
 
                         if (error)
@@ -450,7 +450,7 @@ try_to_apply_intended_configuration (GsdXrandrManager *manager, GdkWindow *paren
         if (user_says_things_are_ok (manager, parent_window))
                 unlink (backup_filename);
         else
-                restore_backup_configuration (manager, backup_filename, intended_filename);
+                restore_backup_configuration (manager, backup_filename, intended_filename, timestamp);
 
 out:
         g_free (backup_filename);
@@ -1564,12 +1564,12 @@ on_config_changed (GConfClient          *client,
 }
 
 static void
-apply_intended_configuration (GsdXrandrManager *manager, const char *intended_filename)
+apply_intended_configuration (GsdXrandrManager *manager, const char *intended_filename, guint32 timestamp)
 {
         GError *my_error;
 
         my_error = NULL;
-        if (!apply_configuration_from_filename (manager, intended_filename, GDK_CURRENT_TIME, &my_error)) { /* FMQ: pass a timestamp */
+        if (!apply_configuration_from_filename (manager, intended_filename, timestamp, &my_error)) {
                 if (my_error) {
                         if (!g_error_matches (my_error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
                                 error_message (manager, _("Could not apply the stored configuration for monitors"), my_error, NULL);
@@ -1580,7 +1580,7 @@ apply_intended_configuration (GsdXrandrManager *manager, const char *intended_fi
 }
 
 static void
-apply_stored_configuration_at_startup (GsdXrandrManager *manager)
+apply_stored_configuration_at_startup (GsdXrandrManager *manager, guint32 timestamp)
 {
         GError *my_error;
         gboolean success;
@@ -1598,13 +1598,13 @@ apply_stored_configuration_at_startup (GsdXrandrManager *manager)
 
         my_error = NULL;
 
-        success = apply_configuration_from_filename (manager, backup_filename, GDK_CURRENT_TIME, &my_error); /* FMQ: pass a timestamp */
+        success = apply_configuration_from_filename (manager, backup_filename, timestamp, &my_error);
         if (success) {
                 /* The backup configuration existed, and could be applied
                  * successfully, so we must restore it on top of the
                  * failed/intended one.
                  */
-                restore_backup_configuration (manager, backup_filename, intended_filename);
+                restore_backup_configuration (manager, backup_filename, intended_filename, timestamp);
                 goto out;
         }
 
@@ -1623,7 +1623,7 @@ apply_stored_configuration_at_startup (GsdXrandrManager *manager)
          * good.  Apply the intended configuration instead.
          */
 
-        apply_intended_configuration (manager, intended_filename);
+        apply_intended_configuration (manager, intended_filename, timestamp);
 
 out:
 
@@ -1694,7 +1694,7 @@ gsd_xrandr_manager_start (GsdXrandrManager *manager,
         }
 
         if (user_configuration_is_newer_than_xorg (manager))
-                apply_stored_configuration_at_startup (manager);
+                apply_stored_configuration_at_startup (manager, GDK_CURRENT_TIME); /* FMQ: pass a real timestamp */
 
         gdk_window_add_filter (gdk_get_default_root_window(),
                                (GdkFilterFunc)event_filter,
-- 
1.6.0.2


From 5f11ab650e44fae5da0e51ee3dae2ed9f6138a6c Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Thu, 28 May 2009 11:21:53 -0500
Subject: [PATCH 08/29] Function to show a utility dialog to show RANDR timestamps

Signed-off-by: Federico Mena Quintero <federico@novell.com>
---
 plugins/xrandr/gsd-xrandr-manager.c |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index 621d075..85b2810 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -243,6 +243,24 @@ handle_tablet_rotation (GsdXrandrManager *manager)
         rotate_tablet (manager, rotation);
 }
 
+static void
+show_timestamps_dialog (GsdXrandrManager *manager, const char *msg)
+{
+        struct GsdXrandrManagerPrivate *priv = manager->priv;
+        GtkWidget *dialog;
+        guint32 change_timestamp, config_timestamp;
+
+        gnome_rr_screen_get_timestamps (priv->rw_screen, &change_timestamp, &config_timestamp);
+
+        dialog = gtk_message_dialog_new (NULL,
+                                         GTK_DIALOG_MODAL,
+                                         GTK_MESSAGE_INFO,
+                                         GTK_BUTTONS_CLOSE,
+                                         "RANDR timestamps: %s\nchange: %u\nconfig: %u", msg, change_timestamp, config_timestamp);
+        gtk_dialog_run (GTK_DIALOG (dialog));
+        gtk_widget_destroy (dialog);
+}
+
 /* Optionally filters out GNOME_RR_ERROR_NO_MATCHING_CONFIG from
  * gnome_rr_config_apply_from_filename_with_time(), since that is not usually an error.
  */
-- 
1.6.0.2


From 63d171a4afb37f75f25d0f3cb856bfcf8897e8ac Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Thu, 28 May 2009 11:23:32 -0500
Subject: [PATCH 09/29] Show timestamps dialog in useful places

Signed-off-by: Federico Mena Quintero <federico@novell.com>
---
 plugins/xrandr/gsd-xrandr-manager.c |    9 ++++-----
 1 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index 85b2810..a52ab60 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -1002,14 +1002,11 @@ static void
 on_randr_event (GnomeRRScreen *screen, gpointer data)
 {
         GsdXrandrManager *manager = GSD_XRANDR_MANAGER (data);
-        GtkWidget *dialog;
 
         if (!manager->priv->running)
                 return;
 
-        dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, "Got RANDR event");
-        gtk_dialog_run (GTK_DIALOG (dialog));
-        gtk_widget_destroy (dialog);
+        show_timestamps_dialog (manager, "Got RANDR event");
 
         /* Scenarios:
          *
@@ -1711,8 +1708,10 @@ gsd_xrandr_manager_start (GsdXrandrManager *manager,
                 gdk_error_trap_pop ();
         }
 
-        if (user_configuration_is_newer_than_xorg (manager))
+        if (user_configuration_is_newer_than_xorg (manager)) {
+                show_timestamps_dialog (manager, "Startup");
                 apply_stored_configuration_at_startup (manager, GDK_CURRENT_TIME); /* FMQ: pass a real timestamp */
+        }
 
         gdk_window_add_filter (gdk_get_default_root_window(),
                                (GdkFilterFunc)event_filter,
-- 
1.6.0.2


From df71105eba95a0318c15747257a06b64039be1d6 Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Thu, 28 May 2009 11:41:45 -0500
Subject: [PATCH 10/29] Fixup wacom rotation to happen from the new centralized error handler

Signed-off-by: Federico Mena Quintero <federico@novell.com>
---
 plugins/xrandr/gsd-xrandr-manager.c |   17 +++--------------
 1 files changed, 3 insertions(+), 14 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index a52ab60..22ccb1f 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -273,8 +273,10 @@ apply_configuration_from_filename (GsdXrandrManager *manager, const char *filena
 
         my_error = NULL;
         success = gnome_rr_config_apply_from_filename_with_time (priv->rw_screen, filename, timestamp, &my_error);
-        if (success)
+        if (success) {
+                handle_tablet_rotation (manager);
                 return TRUE;
+        }
 
         if (g_error_matches (my_error, GNOME_RR_ERROR, GNOME_RR_ERROR_NO_MATCHING_CONFIG)) {
                 /* This is not an error; the user probably changed his monitors
@@ -288,19 +290,6 @@ apply_configuration_from_filename (GsdXrandrManager *manager, const char *filena
         return FALSE;
 }
 
-static gboolean
-apply_stored_configuration_and_rotate_tablet (GsdXrandrManager *manager, const char *filename, GError **error)
-{
-        gboolean success;
-
-        success = apply_configuration_from_filename (manager, filename, error);
-
-        if (success)
-                handle_tablet_rotation (manager);
-
-        return success;
-}
-
 static void
 restore_backup_configuration_without_messages (const char *backup_filename, const char *intended_filename)
 {
-- 
1.6.0.2


From 5b355778c527fa6b253bfe27cd57fbac34f10a8f Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Thu, 28 May 2009 12:16:48 -0500
Subject: [PATCH 11/29] Show timestamps dialog when applying a configuration

Signed-off-by: Federico Mena Quintero <federico@novell.com>
---
 plugins/xrandr/gsd-xrandr-manager.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index 22ccb1f..352aa65 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -270,6 +270,11 @@ apply_configuration_from_filename (GsdXrandrManager *manager, const char *filena
         struct GsdXrandrManagerPrivate *priv = manager->priv;
         GError *my_error;
         gboolean success;
+        char *str;
+
+        str = g_strdup_printf ("Applying %s with timestamp %d", filename, timestamp);
+        show_timestamps_dialog (manager, str);
+        g_free (str);
 
         my_error = NULL;
         success = gnome_rr_config_apply_from_filename_with_time (priv->rw_screen, filename, timestamp, &my_error);
-- 
1.6.0.2


From 8a3a998b3aee3e3dbf0e8323dd6a4298e8d1dcfd Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Thu, 28 May 2009 14:04:07 -0500
Subject: [PATCH 12/29] Disable the timestamps dialog for now

Signed-off-by: Federico Mena Quintero <federico@novell.com>
---
 plugins/xrandr/gsd-xrandr-manager.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index 352aa65..615551c 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -250,6 +250,8 @@ show_timestamps_dialog (GsdXrandrManager *manager, const char *msg)
         GtkWidget *dialog;
         guint32 change_timestamp, config_timestamp;
 
+        return;
+
         gnome_rr_screen_get_timestamps (priv->rw_screen, &change_timestamp, &config_timestamp);
 
         dialog = gtk_message_dialog_new (NULL,
-- 
1.6.0.2


From 8d169787abda43e5f7d03b28ef2b738da6b9b521 Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Sat, 30 May 2009 17:31:33 -0500
Subject: [PATCH 13/29] Oops, type 'x' in d-bus means gint64, not long

The callback signature for the DBus method was wrong, so we always seemed to get
a NULL GError argument --- which was, in fact, garbage from a 64-bit value.

Signed-off-by: Federico Mena Quintero <federico@novell.com>
---
 plugins/xrandr/gsd-xrandr-manager.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index 615551c..a317f22 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -484,15 +484,15 @@ gsd_xrandr_manager_apply_configuration (GsdXrandrManager *manager,
 /* DBus method for org.gnome.SettingsDaemon.XRANDR_2 ApplyConfiguration; see gsd-xrandr-manager.xml for the interface definition */
 static gboolean
 gsd_xrandr_manager_2_apply_configuration (GsdXrandrManager *manager,
-                                          long              parent_window_id,
-                                          long              timestamp,
+                                          gint64            parent_window_id,
+                                          gint64            timestamp,
                                           GError          **error)
 {
         GdkWindow *parent_window;
         gboolean result;
 
         if (parent_window_id != 0)
-                parent_window = gdk_window_foreign_new_for_display (gdk_display_get_default (), parent_window_id);
+                parent_window = gdk_window_foreign_new_for_display (gdk_display_get_default (), (GdkNativeWindow) parent_window_id);
         else
                 parent_window = NULL;
 
-- 
1.6.0.2


From cf0853ff44fc854552c42ba5ccccc398f5fffeda Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Sat, 30 May 2009 20:02:10 -0500
Subject: [PATCH 14/29] GDK_CURRENT_TIME is okay at startup, as we don't have a real timestamp then

Signed-off-by: Federico Mena Quintero <federico@novell.com>
---
 plugins/xrandr/gsd-xrandr-manager.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index a317f22..e0f841d 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -1706,7 +1706,7 @@ gsd_xrandr_manager_start (GsdXrandrManager *manager,
 
         if (user_configuration_is_newer_than_xorg (manager)) {
                 show_timestamps_dialog (manager, "Startup");
-                apply_stored_configuration_at_startup (manager, GDK_CURRENT_TIME); /* FMQ: pass a real timestamp */
+                apply_stored_configuration_at_startup (manager, GDK_CURRENT_TIME); /* we don't have a real timestamp at startup anyway */
         }
 
         gdk_window_add_filter (gdk_get_default_root_window(),
-- 
1.6.0.2


From 4a357946fc2c60aada4b9c70bf3dd76c9943f1e9 Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Sat, 30 May 2009 22:07:38 -0500
Subject: [PATCH 15/29] Make the timestamps dialog non-modal so we can review several of them

---
 plugins/xrandr/gsd-xrandr-manager.c |    9 ++++-----
 1 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index e0f841d..29727ac 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -250,17 +250,16 @@ show_timestamps_dialog (GsdXrandrManager *manager, const char *msg)
         GtkWidget *dialog;
         guint32 change_timestamp, config_timestamp;
 
-        return;
-
         gnome_rr_screen_get_timestamps (priv->rw_screen, &change_timestamp, &config_timestamp);
 
         dialog = gtk_message_dialog_new (NULL,
-                                         GTK_DIALOG_MODAL,
+                                         0,
                                          GTK_MESSAGE_INFO,
                                          GTK_BUTTONS_CLOSE,
                                          "RANDR timestamps: %s\nchange: %u\nconfig: %u", msg, change_timestamp, config_timestamp);
-        gtk_dialog_run (GTK_DIALOG (dialog));
-        gtk_widget_destroy (dialog);
+        g_signal_connect (dialog, "response",
+                          G_CALLBACK (gtk_widget_destroy), NULL);
+        gtk_widget_show (dialog);
 }
 
 /* Optionally filters out GNOME_RR_ERROR_NO_MATCHING_CONFIG from
-- 
1.6.0.2


From 2fec0c53e5411cb3521e38d951340057a83e945d Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Sat, 30 May 2009 22:08:36 -0500
Subject: [PATCH 16/29] Start processing RANDR events

We ignore events that indicate an explicit configuration request;
in those, the screen is already configured and we need to do
nothing.
---
 plugins/xrandr/gsd-xrandr-manager.c |   25 ++++++++++++++++++++++---
 1 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index 29727ac..eaf4a71 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -997,12 +997,12 @@ static void
 on_randr_event (GnomeRRScreen *screen, gpointer data)
 {
         GsdXrandrManager *manager = GSD_XRANDR_MANAGER (data);
+        GsdXrandrManagerPrivate *priv = manager->priv;
+        guint32 change_timestamp, config_timestamp;
 
-        if (!manager->priv->running)
+        if (!priv->running)
                 return;
 
-        show_timestamps_dialog (manager, "Got RANDR event");
-
         /* Scenarios:
          *
          * 1. Monitor gets plugged.
@@ -1037,6 +1037,25 @@ on_randr_event (GnomeRRScreen *screen, gpointer data)
          */
 
         /* FIXME: Set up any new screens here */
+        gnome_rr_screen_get_timestamps (screen, &change_timestamp, &config_timestamp);
+
+        if (change_timestamp > config_timestamp) {
+                /* The event is due to an explicit configuration change.
+                 *
+                 * If the change was performed by us, then we need to do nothing.
+                 *
+                 * 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");
+        } else {
+                /* Here, config_timestamp >= change_timestamp.  This means that
+                 * the screen got reconfigured because of hotplug/unplug; the X
+                 * server is just notifying us, and we need to configure the
+                 * outputs in a sane way.
+                 */
+                show_timestamps_dialog (manager, "need to deal with reconfiguration, as config >= change");
+        }
 }
 
 static void
-- 
1.6.0.2


From 8df325dd165dfc3ee75ec8e94180b1236297485d Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Sat, 30 May 2009 22:14:29 -0500
Subject: [PATCH 17/29] Print a serial number in the timestamps dialog

---
 plugins/xrandr/gsd-xrandr-manager.c |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index eaf4a71..1b86a93 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -249,6 +249,7 @@ show_timestamps_dialog (GsdXrandrManager *manager, const char *msg)
         struct GsdXrandrManagerPrivate *priv = manager->priv;
         GtkWidget *dialog;
         guint32 change_timestamp, config_timestamp;
+        static int serial;
 
         gnome_rr_screen_get_timestamps (priv->rw_screen, &change_timestamp, &config_timestamp);
 
@@ -256,7 +257,11 @@ show_timestamps_dialog (GsdXrandrManager *manager, const char *msg)
                                          0,
                                          GTK_MESSAGE_INFO,
                                          GTK_BUTTONS_CLOSE,
-                                         "RANDR timestamps: %s\nchange: %u\nconfig: %u", msg, change_timestamp, config_timestamp);
+                                         "RANDR timestamps (%d):\n%s\nchange: %u\nconfig: %u",
+                                         serial++,
+                                         msg,
+                                         change_timestamp,
+                                         config_timestamp);
         g_signal_connect (dialog, "response",
                           G_CALLBACK (gtk_widget_destroy), NULL);
         gtk_widget_show (dialog);
-- 
1.6.0.2


From ef4d8cbe9781e9bb382e2a2e143bfba52cfdde54 Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Sat, 30 May 2009 22:41:39 -0500
Subject: [PATCH 18/29] Refresh the tray icon menu if it is active during RANDR events

This way the menu will automagically refresh itself even it the monitors are frobbed
while the menu is active.

Signed-off-by: Federico Mena Quintero <federico@novell.com>
---
 plugins/xrandr/gsd-xrandr-manager.c |   15 +++++++++++++++
 1 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index 1b86a93..124da89 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -112,6 +112,8 @@ static void     gsd_xrandr_manager_finalize    (GObject             *object);
 
 static void error_message (GsdXrandrManager *mgr, const char *primary_text, GError *error_to_display, const char *secondary_text);
 
+static void status_icon_popup_menu (GsdXrandrManager *manager, guint button, guint32 timestamp);
+
 G_DEFINE_TYPE (GsdXrandrManager, gsd_xrandr_manager, G_TYPE_OBJECT)
 
 static gpointer manager_object = NULL;
@@ -999,6 +1001,17 @@ event_filter (GdkXEvent           *xevent,
 }
 
 static void
+refresh_tray_icon_menu_if_active (GsdXrandrManager *manager, guint32 timestamp)
+{
+        GsdXrandrManagerPrivate *priv = manager->priv;
+
+        if (priv->popup_menu) {
+                gtk_menu_shell_cancel (GTK_MENU_SHELL (priv->popup_menu)); /* status_icon_popup_menu_selection_done_cb() will free everything */
+                status_icon_popup_menu (manager, 0, timestamp);
+        }
+}
+
+static void
 on_randr_event (GnomeRRScreen *screen, gpointer data)
 {
         GsdXrandrManager *manager = GSD_XRANDR_MANAGER (data);
@@ -1061,6 +1074,8 @@ on_randr_event (GnomeRRScreen *screen, gpointer data)
                  */
                 show_timestamps_dialog (manager, "need to deal with reconfiguration, as config >= change");
         }
+
+        refresh_tray_icon_menu_if_active (manager, MAX (change_timestamp, config_timestamp));
 }
 
 static void
-- 
1.6.0.2


From 8da119f8dc0d1eb072f9dfa01ab01e8ede83e72c Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Sat, 30 May 2009 23:05:57 -0500
Subject: [PATCH 19/29] Optionally do not ignore GNOME_RR_ERROR_NO_MATCHING_CONFIG

Normally this is not an error; it means that there was no stored configuration that
matched the current set of outputs.  In that case, we ignore the error and return
'success'.

However, in the case where we are reconfiguring the outputs due to a RANDR hotplug event,
we *do* need to know if there was no matching configuration, so that we can fall back
to doing what 'xrandr --auto' does.

Signed-off-by: Federico Mena Quintero <federico@novell.com>
---
 plugins/xrandr/gsd-xrandr-manager.c |   18 +++++++++++++-----
 1 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index 124da89..3814cd2 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -273,7 +273,11 @@ show_timestamps_dialog (GsdXrandrManager *manager, const char *msg)
  * gnome_rr_config_apply_from_filename_with_time(), since that is not usually an error.
  */
 static gboolean
-apply_configuration_from_filename (GsdXrandrManager *manager, const char *filename, guint32 timestamp, GError **error)
+apply_configuration_from_filename (GsdXrandrManager *manager,
+                                   const char       *filename,
+                                   gboolean          no_matching_config_is_an_error,
+                                   guint32           timestamp,
+                                   GError          **error)
 {
         struct GsdXrandrManagerPrivate *priv = manager->priv;
         GError *my_error;
@@ -292,6 +296,9 @@ apply_configuration_from_filename (GsdXrandrManager *manager, const char *filena
         }
 
         if (g_error_matches (my_error, GNOME_RR_ERROR, GNOME_RR_ERROR_NO_MATCHING_CONFIG)) {
+                if (no_matching_config_is_an_error)
+                        goto fail;
+
                 /* This is not an error; the user probably changed his monitors
                  * and so they don't match any of the stored configurations.
                  */
@@ -299,6 +306,7 @@ apply_configuration_from_filename (GsdXrandrManager *manager, const char *filena
                 return TRUE;
         }
 
+fail:
         g_propagate_error (error, my_error);
         return FALSE;
 }
@@ -319,7 +327,7 @@ restore_backup_configuration (GsdXrandrManager *manager, const char *backup_file
                 GError *error;
 
                 error = NULL;
-                if (!apply_configuration_from_filename (manager, intended_filename, timestamp, &error)) {
+                if (!apply_configuration_from_filename (manager, intended_filename, FALSE, timestamp, &error)) {
                         error_message (manager, _("Could not restore the display's configuration"), error, NULL);
 
                         if (error)
@@ -458,7 +466,7 @@ try_to_apply_intended_configuration (GsdXrandrManager *manager, GdkWindow *paren
         backup_filename = gnome_rr_config_get_backup_filename ();
         intended_filename = gnome_rr_config_get_intended_filename ();
 
-        result = apply_configuration_from_filename (manager, intended_filename, timestamp, error);
+        result = apply_configuration_from_filename (manager, intended_filename, FALSE, timestamp, error);
         if (!result) {
                 error_message (manager, _("The selected configuration for displays could not be applied"), error ? *error : NULL, NULL);
                 restore_backup_configuration_without_messages (backup_filename, intended_filename);
@@ -1618,7 +1626,7 @@ apply_intended_configuration (GsdXrandrManager *manager, const char *intended_fi
         GError *my_error;
 
         my_error = NULL;
-        if (!apply_configuration_from_filename (manager, intended_filename, timestamp, &my_error)) {
+        if (!apply_configuration_from_filename (manager, intended_filename, FALSE, timestamp, &my_error)) {
                 if (my_error) {
                         if (!g_error_matches (my_error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
                                 error_message (manager, _("Could not apply the stored configuration for monitors"), my_error, NULL);
@@ -1647,7 +1655,7 @@ apply_stored_configuration_at_startup (GsdXrandrManager *manager, guint32 timest
 
         my_error = NULL;
 
-        success = apply_configuration_from_filename (manager, backup_filename, timestamp, &my_error);
+        success = apply_configuration_from_filename (manager, backup_filename, FALSE, timestamp, &my_error);
         if (success) {
                 /* The backup configuration existed, and could be applied
                  * successfully, so we must restore it on top of the
-- 
1.6.0.2


From 527d34b0c90a156537d29c63c34ffbdd4887e051 Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Sat, 30 May 2009 23:11:38 -0500
Subject: [PATCH 20/29] Configure outputs in the case of hotplug

First we try to apply one of the saved configurations, to go back to a 'known good'
state.

If that doesn't work, we autoconfigure the outputs like 'xrandr --auto' does.  For now,
this is just a stub function.

Signed-off-by: Federico Mena Quintero <federico@novell.com>
---
 plugins/xrandr/gsd-xrandr-manager.c |   38 +++++++++++++++++++++++++++++++++++
 1 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index 3814cd2..c964ef5 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -1020,6 +1020,12 @@ refresh_tray_icon_menu_if_active (GsdXrandrManager *manager, guint32 timestamp)
 }
 
 static void
+auto_configure_outputs (GsdXrandrManager *manager, guint32 timestamp)
+{
+        /* FMQ: implement */
+}
+
+static void
 on_randr_event (GnomeRRScreen *screen, gpointer data)
 {
         GsdXrandrManager *manager = GSD_XRANDR_MANAGER (data);
@@ -1075,12 +1081,44 @@ on_randr_event (GnomeRRScreen *screen, gpointer data)
                  */
                 show_timestamps_dialog (manager, "ignoring since change > config");
         } else {
+                char *intended_filename;
+                GError *error;
+                gboolean success;
+
                 /* Here, config_timestamp >= change_timestamp.  This means that
                  * the screen got reconfigured because of hotplug/unplug; the X
                  * server is just notifying us, and we need to configure the
                  * outputs in a sane way.
                  */
                 show_timestamps_dialog (manager, "need to deal with reconfiguration, as config >= change");
+
+                intended_filename = gnome_rr_config_get_intended_filename ();
+
+                error = NULL;
+                success = apply_configuration_from_filename (manager, intended_filename, TRUE, config_timestamp, &error);
+                g_free (intended_filename);
+
+                if (!success) {
+                        /* We don't bother checking the error type.
+                         *
+                         * Both G_FILE_ERROR_NOENT and
+                         * GNOME_RR_ERROR_NO_MATCHING_CONFIG would mean, "there
+                         * was no configuration to apply, or none that matched
+                         * the current outputs", and in that case we need to run
+                         * our fallback.
+                         *
+                         * Any other error means "we couldn't do the smart thing
+                         * of using a previously- saved configuration, anyway,
+                         * for some other reason.  In that case, we also need to
+                         * run our fallback to avoid leaving the user with a
+                         * bogus configuration.
+                         */
+
+                        if (error)
+                                g_error_free (error);
+
+                        auto_configure_outputs (manager, config_timestamp);
+                }
         }
 
         refresh_tray_icon_menu_if_active (manager, MAX (change_timestamp, config_timestamp));
-- 
1.6.0.2


From cef40c546a52771d48d72a2d84cfeb538273abd9 Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Sat, 30 May 2009 23:36:37 -0500
Subject: [PATCH 21/29] Disable smart configuration on hotplug, and leave just autoconfiguration

We don't want smart configuration to happen when the user hits the 'Detect displays' button
in gnome-display-properties --- the resulting XRRGetScreenResources() will cause the X server
to re-probe the outputs, and we'll get a RANDR event, which makes us reconfigure the outputs.

It is weird to get the outputs reconfigured (resolutions changed, etc.) when you just hit a
'Detect displays' button.  So for now, we'll just do what 'xrandr --auto' does, and leave
the more sophisticated version for later.

Signed-off-by: Federico Mena Quintero <federico@novell.com>
---
 plugins/xrandr/gsd-xrandr-manager.c |   30 ++++++++++++++++++++++++++----
 1 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index c964ef5..39a22a6 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -1081,15 +1081,36 @@ on_randr_event (GnomeRRScreen *screen, gpointer data)
                  */
                 show_timestamps_dialog (manager, "ignoring since change > config");
         } else {
-                char *intended_filename;
-                GError *error;
-                gboolean success;
-
                 /* Here, config_timestamp >= change_timestamp.  This means that
                  * the screen got reconfigured because of hotplug/unplug; the X
                  * server is just notifying us, and we need to configure the
                  * outputs in a sane way.
                  */
+#if 1
+                auto_configure_outputs (manager, config_timestamp);
+#else
+                /* The initial strategy of "on hotplug or unsuspend, restore a
+                 * known-good configuration, and fall back to autoconfiguration"
+                 * works fine as long as you don't happen to be running
+                 * gnome-display-properties and click its "Detect displays"
+                 * button.
+                 *
+                 * If you do that, the RANDR calls from g-d-p will cause the X
+                 * server to re-probe the RANDR outputs.  The server will send
+                 * us an event, we'll restore the configuration to something
+                 * else... and you'll be weirded out, because "just detecting
+                 * your monitors" should not change the current configuration,
+                 * right?
+                 *
+                 * We may need some kind of D-bus API so that g-d-p can inhibit
+                 * this RANDR plugin's reconfiguration-fu when the "Detect
+                 * displays" button is being used.
+                 */
+
+                char *intended_filename;
+                GError *error;
+                gboolean success;
+
                 show_timestamps_dialog (manager, "need to deal with reconfiguration, as config >= change");
 
                 intended_filename = gnome_rr_config_get_intended_filename ();
@@ -1119,6 +1140,7 @@ on_randr_event (GnomeRRScreen *screen, gpointer data)
 
                         auto_configure_outputs (manager, config_timestamp);
                 }
+#endif
         }
 
         refresh_tray_icon_menu_if_active (manager, MAX (change_timestamp, config_timestamp));
-- 
1.6.0.2


From 69da8e3a0c87bc22b14999f7acc3fcf2b15f34c3 Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Sat, 30 May 2009 23:44:35 -0500
Subject: [PATCH 22/29] Be lazy and just call xrandr --auto

Signed-off-by: Federico Mena Quintero <federico@novell.com>
---
 plugins/xrandr/gsd-xrandr-manager.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index 39a22a6..0c7ca57 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -1022,7 +1022,7 @@ refresh_tray_icon_menu_if_active (GsdXrandrManager *manager, guint32 timestamp)
 static void
 auto_configure_outputs (GsdXrandrManager *manager, guint32 timestamp)
 {
-        /* FMQ: implement */
+        g_spawn_command_line_sync ("xrandr --auto", NULL, NULL, NULL, NULL); /* FIXME: this is lazy */
 }
 
 static void
-- 
1.6.0.2


From 785cf4962f4e54da11c6833aeeb5ce9c37ea5eb8 Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Sun, 31 May 2009 13:56:37 -0500
Subject: [PATCH 23/29] Implement autoconfiguration of the outputs

This is similar in spirit to 'xrandr --auto', but we disfavor selecting clone modes.
Instead, we lay out the outputs left-to-right.

Signed-off-by: Federico Mena Quintero <federico@novell.com>
---
 plugins/xrandr/gsd-xrandr-manager.c |   96 ++++++++++++++++++++++++++++++++++-
 1 files changed, 95 insertions(+), 1 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index 0c7ca57..d8fc653 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -1022,7 +1022,101 @@ refresh_tray_icon_menu_if_active (GsdXrandrManager *manager, guint32 timestamp)
 static void
 auto_configure_outputs (GsdXrandrManager *manager, guint32 timestamp)
 {
-        g_spawn_command_line_sync ("xrandr --auto", NULL, NULL, NULL, NULL); /* FIXME: this is lazy */
+        GsdXrandrManagerPrivate *priv = manager->priv;
+        GnomeRRConfig *config;
+        int i;
+        GList *just_turned_on;
+        GList *l;
+        int x;
+        GError *error;
+
+        config = gnome_rr_config_new_current (priv->rw_screen);
+
+        /* For outputs that are connected and on (i.e. they have a CRTC assigned
+         * to them, so they are getting a signal), we leave them as they are
+         * with their current modes.
+         *
+         * For other outputs, we will turn on connected-but-off outputs and turn
+         * off disconnected-but-on outputs.
+         *
+         * FIXME: If an output remained connected+on, it would be nice to ensure
+         * that the output's CRTCs still has a reasonable mode (think of
+         * changing one monitor for another with different capabilities).
+         */
+
+        just_turned_on = NULL;
+
+        for (i = 0; config->outputs[i] != NULL; i++) {
+                GnomeOutputInfo *output = config->outputs[i];
+
+                if (output->connected && !output->on) {
+                        output->on = TRUE;
+                        output->rotation = GNOME_RR_ROTATION_0;
+                        just_turned_on = g_list_prepend (just_turned_on, GINT_TO_POINTER (i));
+                } else if (!output->connected && output->on)
+                        output->on = FALSE;
+        }
+
+        /* Now, lay out the outputs from left to right.  Put first the outputs
+         * which remained on; put last the outputs that were newly turned on.
+         */
+
+        x = 0;
+
+        /* First, outputs that remained on */
+
+        for (i = 0; config->outputs[i] != NULL; i++) {
+                GnomeOutputInfo *output = config->outputs[i];
+
+                if (g_list_find (just_turned_on, GINT_TO_POINTER (i)))
+                        continue;
+
+                if (output->on) {
+                        g_assert (output->connected);
+
+                        output->x = x;
+                        output->y = 0;
+
+                        x += output->width;
+                }
+        }
+
+        /* Second, outputs that were newly-turned on */
+
+        for (l = just_turned_on; l; l = l->next) {
+                GnomeOutputInfo *output;
+
+                i = GPOINTER_TO_INT (l->data);
+                output = config->outputs[i];
+
+                g_assert (output->on && output->connected);
+
+                output->x = x;
+                output->y = 0;
+
+                /* since the output was off, use its preferred width/height (it doesn't have a real width/height yet) */
+                output->width = output->pref_width;
+                output->height = output->pref_height;
+
+                x += output->width;
+        }
+
+        /* Apply the configuration! */
+
+        error = NULL;
+        if (!gnome_rr_config_apply_with_time (config, priv->rw_screen, timestamp, &error)) {
+                error_message (manager, _("Could not switch the monitor configuration"), error, NULL);
+                g_error_free (error);
+        }
+
+        g_list_free (just_turned_on);
+        gnome_rr_config_free (config);
+
+        /* Finally, even though we did a best-effort job in sanitizing the
+         * outputs, we don't know the physical layout of the monitors.  We'll
+         * start the display capplet so that the user can tweak things to his
+         * liking.
+         */
 }
 
 static void
-- 
1.6.0.2


From 6a96854099aa9b40401cbc9313610018d1620b86 Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Sun, 31 May 2009 14:09:18 -0500
Subject: [PATCH 24/29] Run the display capplet when autoconfiguration is done

Although we do a best-effort of automatically configuring new outputs on hotplug,
we don't actually know the physical layout of the monitors.  So we start the
display capplet to let the user tweak that.

Signed-off-by: Federico Mena Quintero <federico@novell.com>
---
 plugins/xrandr/gsd-xrandr-manager.c |   16 ++++++++++++++--
 1 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index d8fc653..bbb6770 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -113,6 +113,7 @@ static void     gsd_xrandr_manager_finalize    (GObject             *object);
 static void error_message (GsdXrandrManager *mgr, const char *primary_text, GError *error_to_display, const char *secondary_text);
 
 static void status_icon_popup_menu (GsdXrandrManager *manager, guint button, guint32 timestamp);
+static void run_display_capplet (GtkWidget *widget);
 
 G_DEFINE_TYPE (GsdXrandrManager, gsd_xrandr_manager, G_TYPE_OBJECT)
 
@@ -1117,6 +1118,8 @@ auto_configure_outputs (GsdXrandrManager *manager, guint32 timestamp)
          * start the display capplet so that the user can tweak things to his
          * liking.
          */
+
+        run_display_capplet (NULL);
 }
 
 static void
@@ -1241,12 +1244,15 @@ on_randr_event (GnomeRRScreen *screen, gpointer data)
 }
 
 static void
-popup_menu_configure_display_cb (GtkMenuItem *item, gpointer data)
+run_display_capplet (GtkWidget *widget)
 {
         GdkScreen *screen;
         GError *error;
 
-        screen = gtk_widget_get_screen (GTK_WIDGET (item));
+        if (widget)
+                screen = gtk_widget_get_screen (widget);
+        else
+                screen = gdk_screen_get_default ();
 
         error = NULL;
         if (!gdk_spawn_command_line_on_screen (screen, GSD_XRANDR_DISPLAY_CAPPLET, &error)) {
@@ -1265,6 +1271,12 @@ popup_menu_configure_display_cb (GtkMenuItem *item, gpointer data)
 }
 
 static void
+popup_menu_configure_display_cb (GtkMenuItem *item, gpointer data)
+{
+        run_display_capplet (GTK_WIDGET (item));
+}
+
+static void
 status_icon_popup_menu_selection_done_cb (GtkMenuShell *menu_shell, gpointer data)
 {
         GsdXrandrManager *manager = GSD_XRANDR_MANAGER (data);
-- 
1.6.0.2


From 13a52ded2f02f1636804acca732146100cc89cea Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Sun, 31 May 2009 14:25:51 -0500
Subject: [PATCH 25/29] Disable the timestamps dialog

Signed-off-by: Federico Mena Quintero <federico@novell.com>
---
 plugins/xrandr/gsd-xrandr-manager.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index bbb6770..2163fe2 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -249,6 +249,9 @@ handle_tablet_rotation (GsdXrandrManager *manager)
 static void
 show_timestamps_dialog (GsdXrandrManager *manager, const char *msg)
 {
+#if 1
+        return;
+#else
         struct GsdXrandrManagerPrivate *priv = manager->priv;
         GtkWidget *dialog;
         guint32 change_timestamp, config_timestamp;
@@ -268,6 +271,7 @@ show_timestamps_dialog (GsdXrandrManager *manager, const char *msg)
         g_signal_connect (dialog, "response",
                           G_CALLBACK (gtk_widget_destroy), NULL);
         gtk_widget_show (dialog);
+#endif
 }
 
 /* Optionally filters out GNOME_RR_ERROR_NO_MATCHING_CONFIG from
-- 
1.6.0.2


From 0ebcbd6931f6a76df7a6527d44ea2c7bfc0883fe Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Sun, 31 May 2009 15:11:57 -0500
Subject: [PATCH 26/29] Remove obsolete comments

Signed-off-by: Federico Mena Quintero <federico@novell.com>
---
 plugins/xrandr/gsd-xrandr-manager.c |   38 ++--------------------------------
 1 files changed, 3 insertions(+), 35 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index 2163fe2..291271c 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -1136,40 +1136,6 @@ on_randr_event (GnomeRRScreen *screen, gpointer data)
         if (!priv->running)
                 return;
 
-        /* Scenarios:
-         *
-         * 1. Monitor gets plugged.
-         *
-         *    - Can we detect if it is a projector?  We want "mirror" in that case.  If it's a monitor,
-         *      we probably want "extend desktop" like MacOS does by default.
-         *
-         * 2. Monitor gets unplugged.
-         *
-         *    - We don't get notification.  User presses XF86Display hotkey - we should come back with
-         *      a visible monitor.  Does this actually happen?
-         *
-         * 3. Machine gets unsuspended.
-         *
-         * Requirements:
-         *
-         * - Always have a visible monitor.
-         *
-         * - Have an easy way to turn on/off monitors.
-         *
-         * - Minimal reconfiguration; maximal DTRT when one plugs/unplugs.
-         */
-
-        /* See if the current configuration matches any saved one; if so, use the
-         * saved one.
-         *
-         * Otherwise, do what "xrandr --auto" does - basically, turn on connected outputs
-         * and turn off disconnected ones.
-         *
-         * Or get a diff between the old/new configurations, and do the
-         * interactive "you plugged a monitor; what do I do?" dance.
-         */
-
-        /* FIXME: Set up any new screens here */
         gnome_rr_screen_get_timestamps (screen, &change_timestamp, &config_timestamp);
 
         if (change_timestamp > config_timestamp) {
@@ -1190,7 +1156,9 @@ on_randr_event (GnomeRRScreen *screen, gpointer data)
 #if 1
                 auto_configure_outputs (manager, config_timestamp);
 #else
-                /* The initial strategy of "on hotplug or unsuspend, restore a
+                /* WHY THIS CODE IS DISABLED:
+                 *
+                 * The strategy of "on hotplug or unsuspend, restore a
                  * known-good configuration, and fall back to autoconfiguration"
                  * works fine as long as you don't happen to be running
                  * gnome-display-properties and click its "Detect displays"
-- 
1.6.0.2


From e6c9f08adbe92563825fd6ab8b9245404da40ddb Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Sun, 31 May 2009 15:24:31 -0500
Subject: [PATCH 27/29] Ignore RANDR events that have the same timestamp

Due to the various RANDR calls that cause events to be generated, we may get
events that have the same timestamps.  However, we don't want to reconfigure
the outputs on every single event; just when we know that something may
really be different.

Signed-off-by: Federico Mena Quintero <federico@novell.com>
---
 plugins/xrandr/gsd-xrandr-manager.c |   14 +++++++++++---
 1 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index 291271c..f4876cb 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -104,6 +104,9 @@ struct GsdXrandrManagerPrivate
         /* fn-F7 status */
         int             current_fn_f7_config;             /* -1 if no configs */
         GnomeRRConfig **fn_f7_configs;  /* NULL terminated, NULL if there are no configs */
+
+        /* Last time at which we got a "screen got reconfigured" event; see on_randr_event() */
+        guint32 last_config_timestamp;
 };
 
 static void     gsd_xrandr_manager_class_init  (GsdXrandrManagerClass *klass);
@@ -1138,7 +1141,7 @@ on_randr_event (GnomeRRScreen *screen, gpointer data)
 
         gnome_rr_screen_get_timestamps (screen, &change_timestamp, &config_timestamp);
 
-        if (change_timestamp > config_timestamp) {
+        if (change_timestamp >= config_timestamp) {
                 /* The event is due to an explicit configuration change.
                  *
                  * If the change was performed by us, then we need to do nothing.
@@ -1148,13 +1151,18 @@ on_randr_event (GnomeRRScreen *screen, gpointer data)
                  */
                 show_timestamps_dialog (manager, "ignoring since change > config");
         } else {
-                /* Here, config_timestamp >= change_timestamp.  This means that
+                /* Here, config_timestamp > change_timestamp.  This means that
                  * the screen got reconfigured because of hotplug/unplug; the X
                  * server is just notifying us, and we need to configure the
                  * outputs in a sane way.
                  */
+
+
 #if 1
-                auto_configure_outputs (manager, config_timestamp);
+                if (config_timestamp != priv->last_config_timestamp) {
+                        priv->last_config_timestamp = config_timestamp;
+                        auto_configure_outputs (manager, config_timestamp);
+                }
 #else
                 /* WHY THIS CODE IS DISABLED:
                  *
-- 
1.6.0.2


From ddfd48f08f327a525759754de9eff5619c33b97d Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Sun, 31 May 2009 19:02:33 -0500
Subject: [PATCH 28/29] Disable launching the display capplet at the end of the auto-configuration process

The display capplet is not a single-instance app.  We have no way to detect if the capplet
is already running; if the user plugs an extra monitor and hits 'Detect displays', then
we should not bring up another instance of the display capplet when we get the RANDR event.

Signed-off-by: Federico Mena Quintero <federico@novell.com>
---
 plugins/xrandr/gsd-xrandr-manager.c |   15 +++++++++++++++
 1 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index f4876cb..15adc97 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -1126,7 +1126,22 @@ auto_configure_outputs (GsdXrandrManager *manager, guint32 timestamp)
          * liking.
          */
 
+#if 0
+        /* FIXME: This is disabled for now.  The capplet is not a single-instance application.
+         * If you do this:
+         *
+         *   1. Start the display capplet
+         *
+         *   2. Plug an extra monitor
+         *
+         *   3. Hit the "Detect displays" button
+         *
+         * Then we will get a RANDR event because X re-probes the outputs.  We don't want to
+         * start up a second display capplet right there!
+         */
+
         run_display_capplet (NULL);
+#endif
 }
 
 static void
-- 
1.6.0.2


From 01bd22460661557bda95c09a0130387c1191a3a4 Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Mon, 8 Jun 2009 17:59:14 -0500
Subject: [PATCH 29/29] For the XF86Display hotkey, use Clone mode before extended-desktop mode

Signed-off-by: Federico Mena Quintero <federico@novell.com>
---
 plugins/xrandr/gsd-xrandr-manager.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index 15adc97..f7b82e3 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -872,8 +872,8 @@ generate_fn_f7_configs (GsdXrandrManager *mgr)
         }
 
         g_ptr_array_add (array, gnome_rr_config_new_current (screen));
-        g_ptr_array_add (array, make_xinerama_setup (screen));
         g_ptr_array_add (array, make_clone_setup (screen));
+        g_ptr_array_add (array, make_xinerama_setup (screen));
         g_ptr_array_add (array, make_laptop_setup (screen));
         g_ptr_array_add (array, make_other_setup (screen));
         g_ptr_array_add (array, gnome_rr_config_new_stored (screen, NULL)); /* NULL-GError - if this can't read the stored config, no big deal */
-- 
1.6.0.2

openSUSE Build Service is sponsored by