Index: gdm-2.24.0/daemon/gdm-session-settings.c
===================================================================
--- gdm-2.24.0.orig/daemon/gdm-session-settings.c
+++ gdm-2.24.0/daemon/gdm-session-settings.c
@@ -22,6 +22,8 @@
 #include "config.h"
 #include "gdm-session-settings.h"
 
+#include "gdm-sysconfig.h"
+
 #include <errno.h>
 #include <pwd.h>
 #include <string.h>
@@ -358,6 +360,122 @@ out:
         return is_loaded;
 }
 
+/* Copied from patched gdm-session-direct.c */
+static char *
+_get_layout_name_from_sax_map (const char *layout)
+{
+        char  *map_file;
+        char **lines;
+        char **fields;
+        int    i;
+        char  *retval;
+
+        if (!layout)
+                return NULL;
+
+        if (!g_file_get_contents ("/usr/share/sax/sysp/maps/Keyboard.map",
+                                  &map_file, NULL, NULL))
+                return NULL;
+
+        lines = g_strsplit (map_file, "\n", 0);
+        g_free (map_file);
+
+        retval = NULL;
+        for (i = 0; lines[i] != NULL; i++) {
+                if (lines[i][0] == '\n' || lines[i][0] == '#')
+                        continue;
+
+                fields = g_strsplit (lines[i], ":", 0);
+
+                g_strstrip (fields[0]);
+                if (fields[0] && fields[1] && fields[2] &&
+                    strcmp (fields[0], layout) == 0) {
+                        char *add_layouts;
+
+                        g_strstrip (fields[2]);
+
+                        add_layouts = strchr (fields[2], ',');
+                        if (add_layouts)
+                                add_layouts[0] = '\0';
+
+                        retval = g_strdup (fields[2]);
+                        g_strfreev (fields);
+                        break;
+                }
+
+                g_strfreev (fields);
+        }
+
+        g_strfreev (lines);
+
+        return retval;
+}
+
+/* Copied from patched gdm-session-direct.c */
+static char *
+_get_default_layout_name_from_sysconfig (void)
+{
+        char *sysconfig_layout;
+        char *layout;
+
+        sysconfig_layout = gdm_sysconfig_load_value ("/etc/sysconfig/keyboard", "KEYTABLE");
+        if (!sysconfig_layout)
+                return NULL;
+
+        if (g_str_has_suffix (sysconfig_layout, ".gz"))
+                *(sysconfig_layout + strlen (sysconfig_layout) - strlen (".gz")) = '\0';
+        if (g_str_has_suffix (sysconfig_layout, ".map"))
+                *(sysconfig_layout + strlen (sysconfig_layout) - strlen (".map")) = '\0';
+
+        layout = _get_layout_name_from_sax_map (sysconfig_layout);
+
+        if (layout) {
+                g_free (sysconfig_layout);
+                return layout;
+        } else
+                return sysconfig_layout;
+}
+
+static gboolean
+is_system_keymap (const gchar *layout)
+{
+        gboolean result = FALSE;
+
+        if (layout && *layout) {
+                gchar *global_layout = _get_default_layout_name_from_sysconfig ();
+                if (global_layout && !strcmp (layout, global_layout))
+                        result = TRUE;
+                g_free (global_layout);
+        } else {
+                result = TRUE;
+        }
+
+        return result;
+}
+
+static gboolean
+is_environment_lang (const gchar *lang)
+{
+        const gchar *env_lang;
+
+        if (!lang)
+                return TRUE;
+
+        env_lang = g_getenv ("LC_ALL");
+        if (env_lang && !strcmp (lang, env_lang))
+                return TRUE;
+
+        env_lang = g_getenv ("LC_MESSAGES");
+        if (env_lang && !strcmp (lang, env_lang))
+                return TRUE;
+
+        env_lang = g_getenv ("LANG");
+        if (env_lang && !strcmp (lang, env_lang))
+                return TRUE;
+
+        return FALSE;
+}
+
 gboolean
 gdm_session_settings_save (GdmSessionSettings  *settings,
                            const char          *home_directory,
@@ -389,14 +507,43 @@ gdm_session_settings_save (GdmSessionSet
                                        settings->priv->session_name);
         }
 
-        if (settings->priv->language_name != NULL) {
+        /* If the chosen language is the same as the system language,
+         * as provided by the environment, don't save a language
+         * preference. This solves the problem where the user changes the
+         * system language, but keeps getting the previous "preferred" language
+         * from his .dmrc, which is confusing since he/she never explicitly
+         * expressed any preference on login.
+         *
+         * See https://bugzilla.novell.com/show_bug.cgi?id=490376 and others.
+         *
+         * On multi-user systems, this also lets the sysadmin change the
+         * language globally without editing each user's .dmrc or relying on
+         * users to manipulate the (confusing) language option widget after
+         * entering their account name.
+         *
+         * This is a hack, and doesn't really belong here - it would be better
+         * in gdm-session-worker.c:_save_user_settings (). However, since this
+         * function actually merges the changes instead of overwriting the file
+         * (note the g_key_file_load_from_file () call above), we wouldn't be
+         * able to remove any keys. */
+
+        if (settings->priv->language_name != NULL &&
+            !is_environment_lang (settings->priv->language_name)) {
                 g_key_file_set_string (key_file, "Desktop", "Language",
                                        settings->priv->language_name);
+        } else {
+                g_key_file_remove_key (key_file, "Desktop", "Language", NULL);
         }
 
-        if (settings->priv->layout_name != NULL) {
+        /* The "stubborn" layout setting confuses users in the same way as the
+         * language setting, described above. */
+
+        if (settings->priv->layout_name != NULL &&
+            !is_system_keymap (settings->priv->layout_name)) {
                 g_key_file_set_string (key_file, "Desktop", "Layout",
                                        settings->priv->layout_name);
+        } else {
+                g_key_file_remove_key (key_file, "Desktop", "Layout", NULL);
         }
 
         contents = g_key_file_to_data (key_file, &length, &file_error);
