Update: New version of the layout can be found here; it has a number of improvements and visuals. History & Rationale remain in this post, though, along with installation instructions.

Now playing: Shia LaBeouf by Rob Cantor.

It all started when I was looking into options for one-hand typing, simply because it seemed like a pretty interesting thing to learn. (I love the feeling of the brain rewiring, haha.)

I stumbled upon this blog post by Randall Munroe about his Mirrorboard layout.

The key moment was when I realized that the brain command I use to type the letter ‘e’ is very similar to the one I use to type ‘i’. I found that if I held my right hand away from the keyboard and tried to type “the kitten parked the hovercraft”, it came out “tge dettev qarded gte gwvercraft” — I was doing the same motions with my left hand that I’d normally do with my right. Mirrorboard is a keyboard layout that lets you type simple things on a QWERTY keyboard with only the left hand. It works by mirroring the layout between the left and right hands when you press caps lock. “asdf” becomes “;lkj” — the entire keyboard is reflected. To press a key on the right side of the board, you hold caps-lock with your pinky and then press the corresponding key on the left side.

Which is actually really fascinating and true.

After Googling around, I did not find any Dvorak version of the keyboard layout, so I decided to make one. Learning quite a lot about xkb and Linux’s handling of keystrokes in the process.

Another reason to change it a bit was because I use a pretty complex keyboard setup, with dvorak+Russian+Ukrainian, a compose key, and multiple remapped keys on my keyboard, and I wanted to integrate left-hand typing seamlessly in my workflow.

Changes made from the original Mirrorboard layout:

Made it Dvorak-friendly Left-alt is used as modifier key, instead of Caps. (Which is remapped as Ctrl on my keyboard). Return is Modifier+Tilde Modifier+Tab is “/” Modifier key is a Latch-style key instead of Shift-style key. (Basically, the difference between the two is that Shift-style keys work only when pressed together with the key that’s being modified, while Latch-style keys may be pressed before the key, or at the same time, or twice to “Lock” it until the next time you press it; Here’s an excellent explanation) Adapted it to contain only the modified keys, so it can be put in /usr/share/X11/xkb/symbols/our_dvorak_mapping and later used as just another keyboard layout, say, setxkbmap -option 'grp:rshift_toggle, compose:rctrl' dvorak,sh-mirror3,ru,ua (right shift to change keyboard layout, right Ctrl as compose key) Maybe some other things I have forgotten

Additional resources that helped me in the process have been this excellent post on how to create your own layouts and the legendary Arch linux wiki.

The layout is on Github.

// Dvorak Mirrorboard, based on Mirrorboard one-hand keymapping // Original keymap: https://blog.xkcd.com/2007/08/14/mirrorboard-a-one-handed-keyboard-layout-for-the-lazy/ // Changes: http://pchr8.net/blog/... // Details: http://www.pchr8.net/blog/2017/02/02/dvorak-mirrorboard-layout/ // Added name so I can use it inside setxkbmap default partial alphanumeric_keys modifier_keys xkb_symbols "sh-mirror" { // Using Left alt as modifier instead of Caps lock, // since I have Caps lock mapped to Ctrl. // Additionally, it's a Latch key, not a Shift one, so pressing it once activates the group. key <LALT> { type[Group1] = "ONE_LEVEL", symbols[Group1] = [ ISO_Level3_Latch ] }; // Caps+Space is return // Tilde is Backspace by itself, Return with modifier. key <SPCE> { [ space, space, Return ] }; key <TLDE> { [ BackSpace, asciitilde, Return, asciitilde ] }; // Tab+Modifier gives a slash, which I use often (searching etc.) key <TAB> { [ Tab, ISO_Left_Tab, slash, slash] }; key <AE01> { [ 1, exclam ] }; key <AE02> { [ 2, at ] }; key <AE03> { [ 3, numbersign ] }; key <AE04> { [ 4, dollar ] }; key <AE05> { [ 5, percent ] }; key <AE06> { [ 6, asciicircum, dead_circumflex, dead_circumflex ] }; key <AE07> { [ 7, ampersand ] }; key <AE08> { [ 8, asterisk ] }; key <AE09> { [ 9, parenleft, dead_grave] }; key <AE10> { [ 0, parenright ] }; key <AE11> { [ bracketleft, braceleft ] }; key <AE12> { [ bracketright, braceright, dead_tilde] }; key <AD01> { [ apostrophe, quotedbl, l, L] }; key <AD02> { [ comma, less, r, R] }; key <AD03> { [ period, greater, c, C] }; key <AD04> { [ p, P, g, G ] }; key <AD05> { [ y, Y, f, F ] }; key <AD06> { [ f, F ] }; key <AD07> { [ g, G ] }; key <AD08> { [ c, C ] }; key <AD09> { [ r, R ] }; key <AD10> { [ l, L ] }; key <AD11> { [ slash, question ] }; key <AD12> { [ equal, plus ] }; key <AC01> { [ a, A, s, S ] }; key <AC02> { [ o, O, n, N ] }; key <AC03> { [ e, E, t, T ] }; key <AC04> { [ u, U, h, H ] }; key <AC05> { [ i, I, d, D ] }; key <AC06> { [ d, D ] }; key <AC07> { [ h, H ] }; key <AC08> { [ t, T ] }; key <AC09> { [ n, N ] }; key <AC10> { [ s, S ] }; key <AC11> { [ minus, underscore ] }; key <AB01> { [ semicolon, colon,z, Z] }; key <AB02> { [ q, Q, v, V ] }; key <AB03> { [ j, J, w, W ] }; key <AB04> { [ k, K, m, M ] }; key <AB05> { [ x, X, b, B ] }; key <AB06> { [ b, B ] }; key <AB07> { [ m, M ] }; key <AB08> { [ w, W ] }; key <AB09> { [ v, V ] }; key <AB10> { [ z, Z ] }; key <BKSL> { [ backslash, bar ] }; // Did not change anything here, need to think this over. key <AE01> { [ 1, exclam, minus, plus ] }; key <AE02> { [ 2, at, 0, parenleft ] }; key <AE03> { [ 3, numbersign, 9, parenright ] }; key <AE04> { [ 4, dollar, 8, asterisk ] }; key <AE05> { [ 5, percent, 7, ampersand ] }; key <AE06> { [ 6, asciicircum ] }; key <AE07> { [ 7, ampersand ] }; key <AE08> { [ 8, asterisk ] }; key <AE09> { [ 9, parenleft ] }; key <AE10> { [ 0, parenright ] }; key <AE11> { [ minus, underscore ] }; key <AE12> { [ equal, plus ] }; };

To use:

Fit it to your needs Copy to your key definitions folder (usually /usr/share/X11/xkb/symbols/ ) Either just setxkbmap sh-mirror3 or integrate it in whatever you are using (e.g. setxkbmap -option 'grp:rshift_toggle, compose:rctrl' dvorak,sh-mirror3,ru,ua) In case you want to edit it, copy it every time to a new name. The layout gets cached to the DE, and for it to read the new changes you would have to reload X, unless it’s a new file. (That’s why sh-mirror3; same number of tries as it took this person I learned this fact from). Or just during editing do xkbcomp mirrorboard.xkb $DISPLAY 2>/dev/null as recommended in the original post, maybe removing the last part to see any errors.

Then I did a couple of changes to my i3, cvim and keynav configs, to make them easier to use with just the left hand.

keynavrc

Keynav is an excellent little program to avoid using the mouse. I divide the screen in 16 areas, and decided to move the lower ones to my left hand, used with shift. Relevant fragment is:

#First two rows of the screen areas apostrophe cell-select 1 comma cell-select 5 period cell-select 9 p cell-select 13 a cell-select 2 o cell-select 6 e cell-select 10 u cell-select 14 # Third and fourth row g cell-select 3 c cell-select 7 r cell-select 11 l cell-select 15 h cell-select 4 t cell-select 8 n cell-select 12 s cell-select 16 #Third and fourth row using shift and left-hand keys shift+apostrophe cell-select 3 shift+comma cell-select 7 shift+period cell-select 11 shift+p cell-select 15 shift+a cell-select 4 shift+o cell-select 8 shift+e cell-select 12 shift+u cell-select 16

On my keynav 0.20170124.0 the areas seem to be numbered vertically, not horizontally as mentioned on the page linked above.

cvim

Cvim is my favourite extension that adds vim-like keybindings to Chrome.

I added a keystroke to change the hint characters to left-hand ones and back, which conveniently was exactly the example given by the author for JavaScript mode:

switchHintCharacters -& gt ; {{ settings . hintset_a = ! settings . hintset_a ; if ( settings . hintset_a ) { settings . hintcharacters = ' snthlrcgd ' ; // equivalent to "let hintcharacters = '...'" } else { settings . hintcharacters = ' aoeujk ' ; } PORT ( ' syncSettings ' , { settings : settings }); // Display cVim's status bar for 1 seconds. Status . setMessage ( ' Changed hint set ' , 1 ); }} map a : call switchHintCharacters & lt ; CR & gt ;

All of this is definitely a work in progress, but it was really interesting.

Current left-hand typing speed is 12WPM, compared to my usual 80, I wanna see how and if it will improve. It’s really not about actual use, but because it seems something cool to do. Something like shorthand-writing, which I’ve almost learned. I wonder what comes next. Dozenal counting, perhaps?