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

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