summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2007-12-18 03:24:17 +0000
committerMatthias Clasen <matthiasc@src.gnome.org>2007-12-18 03:24:17 +0000
commitf8a1be3a0401f42f84b83a85a1fb6ac69e6ffd47 (patch)
treeafb6e0c047ae6c2efb4b0578e8130dd46a045296
parentcba696a7027ac03146f4a2e0344ba742da518536 (diff)
downloadgtk+-f8a1be3a0401f42f84b83a85a1fb6ac69e6ffd47.tar.gz
Add a gtk-im-module GTK setting
2007-12-17 Matthias Clasen <mclasen@redhat.com> * gtk/gtksettings.c: Add a gtk-im-module GTK setting * gdk/win32/gdkproperty-win32.c: * gdk/x11/gdksettings.c: ...and back it by a Gtk/IMModule X setting. * gtk/gtkimmodule.[hc]: * gtk/gtkimmulticontext.[hc]: When determining the default context, look at the gtk-im-module setting, and listen for changes to the setting. (#502446, Akira Tagoh) svn path=/trunk/; revision=19195
-rw-r--r--ChangeLog11
-rw-r--r--docs/reference/ChangeLog4
-rw-r--r--docs/reference/gtk/running.sgml5
-rw-r--r--gdk/win32/gdkproperty-win32.c1
-rw-r--r--gdk/x11/gdksettings.c7
-rw-r--r--gtk/gtkimmodule.c55
-rw-r--r--gtk/gtkimmodule.h8
-rw-r--r--gtk/gtkimmulticontext.c85
-rw-r--r--gtk/gtkimmulticontext.h2
-rw-r--r--gtk/gtksettings.c17
10 files changed, 154 insertions, 41 deletions
diff --git a/ChangeLog b/ChangeLog
index 6d6ec01d9b..68be1d1fa1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2007-12-17 Matthias Clasen <mclasen@redhat.com>
+
+ * gtk/gtksettings.c: Add a gtk-im-module GTK setting
+ * gdk/win32/gdkproperty-win32.c:
+ * gdk/x11/gdksettings.c: ...and back it by a Gtk/IMModule X setting.
+
+ * gtk/gtkimmodule.[hc]:
+ * gtk/gtkimmulticontext.[hc]: When determining the default context,
+ look at the gtk-im-module setting, and listen for changes to the
+ setting. (#502446, Akira Tagoh)
+
2007-12-17 Kristian Rietveld <kris@imendio.com>
* gtk/gtktooltip.c (gtk_tooltip_finalize),
diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog
index e9602ab5e9..8cd21796a1 100644
--- a/docs/reference/ChangeLog
+++ b/docs/reference/ChangeLog
@@ -1,3 +1,7 @@
+2007-12-17 Matthias Clasen <mclasen@redhat.com>
+
+ * gtk/running.sgml: Mention the Gtk/IMModule XSetting.
+
2007-12-12 Matthias Clasen <mclasen@redhat.com>
* gdk/gdk-docs.sgml:
diff --git a/docs/reference/gtk/running.sgml b/docs/reference/gtk/running.sgml
index 206e470b7a..c5d1c1017a 100644
--- a/docs/reference/gtk/running.sgml
+++ b/docs/reference/gtk/running.sgml
@@ -242,7 +242,10 @@ additional environment variables.
<para>
Specifies an IM module to use in preference to the one determined
- from the locale.
+ from the locale. If this isn't set and you are running on the system
+ that enables <literal>XSETTINGS</literal> and has a value in
+ <literal>Gtk/IMModule</literal>, that will be used for the default
+ IM module.
</para>
</formalpara>
diff --git a/gdk/win32/gdkproperty-win32.c b/gdk/win32/gdkproperty-win32.c
index f4a409a4aa..1102f8850e 100644
--- a/gdk/win32/gdkproperty-win32.c
+++ b/gdk/win32/gdkproperty-win32.c
@@ -353,6 +353,7 @@ gdk_property_delete (GdkWindow *window,
{ "Gtk/ToolbarIconSize", "gtk-toolbar-icon-size" },
{ "Gtk/IMPreeditStyle", "gtk-im-preedit-style" },
{ "Gtk/IMStatusStyle", "gtk-im-status-style" },
+ { "Gtk/IMModule", "gtk-im-module" },
{ "Net/CursorBlink", "gtk-cursor-blink" },
{ "Net/CursorBlinkTime", "gtk-cursor-blink-time" },
{ "Net/ThemeName", "gtk-theme-name" },
diff --git a/gdk/x11/gdksettings.c b/gdk/x11/gdksettings.c
index 3e62095abc..6ef672e2ff 100644
--- a/gdk/x11/gdksettings.c
+++ b/gdk/x11/gdksettings.c
@@ -68,7 +68,9 @@ static const char gdk_settings_names[] =
"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
{
@@ -113,5 +115,6 @@ static const struct
{ 1285, 1305 },
{ 1326, 1343 },
{ 1361, 1381 },
- { 1402, 1430 }
+ { 1402, 1430 },
+ { 1460, 1473 }
};
diff --git a/gtk/gtkimmodule.c b/gtk/gtkimmodule.c
index 52d86d670a..9229504ca9 100644
--- a/gtk/gtkimmodule.c
+++ b/gtk/gtkimmodule.c
@@ -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 @@ _gtk_im_module_list (const GtkIMContextInfo ***contexts,
#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 (const gchar *locale)
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 (const gchar *locale)
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 (const gchar *locale)
{
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 @@ _gtk_im_module_get_default_context_id (const gchar *locale)
g_free (tmp_locale);
- return g_strdup (context_id ? context_id : SIMPLE_ID);
+ return context_id ? context_id : SIMPLE_ID;
}
diff --git a/gtk/gtkimmodule.h b/gtk/gtkimmodule.h
index d58ef15678..a6e3a2d361 100644
--- a/gtk/gtkimmodule.h
+++ b/gtk/gtkimmodule.h
@@ -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 --git a/gtk/gtkimmulticontext.c b/gtk/gtkimmulticontext.c
index 7d37cd795f..484ae51e6d 100644
--- a/gtk/gtkimmulticontext.c
+++ b/gtk/gtkimmulticontext.c
@@ -85,6 +85,7 @@ static gboolean gtk_im_multicontext_delete_surrounding_cb (GtkIMContext *
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 *object)
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 (GtkIMMulticontext *multicontext)
{
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 (GtkIMContext *context)
* 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 (GtkIMMulticontext *context,
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 (GtkIMMulticontext *context,
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 --git a/gtk/gtkimmulticontext.h b/gtk/gtkimmulticontext.h
index d80b81d650..aa410f172c 100644
--- a/gtk/gtkimmulticontext.h
+++ b/gtk/gtkimmulticontext.h
@@ -45,7 +45,7 @@ struct _GtkIMMulticontext
GtkIMMulticontextPrivate *priv;
- const gchar *context_id;
+ gchar *context_id;
};
struct _GtkIMMulticontextClass
diff --git a/gtk/gtksettings.c b/gtk/gtksettings.c
index 8fdcfb9a37..3081e8711a 100644
--- a/gtk/gtksettings.c
+++ b/gtk/gtksettings.c
@@ -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 (GtkSettingsClass *class)
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