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?

csha
  • 447
  • 2
  • 6
  • 25

2 Answers2

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.

xiota
  • 5,038
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.