diff -up gtk+-2.12.3/gtk/gtkimmulticontext.h.im-setting gtk+-2.12.3/gtk/gtkimmulticontext.h --- gtk+-2.12.3/gtk/gtkimmulticontext.h.im-setting 2007-12-17 23:50:52.000000000 -0500 +++ gtk+-2.12.3/gtk/gtkimmulticontext.h 2007-12-17 23:51:31.000000000 -0500 @@ -45,7 +45,7 @@ struct _GtkIMMulticontext GtkIMMulticontextPrivate *priv; - const gchar *context_id; + gchar *context_id; }; struct _GtkIMMulticontextClass diff -up gtk+-2.12.3/gtk/gtksettings.c.im-setting gtk+-2.12.3/gtk/gtksettings.c --- gtk+-2.12.3/gtk/gtksettings.c.im-setting 2007-12-17 23:51:11.000000000 -0500 +++ gtk+-2.12.3/gtk/gtksettings.c 2007-12-17 23:51:31.000000000 -0500 @@ -106,7 +106,8 @@ enum { 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_settings_class_init (GtkSettingsClas 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 diff -up gtk+-2.12.3/gtk/gtkimmodule.c.im-setting gtk+-2.12.3/gtk/gtkimmodule.c --- gtk+-2.12.3/gtk/gtkimmodule.c.im-setting 2007-12-17 23:50:34.000000000 -0500 +++ gtk+-2.12.3/gtk/gtkimmodule.c 2007-12-17 23:51:31.000000000 -0500 @@ -37,6 +37,8 @@ #include #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 @@ _gtk_im_module_list (const GtkIMContextI #endif GtkIMContextInfo simple_context_info = { SIMPLE_ID, - N_("Default"), + N_("Simple"), GETTEXT_PACKAGE, #ifdef GTK_LOCALEDIR GTK_LOCALEDIR, @@ -546,17 +548,15 @@ match_locale (const gchar *locale, /** * _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 @@ _gtk_im_module_get_default_context_id (c gint i; gchar *tmp_locale, *tmp; const gchar *envvar; + GdkScreen *screen; + GtkSettings *settings; if (!contexts_hash) gtk_im_module_initialize (); @@ -571,12 +573,41 @@ _gtk_im_module_get_default_context_id (c 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 @@ _gtk_im_module_get_default_context_id (c { GtkIMModule *module = tmp_list->data; - for (i=0; in_contexts; i++) + for (i = 0; i < module->n_contexts; i++) { const gchar *p = module->contexts[i]->default_locales; while (p) @@ -612,5 +643,5 @@ _gtk_im_module_get_default_context_id (c g_free (tmp_locale); - return g_strdup (context_id ? context_id : SIMPLE_ID); + return context_id ? context_id : SIMPLE_ID; } diff -up gtk+-2.12.3/gtk/gtkimmodule.h.im-setting gtk+-2.12.3/gtk/gtkimmodule.h --- gtk+-2.12.3/gtk/gtkimmodule.h.im-setting 2007-12-17 23:50:41.000000000 -0500 +++ gtk+-2.12.3/gtk/gtkimmodule.h 2007-12-17 23:51:31.000000000 -0500 @@ -38,10 +38,10 @@ struct _GtkIMContextInfo /* 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 */ diff -up gtk+-2.12.3/gtk/gtkimmulticontext.c.im-setting gtk+-2.12.3/gtk/gtkimmulticontext.c --- gtk+-2.12.3/gtk/gtkimmulticontext.c.im-setting 2007-12-17 23:51:01.000000000 -0500 +++ gtk+-2.12.3/gtk/gtkimmulticontext.c 2007-12-17 23:51:31.000000000 -0500 @@ -85,6 +85,7 @@ static gboolean gtk_im_multicontext_dele 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 @@ gtk_im_multicontext_finalize (GObject *o 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 @@ gtk_im_multicontext_get_slave (GtkIMMult { 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 @@ gtk_im_multicontext_focus_in (GtkIMConte * 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 @@ activate_cb (GtkWidget *menuitem 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 @@ gtk_im_multicontext_append_menuitems (Gt 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 @@ gtk_im_multicontext_append_menuitems (Gt 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)); diff -up gtk+-2.12.3/gdk/x11/gdksettings.c.im-setting gtk+-2.12.3/gdk/x11/gdksettings.c --- gtk+-2.12.3/gdk/x11/gdksettings.c.im-setting 2007-12-17 23:49:43.000000000 -0500 +++ gtk+-2.12.3/gdk/x11/gdksettings.c 2007-12-17 23:54:19.000000000 -0500 @@ -65,7 +65,8 @@ static const char gdk_settings_names[] = "Xft/RGBA\0" "gtk-xft-rgba\0" "Xft/DPI\0" "gtk-xft-dpi\0" "Net/FallbackIconTheme\0" "gtk-fallback-icon-theme\0" - "Gtk/TouchscreenMode\0" "gtk-touchscreen-mode\0"; + "Gtk/TouchscreenMode\0" "gtk-touchscreen-mode\0" + "Gtk/IMModule\0" "gtk-im-module\0"; static const struct { @@ -107,5 +108,6 @@ static const struct { 1197, 1206 }, { 1219, 1227 }, { 1239, 1261 }, - { 1285, 1305 } + { 1285, 1305 }, + { 1326, 1339 } };