Input module can only be loaded at startup on Windows
Steps to reproduce
-
Set current keyboard layout to English
-
Run a GTK application
-
Note that no input module is loaded.
-
Change keyboard layout to Korean.
-
Note that IME input module (used for Korean) is still not loaded.
-
Close the application
-
Set current keyboard layout to Korean (any variant - Korean/English or Korean/Hangul)
-
Run a GTK application
-
Note that IME input module is loaded
Current behavior
GTK checks current input language at startup, and uses that to choose an input module to load
Expected outcome
There should be a way to change input modules at runtime. At the very least GTK shouldn't look only at current active keyboard layout, but take other installed layouts into account as well.
Version information
GTK3 git master
Additional information
On X it goes like this:
- Input module is switched in the shell
-
Gtk/IMModule
XSetting changes - X11 GDK backend is notified of
Gtk/IMModule
XSetting change - X11 GDK backend sends
GDK_SETTING
withgtk-im-module
name in it - GTK catches
GDK_SETTING
and calls its handler,_gtk_settings_handle_event()
-
_gtk_settings_handle_event()
callssettings_update_xsetting()
-
settings_update_xsetting()
callsgdk_screen_get_setting()
, which calls the backendget_setting()
function, which (on X11) asks the system for the value ofGTK/IMModule
. If it manages to get a value (any value),settings_update_xsetting()
returns TRUE - If
settings_update_xsetting()
returns TRUE,_gtk_settings_handle_event()
callsg_object_notify_by_pspec()
to emitnotify::gtk-im-module
signal, which is caught bygtkimmulticontext
, causing it to setglobal_context_id
toNULL
- Next time
get_effective_context_id()
called forgtkimmulticontext
, it calls_gtk_im_module_get_default_context_id()
, becauseglobal_context_id == NULL
, and caches the result inglobal_context_id
-
_gtk_im_module_get_default_context_id()
grabs thegtk-im-module
value fromGtkSettings
for the appropriate screen, and tries to load the appropriate module(s). If it succeeds, it returns the context ID for that module. If it fails (becausegtk-im-module
is unset or no modules by that name(s) are found), it queriesLC_CTYPE
locale variable, strips it down, and uses that locale name to look up a module. It either loads that (and returns corresponding ID), or returns the ID forgtkimcontextsimple
(no module loaded).
I've asked around. I was told that these days Gnome understands IBus and Simple input methods by default, and that IBus input method module is not included in GTK source tree. I'm not sure how IBus decides which input method to use (it's a framework, so it actually can have multiple different methods hooked up to it).
Anyway, this is how Gnome switches input modules. I propose we emulate some of that on Windows by expanding the get_setting()
backend method to support gtk-im-module
setting. We should also expand the WM_INPUTLANGCHANGE
handling to emit GDK_SETTING
event with gtk-im-module
name attached.
The real question is how to figure out which method to use. I don't think that doing the same thing gtkimmodule.c
does (reading input module cache) is appropriate for GDK. We could just set gtk-im-module
to some nonsense (or even keep it unset) - as long as settings_update_xsetting()
returns TRUE, the notification will be sent, and gtkimmulticontext
will try to re-load the module. It will fail to load a particular module (because there's no such module, or because module name is empty), and then will go the LC_CTYPE
route. Windows version of that code queries current input language instead of LC_CTYPE
locale variable, which probably is the right thing to use in these circumstances (as each WM_INPUTLANGCHANGE
will trigger a potential module re-load, we don't need to look at all available keyboard layouts).