Commit f8a1be3a authored by Matthias Clasen's avatar Matthias Clasen Committed by Matthias Clasen

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
parent cba696a7
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),
......
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:
......
......@@ -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>
......
......@@ -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" },
......
......@@ -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 }
};
......@@ -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;
}
......@@ -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
*/
......
......@@ -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));
......
......@@ -45,7 +45,7 @@ struct _GtkIMMulticontext
GtkIMMulticontextPrivate *priv;
const gchar *context_id;
gchar *context_id;
};
struct _GtkIMMulticontextClass
......
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment