Hacker News new | ask | show | jobs
by PureParadigm 1892 days ago
It's not just international keyboards that are affected by this. I'm a Dvorak user so I run into these issues from time to time.

As the article explains, there is a difference between the physical keyCode and character it corresponds to. Which to use really depends on what it is being used for, and there are situations for both. The article suggests checking the character typed, but this is not always the correct way to do it.

For instance, the most annoying are games which default to WASD based on the letter typed and not the physical keys (I've seen this both in web app and native games). Using WASD based on letters simply does not make sense because the whole purpose is to mimic arrow keys. If you base it off of letters typed, then on Dvorak it's like if you used ,A;H on Qwerty which makes absolutely no sense for directional navigation.

For shortcuts where the letter has a meaning, then you might want to look at the actual character. But beware that even alphanumeric keys are not always in the same place because of layouts such as Dvorak and Colemak.

6 comments

No, `keyCode` can also change with layout. Since you mentioned WASD, ‘W’ on a US layout has `keyCode` 87. Select a French layout, and the same physical key now has `keyCode` 90.

If you're using `keyCode` for anything, you're doing it wrong. There's a reason it's marked ‘legacy’.

Physical key position is the UI Event ‘code’, which is in this example will be "KeyW" regardless of layout. This field is essentially 1:1 with hardware HID codes (as used by USB and Bluetooth keyboards).

I've used dvorak and now workman and I don't mind the shortcuts moving around.

The biggest annoyance for me is if you want to sometimes use hardware-level dvorak or another layout (which expects software-level qwerty) and sometimes use it in software. Like, if your keyboard runs QMK but you use it with a laptop and might want to use the laptop's built-in keyboard if you take it on the go.

GTK also has some weird issues if you have multiple layouts enabled where the shortcuts are in the wrong place and don't all work (happens in Dino and Gedit). So, I now have only qwerty enabled in Sway and I'll just edit the config if I ever need to change virtual layouts instead of doing it with a couple keypresses.

Does windows a way to simultaneously use different layouts for different connected devices? It's really annoying shifting between my Japanese USB keyboard and English laptop. In Ubuntu I had startup script to detect input devices IDs by name and force different layouts, but even that was a bit of a hack.
Judging by the comments here, looks like we’re globally a rare breed that want absolute priority for keytop labeling over software configuration items.
Another Dvorak typist here! Personal funny anecdote: I learned vim modal navigation after I learned Dvorak, and never bothered to remap the keys. Totally debilitating if I'm using a coworkers QWERTY keyboard for vim navigation, but at least I can still navigate on remote servers without reconfiguring anything!
> For instance, the most annoying are games which default to WASD based on the letter typed and not the physical keys

Is it even possible to do anything else? I can’t imagine keyboards report their physical layout..

Physical layout is mostly irrelevant, different keycap label arrangements use the same keycodes - the input system in your OS or application uses a keyboard layout to translate those into what you want to type.

Windows, macOS and the various input libraries on Linux provide ways to query the key map - and a number of games do use this to provide localized bindings (Ubisoft and Blizzard are notorious for doing this right, something I appreciate as a dvorak user who hates dealing with rebinding or constantly having to toggle layouts). As far as the browser there is coming support for reading the keyboard layout as well: https://developer.mozilla.org/en-US/docs/Web/API/Keyboard/ge...

Normally, keyboards report data to the computer which represents the location of a key on a standard keyboard. The OS translates to characters based on configured layout. The actual letters printed on the key caps are just decorative.

If you type WASD on a US layout USB keyboard, the computer will receive key codes 26, 4, 22, 7.

If you type ZQSD on a French keyboard you get exactly the same result.

So if you are writing a game, you might listen for codes 26, 4, 22, 7 and these will be in the sample place on the keyboard regardless of layout. You can ask the OS to translate these codes to letters for help text.

(Some of the details here are omitted—the codes above are USB HID codes, but those go through an additional OS-specific translation table before they are sent to your program.)

The only possibility is to allow the user to assign custom keys, which is pretty common.

It’s impossible to know the physical layout for absolute certainty. For all you know, my “Enter” could be a pedal under the desk.

In X11 with the Xkb extension you can configure simplified vector drawings of your input devices, which any application can query. It is intended that applications use these drawings in their help systems and tutorials, as well as in their key binding editors. Few applications bother though.

https://www.x.org/releases/current/doc/libX11/XKB/xkblib.htm...

Starcraft II had a grid (I don't remember the actual name) mode keyboard layout that worked perfectly with Dvorak without having to remap keys.

Other games like the Java version of minecraft didn't work with Dvorak when I tried them. Even with key remapping.

Scancodes from PS/2 keyboards are layout-based.
A few games map based on the key codes. For example, SC2 will get grid layout right on Dvorak or Colemak without any remapping. It did take me directly emailing a designer, who passed it on to the developers, though. ;)
Yes, the UI Events ‘code’ field represents the physical key (essentially 1:1 with USB hardware codes). The key that's labelled ‘W’ on a US keyboard and ‘Z’ on a French keyboard and ‘Ц’ on a Russian keyboard and ‘て’ on a Japanese keyboard (and so on) will have code=="KeyW" in all cases.
> Is it even possible to do anything else? I can’t imagine keyboards report their physical layout..

You can easily ask the OS what layout is being used or even ask the user.

Is there a programmatic way to figure out what letter corresponds to a given keycode without that key being pressed? Because you may have to display that info somewhere to give an indication what the user has to press.
Yes. You have to dig a bit to find these APIs, and they are OS-specific (and the scan codes reported by the OS are OS-specific too, even though most keyboards are USB HID these days).

Here is the function for macOS:

https://developer.apple.com/documentation/coreservices/13905...

Not that I know of.

Also, not that “alt-s” will produce an s character on a US keyboard on windows, but will not produce an s on MacOS with a US layout - alt-anything will produce all sorts of interesting characters on MacOS.

There are APIs available on all major OSs that do this. Example:

https://developer.apple.com/documentation/coreservices/13905...

My memory is that if you press option E on a Mac, the translation function reports a non-zero state but no character output. You can detect this and call the translation function again with a space to get the diacritic by itself.

OS X's solution works perfectly: Dvorak + QWERTY shortcuts layout. It's brilliant and elegant, Windows needs to implement the same thing (revert to QWERTY when holding the ctrl or windows keys).