I have just implemented a GTK+ input method to allow input via multiple key presses, with a timeout, as on mobile phones.
(Update: here is a source tarball – improvements welcome. I’m now wondering how I can specify this as the default input method.)
I didn’t find any documentation about how to do this, but there are examples:
From these examples, I figured out the following, which I might try to get into the gtk-doc documentation later:
Functions that the shared library should export
The shared library must export:
The input modules must be listed in the /etc/gtk-2.0/gtk.immodules file, which is a cache of input modules information. Your Makefile should generate a new gtk.immodules file, using gtk-query-immodules-2.0, then install it.
Implementing a GtkIMContext
You must implement a GtkIMContext, an instance of which will be returned by your im_module_create() function.
Though most GObjects would have a *_get_type() function that calls g_type_register_static(), input modules need a *_register_type() function that takes a GTypeModule, which it provides to g_type_module_register_type(). This *_register_type() function should be called from your im_module_init() function. This means:
- You can’t use the G_DEFINE_TYPE macro.
- You can implement a *_get_type() function that just gets the GType if it has been registered by your *_register_type() function, but which fails otherwise. This seems to make if difficult (maybe impossible) to implement a GtkIMContext which is both directly usable and which may be a base class for other GtkIMContext implementations.
For “table-based” input methods, you can just derive from GtkIMContextSimple and call gtk_im_context_simple_add_table() with your table array, which specifies which sequences of characters can be used to specify an actual output character. When entering one of these intermediate characters an underline indicates that the user is in compose mode. Pressing the right arrow, or pressing a non-relevant character, accepts the displayed character. For instance, see the Tigrigna-Eritrean input method from GTK+, or the Esperanto input method in gtk-im-extra.
GtkIMContext has several virtual functions that you may want to override. These are not documented, but you can at least see their signatures in the GtkIMContext header file. The most important ones seem to be:
- filter_keypress: This can emit the (undocumented) “commit” signal, sending a string when composing has finished, resulting in a character, and it can emit the “preedit_changed” signal, which will cause your get_preedit_string vfunc to be called.
- get_preedit_string: This returns a string to be shown to the user, to indicate what character would be used if it were accepted. This can use Pango to show the pre-edit UI, such as underlined text to indicate a possible character.
8 thoughts on “Creating GTK+ input methods”
I like gtk+ because it is (used to be) modular. Ie. Program, which use gtk+ do not load all things into memory – it loads only what he need (and –as-needed make much more sense). Couldn’t we use modular gtk+ and, because lack of packet manager, all-in-one for MS Windows users?
Uzytkownik, sorry, I don’t see the relevance. However, note that the overload of loading extra shared libraries is often greater than the overload of linking to what you don’t use.
I’m curious, is it technically possible to implement a ‘vi’ input method, that would allow cursor navigation using hjkl and things like yw (yank word), d$ (delete until end of line) just like in the vi editor?
thouters, yes, probably. Please don’t.
Nice description, but after browsing around a bit, going for SCIM or UIM seems like a better choice as it will then work with more than just GTK+… I’m thinking about creating an IM for input with dasher (http://www.inference.phy.cam.ac.uk/dasher/), so I was wondering if you had any particular reasons for doing it in gtk directly (apart from better integration perhaps)…
People wanting the input method described here (text input via a numpad) are probably targetting a small device, where it may be beneficial to avoid the size and cpu (hence battery) cost of going through scim or uim as an interface to gtk im. (I haven’t checked the size or cpu cost of scim or uim.)
Is there an ease-of-programming argument in favour of targetting any of these options (gtk im, scim, uim) ?
just wanted to mention that “The input modules must be listed in the /etc/gtk-2.0/gtk.immodules file” is no more accurate
seems that modules are rather listed in files in the /usr/lib/gtk-2.0/2.10.0/immodule-files.d/ directory
also, apart from your blog entry, creating GTK+ Input Method modules remains poorly documented
my bad, my comment above seems only to apply to debian based distros