pcb-rnd knowledge pool


Fine tuning for non-english keyboard layout

key_non_us by Tibor 'Igor2' Palinkas on 2020-08-15

Tags: howto, keyboard, layout, hotkey, preferences, menu, config

node source



Abstract: By design, pcb-rnd speaks English and assumes an English keyboard layout. For most of the default key assignment using another layout doesn't make any difference but there are a few special cases. This article explains how those special cases arise and how to fix them on non-english keyboard layout.


librnd/hidlib hotkey handling

Long ago, before version 2.0.0, with the old menu file the default keys were heavily based on modifiers (as inherited from our ancestor project). Before they started to run out of available keys, the old policy used modifiers in a predictable way, e.g. "s increases the size of an object, shift+s decreases the size of an object".

In this setup the code is interested in the key combination pressed, not in the character that would be input by that combination. That is, the code is interested in shift+s, not S, or (assuming US keyboard) shift+3, not #. This is the most common way of describing key combinations in the menu file (as "<Key>s" and "Shift<Key>s" and "<Key>3" and "Shift<Key>3" in the above example). This (mostly) works for the basic alphanumeric keys, enter, F-keys, arrow keys, space, tab. This description uses the raw key code acquired by the system, before any locale/layout translation.

This, however, doesn't work reliably for punctuation keys, such as "|" or ",". Thus pcb-rnd introduced a second description: "<char>|" matches on a key press whose locale/layout translated character is |, that is "the combination would result in typing a | in an input field". Such description should not use modifiers, as on some layouts the user has to press modifiers to get the desired translated character.

Note: this all affects only hotkey handling and does not affect any text input field. Librnd takes over hotkey processing from the GUI toolkit lib (such as gtk), but leaves input text editing at the toolkit.

Special cases of failure

On some layouts this system may fail. For example the Hungarian layout swaps y and z. The problem is that the raw <key> is always before any locale/layout translation, so y and z are not really swapped on this level. We could just use <char> instead of <key> "for these cases", but that would have three disadvantages:

The solution: config level

The solution is an inelegant workaround: a config node with a list of "as pressed" -> "as interpreted" key description translations, in the config node editor/translate_key . The code uses this table to translate key descriptions as the very first step of processing after getting the key from the GUI HID. The table is searched linearly from top to bottom and only the first match is applied to the key press.

For example the following two translation table lines in user config swaps z and y:

ha:editor {
 li:translate_key {
  <key>y = <key>z
  <key>z = <key>y

Configuring using the GUI

The preferences dialog (invoked from file menu or using hotkey {i c p}) presents the table and offers a GUI mechanism for editing it, via the "remove" and "add new..." button.

screenshot: key tab of the preferences dialog

The first button removes the currently selected row of the table. The second pops up a new modal dialog for creating a new keyboard translation entry:

screenshot: add key dialog

Both text fields are in the above described key description format. The input side can be auto-filled using the empty framed area on the top right and pressing the key.

When to use, when not to use it

If a specific hotkey is not to your liking, consider menu patching to change the hotkey of that one menu entry. An unreachable or hard-to-type character (on your layout), like "|" for wireframe draw falls in this category. Most often these menus with have a <char> kind of key description. Pros: easy to do, can bind to any character or key sequence, won't affect any other keys. Cons: when the documentation or other users say "press |", it won't work on your modified system.

If a key used often in different combinations have the same meaning on your layout but is physically located elsewhere, e.g. two keys swapped, it's best to use this feature to apply the layout change once and make it work for any key sequence. The y-z or a-q swaps are common examples. Typically these menu bindings are specified with <key> in they key desc. Pros: one binding affects any key sequence, works with modifiers. Cons: you can't radically change the key sequence of a hotkey this way.