Index: gdk/x11/gdksettings.c
===================================================================
--- gdk/x11/gdksettings.c	(revision 19181)
+++ gdk/x11/gdksettings.c	(working copy)
@@ -68,8 +68,10 @@
   "Gtk/TouchscreenMode\0"     "gtk-touchscreen-mode\0"
   "Gtk/EnableAccels\0"        "gtk-enable-accels\0"
   "Gtk/EnableMnemonics\0"     "gtk-enable-mnemonics\0"
-  "Gtk/ScrolledWindowPlacement\0" "gtk-scrolled-window-placement\0";
+  "Gtk/ScrolledWindowPlacement\0" "gtk-scrolled-window-placement\0"
+  "Gtk/IMModule\0"            "gtk-im-module\0";
 
+
 static const struct
 {
   gint xsettings_offset;
@@ -113,5 +115,6 @@
   { 1285, 1305 },
   { 1326, 1343 },
   { 1361, 1381 },
-  { 1402, 1430 }
+  { 1402, 1430 },
+  { 1460, 1473 }
 };
Index: gtk/gtkimmulticontext.c
===================================================================
--- gtk/gtkimmulticontext.c	(revision 19181)
+++ gtk/gtkimmulticontext.c	(working copy)
@@ -85,6 +85,7 @@
 							     gint               n_chars,
 							     GtkIMMulticontext *multicontext);
 
+static const gchar *user_context_id = NULL;
 static const gchar *global_context_id = NULL;
 
 G_DEFINE_TYPE (GtkIMMulticontext, gtk_im_multicontext, GTK_TYPE_IM_CONTEXT)
@@ -141,6 +142,7 @@
   GtkIMMulticontext *multicontext = GTK_IM_MULTICONTEXT (object);
   
   gtk_im_multicontext_set_slave (multicontext, NULL, TRUE);
+  g_free (multicontext->context_id);
 
   G_OBJECT_CLASS (gtk_im_multicontext_parent_class)->finalize (object);
 }
@@ -224,35 +226,68 @@
     {
       GtkIMContext *slave;
 
-      if (!global_context_id)
-	{
-	  gchar *locale = _gtk_get_lc_ctype ();
-	  global_context_id = _gtk_im_module_get_default_context_id (locale);
-	  g_free (locale);
-	}
-	
+      if (!global_context_id) 
+        {
+          if (user_context_id)
+            global_context_id = user_context_id;
+          else
+            global_context_id = _gtk_im_module_get_default_context_id (multicontext->priv->client_window);
+        }
       slave = _gtk_im_module_create (global_context_id);
       gtk_im_multicontext_set_slave (multicontext, slave, FALSE);
       g_object_unref (slave);
 
-      multicontext->context_id = global_context_id;
+      multicontext->context_id = g_strdup (global_context_id);
     }
 
   return multicontext->slave;
 }
 
 static void
+im_module_setting_changed (GtkSettings *settings, 
+                           gpointer     data)
+{
+  global_context_id = NULL;
+}
+
+
+static void
 gtk_im_multicontext_set_client_window (GtkIMContext *context,
 				       GdkWindow    *window)
 {
   GtkIMMulticontext *multicontext = GTK_IM_MULTICONTEXT (context);
-  
-  GtkIMContext *slave = gtk_im_multicontext_get_slave (multicontext);
+  GtkIMContext *slave; 
+  GdkScreen *screen; 
+  GtkSettings *settings;
+  gboolean connected;
 
   multicontext->priv->client_window = window;
-  
+
+  slave = gtk_im_multicontext_get_slave (multicontext);
+
   if (slave)
     gtk_im_context_set_client_window (slave, window);
+
+  if (window == NULL) 
+    return;
+   
+  screen = gdk_drawable_get_screen (GDK_DRAWABLE (window));
+  if (screen)
+    settings = gtk_settings_get_for_screen (screen);
+  else
+    settings = gtk_settings_get_default ();
+
+  connected = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (settings),
+                                                  "gtk-im-module-connected"));
+  if (!connected) 
+    {
+      g_signal_connect (settings, "notify::gtk-im-module",
+                        G_CALLBACK (im_module_setting_changed), NULL);
+      g_object_set_data (G_OBJECT (settings), "gtk-im-module-connected",
+                         GINT_TO_POINTER (TRUE));
+
+      global_context_id = NULL;  
+    }
 }
 
 static void
@@ -298,7 +333,8 @@
    * using before, get rid of the old slave and create a new one
    * for the new global context type.
    */
-  if (!multicontext->context_id ||
+  if (multicontext->context_id == NULL || 
+      global_context_id == NULL ||
       strcmp (global_context_id, multicontext->context_id) != 0)
     gtk_im_multicontext_set_slave (multicontext, NULL, FALSE);
 
@@ -459,7 +495,8 @@
 
       gtk_im_context_reset (GTK_IM_CONTEXT (context));
       
-      global_context_id = id;
+      user_context_id = id;
+      global_context_id = NULL;
       gtk_im_multicontext_set_slave (context, NULL, FALSE);
     }
 }
@@ -500,12 +537,22 @@
   const GtkIMContextInfo **contexts;
   guint n_contexts, i;
   GSList *group = NULL;
+  GtkWidget *menuitem;
   
+  menuitem = gtk_radio_menu_item_new_with_label (group, Q_("input method menu|System"));
+  if (!user_context_id)
+    gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem), TRUE);
+  group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menuitem));
+  g_object_set_data (G_OBJECT (menuitem), I_("gtk-context-id"), NULL);
+  g_signal_connect (menuitem, "activate", G_CALLBACK (activate_cb), context);
+
+  gtk_widget_show (menuitem);
+  gtk_menu_shell_append (menushell, menuitem);
+
   _gtk_im_module_list (&contexts, &n_contexts);
 
-  for (i=0; i < n_contexts; i++)
+  for (i = 0; i < n_contexts; i++)
     {
-      GtkWidget *menuitem;
       const gchar *translated_name;
 #ifdef ENABLE_NLS
       if (contexts[i]->domain && contexts[i]->domain[0])
@@ -562,11 +609,9 @@
       menuitem = gtk_radio_menu_item_new_with_label (group,
 						     translated_name);
       
-      if ((global_context_id == NULL && group == NULL) ||
-          (global_context_id &&
-           strcmp (contexts[i]->context_id, global_context_id) == 0))
-        gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem),
-                                        TRUE);
+      if ((user_context_id &&
+           strcmp (contexts[i]->context_id, user_context_id) == 0))
+        gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem), TRUE);
       
       group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menuitem));
       
Index: gtk/gtkimmulticontext.h
===================================================================
--- gtk/gtkimmulticontext.h	(revision 19181)
+++ gtk/gtkimmulticontext.h	(working copy)
@@ -45,7 +45,7 @@
 
   GtkIMMulticontextPrivate *priv;
 
-  const gchar *context_id;
+  gchar *context_id;
 };
 
 struct _GtkIMMulticontextClass
Index: gtk/gtksettings.c
===================================================================
--- gtk/gtksettings.c	(revision 19181)
+++ gtk/gtksettings.c	(working copy)
@@ -106,7 +106,8 @@
   PROP_PRINT_PREVIEW_COMMAND,
   PROP_ENABLE_MNEMONICS,
   PROP_ENABLE_ACCELS,
-  PROP_RECENT_FILES_LIMIT
+  PROP_RECENT_FILES_LIMIT,
+  PROP_IM_MODULE
 };
 
 
@@ -805,6 +806,20 @@
  							       GTK_PARAM_READWRITE),
 					     NULL);
   g_assert (result == PROP_RECENT_FILES_LIMIT);
+
+  /**
+   * GtkSettings:gtk-im-module:
+   *
+   * Which IM module should be used by default.
+   */
+  result = settings_install_property_parser (class,
+					     g_param_spec_string ("gtk-im-module",
+								  P_("Default IM module"),
+								  P_("Which IM module should be used by default"),
+								  NULL,
+								  GTK_PARAM_READWRITE),
+					     NULL);
+  g_assert (result == PROP_IM_MODULE);
 }
 
 static void
Index: gtk/gtkimmodule.c
===================================================================
--- gtk/gtkimmodule.c	(revision 19181)
+++ gtk/gtkimmodule.c	(working copy)
@@ -37,6 +37,8 @@
 #include <pango/pango-utils.h>
 #include "gtkimmodule.h"
 #include "gtkimcontextsimple.h"
+#include "gtksettings.h"
+#include "gtkmain.h"
 #include "gtkrc.h"
 #include "gtkintl.h"
 #include "gtkalias.h"
@@ -418,7 +420,7 @@
 #endif
 		GtkIMContextInfo simple_context_info = {
     SIMPLE_ID,
-    N_("Default"),
+    N_("Simple"),
     GETTEXT_PACKAGE,
 #ifdef GTK_LOCALEDIR
     GTK_LOCALEDIR,
@@ -546,17 +548,15 @@
 
 /**
  * _gtk_im_module_get_default_context_id:
- * @locale: a locale id in the form 'en_US'
+ * @client_window: a window
  * 
- * Return the context_id of the best IM context type
- * for the given locale ID.
+ * Return the context_id of the best IM context type 
+ * for the given window.
  * 
  * Return value: the context ID (will never be %NULL)
- *    the value is newly allocated and must be freed
- *    with g_free().
  **/
 const gchar *
-_gtk_im_module_get_default_context_id (const gchar *locale)
+_gtk_im_module_get_default_context_id (GdkWindow *client_window)
 {
   GSList *tmp_list;
   const gchar *context_id = NULL;
@@ -564,6 +564,8 @@
   gint i;
   gchar *tmp_locale, *tmp;
   const gchar *envvar;
+  GdkScreen *screen;
+  GtkSettings *settings;
       
   if (!contexts_hash)
     gtk_im_module_initialize ();
@@ -571,12 +573,41 @@
   envvar = g_getenv ("GTK_IM_MODULE");
   if (envvar &&
       (strcmp (envvar, SIMPLE_ID) == 0 ||
-       g_hash_table_lookup (contexts_hash, envvar)))
-    return g_strdup (envvar);
+       g_hash_table_lookup (contexts_hash, envvar))) 
+    return envvar;
 
+  /* Check if the certain immodule is set in XSETTINGS.
+   */
+  if (client_window != NULL && GDK_IS_DRAWABLE (client_window))
+    {
+      screen = gdk_drawable_get_screen (GDK_DRAWABLE (client_window));
+      if (screen)
+        settings = gtk_settings_get_for_screen (screen);
+      else
+        settings = gtk_settings_get_default ();
+
+      g_object_get (G_OBJECT (settings), "gtk-im-module", &tmp, NULL);
+      if (tmp)
+        {
+          if (strcmp (tmp, SIMPLE_ID) == 0)
+            context_id = SIMPLE_ID;
+          else 
+            {
+              GtkIMModule *module;
+              module = g_hash_table_lookup (contexts_hash, tmp);
+              if (module)
+                context_id = module->contexts[0]->context_id;
+            }
+          g_free (tmp);
+
+       	  if (context_id) 
+            return context_id;
+        }
+    }
+
   /* Strip the locale code down to the essentials
    */
-  tmp_locale = g_strdup (locale);
+  tmp_locale = _gtk_get_lc_ctype ();
   tmp = strchr (tmp_locale, '.');
   if (tmp)
     *tmp = '\0';
@@ -589,7 +620,7 @@
     {
       GtkIMModule *module = tmp_list->data;
      
-      for (i=0; i<module->n_contexts; i++)
+      for (i = 0; i < module->n_contexts; i++)
 	{
 	  const gchar *p = module->contexts[i]->default_locales;
 	  while (p)
@@ -612,5 +643,5 @@
 
   g_free (tmp_locale);
   
-  return g_strdup (context_id ? context_id : SIMPLE_ID);
+  return context_id ? context_id : SIMPLE_ID;
 }
Index: gtk/gtkimmodule.h
===================================================================
--- gtk/gtkimmodule.h	(revision 19181)
+++ gtk/gtkimmodule.h	(working copy)
@@ -38,10 +38,10 @@
 
 /* Functions for use within GTK+
  */
-void          _gtk_im_module_list                   (const GtkIMContextInfo ***contexts,
-						    guint                    *n_contexts);
-GtkIMContext *_gtk_im_module_create                 (const gchar             *context_id);
-const gchar * _gtk_im_module_get_default_context_id (const gchar             *lang);
+void           _gtk_im_module_list                   (const GtkIMContextInfo ***contexts,
+						      guint                    *n_contexts);
+GtkIMContext * _gtk_im_module_create                 (const gchar              *context_id);
+const gchar  * _gtk_im_module_get_default_context_id (GdkWindow                *client_window);
 
 /* The following entry points are exported by each input method module
  */
