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
This commit is contained in:
Matthias Clasen 2007-12-18 03:24:17 +00:00 committed by Matthias Clasen
parent cba696a702
commit f8a1be3a04
10 changed files with 154 additions and 41 deletions

View File

@ -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),

View File

@ -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:

View File

@ -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>

View File

@ -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" },

View File

@ -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 }
};

View File

@ -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;
}

View File

@ -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
*/

View File

@ -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));

View File

@ -45,7 +45,7 @@ struct _GtkIMMulticontext
GtkIMMulticontextPrivate *priv;
const gchar *context_id;
gchar *context_id;
};
struct _GtkIMMulticontextClass

View File

@ -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