Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should we recommend compose state to be global, per-seat, per-device? #254

Open
crater2150 opened this issue Jul 12, 2021 · 11 comments
Open
Labels
compose Indicates a need for improvements or additions to Compose handling question Indicates that an issue, pull request, or discussion needs more information

Comments

@crater2150
Copy link

Hi,
I filed a bug against kitty today, because my user XCompose was ignored (see kovidgoyal/kitty#3827). According to its developer, this is an issue with libxkbcommon and should be filed here.

Since reporting the bug there, I ran an strace to see if the file is read and just now noticed, that it actually reads ~/.config/XCompose instead of ~/.XCompose (the latter being a symlink to the former on my system), which means that it didn't use my minimal version in the previous test, so I tried again replacing the correct file. The results are mostly the same, except that
the system locale's compose was also not loaded until adding include "%L".

The sample configuration that I used is a ~/.config/XCompose with just a single line:

<Multi_key> <asterisk> <a>      : "α"  U03B1       # GREEK SMALL LETTER ALPHA

When typing Compose, * in kitty, a * will be inserted immediately, pressing a afterwards will also just insert it instead of producing α. When adding include "%L" before or after that line, system compose sequences will work as expected, but inserting α still won't.

The same XCompose file works in other applications (e.g. Qt-based apps, GTK-based apps if exporting GTK_IM_MODULE=xim).

Please let me know, if there is other debug information I can provide.

@bluetech
Copy link
Member

The following should work:

include "%L"
<Multi_key> <asterisk> <a>      : "α"  U03B1       # GREEK SMALL LETTER ALPHA

In XCompose, when there's an exact conflict, the latter wins. I just tested it and it works for me. If it indeed doesn't work for you, please run the following command in your terminal, try to insert the sequence (I configured right Alt to be the Compose key), and paste the output.

XKB_LOG_LEVEL=debug sudo -E xkbcli interactive-evdev --enable-compose --options compose:ralt

@crater2150
Copy link
Author

The config you posted was already one of the variants I tried, sadly it doesn't work.

My keyboard doesn't have a right alt, so I used the above command, but with compose:102 as with my normal layout. The output:

% XKB_LOG_LEVEL=debug sudo -E xkbcli interactive-evdev --enable-compose --options compose:102
xkbcommon: DEBUG: Include path failed: /home/crater2150/.config/xkb (No such file or directory)
xkbcommon: DEBUG: Include path failed: /home/crater2150/.xkb (No such file or directory)
xkbcommon: DEBUG: Include path failed: /etc/xkb (No such file or directory)
xkbcommon: DEBUG: Include path added: /usr/share/X11/xkb
xkbcommon: DEBUG: Compiling from RMLVO: rules 'evdev', model 'pc105', layout 'us', variant '(null)', options 'compose:102'
xkbcommon: DEBUG: Compiling from KcCGST: keycodes 'evdev+aliases(qwerty)', types 'complete', compat 'complete', symbols 'pc+us+inet(evdev)+compose(102)'
xkbcommon: DEBUG: Compiling xkb_keycodes "(unnamed)"
xkbcommon: DEBUG: Compiling xkb_types "(unnamed)"
xkbcommon: DEBUG: Compiling xkb_compatibility "(unnamed)"
xkbcommon: DEBUG: The "group" statement in compat is unsupported; Ignored
xkbcommon: DEBUG: The "group" statement in compat is unsupported; Ignored
xkbcommon: DEBUG: The "group" statement in compat is unsupported; Ignored
xkbcommon: DEBUG: The "allowExplicit" field in indicator statements is unsupported; Ignored
xkbcommon: DEBUG: The "allowExplicit" field in indicator statements is unsupported; Ignored
xkbcommon: DEBUG: The "allowExplicit" field in indicator statements is unsupported; Ignored
xkbcommon: DEBUG: The "allowExplicit" field in indicator statements is unsupported; Ignored
xkbcommon: DEBUG: The "indicatorDrivesKeyboard" field in indicator statements is unsupported; Ignored
xkbcommon: DEBUG: The "allowExplicit" field in indicator statements is unsupported; Ignored
xkbcommon: DEBUG: Indicator name "Shift Lock" was not declared in the keycodes section; Adding new indicator
xkbcommon: DEBUG: Indicator name "Group 2" was not declared in the keycodes section; Adding new indicator
xkbcommon: DEBUG: Indicator name "Mouse Keys" was not declared in the keycodes section; Adding new indicator
xkbcommon: DEBUG: Compiling xkb_symbols "(unnamed)"
xkbcommon: WARNING: /usr/share/X11/locale/en_US.UTF-8/Compose:5089:46: this compose sequence is a duplicate of another; skipping line
xkbcommon: WARNING: /usr/share/X11/locale/en_US.UTF-8/Compose:5091:48: this compose sequence is a duplicate of another; skipping line
xkbcommon: WARNING: /usr/share/X11/locale/en_US.UTF-8/Compose:5093:48: this compose sequence is a duplicate of another; skipping line
xkbcommon: WARNING: /usr/share/X11/locale/en_US.UTF-8/Compose:5097:47: this compose sequence is a duplicate of another; skipping line
xkbcommon: WARNING: /usr/share/X11/locale/en_US.UTF-8/Compose:5099:46: this compose sequence is a duplicate of another; skipping line
xkbcommon: WARNING: /usr/share/X11/locale/en_US.UTF-8/Compose:5107:48: this compose sequence is a duplicate of another; skipping line
xkbcommon: WARNING: /usr/share/X11/locale/en_US.UTF-8/Compose:5111:46: this compose sequence is a duplicate of another; skipping line
xkbcommon: WARNING: /usr/share/X11/locale/en_US.UTF-8/Compose:5113:46: this compose sequence is a duplicate of another; skipping line
xkbcommon: WARNING: /usr/share/X11/locale/en_US.UTF-8/Compose:5117:45: this compose sequence is a duplicate of another; skipping line
xkbcommon: WARNING: /usr/share/X11/locale/en_US.UTF-8/Compose:5120:46: this compose sequence is a duplicate of another; skipping line
xkbcommon: WARNING: /home/crater2150/.config/XCompose:2:41: this compose sequence already exists; overriding
xkbcommon: DEBUG: created compose table from locale en_US.UTF-8 with path /home/crater2150/.config/XCompose
keysyms [ 8                ] unicode [ 8 ] layout [ English (US) (0) ] level [ 0 ] mods [ ] leds [ ] 
keysyms [ aring            ] unicode [ å ] layout [ English (US) (0) ] level [ 0 ] mods [ ] leds [ ]

When pressing the compose key, there is no output. The line with keysym 8 appears when pressing * (Shift + 8), while the one with å appears after pressing a twice. There is no output on the first key press.

I ran the program in kitty and in xterm with the same results, if this makes any difference.

@bluetech
Copy link
Member

I can't reproduce this, so something must be going on here.

xkbcommon: WARNING: /home/crater2150/.config/XCompose:2:41: this compose sequence already exists; overriding

This looks good.

When pressing the compose key, there is no output.

This too.

The line with keysym 8 appears when pressing * (Shift + 8)

That should not happen.

Which libxkbcommon version is this?

Can you think of anything else unusual?

@crater2150
Copy link
Author

My system uses libxkbcommon 1.3.0 (Void Linux). But I think I may have found the issue, and it probably is indeed my unusual hardware setup. I have a split keyboard, and both halfes are connected via separate USB cables, so they are seen as two separate keyboards. With normal X input, like e.g. Xterm, compose works across those halfs, but it seems with libxkbcommon-based input it doesn't.

My Compose key and a are on the left keyboard, while 8/* is on the right one. I added another entry with <exclam> (left half) instead of <asterisk>, and it works, which confirms my suspicion.

@bluetech
Copy link
Member

bluetech commented Jul 13, 2021

Huh that's interesting. This is beyond the scope of libxkbcommon itself -- the library user decides how the keyboard devices map to xkb_state and xkb_compose_state objects.

It's interesting that you say that in X the compose state is not per-device but global. I'll need to refresh my memory on how it (X input methods) really works there, and we might amend our recommendations accordingly.

@bluetech bluetech changed the title User XCompose file ignored Should we recommend compose state to be global, per-seat, per-device? Jul 13, 2021
@bluetech
Copy link
Member

(I've edited the title to the new question)

@fooishbar
Copy link
Member

Most X11 clients will receive a unified stream of key events (as well as unified keymap) through a single master device, usually the Virtual core keyboard. So this might be a GLFW bug for not doing that.

@crater2150
Copy link
Author

So this might be a GLFW bug for not doing that.

The behaviour and output of xkbcli I described above is the same in xterm and in urxvt, AFAIK both of them don't use GLFW.

Another thing, which might be relevant to this issue: modifier keys (Ctrl, Shift, etc.) do work across keyboards without problem.

@bluetech
Copy link
Member

@crater2150 Are you using kitty under X or Wayland?

If X, can you show the output of xinput?

If Wayland, which compositor?

And for both, can you show the output of sudo libinput list-devices?

The behaviour and output of xkbcli I described above is the same in xterm and in urxvt, AFAIK both of them don't use GLFW.

That's right, xkbcli interactive-evdev currently creates a compose state per device. This is probably the wrong thing to do.

Another thing, which might be relevant to this issue: modifier keys (Ctrl, Shift, etc.) do work across keyboards without problem.

Hmm I know some compositors like sway have the concept of a "keyboard group" to allow multiple devices to use the same keymap/state/repeat info etc. But I'm not sure how prevalent this is.

@crater2150
Copy link
Author

@bluetech I'm using X.
Output of xinput:

⎡ Virtual core pointer                    	id=2	[master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer              	id=4	[slave  pointer  (2)]
⎜   ↳ UGTABLET 13.3 inch PenDisplay Mouse     	id=9	[slave  pointer  (2)]
⎜   ↳ ROCCAT ROCCAT Nyth Consumer Control     	id=14	[slave  pointer  (2)]
⎜   ↳ ROCCAT ROCCAT Nyth Mouse                	id=16	[slave  pointer  (2)]
⎜   ↳ Valve Software Steam Controller         	id=18	[slave  pointer  (2)]
⎣ Virtual core keyboard                   	id=3	[master keyboard (2)]
    ↳ Virtual core XTEST keyboard             	id=5	[slave  keyboard (3)]
    ↳ Power Button                            	id=6	[slave  keyboard (3)]
    ↳ Power Button                            	id=7	[slave  keyboard (3)]
    ↳ UGTABLET 13.3 inch PenDisplay Keyboard  	id=10	[slave  keyboard (3)]
    ↳ UGTABLET 13.3 inch PenDisplay           	id=11	[slave  keyboard (3)]
    ↳ bareminimum bareminimum keys            	id=12	[slave  keyboard (3)]
    ↳ bareminimum bareminimum keys            	id=13	[slave  keyboard (3)]
    ↳ ROCCAT ROCCAT Nyth System Control       	id=15	[slave  keyboard (3)]
    ↳ ROCCAT ROCCAT Nyth                      	id=17	[slave  keyboard (3)]
    ↳ ROCCAT ROCCAT Nyth Consumer Control     	id=19	[slave  keyboard (3)]
    ↳ Valve Software Steam Controller         	id=20	[slave  keyboard (3)]

The split keyboard is the bareminimum bareminimum keys, id 12 and 13.

Output of sudo libinput list-devices for relevant devices (full output. Group is different for other devices):

Device:           bareminimum bareminimum keys
Kernel:           /dev/input/event6
Group:            4
Seat:             seat0, default
Capabilities:     keyboard 
Tap-to-click:     n/a
Tap-and-drag:     n/a
Tap drag lock:    n/a
Left-handed:      n/a
Nat.scrolling:    n/a
Middle emulation: n/a
Calibration:      n/a
Scroll methods:   none
Click methods:    none
Disable-w-typing: n/a
Accel profiles:   n/a
Rotation:         n/a

Device:           bareminimum bareminimum keys
Kernel:           /dev/input/event7
Group:            4
Seat:             seat0, default
Capabilities:     keyboard 
Tap-to-click:     n/a
Tap-and-drag:     n/a
Tap drag lock:    n/a
Left-handed:      n/a
Nat.scrolling:    n/a
Middle emulation: n/a
Calibration:      n/a
Scroll methods:   none
Click methods:    none
Disable-w-typing: n/a
Accel profiles:   n/a
Rotation:         n/a

@whot
Copy link
Contributor

whot commented Jul 14, 2021

That's right, xkbcli interactive-evdev currently creates a compose state per device. This is probably the wrong thing to do.

unless you want to have to deal with seats and device groups etc. I'd argue it's the best thing to do for a debugging tool.

Hmm I know some compositors like sway have the concept of a "keyboard group" to allow multiple devices to use the same keymap/state/repeat info etc. But I'm not sure how prevalent this is

From the libinput side which all compositors use: libinput_event_keyboard_get_seat_key_count() returns the number of times the given key is down for all devices attached to the seat. So two keyboards on the same seat (e.g. laptop + USB), you press space on both, you get a count of 1, then 2 for the events. Compositors usually only toggle actions on the transition between 0 and 1, all other events have no effect on state.

It's interesting that you say that in X the compose state is not per-device but global.

X didn't have a per device-state until XI came along and that wasn't used for keyboards until XI2. Anything handling XI2 would probably handle compose per master device but since there's only one in 99.99% of all case, it's effectively a single global state :)

@wismill wismill added question Indicates that an issue, pull request, or discussion needs more information compose Indicates a need for improvements or additions to Compose handling labels May 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compose Indicates a need for improvements or additions to Compose handling question Indicates that an issue, pull request, or discussion needs more information
Projects
None yet
Development

No branches or pull requests

5 participants