Remapping zoom slider on Microsoft Ergonomic Keyboard

I’m a big fan of Microsoft’s “Natural Ergonomic Keyboard 4000”. I’m just not a fan of it’s name, it’s a mouthful! (How about for future reference we just call it the Ergo?)

b112ddfc-0541-4948-a804-a7268b0cc2a7

 

The Ergo’s great for typing on and also has a selection of feature keys that you can key-map to. Depending on your distro/desktop environment, you can map keys for all sorts of reasons: to replace caps lock with ctrl, control your music player, to run scripts, etc. There’s plenty of guides about remapping keys around so I won’t talk too much about that here. Google around and if you have questions askubuntu.com is a great place to find answers. What I’m interested in is getting the zoom slider working!

The zoom slider sits above the space bar and between the two primary sets of keys. It’s a spring-loaded rocker switch and button that’s supposed to be used to zoom in/out (I’ve never used it in Windows so I’ve never actually seen it in action). I thought it’d be cool to remap but it doesn’t seem to work like the other keys. Turns out it needs a little fiddling.

Enabling the zoom slider

When I try to use it, the zoom slider just seems to be totally ignored. I believe this is because they’re custom keys created specifically for (and supported only by) Windows. They have no analogue in Linux. To get them working we’ll have tell Linux that they’re equivalent to some other keys.

This is where udev steps in. We need to write rules to interpret these as keys and put em into the hardware database. Easy! Create a new set of keyboard rules like so:

$ sudo mkdir /etc/udev/hwdb.d
$ sudo vim /etc/udev/hwdb.d/61-keyboard-local.hwdb

And add this:

keyboard:usb:v045Ep00DB*
keyboard:usb:v045Ep071D*
KEYBOARD_KEY_0c022d=pageup
KEYBOARD_KEY_0c022e=pagedown

Hwdb rules are grouped together by device. The first two lines here identify two different models of Ergo (the 4000 and the 7000) that our block of rules will apply to. It’s pretty obvious that these are for targeting USB keyboards but what is the set of seemingly random characters near the end? They are for matching specific devices by vendor/product code, they follow the following pattern:

v<vendor_code>p<product_code>

How could you be certain that your device will match this code? You can check your keyboard’s code by running:

$ lsusb | grep Ergo | awk '{print $6}'.

It should appear in the form <vender>:<product>. For my keyboard I get “045e:00db” which matches the first line of the example as expected.

The next two lines (each indented with a single space) are the rules to tell udev which scan codes map to which buttons. In this case we’re telling udev that the slider keys (scan code 0c022d and 0c022e) are supposed to be pageup/pagedown.

For these rules to take effect, you’ll need to recompile the hwdb and reload udev:

$ sudo udevadm hwdb --update
$ sudo udevadm control --reload

At this point you might need to plug the keyboard out/in to get it to work.

Identifying other keys and scan codes

Okay that’s great if all you wanna do is page up or down. Where do you go to find the names of other keys to map to? They’re all listed (in upper case with “KEY_” as a prefix) in /usr/include/linux/input-event-codes.h.

If you want to write udev rules for other keys you’ll need a way to identify key scan codes. For that we’ll use evtest.

$ evtest /dev/input/event0

When this is running you can move the slider up and down and it should post event logs like this:

Event: time 1468247448.373417, type 4 (EV_MSC), code 4 (MSC_SCAN), value c022e
Event: time 1468247448.373417, type 1 (EV_KEY), code 109 (KEY_PAGEDOWN), value 0

If it doesn’t, kill it with CTRL+C and try the next event file (/dev/input/event1) and keep going until you get these kind of logs (for me it was event10).

UPDATE: A friend of mine pointed out (in the comments below) that you don’t need to step through each of the devices manually. You can run sudo evtest without any arguments and it will display all devices as a list with short descriptions for you to choose from by simply entering the device number.

The first line in each event will be the scan code (“MSC_SCAN”) and the value listed (“c022e”) is the scan code.

Suggested Fixes

Depending on what distro of Linux you’re using, you might need to tweak the rules a bit. The ones I’ve shown above worked fine for me with Ubuntu 12.04. I’ve also had success getting them working with CentOS 7. Here’s two suggested changes if you run into trouble.

In newer versions of Ubuntu (15.01+) you might need to change the device matching rule to include a bus number (a four digit code, 0003 for USB devices). Here’s an example:

“`
keyboard:usb:b0003v045Ep00DB*
“`

In the example the scan codes started with a zero. Sometimes this doesn’t work (but I’ve no idea why). Try it out without the leading zero, like so:

“`
KEYBOARD_KEY_c022d=pageup
“`

Footnotes

  1. Originally got this working by reading this askubuntu question.
  2. Learned about hwdb was by reading the man page.
  3. Got some of the nitty gritty details of how to write hwdb rules by reading this Arch wiki page.
  4. To figure out how to use evtest I used this guide.
Advertisements
Remapping zoom slider on Microsoft Ergonomic Keyboard

A Markdown notes server

I keep a lot of notes…

Writing notes

Any time I’m researching anything computing related, whether it’s for work or in my spare time, I keep a log of my “stream of conciousness”. This includes thoughts like “I think this is because…”, “I wonder if this is related to…”, “What the fuck is…?”.

This is great when I’ve spent a lot of time learning something new and I can look back over them once a week to reinforce the stuff I’ve covered. I get to see how wrong I was about some things and I can gain a new appreciation for other things that might not have dawned on me the first time around. I encourage anyone to keep stream of conciousness notes while they’re in learning mode.

A few specifics: I write these notes in vim using Markdown. I typically write the date as a header and use sub-headers for breaking up a days thoughts into topics. Then I write down what ever thoughts occur to me as I go in a bullet-point list. If I’m googling and find helpful resources I’ll throw the links into the notes as well so I can come back to them later, rather than break the flow of my exploration.

These aren’t strict rules you have to follow; just my own personal style. There’s nothing wrong with experimenting and finding what works for you!

Reading notes

When it comes to reviewing what I’ve written, I’ve found that reading markdown in vim sucks.

What I really wanted was to format the notes in HTML and make them look visually appealing (this makes a big difference when you’ve got an attention span as short as mine).

Hosting them from a webpage (over LAN) would be ideal because then I could check ’em from a phone or tablet when I’m away from my desk (great for recounting details during stand ups).

It should be noted that I didn’t want to use any of the note taking web apps like Evernote or Google Keep or even though they’d making note syncing really easy. Why you ask? Because 1) vim, 2) grep, and 3) I wanna host my own notes and not expose them over the internet because sometimes they’re sensitive work related stuff.

What did I come up with?

Simple: flask app in a docker container. It uses pandoc to convert to HTML and it spruces things up with dashed/github-pandoc.css.

You can pull it from the Docker Hub and mount the folder with all your notes when you run it. No fuss, relatively little muss. Here’s the commands to serve files from ~/notes at localhost:4000 if you wanna try it yourself:

Want to take a closer look? The code is up on my github and the latest image is on the docker hub! It’s just something I threw together quickly. If you have ideas for improvements I’ll be happy to look at any pull requests.

This is actually the first image I put on the hub so that was fun.

I also posted some screenshots below:

Give it a go and let me know what you think! I’d love to hear from you about your own note taking strategies.

Enjoy!

A Markdown notes server