Tk Source Code

View Ticket
Login
Ticket UUID: 701d8f8953b503e14703a4a8a147795027e70b57
Title: <Alt-key> bindings and %K do not work with a non-Latin keyboard layout on X11
Type: Bug Version: 8.6, 9.0, main
Submitter: serhiy.storchaka Created on: 2026-09-17 16:18:05
Subsystem: 01. Bindings Assigned To: jan.nijtmans
Priority: 9 Immediate Severity: Important
Status: Closed Last Modified: 2026-10-20 18:11:28
Resolution: Fixed Closed By: jan.nijtmans
    Closed on: 2026-10-20 14:22:11
Description:
This is the X11 counterpart of [433261290b] (Windows), split out as suggested there. The scope on X11 is narrower, because libX11 already does part of the job.

The examples below use the physical key that carries both "Q" and "Й": with a Latin layout it produces `q`, with the Ukrainian layout it produces `й` (keysym `Cyrillic_shorti`).

With a non-Latin XKB layout active (for example `setxkbmap us,ua` with the second group selected):

1. `<Alt-q>` does not match Alt pressed together with that key: the event's keysym is `Cyrillic_shorti`, not `q`. This breaks all application `<Alt-...>` shortcuts. (`<Control-q>` *does* match Ctrl plus the same key, because `XLookupString()` in libX11 retries the first XKB group when Control is held and the keysym is not Latin — but only for Control, and only if the first group is Latin.)
2. With input methods off (`tk useinputmethods 0`), `%K`/`%N` of the plain key are `q`/113 although `%A` is `й`: `TkpGetKeySym()` in `unix/tkUnixKey.c` calls `XkbKeycodeToKeysym()` with group 0 hard-coded, ignoring the group bits of the event's state. So `bind . <Cyrillic_shorti> ...` never fires.
3. If the non-Latin layout is the *first* group (`setxkbmap ua,us`), Control shortcuts are broken as well, since neither libX11's fallback nor the group-0 lookup ever sees a Latin keysym.

Other X11 toolkits (GTK, Qt) handle this by falling back to the Latin keysym of the same key for keyboard shortcuts, so Ctrl/Alt shortcuts work regardless of the active layout; Tkinter/IDLE users hit this regularly.

Proposed fix (branch x11-nonlatin-shortcuts to follow): in `TkpGetKeySym()`, use the XKB group of the event for the keymap lookup (falling back to group 0 for keys that have no such group), and, when Control or Alt is down and the keysym is not Latin-1, take the first Latin-1 keysym of the key from any XKB group. `%A` is not affected and still gives the character of the current layout (`й`), so menu mnemonics, which match on `%A`, keep working with non-Latin labels — the same script-level behaviour as on Windows after [433261290b].

To reproduce on Linux:
```
setxkbmap -layout us,ua -option grp:alt_shift_toggle
wish
% bind . <Key> {puts "K=%K A=%A"}
% bind . <Alt-q> {puts "Alt-q matched"}
```
Switch to the Ukrainian group and press Alt and the Q/Й key: `K=Cyrillic_shorti A=й` is printed, but "Alt-q matched" is not. With the US group both lines appear. Then `tk useinputmethods 0` and press the key alone: `K=q A=й`.
User Comments: serhiy.storchaka added on 2026-10-20 11:01:36:

Thank you, Jan and Harald! Backported to core-8-6-branch in [7407bcb401]. Without XKB only the first group is used. event.test, bind.test and key.test pass on X11, also with setxkbmap us,ua.


jan.nijtmans added on 2026-10-20 10:29:18:

Many thanks. I agree this should be in Tk 9.0.5.

Merged to [8510c93f|trunk], core-9-0-branch.

Merge to 8.6 still to be done.


serhiy.storchaka added on 2026-10-20 08:50:57:

Thank you, Jan! event-8.3 failed because the Num Lock handling of keypad keys ([481308]) was lost in the merge of trunk ([d2a67f671f]): the branch moved this code to KeycodeToKeysym(). Restored in [9a51c48c4c], now using the XKB group of the event. event.test, bind.test and key.test pass on X11.

Could you raise the priority of this ticket? For users with a non-Latin keyboard layout (Cyrillic, Greek, Hebrew, Arabic, etc.) all Alt shortcuts in Tk applications are broken on X11, and with a non-Latin first layout Control shortcuts too. This is a very common complaint from Tkinter and IDLE users.


jan.nijtmans added on 2026-10-20 07:20:19:

I'm seeing this test failure on Linux:

==== event-8.3 keysym of a keypad key with Num Lock on X11 - bug 481308 FAILED
==== Contents of test case:

set t [toplevel .t] set e [entry $t.e] pack $e focus -force $e update bind $e <Key> {set keycode %k} event generate $e <Key> -keysym KP_Left bind $e <Key> {lappend res %K} # Num Lock is usually Mod2, but its modifier is not fixed. Exactly # one of Mod1..Mod5 must select the keypad digit, and Shift with it # must revert to the cursor key, as in XLookupString(). foreach mask {0x8 0x10 0x20 0x40 0x80} { set res {} event generate $e <Key> -keycode $keycode -state $mask event generate $e <Key> -keycode $keycode -state [expr {$mask | 1}] if {$res eq {KP_4 KP_Left}} { lappend numlock $mask } } llength $numlock

---- Result was: 0 ---- Result should have been (exact matching): 1 ==== event-8.3 FAILED

Change looks good to me, if this test failure is fixed.

See here for the CI build


serhiy.storchaka added on 2026-09-17 16:28:14:

Fixed on branch x11-nonlatin-shortcuts in b052917bd2, with test event-8.2.