Handling keyboard shortcuts on non-Latin alphabet layouts

Suppose you build a desktop app and add keyboard shortcuts such as Ctrl+S to save the document. It’s pretty straightforward to wire it for keyboard layouts that are based on the Latin script. How would you go about handling keyboard shortcuts on non-Latin layouts such as Cyrillic or Greek?

Languages that do not use Latin script are actively used by over 4 billion people. Even if we exclude Chinese which is mostly typed on QWERTY, that still makes it as much as 2.5 billion people and makes a significant chunk of the world population…

And a significant percentage of users that may struggle with your app’s keyboard shortcuts if you were to apply the generic advice you could find on StackOverflow or answered by ChatGPT to just check the KeyboardEvent.key and upper case it.

Countries whose official language does not use Latin script
Countries whose official language does not use Latin script
By User:Quintucket, based on work by User:Canuckguy and others. – Own work based on: Writing systems worldwide.png, BlankMap-World6.svg and Blank Map World Secondary Political Divisions.svg, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=29145034

How do those layouts allow the user to input Latin characters? They have 2 sets of characters printed on each key. They are basically the standard US QWERTY layout that has the native alphabet characters printed on it in addition and a mode to switch between them. That is usually facilitated by pressing Caps Lock key.

A laptop with a Ukrainian keyboard layout
A laptop with a Ukrainian keyboard layout

Taking a look at the keyboard input API in JavaScript to get a solution

Note that while the article is about JavaScript, it may also be relevant to other languages / environments.

When it comes to JavaScript, there are 2 properties of the KeyboardEvent that are of interest – key and code. key is the actual key being input – dependent on the layout and something that would be very useful for a text editor implementation. code is the fixed code of the key on the keyboard that’s layout-independent.

Layout Character code key*
QWERTY Q KeyQ q
QWERTY W KeyW w
QWERTY 1 Digit1 1
AZERTY Q KeyQ a
AZERTY W KeyQ z
Dvorak KeyQ
Dvorak , KeyW ,
Greek Q / ; KeyQ ;
Greek W / ฯ‚ KeyW ฯ‚
Greek E / ฮต KeyE ฮต
key and code on different keyboard layouts. (* key is case sensitive. When pressed with Shift or Caps Lock on, the value will be uppercase.)

As you can see code is a constant independent of the layout. Therefore, it would make sense to use it instead of key for non-Latin keyboard layouts since it does not require the user to switch to Latin mode just to hit the keyboard shortcut…

However, that would break Dvorak, QWERTZ, AZERTY or any other non QWERTY layout. For those we would rather be using key.

So the proper solution would be to use both. Use key if it’s a Latin alphabet key or a symbol and if key is non-Latin (char code greater than / equal 880) – use code.

The full spec and implementation for getting the shortcut key on all layouts:

The full spec for handling keyboard shortcuts on all layouts, including non-Latin ones is as follows:

  • Detect if the key is a Latin alphabet character (its char code must be lower than 880). If it is, return the key in upper case.
  • Check if the code starts with "Key" and is exactly 4 characters in length – return the last character (i.e. "W" from "KeyW")
  • Check if the code starts with "Digit" and is exactly 6 characters in length – return the digit
  • Otherwise return the key in upper case

Limitations:

  • This does not consider custom layouts such as using Dvorak instead of QWERTY for Latin-mode on a non-Latin layout. In that case the shortcut would be mapped per QWERTY while the user uses something different for Latin alphabet input.
  • Some non-Latin layouts (i.e. Greek) have a symbol on "KeyQ". That makes it impossible to distinguish it from Dvorak layout or any custom Latin layout without full layout detection. KeyQ would not work for those.

Of course, you do not need to implement it yourself ๐Ÿ™‚ This feature is available in Shocut keyboard shortcuts library. You can see the implementation of the shortcut key retrieving function here.

I have also prepared a demo that outputs key, code and the “shortcut key” for every character typed. If you are a Mac user, you can easily switch keyboard layout in System Preferences -> Keyboard -> Input Sources to test it out.

By the way, avoid Alt for keyboard combinations as it’s used to generate extended Latin characters. I.e. Alt+s = ล› on a Polish keyboard, the event will have ล› as the key and event.altKey will be false.