X keyboard layout (Dvorak) being treated incorrectly

Questions about Wine on Linux
Locked
julianjames7
Newbie
Newbie
Posts: 1
Joined: Sat Jun 15, 2019 11:52 pm

X keyboard layout (Dvorak) being treated incorrectly

Post by julianjames7 »

I've noticed several issues with my keyboard layout when running Windows games through Wine or Proton. I use Dvorak, and have my system (Gnome Shell using Xorg on Arch) set up to be able to switch between US Dvorak and US Qwerty on the fly, with Dvorak as the default.

Firstly, Wine seems to ignore the currently-selected keyboard layout, and always uses the default keyboard layout instead. In my case, even if I use the hotkeys in either Gnome Shell or Xorg itself to swap layouts, it always uses Dvorak, even if I switch before launching the program. I need to replace Dvorak with Qwerty as the default in order to use Qwerty at all with Wine.

The following issues relate directly to the keyboard layout detection in winex11drv. I don't claim to understand why Wine needs to pick one out of a small set of layouts in order to map keysyms to scancodes instead of either passing on both directly or using the detected layout used in the comparison function as the keyboard layout itself. Since Windows supports over 200 layouts and Xorg supports over 550, it seems strange to rely on a small hard-coded list of layouts. However, given that this is how Wine currently functions, I have noticed several issues with its keyboard layout detection.

Wine consistently fails to detect the correct keyboard layout on my system as Dvorak, instead treating it as "United States keyboard layout (phantom key version)". It seems that my X keyboard layout includes the "phantom key" at 0x5E = 94 corresponding to the characters '<>|¦' (as well as three others; '±±' at 126, '((' at 187, and '))' at 188), and so despite the "seq" variable being lower with the Qwerty layouts than with Dvorak, the single extra match means Wine assumes that I'm using the phantom key version of the Qwerty layout. The simplest fix would be to add a "phantom key" version of Dvorak to the list of known layouts. Since Qwerty and modern Dvorak have identical keys, just in different positions, their comparison scores will always be identical. It seems strange to rely on their relative positions only indirectly, through the "seq" variable, given that that ordering is the key difference between Qwerty and Dvorak, as well as layouts like Colemak (which Wine doesn't seem to support at all.) Perhaps an alternative solution could involve replacing the current matching algorithm with one that takes key positions into account directly. Indeed, I was able to get the detection to work for my case by replacing the matching score with a function to determine the length of the longest common subsequence between the detected and comparison layouts.

Additionally, the scancodes for Dvorak are incorrect. I, and as far as I am aware the majority of Dvorak users, use a standard Qwerty physical keyboard, only changing the layout in software. When playing a video game, the controls most often depend not on the keysym, but on the scancode. Thus, when a game uses, say, W A S D to move around, in Dvorak the , A O E keys in the same position are used. The scancodes for Dvorak used in winex11drv's keyboard.c are the same scancodes as the Qwerty keys of the same letter, not the correct scancodes for those positions on the keyboard. This means that playing any video games through Wine using Dvorak will require key remapping to be playable at all, even if playing them on Windows using Dvorak works perfectly. The fix for this is very simple; just replace the reference to &main_key_scan_dvorak in dlls/winex11drv/keyboard.c with &main_key_scan_qwerty.
Locked