File gnome-settings-daemon-bnc486093-centralize-no-matching-config.diff of Package gnome-settings-daemon

diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index ec88e13..e3c16b6 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -237,13 +237,39 @@ 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.
+ */
 static gboolean
-apply_stored_configuration_and_rotate_tablet (GsdXrandrManager *manager, const char *filename, GError **error)
+apply_configuration_from_filename (GsdXrandrManager *manager, const char *filename, GError **error)
 {
         struct GsdXrandrManagerPrivate *priv = manager->priv;
+        GError *my_error;
         gboolean success;
 
-        success = gnome_rr_config_apply_from_filename (priv->rw_screen, filename, error);
+        my_error = NULL;
+        success = gnome_rr_config_apply_from_filename (priv->rw_screen, filename, &my_error);
+        if (success)
+                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
+                 * and so they don't match any of the stored configurations.
+                 */
+                g_error_free (my_error);
+                return TRUE;
+        }
+
+        g_propagate_error (error, my_error);
+        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);
@@ -262,7 +288,6 @@ static void
 restore_backup_configuration (GsdXrandrManager *manager, const char *backup_filename, const char *intended_filename)
 {
         int saved_errno;
-        char *msg;
 
         if (rename (backup_filename, intended_filename) == 0) {
                 GError *error;
@@ -280,14 +305,25 @@ restore_backup_configuration (GsdXrandrManager *manager, const char *backup_file
 
         saved_errno = errno;
 
-        msg = g_strdup_printf ("Could not rename %s to %s: %s",
-                               backup_filename, intended_filename,
-                               g_strerror (saved_errno));
-        error_message (manager,
-                       _("Could not restore the display's configuration from a backup"),
-                       NULL,
-                       msg);
-        g_free (msg);
+        /* ENOENT means the original file didn't exist.  That is *not* an error;
+         * the backup was not created because there wasn't even an original
+         * monitors.xml (such as on a first-time login).  Note that *here* there
+         * is a "didn't work" monitors.xml, so we must delete that one.
+         */
+        if (saved_errno == ENOENT)
+                unlink (intended_filename);
+        else {
+                char *msg;
+
+                msg = g_strdup_printf ("Could not rename %s to %s: %s",
+                                       backup_filename, intended_filename,
+                                       g_strerror (saved_errno));
+                error_message (manager,
+                               _("Could not restore the display's configuration from a backup"),
+                               NULL,
+                               msg);
+                g_free (msg);
+        }
 
         unlink (backup_filename);
 }
@@ -1211,6 +1247,31 @@ add_unsupported_rotation_item (GsdXrandrManager *manager)
 }
 
 static void
+ensure_current_configuration_is_saved (void)
+{
+        GnomeRRScreen *rr_screen;
+        GnomeRRConfig *rr_config;
+
+        /* Normally, gnome_rr_config_save() creates a backup file based on the
+         * old monitors.xml.  However, if *that* file didn't exist, there is
+         * nothing from which to create a backup.  So, here we'll save the
+         * current/unchanged configuration and then let our caller call
+         * gnome_rr_config_save() again with the new/changed configuration, so
+         * that there *will* be a backup file in the end.
+         */
+
+        rr_screen = gnome_rr_screen_new (gdk_screen_get_default (), NULL, NULL, NULL); /* NULL-GError */
+        if (!rr_screen)
+                return;
+
+        rr_config = gnome_rr_config_new_current (rr_screen);
+        gnome_rr_config_save (rr_config, NULL); /* NULL-GError */
+
+        gnome_rr_config_free (rr_config);
+        gnome_rr_screen_destroy (rr_screen);
+}
+
+static void
 output_rotation_item_activate_cb (GtkCheckMenuItem *item, gpointer data)
 {
         GsdXrandrManager *manager = GSD_XRANDR_MANAGER (data);
@@ -1223,6 +1284,8 @@ output_rotation_item_activate_cb (GtkCheckMenuItem *item, gpointer data)
 	if (!gtk_check_menu_item_get_active (item))
 		return;
 
+        ensure_current_configuration_is_saved ();
+
         output = g_object_get_data (G_OBJECT (item), "output");
         rotation = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (item), "rotation"));
 
@@ -1467,12 +1530,7 @@ apply_intended_configuration (GsdXrandrManager *manager, const char *intended_fi
         my_error = NULL;
         if (!apply_stored_configuration_and_rotate_tablet (manager, intended_filename, &my_error)) {
                 if (my_error) {
-                        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 and then logged in
-                                 * again, thus restarting gnome-settings-daemon.
-                                 */
-                        } else if (!g_error_matches (my_error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
+                        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);
 
                         g_error_free (my_error);
openSUSE Build Service is sponsored by