Rework the way IM contexts are set

Add a function to obtain the effective context id, and reset the slave
only when the effective context id is different from the current context
id, when setting a client window and on focus in. This might fix
bug 593868 and bug 567124.
This commit is contained in:
Matthias Clasen
2009-09-04 18:09:44 -04:00
parent ea98cdc164
commit 1c0ecc0380
2 changed files with 36 additions and 46 deletions

View File

@ -685,17 +685,13 @@ _gtk_im_module_get_default_context_id (GdkWindow *client_window)
if (GDK_IS_DRAWABLE (client_window)) if (GDK_IS_DRAWABLE (client_window))
{ {
screen = gdk_drawable_get_screen (GDK_DRAWABLE (client_window)); screen = gdk_drawable_get_screen (GDK_DRAWABLE (client_window));
if (screen) settings = gtk_settings_get_for_screen (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); g_object_get (G_OBJECT (settings), "gtk-im-module", &tmp, NULL);
if (tmp) if (tmp)
{ {
if (strcmp (tmp, SIMPLE_ID) == 0) if (strcmp (tmp, SIMPLE_ID) == 0)
context_id = SIMPLE_ID; context_id = SIMPLE_ID;
else else
{ {
GtkIMModule *module; GtkIMModule *module;
module = g_hash_table_lookup (contexts_hash, tmp); module = g_hash_table_lookup (contexts_hash, tmp);
@ -704,7 +700,7 @@ _gtk_im_module_get_default_context_id (GdkWindow *client_window)
} }
g_free (tmp); g_free (tmp);
if (context_id) if (context_id)
return context_id; return context_id;
} }
} }

View File

@ -220,23 +220,28 @@ gtk_im_multicontext_set_slave (GtkIMMulticontext *multicontext,
g_signal_emit_by_name (multicontext, "preedit-changed"); g_signal_emit_by_name (multicontext, "preedit-changed");
} }
static const gchar *
get_effective_context_id (GtkIMMulticontext *multicontext)
{
if (multicontext->priv->context_id)
return multicontext->priv->context_id;
if (!global_context_id)
global_context_id = _gtk_im_module_get_default_context_id (multicontext->priv->client_window);
return global_context_id;
}
static GtkIMContext * static GtkIMContext *
gtk_im_multicontext_get_slave (GtkIMMulticontext *multicontext) gtk_im_multicontext_get_slave (GtkIMMulticontext *multicontext)
{ {
if (!multicontext->slave) if (!multicontext->slave)
{ {
GtkIMContext *slave; GtkIMContext *slave;
g_free (multicontext->context_id); g_free (multicontext->context_id);
if (multicontext->priv->context_id) multicontext->context_id = g_strdup (get_effective_context_id (multicontext));
multicontext->context_id = g_strdup (multicontext->priv->context_id);
else
{
if (!global_context_id)
global_context_id = _gtk_im_module_get_default_context_id (multicontext->priv->client_window);
multicontext->context_id = g_strdup (global_context_id);
}
slave = _gtk_im_module_create (multicontext->context_id); slave = _gtk_im_module_create (multicontext->context_id);
gtk_im_multicontext_set_slave (multicontext, slave, FALSE); gtk_im_multicontext_set_slave (multicontext, slave, FALSE);
g_object_unref (slave); g_object_unref (slave);
@ -264,28 +269,26 @@ gtk_im_multicontext_set_client_window (GtkIMContext *context,
multicontext->priv->client_window = window; multicontext->priv->client_window = window;
gtk_im_multicontext_set_slave (multicontext, NULL, FALSE); if (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", screen = gdk_drawable_get_screen (GDK_DRAWABLE (window));
G_CALLBACK (im_module_setting_changed), NULL); settings = gtk_settings_get_for_screen (screen);
g_object_set_data (G_OBJECT (settings), "gtk-im-module-connected",
GINT_TO_POINTER (TRUE));
global_context_id = NULL; 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;
}
} }
if (g_strcmp0 (multicontext->context_id, get_effective_context_id (multicontext)) != 0)
gtk_im_multicontext_set_slave (multicontext, NULL, FALSE);
} }
static void static void
@ -327,16 +330,7 @@ gtk_im_multicontext_focus_in (GtkIMContext *context)
GtkIMMulticontext *multicontext = GTK_IM_MULTICONTEXT (context); GtkIMMulticontext *multicontext = GTK_IM_MULTICONTEXT (context);
GtkIMContext *slave; GtkIMContext *slave;
/* If the global context type is different from the context we were if (g_strcmp0 (multicontext->context_id, get_effective_context_id (multicontext)) != 0)
* using before, get rid of the old slave and create a new one
* for the new global context type.
*/
if (multicontext->context_id == NULL ||
(multicontext->priv->context_id != NULL &&
strcmp (multicontext->priv->context_id, multicontext->context_id) != 0) ||
(multicontext->priv->context_id == NULL &&
(global_context_id == NULL ||
strcmp (global_context_id, multicontext->context_id) != 0)))
gtk_im_multicontext_set_slave (multicontext, NULL, FALSE); gtk_im_multicontext_set_slave (multicontext, NULL, FALSE);
slave = gtk_im_multicontext_get_slave (multicontext); slave = gtk_im_multicontext_get_slave (multicontext);