2

How do I add user-defined compose key rules in Ubuntu 18.04? I turned my Compose key on using Gnome Tweaks (it's on CapsLock), created a .XCompose starting with these lines:

include "%L"   # import the default Compose file for your locale

# IPA

<Multi_key> <a> <h>                        : "ɑ" 
<Multi_key> <A> <h>                        : "Ɑ"
# Some more lines
<Multi_key> <ampersand> <underscore> <m>   : "̼"



# Math

<Multi_key> <minus> <0>          : "−"
<Multi_key> <asterisk> <1>       : "⋅"
<Multi_key> <x> <x>              : "×"
# ...

I followed this advice, installed uim and set it as GTK_ and QT_IM_MODULE but every sequence starting with the <minus> <0> line gets ignored. When I tried xim, it did a bit better but it made gedit glitch:

xim glitch

.

When I tried GTK_IM_MODULE=gtk-im-context-simple, most of the sequences started working, but some of them just don't.

<Multi_key> <minus> <0>          : "−"  # doesn't work
<Multi_key> <asterisk> <1>       : "⋅"  # doesn't work
<Multi_key> <e> <m> <o> <colon> <space>          : "😶"  # works
<Multi_key> <e> <m> <o> <colon> <Up>             : "🙄"  # works
<Multi_key> <e> <m> <o> <x> <asterisk> <space>   : "😙"  # doesn't work
<Multi_key> <e> <m> <o> <c> <a> <l> <l>          : "🤙"  # doesn't work
<Multi_key> <e> <m> <o> <o> <k>                  : "👌"  # works
<Multi_key> <w> <t> <f>                    : "ಠ_ಠ"       # doesn't work
<Multi_key> <w> <h> <y>                    : "ლ(ಠ益ಠლ)"  # doesn't work
<Multi_key> <0> <space>      : "​" # zero-width space doesn't work

.

What should I do to make my Compose key work properly?

3
  • 1
    Can you add info about what you did to turn on the compose key? That is, what is the location of the settings you changed and which settings you selected? (Wondering if you used the GUI or edited /etc/default/keyboard or something else?)
    – xiota
    May 18, 2018 at 12:03
  • I used Gnome Tweaks, see the updated question.
    – m93a
    May 20, 2018 at 14:53
  • I put keyboard settings in /etc/default/keyboard. Don't know if it makes a difference. You can also try putting the include at the end of the config to see if it makes a difference. Otherwise, it looks like multi-character output and sequences longer than 5 won't work.
    – xiota
    May 20, 2018 at 16:11

2 Answers 2

1

The link you point to is basically correct, with a few caveats:

  • Compose inserts the character corresponding to the first (shortest) match. Suppose .XCompose contains the following entries:

     <Multi_key> <space>                  : " "   nobreakspace # NO-BREAK SPACE
     <Multi_key> <space> <space>          : " "   U2002        # EN SPACE
     <Multi_key> <space> <space> <space>  : " "   U2003        # EM SPACE
    

    Attempts to use EN-SPACE or EM-SPACE will never work.

  • To get Compose to work with GTK, add the following line to .profile:

    export GTK_IM_MODULE=gtk-im-context-simple
    

Regarding gtk-im-context-simple, Jens Mühlenhoff notes (1, 2):

In the API documentation:

GtkIMContextSimple reads additional compose sequences from the first of the following files that is found:

  • ~/.config/gtk-3.0/Compose

  • ~/.XCompose, /usr/share/X11/locale/$locale/Compose (for locales that have a nontrivial Compose file)

So the gtk-im-context-simple method has a built-in table and it loads compose sequences from several additional locations. That means it could possible load shorter sequences that you don't expect.

7
  • My problem isn't that my rules are overwritten with shorter ones -- they simply don't work at all, they just do nothing. And it seems to me that which rules work and which don't changes during the session. For example just a while ago I could use minus minus period to write a dash, but now it just doesn't work. (I would add a thinking emoji but -- you know, my compose key doesn't work...)
    – m93a
    May 18, 2018 at 9:23
  • Have you tried adding export GTK_IM_MODULE=gtk-im-context-simple to ~/.profile?
    – xiota
    May 18, 2018 at 12:01
  • I tried it but some sequences (especially the longer ones) just don't work.
    – m93a
    May 20, 2018 at 14:10
  • 1
    In the API documentation you can find a paragraph "GtkIMContextSimple reads additional compose sequences from the first of the following files that is found: ~/.config/gtk-3.0/Compose, ~/.XCompose, /usr/share/X11/locale/$locale/Compose (for locales that have a nontrivial Compose file)." developer.gnome.org/gtk3/stable/GtkIMContextSimple.html Apr 8, 2019 at 23:01
  • 1
    So the gtk-im-context-simple method has a built-in table and it loads compose sequences from several additional locations. That means it could possible load shorter sequences that you don't expect. The name "simple" is a bit misleading here really. It would be nice if there was a tool that looks for sequence collissions based on the same algorithm that gtk-im-context-simple uses to load it's tables. Apr 8, 2019 at 23:04
1

There are several possibilities for Gtk+ input method modules.

The im module decides how additional input aside direct key translation is handled in Gtk+.

So the available compose key sequences depend on what im module you are using. (The symbolic X11 name for the compose key is Multi_key btw.)

The gtk-query-immodules-3.0 command can be used to show the installed modules and it can also be used to upate the cache (with sudo gtk-query-immodules-3.0 --update-cache).

Sample output:

# GTK+ Input Method Modules file
# Automatically generated file, do not edit
# Created by gtk-query-immodules-3.0 from gtk+-3.24.1
#
# ModulesPath = /usr/lib64/gtk-3.0/3.0.0/x86_64-pc-linux-gnu/immodules:/usr/lib64/gtk-3.0/3.0.0/immodules:/usr/lib64/gtk-3.0/x86_64-pc-linux-gnu/immodules:/usr/lib64/gtk-3.0/immodules
#
"/usr/lib64/gtk-3.0/3.0.0/immodules/im-am-et.so" 
"am_et" "Amharic (EZ+)" "gtk30" "/usr/share/locale" "am" 

"/usr/lib64/gtk-3.0/3.0.0/immodules/im-cedilla.so" 
"cedilla" "Cedilla" "gtk30" "/usr/share/locale" "az:ca:co:fr:gv:oc:pt:sq:tr:wa" 

"/usr/lib64/gtk-3.0/3.0.0/immodules/im-cyrillic-translit.so" 
"cyrillic_translit" "Cyrillic (Transliterated)" "gtk30" "/usr/share/locale" "" 

"/usr/lib64/gtk-3.0/3.0.0/immodules/im-ibus.so" 
"ibus" "IBus (Intelligent Input Bus)" "ibus" "" "ja:ko:zh:*" 

"/usr/lib64/gtk-3.0/3.0.0/immodules/im-inuktitut.so" 
"inuktitut" "Inuktitut (Transliterated)" "gtk30" "/usr/share/locale" "iu" 

"/usr/lib64/gtk-3.0/3.0.0/immodules/im-ipa.so" 
"ipa" "IPA" "gtk30" "/usr/share/locale" "" 

"/usr/lib64/gtk-3.0/3.0.0/immodules/im-multipress.so" 
"multipress" "Multipress" "gtk30" "" "" 

"/usr/lib64/gtk-3.0/3.0.0/immodules/im-thai.so" 
"thai" "Thai-Lao" "gtk30" "/usr/share/locale" "lo:th" 

"/usr/lib64/gtk-3.0/3.0.0/immodules/im-ti-er.so" 
"ti_er" "Tigrigna-Eritrean (EZ+)" "gtk30" "/usr/share/locale" "ti" 

"/usr/lib64/gtk-3.0/3.0.0/immodules/im-ti-et.so" 
"ti_et" "Tigrigna-Ethiopian (EZ+)" "gtk30" "/usr/share/locale" "ti" 

"/usr/lib64/gtk-3.0/3.0.0/immodules/im-viqr.so" 
"viqr" "Vietnamese (VIQR)" "gtk30" "/usr/share/locale" "vi" 

"/usr/lib64/gtk-3.0/3.0.0/immodules/im-wayland.so" 
"wayland" "Wayland" "gtk30" "/usr/share/locale" "" 

"/usr/lib64/gtk-3.0/3.0.0/immodules/im-waylandgtk.so" 
"waylandgtk" "Waylandgtk" "gtk30" "/usr/share/locale" "" 

"/usr/lib64/gtk-3.0/3.0.0/immodules/im-xim.so" 
"xim" "X Input Method" "gtk30" "/usr/share/locale" "ko:ja:th:zh" 

xim is the traditional X11 Input Method.

ibus is a more modern input method.

There are several input methods that are used for languages which use non-latin scripts / alphabets.

There are two built-in modules that are not listed by the tool, which are:

  • gtk-im-context-none (which disables all advanced input)
  • gtk-im-context-simple (which is described well in xiotas answer)

It is possible to write your own module if you have the necessary programming skills, see the API documentation here:

https://developer.gnome.org/gtk3/stable/GtkIMContext.html#GtkIMContext.description

I found a useful test tool to easily try out input methods:

https://github.com/ibus/ibus/files/1829333/window.py.txt

from gi import require_version as gi_require_version
gi_require_version('Gtk', '3.0')
gi_require_version('Gdk', '3.0')
from gi.repository import Gtk
from gi.repository import Gdk
import sys

label = None

def __entry_key_press_cb(entry, event):
    label.set_text('%s %x %x' % (Gdk.keyval_name(event.keyval), event.hardware_keycode, event.state))

Gtk.init(sys.argv)
window = Gtk.Window(type = Gtk.WindowType.TOPLEVEL)
window.connect('destroy', Gtk.main_quit)
box = Gtk.Box(orientation = Gtk.Orientation.VERTICAL, spacing = 0)
window.add(box)
entry = Gtk.Entry()
entry.connect('key-press-event', __entry_key_press_cb)
#box.pack_start(entry, False, False, 0)
box.add(entry)
label  = Gtk.Label(label = 'Press keys')
#box.pack_start(label, False, False, 0)
box.add(label)
window.show_all()
Gtk.main()

You can run it like this:

env GTK_IM_MODULE=gtk-im-context-simple python window.py

or

env GTK_IM_MODULE=xim python window.py

etc.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.