Dvorak Mirrorboard layout (Based on Randall Munroe’s Mirrorboard)

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:

  1. Made it Dvorak-friendly
  2. Left-alt is used as modifier key, instead of Caps. (Which is remapped as Ctrl on my keyboard).
  3. Return is Modifier+Tilde
  4. Modifier+Tab is “/”
  5. 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)
  6. 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)
  7. 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:
// Changes:
// Details:

// 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:

  1. Fit it to your needs
  2. Copy to your key definitions folder (usually /usr/share/X11/xkb/symbols/)
  3. 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)
  4. 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.


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 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?

Pentachronological #0013 | Вошедшие на Касталии, деньги передаем!



Очень четко знаю, что сегодня буду листать отрывок “Книги Книг” Алексея Александрова про Классика, Янку и Лева, вероятно еще “Ночь перед Рождеством” Гоголя. Еще по традиции где-то там затесается “A Christmas Carol in Prose, Being a Ghost-Story of Christmas”. В этом же ассоциативном ряду “Вий” 1967 года, надо таки посмотреть его.

Нужно со всех сил не дать жизни скатиться в однообразие, нужно своими силами по-максимуму генерировать атмосферу. Религии, традиции, около-тоталитарные строи умеют это делать отлично, надо без особых комплексов оттуда черпать мысли. Сюди ж думки Костя Москальця про ритуали. (Останні три дні перечитую “Келію Чайної Троянди”, згадую мій 11 клас, повертаюсь до того стану душі. Ех.)

Некоторые книги стоит действительно перечитывать как способ focusing on what you want to grow.

И вообще, eсли праздника нет,то без этой жизни можно обойтись.


Now playing: A fairytale of New York

“You were handsome!” “You were pretty
Queen of New York City”
When the band finished playing
They howled out for more
Sinatra was swinging
All the drunks, they were singing
We kissed on a corner
Then danced through the night

2016 был очередным невероятно интересным годом. Много чего понято, много чего пережитого (но не излишне много, далеко не такой треш как 2015), но, не особо много чего сделано. Воспринимаю его его как год около-паузы подготовки к намного более активному году.

(Любимое исполнение второй любимой рождественской песни).

А ще:

Нова радість стааа-ааа-лааа
Яка не буваа-лааа
Над вертепом зірка ясна
На весь світ засіяяяя-лаа.

І взагалі:

Але кожен по-своєму
Ми дійдем до Вифлеє-ее-мууу

Це мав бути пост про те, яким я хочу, щоб був 2017 рік, але хай це буде абстрактно-різдвяно-новорічним постом. \

Вершини в снігу
Світяться навіть уночі
(Ватанабе Тацуо) 1As quoted here, my translation.

З Різдвом. Цей рік буде прекрасним.


Footnotes   [ + ]

1. As quoted here, my translation.

Підсумки 2016

Невже цьому 5 років, Боже мій…

Пишу ці рядки 31/12/2016, в Мюнхенському аеропорту за годинку до початку посадки.

UPD: Політ  Мюнхен->Варшава був дуже милим. В літаку крутять тихі джазові новорічні пісні через public announcement system, всі посміхаються, стюардеси ходять і роздають цукерки, пілот теж у явно чудовому настрої і дуже-дуже багато балакає ні про що. Чи не вперше за ці пару тижнів відчув ту саму атмосферу. До 2017 року менше ніж півдоби. Продовжую писати у аеропорту ім. Шопена у Варшаві у затишній кафешці

Now playing: “Нанэ цоха” та ця чудова пісня без відомої мені назви з “Табор уходит в небо”.
Досягнення року: почав напів-серйозно займатися здоров’ям, долаючи тонни бюрократичних перешкод
Подія року: 33C3, про це буде окремий пост!
Настрій року: Перечікування дощу, виход з мертвої петлі
Зустріч року: Я версії $дата-10 року народження
Геморой року: хай будуть ті самі бюрократичні перешкоди, а так відносно тихий рік без очевидних великих стресів
Країна року: Україна
Місто року: Фуртверк!
Слово року: Melancholy
Подорож року: Гамбург і ця надзвичайно довга дорога додому
Веб-сервіс року: (сам себе не похвалиш, …)
Колір року: #184e7b
Запах року: Арома-лампи, композиції “ясный ум” та масло ладану; приємний дим чергової інкарнації моєї воскової свічки після тушіння
Новина року: див. “Жах року”.

Оставь ее, баро, погубит она тебя и никто не сможет тебя спасти из беды, даже я не смогу. Оставь ее, баро, она же ведьма! 1 

Книга року: Die Biographie über Steve Jobs; To kill a mockingbird; Wir Kinder from Bahnhof Zoo; Sophies Welt; The autobiography of Benjamin Franklin
Фільм року: “Табор уходит в небо”
Пісня року: Крематорий – Мусорный ветер; “Табор уходит в небо” Каспийского Груза;
Жах року: Trump&Brexit
Заклад року: JB @ München + столовка у Школі
Напій року: Чай — вкотре.
Їжа року: Заморожена піца; Kinder County; заморожені булочки, які zum Fertigbacken
Транспорт року: Benz Express, рейс Київ-Лейпциг-Київ
Бренд року:
Антилюдина року: так класно, що хвилин 5 думаю над цим. Можливо таки рухаюсь у правильному напрямку у житті
МріяЦіль на наступний рік:  Закінчити КПІ, активно вчитись і вирішити, що мені потрібно в житті (в тому числі в плані магістратури). Отримувати нормальні оцінки, щоб спростити вибір магістратури. Знайти стимулюючу роботу.
Побажання собі на 2013 2014 2015 2016 2017 рік: 
Хм. По-максимуму стабілізуватись, дуже-дуже класно спати, гарно харчуватися, тримати себе в найкращій можливій формі, займатися спортом, не давати моху рости і ставати теплим і затишним. Я дуже непогано собі уявляю, що саме робити, щоб прибрати туман з голови — ну от саме це все і робити. Почати активно creating value, мутити масштабність рівня 7-9 класу. Вчитися caring about things знову, чисто вольовим зусиллям цікавитися всім, поки воно не стане більш-менш звичкою.


Footnotes   [ + ]