Behind The Scenes: International Keyboard Shortcuts

Node.js Libraries
Top 10 Node.js Libraries to Optimize Your Code and Simplify Development
5th April 2023
Configure ESLint, Prettier, and Flow in VS Code for React Development
14th April 2023
Show all

Behind The Scenes: International Keyboard Shortcuts

I didn’t know much about keyboards going into this project. As a software engineer on Figma’s Editor Usability team, my day-to-day typically focuses on the design editor experience. Turns out, keyboard shortcuts are a big part of that. These preset key combinations are essential for efficient, intuitive workflows and have a host of accessibility benefits—such as making it easier to access menus and functions. Yet Figma’s many shortcuts were originally designed based on US keyboards, which meant that they didn’t work for many other types of keyboards.

Our team began seeing a steady stream of shortcut-related bug reports as users encountered instructions in Figma like “press ⌘ + \ to toggle the UI”—despite their keyboards not having a \ (backslash) key—or barring folks from cursor chat conversations because it was impossible for them to press / (forward slash) to initiate messages. Figma users are passionate about their workflows and, in turn, their keyboard shortcuts. We wanted to make sure that everyone, everywhere, could access the same keyboard efficiencies. We brought together a cross-functional team to begin working on making Figma shortcuts friendlier to international keyboards, a charter that would take us on a twisty journey through the next year.

A Quick Overview Of Keyboard Shortcuts

When you press any key, the browser sends Figma standard KeyboardEvents with information about which key was pressed. Our first step after receiving a KeyboardEvent is to translate it into something that our editor can interpret. Separately, we specify possible keyboard shortcuts and the actions they trigger in a JSON file. These actions vary based on whether the shortcuts themselves are enabled or disabled, which depends on user and product state, aspects like preferences, which product they’re in, the operating system (OS), and more. Once we receive a user’s key press, we run it against that list of possible shortcuts. If there is a match, we execute the associated action (and if not, nothing happens). Et voila ✨ A frame is pasted, the UI is toggled, and a cursor chat bubble appears.

Easy Fix? Not So fast

At face value, it would seem that all we needed to do was add some new shortcut definitions to the JSON file. If a user has a Swedish keyboard, give them the mapping Meta + Ä for “Bring forward” instead of ⌘ + ]. If a user has a Korean keyboard, give them the mapping  for “Toggle UI” instead of ⌘ + \.

This is where the rabbit hole starts. 🐇🕳

On a German keyboard, the shortcut for “Decrease text weight” is Meta + Alt + ß. Seems straightforward enough, yet this particular keyboard shortcut did not work when plugged into our keyboard shortcuts JSON. It turned out that when we tried to normalize shortcuts by capitalizing them, we saw that "ß".toUpperCase() becomes SS, causing unexpected behaviour when transforming a single key character ß into two SS. Most unintuitively, that means "ß".toUpperCase().toLowerCase() does not give us ß, the original character.

Beware! We worked around this by using the new uppercase Eszett character, , which thankfully remains the same when upper-cased.

Choosing Keyboard Layouts

With an overwhelming number of possible keyboard layouts, we wanted to start by supporting shortcuts for keyboard layouts that our users most commonly use. Gathering this information was easier via the desktop app, where we are able to detect the OS keyboard setting. However, on browsers, the best we could do was make guesses based on heuristics involving the experimental Keyboard API, which has its own limitations. Here’s how our heuristics work: This API tells us the character associated with each positional key code for the current user, which we then map to known keyboard layouts. For example, we might get data that the keyboard’s Quote code has the ä character, and, in combination with other such mappings, we can extrapolate that perhaps the user has a Swedish keyboard.

With keyboard detection logging in place, we saw over 2.5k distinct layouts used on Figma within 30 days! I didn’t even know this many keyboard layouts existed, and it turns out that there have always been thousands of keyboard layouts. Marcin introduced us to these century-old Remington Typewriter layouts for Domestic, Swiss-Standard, and Swedish. Put a pin in this detail, because the struggle of keyboard detection comes back later.

Combining our detection data with forum feedback posts, we narrowed down our initial work to a (not so short) shortlist of standard keyboards: German, French AZERTY, Japanese, British, Swedish, Finnish, Danish, Norwegian, Italian, Spanish, Spanish LATAM, Chinese, Portuguese, and Korean.

Designing New Shortcuts

With keyboards identified, the next step was auditing which keyboard shortcuts were problematic, either due to missing keys, physical inaccessibility, or conflicts with other shortcuts. Almost all of these shortcuts involved symbol characters (as opposed to Roman letters), which cut down the number of shortcuts to investigate.

As a graphic tool and a text editor that exists within the realm of a browser (which also exists within an operating system)—Figma inherits all the shortcuts from each of these spaces, many of which are already in conflict with each other. Keeping a holistic view of where Figma fits within these various ecosystems is important when developing shortcuts that will impact a user’s workflow. For example, we want to maintain motor memory that users may already have from other tools, aligning our shortcuts to similar actions (say, copy, paste, zoom). At the same time, we need to avoid duplicate shortcut conflicts not only between existing Figma shortcuts but also between shortcuts defined by the OS or other major desktop applications.

Related Blog: https://xpertlab.com/what-is-unity-get-started-with-game-development-using-unity/