RSI issues

A few months ago I got some beginning RSI symptoms: pain and tingling sensations throughout the lower arms and hands. The direct cause was an intense weekend writing a large pentest report, combined with programming scripts to ease the reporting in the future. At the same time I was configuring my new laptop and using a new windowing system which relied heavily on key combinations (win+this, alt+that, …). All in all I was hurting my hands heavily and they needed rest.

I took the symptoms seriously and took a number of steps. I bought a new much more ergonomic desk and an ergonomic keyboard. I started taking frequent typing breaks and more and longer breaks in general. And I read online about methods to decrease strain on my hands while using my computer. After a few weeks, the symptoms subsided and currently I feel like I’m back to normal.

Single key shortcuts

While reading about computing ergonomics, I found a provocative article from Xah Lee called Why Tiling Window Manager Sucks. I encourage you to read it even if you disagree with his conclusion, because he writes an interesting challenge to those who use tiling window managers in the article:

Try the following workflow for a week. I’d be interested to know if you still think tiling windows great.

  • Remove tiling manager. Use a basic, normal, one, such as xfce.
  • Set workspace/virtual-screen to just 1. (and remove the tens of related keybindings)
  • Set up 3 function keys to switch to 3 of your most used app. For example, {F8, F9, F10} for {emacs, browser, terminal}. [see How to Set Key to Switch to Browser]
  • Set up 1 key to cycle windows within a app. F3. (trivial to do in xfce. Harder in lxde/openbox.)
  • Set up 1 key to switch to last window, such as F4. (this is normally Alt+Tab. In xfce, can be done easily. In lxde/openbox, the problem is that it requires pressing Enter to “exit” the switch, similar to releasing Alt.)
  • Set up 1 key to toggle max/restore window size. F1
  • Set up 1 key to close window. For example, F6 (must be 1 single key. Alt+F4 is not good.)
  • Set up 1 key to switch prev tab, and 1 key to switch next tab. (i use {F11, F12})
  • Set up 1 key to close tab. For example, the Pause/Break key. [see Print Screen, SysRq, ScrLk, Pause, Break Keys] (note: the prev/next tab key, and close tab key, should be next to each other. If you are using a full-sized IBM PC keyboard with numberpad, best to use / * - for {close, prev, next} tab, in that order. [see How to Program Number Keypad as Function Keys] )
  • Turn on mouse hover auto-raise window. (not just focus, but raise.) [see Linux: Mouse Hover to Raise Window]
  • Ban double-click. [see Linux: Set Mouse Single-Click to Open File]

As a heavy user of workspaces and having over time learned many keyboard shortcuts, I did feel like typing a lot of awkward combinations caused me a lot of awkward hand movements. I was intrigued by the idea of creating single key shortcuts using rarely used keys, an idea I had not thought of before.

Since then I’ve setup my system to use a bunch of Xah Lee’s suggestions, and they’ve been working great. I’ve made my own changes though. Currently both my personal Linux system and my work Windows system have the following shortcuts configured:

  • F2 - Copy
  • F3 - Paste
  • F4 - Switch to previous window (Alt+Tab)
  • F6 - Close window (Alt+F4)

In addition, I’ve configured F8 to F10 for my most used apps on both systems. On Windows I reconfigured printscreen to be the same as ctrl+shift+s (select a region and make a screenshot) as I used it way more often. On Linux I set printscreen to the following script, which makes a screenshots and copies it to the clipboard:

#!/bin/sh
file=/tmp/screenshot-$(date +%s).png
maim --select "$file"
xclip -selection clipboard -t image/png "$file"

I’m really happy with the new shortcuts as they save me from needing to make awkward hand combos for my most commonly used tasks. For Windows I used PowerToys to configured they keys. On Linux I used Autokey as well as regular Xfce key bindings.

Key sequences to key menu

Another interesting article I found from Xah Lee was Ban Key Chords where he talks about key chords versus key sequences. Key chords require you to type multiple keys together, such as ctrl+shift+s, while key sequences let you type them like a text, for example alt, then e, then c to copy. I thought the idea of key sequences to be smart and I’m surprised they seem to be rarely used on Linux. In fact I couldn’t find a way to configure my own sequences in any way.

At this time I thought it would be great to use a single rarely used key, such as F12, to show a menu where every key would lead to a specific action defined by me. I did some research, and couldn’t find any software that let me create such a menu easily. Eventually I decided I could take dmenu which comes close, and edit it so it would select an option as soon as it is no longer ambiguous. dmenu turned out to be easy to hack, and so I created my own kbmenu, which can be used in scripts such as the following:

#!/bin/bash
run=$(<$HOME/Documents/keymenu.txt kbmenu -l 20 -b | cut -d' ' -f 2-)
bash <<< "$run"

Where keymenu.txt contains the following sequences:

c tcopydb cwe.csv
r tradio*
s select-window-kb
m sleep 0.1s && xdotool type ik@thomasvanderberg.nl
v tcopydb vuln-nl.csv

* (See also tradio)

The effect is that I can type F12, then any of the keys to run a command I’ve created. For example F12,m will write my full email address into any selected field. A number of other commands link to other scripts I’ve created, and it’s easy to add anything new to it.

For ease of access I’ve put kbmenu on Github though it is just a simple change. The only change was in the match function, which was replaced with the following:

static void
match(void)
{
    size_t textsize;
    struct item *item;

    matches = matchend = NULL;
    textsize = strlen(text);
    for (item = items; item && item->text; item++) {
        if (!fstrncmp(text, item->text, textsize))
            appenditem(item, &matches, &matchend);
    }
    curr = sel = matches;
    if (curr == matchend) {
        if (curr && curr->text) {
            puts(curr->text);
            cleanup();
            exit(0);
        } else {
            cleanup();
            exit(1);
        }
    }
    calcoffsets();
}

Hope I gave you some interesting ideas for increasing your own ergonomics or computer efficiency. If you’re feeling pain in your arms and/or tingling, please take rest to let your hands recover and possibly check with a doctor if it takes longer than expected.