From: R. Steve McKown Date: Sat, 31 Jan 2015 05:49:06 +0000 (-0700) Subject: Blog entry keyboard-specific-mappings.md X-Git-Url: https://oss.titaniummirror.com/gitweb?p=oss-web.git;a=commitdiff_plain;h=5c85f4ade01905eadd79b2c44109b3f8b6d6ce89 Blog entry keyboard-specific-mappings.md --- diff --git a/in/blog/2015-01.md b/in/blog/2015-01.md new file mode 100644 index 0000000..8e73a44 --- /dev/null +++ b/in/blog/2015-01.md @@ -0,0 +1,5 @@ +title: 2015-01 blogs +linktitle: 2015-01 +parent: 2015 +ctime: 2015-01-01 +mtime: 2000-01-01 diff --git a/in/blog/2015.md b/in/blog/2015.md new file mode 100644 index 0000000..fc36e43 --- /dev/null +++ b/in/blog/2015.md @@ -0,0 +1,5 @@ +title: 2015 blogs +linktitle: 2015 +parent: blog +ctime: 2015-01-01 +mtime: 2000-01-01 diff --git a/in/blog/keyboard-specific-mappings.md b/in/blog/keyboard-specific-mappings.md new file mode 100644 index 0000000..0145f78 --- /dev/null +++ b/in/blog/keyboard-specific-mappings.md @@ -0,0 +1,188 @@ +title: X Keyboard Specific Mappings +linktitle: xkbmap +parent: 2015-01 +ctime: 2015-01-30 +mtime: 2015-01-30 + +# Why global keyboard remapping can be bad + +In an [[earlier post|swapkeys]], I blogged about remapping keys on a keyboard +for better typing comfort. The change was to swap the Control and Windows keys +on a [CM Storm Stealth](http://gaming.coolermaster.com/en/products/keyboards/stealth/) +USB keyboard. + +![CM Storm Stealth keyboard][cmstorm_img] + +Using the "partial fist" method I described in my [[prior post|swapkeys]], the +pinky ends up hitting the Windows key, both with left and right pinkies. And +because I use vim heavily, I want the control key at this position. The CM +Storm keyboard is nice because its placement of the Control and Window keys are +symmetrical in relation to the hands on the home row of the keyboard. + +The xmodmap mappings described in my [[earlier post|swapkeys]] works fine to +swap the Control and Windows keys, but because it changes the mappings globally, +it remaps the Control and Windows keys on all attached keyboards. I use a +Thinkpad X201 notebook, and swapping its Control and Windows keys is not +desirable. + +![Thinkpad X201 keyboard][x201_keyboard_img] + +The position of the Control keys on the Thinkpad keyboard is already ideal +according to my preference. So what I really want is a method to change the +mappings for only one keyboard device attached to the computer, and not all of +them. + +# How to implement device specific remapping + +[[!pquote text="xkb allows per-device mapping"]] + +The solution is to ditch the xmodmap solution presented [[before|swapkeys]] and +instead use the capabilities of xkb. Using the Xorg evdev input driver, it is +possible to configure different settings for different input devices. For +keyboards, we can therefore select different xkb options. + +The configuration changes describe here are available in the +[cmstorm](/gitweb/?p=cmstorm.git;a=summary) repository. + +## Step 1 -- Create a new xkb option + +I first created a new xkb option. New file `/usr/share/X11/xkb/symbols/ctrlwin` +contains the option named `ctrlwin:swap_ctrl_win`: + + + // Swap the Ctrl and Win keys. + partial modifier_keys + xkb_symbols "swap_ctrl_win" { + key { [ Control_L ] }; + key { [ Super_L ] }; + key { [ Control_R ] }; + key { [ Super_R ] }; + }; + +## Step 2 -- Reference the new option so it can be used + +The new option should show up in the proper reference files to be usable. +Specifically, the evdev and evdev.lst files, found in the +`/usr/share/X11/xkb/rules` directory, at least on Ubuntu 14.04. + +Here's the patch for evdev. + + --- evdev.orig 2014-01-15 07:42:33.000000000 -0700 + +++ evdev 2015-01-30 20:20:08.708389769 -0700 + @@ -971,6 +971,7 @@ + altwin:hyper_win = +altwin(hyper_win) + altwin:alt_super_win = +altwin(alt_super_win) + altwin:swap_alt_win = +altwin(swap_alt_win) + + ctrlwin:swap_ctrl_win = +ctrlwin(swap_ctrl_win) + grp:switch = +group(switch) + grp:lswitch = +group(lswitch) + grp:win_switch = +group(win_switch) + +Here is the patch for evdev.lst. + + --- evdev.lst.orig 2014-01-15 07:42:33.000000000 -0700 + +++ evdev.lst 2015-01-30 20:20:20.976390083 -0700 + @@ -800,6 +800,8 @@ + altwin:hyper_win Hyper is mapped to Win-keys + altwin:alt_super_win Alt is mapped to Right Win, Super to Menu + altwin:swap_alt_win Alt is swapped with Win + + ctrlwin Ctrl/Win key behavior + + ctrlwin:swap_ctrl_win Ctrl and Win keys are swapped + Compose key Position of Compose key + compose:ralt Right Alt + compose:lwin Left Win + +With these changes, one can activate the option on a given X keyboard input +device to swap the Control and Windows keys. Something like this: + + setxkbmap -device 10 -option ctrlwin:swap_ctrl_win + +where `10` is the id of the device. One can see all the X input devices by +running at a shell prompt: + + xinput -list + +To de-activate the option, issue the command again but with `""` as the option +argument. Or, since this device is a USB keyboard, simply unplug it and then +plug it back in. At this point, we have shown the option works correctly (or +not!) but the change is not persistent. + +## Step 3 -- Set the new option for the appropriate devices + +In Ubuntu 14.04, `/usr/share/X11/xorg.conf.d/` contains a set of files used for +the configuration of X. Add the new file +`/usr/share/X11/xorg.conf.d/90-evdev-CM-Storm.conf`: + + Section "InputClass" + Identifier "CM Storm keyboard" + MatchIsKeyboard "on" + MatchDevicePath "/dev/input/event*" + Driver "evdev" + MatchUSBID "2516:0017" + Option "XkbOptions" "ctrlwin:swap_ctrl_win" + EndSection + +This file defines an InputClass that overrides the default for keyboards defined +in `10-evdev.conf`. It is applicable for devices that are keyboards, whose +device path starts with `/dev/input/event`, and shows USB VID:PID is +`2516:0017`. The CM Storm keyboard has this VID:PID, although it's hard to +track it down via `lsusb`. Here is the `lsusb` output on my Thinkpad: + + Bus 002 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub + Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub + Bus 001 Device 080: ID 17ef:4816 Lenovo + Bus 001 Device 088: ID 1366:0101 SEGGER J-Link ARM + Bus 001 Device 087: ID 046d:c52f Logitech, Inc. Unifying Receiver + Bus 001 Device 086: ID 1a40:0101 Terminus Technology Inc. 4-Port HUB + Bus 001 Device 085: ID 1fc9:0083 NXP Semiconductors + Bus 001 Device 084: ID 1058:1110 Western Digital Technologies, Inc. + Bus 001 Device 083: ID 1a40:0201 Terminus Technology Inc. FE 2.1 7-port Hub + Bus 001 Device 082: ID 046d:0825 Logitech, Inc. Webcam C270 + Bus 001 Device 092: ID 2516:0017 + Bus 001 Device 079: ID 17ef:1005 Lenovo + Bus 001 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub + Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub + +But the Xorg log file has the information + + $ grep "CM Storm.*Vendor" /var/log/Xorg.0.log.old | tail -1 + [100514.151] (--) evdev: CM Storm Side print: Vendor 0x2516 Product 0x17 + +## Step 4 -- Log out and back in + +X only reads the configurations in /usr/share/X11/xorg.conf.d on startup, so the +X session needs to be restarted. The simplest way to do this is to log out and +back in again. Now, upon detecting the CM Storm keyboard, its Control and +Windows keys should be swapped without affecting any other keyboards attached to +the system -- in my case the Thinkpad's built-in keyboard. Here's an Xorg +snippet that shows the more specific InputClass definition working: + + [101104.743] (II) config/udev: Adding input device CM Storm Side print (/dev/input/event14) + [101104.743] (**) CM Storm Side print: Applying InputClass "evdev keyboard catchall" + [101104.743] (**) CM Storm Side print: Applying InputClass "CM Storm keyboard" + [101104.743] (II) Using input driver 'evdev' for 'CM Storm Side print' + [101104.743] (**) CM Storm Side print: always reports core events + [101104.743] (**) evdev: CM Storm Side print: Device: "/dev/input/event14" + [101104.743] (--) evdev: CM Storm Side print: Vendor 0x2516 Product 0x17 + [101104.743] (--) evdev: CM Storm Side print: Found keys + [101104.743] (II) evdev: CM Storm Side print: Configuring as keyboard + [101104.743] (**) Option "config_info" "udev:/sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.5/1-1.5.2/1-1.5.2:1.1/input/input60/event14" + [101104.743] (II) XINPUT: Adding extended input device "CM Storm Side print" (type: KEYBOARD, id 9) + [101104.744] (**) Option "xkb_rules" "evdev" + [101104.744] (**) Option "xkb_model" "pc105" + [101104.744] (**) Option "xkb_layout" "us" + [101104.744] (**) Option "xkb_options" "ctrlwin:swap_ctrl_win" + +Line three of the output shows use of the new InputClass, and the last line of +the output above shows the xkb option applied by that class. + +## Step 5 -- Swap the key caps on the keyboard + +The CM Storm comes with a key cap puller, so it's trivial to swap the Control +and Windows keys and have the key legends match with the new keyboard mapping. + +[cmstorm_img]: /image/cmstorm.jpg + "CM Storm Stealth image" + +[x201_keyboard_img]: /image/thinkpad-x201-keyboard.jpg + "Thinkpad X201 keyboard" diff --git a/in/image/cmstorm.jpg b/in/image/cmstorm.jpg new file mode 100644 index 0000000..15a0044 Binary files /dev/null and b/in/image/cmstorm.jpg differ diff --git a/in/image/thinkpad-x201-keyboard.jpg b/in/image/thinkpad-x201-keyboard.jpg new file mode 100644 index 0000000..e65883e Binary files /dev/null and b/in/image/thinkpad-x201-keyboard.jpg differ