Compose key does not always work
Summary
I have mapped Compose key to CapsLock physical key. Then, I have noticed the behavior of the Compose key is ignored half of the time.
Steps to reproduce
Map CapsLock to Compose using KDE System Settings > Input Devices > Keyboard > Advanced > Position of Compose Key > Caps Lock.
Open a KDE application (tested with konsole and kontact). Keep Compose pressed, then type '=', then 'c', then release Compose. Repeat several times. Euro symbol (€) should be typed, but sometime you get "=c".
Useful observations
The behavior is correct if user release Compose before typing '=' and 'c'.
If you install ibus, ibus feedback show that maintaining Compose press quickly start/abort the compose sequence. So, the issue is somewhere in the repetition code of the Compose key.
I know this behavior happens in KDE applications, GIMP and LibreOffice. However, Chrome has a different behavior (it works very well with ibus).
I have first reported this bug to libinput, however they say the issue is rather related to libxkbcommon.
Required information
$ dpkg -l libinput* libxkbcommon*
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-========================-============-============-=======================================================================
ii libinput-bin 1.22.1-1 amd64 input device management and event handling library - udev quirks
ii libinput-tools 1.22.1-1 amd64 input device management and event handling library - command line tools
ii libinput10:amd64 1.22.1-1 amd64 input device management and event handling library - shared library
ii libxkbcommon-tools 1.5.0-1 amd64 library interface to the XKB compiler - tools
ii libxkbcommon-x11-0:amd64 1.5.0-1 amd64 library to create keymaps with the XKB X11 protocol
ii libxkbcommon0:amd64 1.5.0-1 amd64 library interface to the XKB compiler - shared library
ii libxkbcommon0:i386 1.5.0-1 i386 library interface to the XKB compiler - shared library
$ cat .config/kxkbrc
[$Version]
update_info=kxkb_variants.upd:split-variants,kxkb.upd:remove-empty-lists,kxkb.upd:add-back-resetoptions
[Layout]
DisplayNames=us,
LayoutList=us,fr
LayoutLoopCount=-1
Model=pc101
Options=compose:caps
ResetOldOptions=true
ShowFlag=false
ShowLabel=true
ShowLayoutIndicator=true
ShowSingle=false
SwitchMode=Global
Use=true
VariantList=mac,
$ cat .config/kcminputrc
[$Version]
update_info=delete_cursor_old_default_size.upd:DeleteCursorOldDefaultSize,kcminputrc_fix_botched_5_21_0.upd:kcminputrc_fix_botched_5_21_0_pre,kcminputrc_fix_botched_5_21_0.upd:kcminputrc_fix_botched_5_21_0,kcminputrc_repeat.upd:kcminputrc_migrate_key_repeat
[Keyboard]
KeyboardRepeating=0
NumLock=2
RepeatDelay=140
RepeatRate=50
[Libinput][1160][4122][DELL0A36:00 0488:101A Touchpad]
ClickMethod=2
LmrTapButtonMap=true
TapToClick=true
[Libinput][1267][1842][ELAN25B6:00 04F3:0732]
OutputName=eDP-1
[Libinput][8146][45061][MELF0410:00 1FD2:B005]
Enabled=false
[Mouse]
X11LibInputXAccelProfileFlat=false
XLbInptPointerAcceleration=-0.4
cursorTheme=oxy-whitewater
[Tmp]
update_info=delete_cursor_old_default_size.upd:DeleteCursorOldDefaultSize
Note RepeatDelay=140 is a rather low value.
Just to be clear: are you using a specific Input Method (i.e. IBus), or is it just for debugging and you rely on default settings?
I have made my tests again with (note libibus is installed):
$ dpkg -l *ibus*
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-=======================-===========================-============-==========================================================================
un ibus-data <none> <none> (no description available)
ii libhidapi-libusb0:amd64 0.13.1-1 amd64 Multi-Platform library for communication with HID devices (libusb backend)
ii libibus-1.0-5:amd64 1.5.27-5 amd64 Intelligent Input Bus - shared library
un libusb-0.1-4 <none> <none> (no description available)
ii libusb-1.0-0:amd64 2:1.0.26-1 amd64 userspace USB programming library
ii libusb-1.0-0:i386 2:1.0.26-1 i386 userspace USB programming library
ii libusb-1.0-0-dev:amd64 2:1.0.26-1 amd64 userspace USB programming library development files
ii libusb-1.0-doc 2:1.0.26-1 all documentation for userspace USB programming
ii libusb3380-0:amd64 0.0.1+git20190125.c83d1e9-2 amd64 USB3380 abstraction layer for libusb
un libusbmuxd-tools <none> <none> (no description available)
ii libusbmuxd6:amd64 2.0.2-3 amd64 USB multiplexor daemon for iPhone and iPod Touch devices - library
un libusbredirparser1 <none> <none> (no description available)
ii libuser-identity-perl 1.01-1 all module to manage a person's identities/roles
It seems I made a few error during my first tests:
- konsole has the issue
- LibreOffice Writer has the issue
- gimp does not have the issue
- chrome does not have the issue (note Chrome is statically linked, difficult to know which libraries are really used)
Having ibus installed does not mean it is active. Do you have the IM env variables set? This is very important to know, as ibus does not use xkbcommon.
It seems Gtk handles Compose very differently than xkbcommon (and thus Qt and KDE apps):
- Gtk:
Multi_keyhas definitely a different handling than e.g.dead_acute. Try maintaining them to see what I mean: acute repeats whileMulti_keyseems not. And then typing a letter or a space after repeatingdead_acutehas also quite different results. - xkbcommon: repeating a key is feeding repetitively a new input to the state machine, so if you have e.g.
then the 1st time<Multi_key> <e> <e> : "ə" U0259Multi_keyrepeats, the state machine is reinitialized because there is no sequences starting by<Multi_key> <Multi_key>. After the 2nd repeat the state machine then expects<e>to continue. At the 3rd repeat, it reinitializes. Etc.
So I do not think this is a bug: Compose is not a modifier key, it is not expected to be held down.
Thank you for your feedback.
No, I don't export any IM variables (I did when I tested with ibus, but I reset my environment meanwhile).
On X11, the behavior of Multi_key was the one you describe in GTK (which I believe is the expected one):
- press
<Multi_key>,<e>,<e>, release<Multi_key>→ə - press
<Multi_key>, release<Multi_key>,<e>,<e>→ə - press
<Multi_key>, release<Multi_key>, press<Multi_key>, release<Multi_key>,<e>,<e>→ee - press
<Multi_key>, release<Multi_key>, press<Multi_key>,<e>,<e>, release<Multi_key>→ee
So, you're right this key is really specific. It is neither a modifier neither a normal key.
In fact on GTK/X11, Multi_key acts as a normal key, but repetition is ignored.
Do you to have the same issue when using Menu as Compose?
I don't have Menu on my keyboard. I tested with Left Win. The behavior is identical to CapsLock.
Thank you for your feedback.
No, I don't export any IM variables (I did when I tested with ibus, but I reset my environment meanwhile).
On X11, the behavior of
Multi_keywas the one you describe in GTK (which I believe is the expected one):* press `<Multi_key>`, `<e>`, `<e>`, release `<Multi_key>` → `ə` * press `<Multi_key>`, release `<Multi_key>`, `<e>`, `<e>` → `ə` * press `<Multi_key>`, release `<Multi_key>`, press `<Multi_key>`, release `<Multi_key>`, `<e>`, `<e>` → `ee` * press `<Multi_key>`, release `<Multi_key>`, press `<Multi_key>`, `<e>`, `<e>`, release `<Multi_key>` → `ee`So, you're right this key is really specific. It is neither a modifier neither a normal key.
It is the expected behavior for Gtk. The last two “do not work” because the sequence <Multi_key> <Multi_key> <e> <e> is not defined. If you add <Multi_key> <Multi_key> <e> <e> : "ə" U0259 you should have the same result than the first two examples. Could you confirm it?
So what we have here are implementation differences (Gtk/xkbcommon-Qt). As Compose key and Multi_key keysym are not modifiers, I do not think there is something to fix.
But I will try to have a look at the Gtk implementation, to check if this is a feature or an unintended side effect. If this is a feature, I would like to known the motivation.
In fact the only difference between GTK and xkbcommon is: press <Multi_key>, <e>, <e>, release <Multi_key>. On GTK and X11, you always get ə, while on xkbcommon-Qt, you sometime get ee (depending of the repeat delay/rate).
I did not dive into Gtk code, but the behavior seems simple enough to understand: when no valid sequence is found, Gtk does not reset its state machine. You can use <Multi_key> <Multi_key> : "!" exclam to get similar behavior than e.g. dead_acute.
If you want the same behavior in non-Gtk apps, you should open a ticket in e.g. Qt repository and point to this issue.
@whot @bluetech I think we would still need a new API for that though: something like:
// Option 1: new function with configurable behavior, using an additional argument
enum xkb_compose_feed_result
xkb_compose_state_feed2(struct xkb_compose_state *state, xkb_keysym_t keysym, bool reset)
// Option 2: new function that keep previous state in case of failure
enum xkb_compose_feed_result
xkb_compose_state_feed_no_reset(struct xkb_compose_state *state, xkb_keysym_t keysym)