Welcome to "At Home Modifier" hack of xf86-input-evdev. The original README is moved to README.orig. Search for the word "News" for the news. Contents ======== * What it is * Web site * Get it * Usage * FAQ * Author * Bugs * Future direction * Random bits * History (News are here) * Source code * Copyright What it is ========== It enables for example "Shift/Space dual role key." When you press the space key alone, it's a space; but when you press it with another key, it's a shift. And/or Alt/Esc, AltGr/BS... It is a fork of evdev driver = xf86-input-evdev. It's ** only for Linux ** - X in other platforms don't use evdev driver. You can use "xcape" referred below if you're not a Linux user. (For MS Win, use AutoHotKey, and for Mac, Karabiner, formerly named keyremap4macbook) With this hack, your hands can stay at the home position almost always, and feel more "at home", thus "At Home Modifier". More precisely, you specify pairs of two keycodes, the "original", and the "translated". The last event gets recorded in this patch. After the press of an "original" key, the driver instead reports a translated key press event. When an original key is released, it sends a release of the translated key. And it sends a press and release of the original key if necessary, judging from the last event. Web site ======== https://gitlab.com/at-home-modifier/at-home-modifier-evdev/wikis/home (Until Mar 2015, it was hosted at gitorious.org.) Distro forum threads: * Gentoo: https://forums.gentoo.org/viewtopic-t-865313.html * Arch: https://bbs.archlinux.org/viewtopic.php?pid=938140 * Debian: http://forums.debian.net/viewtopic.php?f=20&t=65950 * Ubuntu: http://ubuntuforums.org/showthread.php?p=10907505 (Sorry, closed thread. Use Debian forum instead.) Get it ====== Download -------- The tar.gz is at: https://gitlab.com/at-home-modifier/download/raw/master/source/ahm-2.10.3.tar.gz You can also download the patch against the Xorg's original driver, "xf86-input-evdev" from the website. git --- Git access is available, too. For the first time, install git, and clone as $ cd some/dir $ git clone git@gitlab.com:at-home-modifier/at-home-modifier-evdev.git You can receive updates by $ cd some/dir/at-home-modifier $ git pull Version tags ------------ $ git tag -l "ahm*" lists all releases, like ahm-2.5.1. You can see the difference to the original code by: $ git diff xf86-input-evdev-2.5.0..ahm-2.5.0 Install ------- * Gentoo Linux users can use ebuild files. Visit the Gentoo Forum thread. * Arch Linux AUR entries are there. Visit the Arch Forum thread. * Debian and its derivatives: Visit the Debian Forum thread. *** In Debian, the original package is called "xserver-xorg-input-evdev" *** For Ubuntu, Yuri Khan has been providing PPA for years: https://launchpad.net/~yurivkhan/+archive/ahm Forum threads are listed above. Other Linux users can install it by replacing xf86-input-evdev. Compilation can be done just the same way as the original. I'd appreciate it a lot if you could send me your distro support. ** Server upgrading note ** When you upgrade your xorg-server-x.y.z, be sure to rebuild this driver, too. (Change in z doesn't affect, but x or y does.) Usage ===== First, know the keycodes you need, which are numbers assigned to each physical key. It's easiest to invoke "xmodmap -pk" or "xev" commands. In my case it says space is 65, and left shift is 50. OK. (See below for complicated cases.) Then write your xorg.conf or xorg.conf.d/10-keyboard.conf: # For the details see "man xorg.conf" or your distro doc. Section "InputClass" Identifier "my keyboard" # You can name this arbitrarily Driver "evdev" Option "XKBOptions" "terminate:ctrl_alt_bksp" # and so on # If you save this file under xorg.conf.d/ : Option "AutoServerLayout" "on" MatchIsKeyboard "on" # If you have multiple keyboards, you want something like one of them: # MatchProduct "AT Translated Set 2 keyboard" # MatchUSBID "0566:3029" # Name is found in Xorg log, following the message "Adding input device" # or by # $ cat /proc/bus/input/devices ### at-home-modifier options begin here. # The basic option. Option "TransMod" "65:50 102:241" # Defines key/modifier pairs. ## Fine tuning options. Explained in a later section. # For the first time, omit them. # Option "AhmTimeout" "400" # In millisecond. # Option "AhmDelay" "65 102" # Delayed keys. Seperate by spaces. # Option "AhmFreezeTT" "true" # Option "AhmResetTime" "10" # In sec. # Option "AhmPaddingInterval" "10" # In millisecond. EndSection If you want to specify multiple pairs for TransMod, separate them with whitespaces, like this: Option "TransMod" "65:240 102:241 100:241" Don't forget to restart X! Notice that the modifier keys should come to the second of pairs. Options recognized by at-home-modifier (in fact, by any X drivers) are printed to X log, typically /var/log/Xorg.0.log, like this: [ 50.579] (**) Option "AhmTimeout" "400" Fine tuning options ------------------- For the first time, skip this section. Come back after you actually try. *** Other keys *** Suppose you want the Left-Alt to be Alt/Esc. Then assign Esc to that key, using xmodmap. If you don't have any other Alt keys, then allocate Alt to keycode 240 or so, which must be unused on usual keyboards. For more complicated changes, you can tamper with files in /usr/share/X11/xkb/symbols/. See also the section "More on keycodes" below. The bottom row of my keyboard is Esc-BS-Spc-Ret-Tab, from left to right, with the overlay Alt-Shift-Ctrl-Shift-Alt. (Japanese keyboards have many keys you can press with thumbs. Now you can switch Firefox tabs with thumbs.=) You can use any keys for transmods. "d" & "k" (and so on) may be good. When you want to capitalize the left-hand keys, press "k", and "d" for right-hands. This may sound too complex, but you'll be soon accustomed. *** Cancellation by long press (timeout) *** Suppose you were about to input shift + A and pressed space/shift, but you changed your mind. If you release the space/shift key, you'll receive one space, but it's not what you want! Actually, a workaround is provided by time-out; a long enough press cancels that kind of press. If you have the following line in evdev driver configuration, Option "AhmTimeout" "400" # In millisecond. then a single press and release of space/shift key produces nothing if the press lasts more than 0.4 sec. The default is 0.6 sec. You can disable timeout by setting it to 0. *** Successive transmod tuning *** A subtle fix is enabled by default; suppose a transmod X has been pressed. If "transmod Y press, X release" follows, then the press of Y is treated as the original key. It's probably what you want. You can disable it by setting the boolean option "AhmFreezeTT" to false. ("TT" is meant for "transmod-transmod".) See also "Corner cases in press and release order" below. *** Reset *** Sometimes translated modifiers get frozen (See "Switching VT" section below), so a workaround is provided; just leave the keyboard long enough time (default 10 secs) untouched. You can change this time with the following option: Option "AhmResetTime" "10" # In sec. To disable this feature, set it to 0. Reset is implemented by sending release events to all translated modifiers, and clearing internal variables. The time measurement is not exact, and the maximal error is 1 sec. (Implementation note: It's because the sub-second field of timeval struct is ignored.) The exact time things get reset is the first time you touch the keyboard. *** Gtk widget double-press workaround (padding interval) *** Suppose you focus a gtk window with a button widget. When you press the shift/space, the gtk button should be pressed. But with this hack, you may have to press the key twice; the first press merely focuses the button, and the second key press becomes the real push. As a workaround, "padding interval" can be set: Option "AhmPaddingInterval" "10" # In millisecond. The default value is 10 ms, and I think it's good, but if it doesn't work, set it bigger. How it works: remember that a release of shift/space key, without touching other keys, sends a release of shift, a press of space, and its release. Padding interval is inserted between the shift release and the space press. Bigger the value, likelier to work, but the latency gets bigger, too. I don't know what's happening inside of gtk, but this solves. *** Fast type fix (delay) *** (Probably this option is not so satisfactory) Users of this hack often have "tongue-twister of fingers": Suppose you want a space and a lower case x. If the first press of space/shift is followed first by a press of x and then a release of space/shift, you'll get an upper-case X instead. To fix it, you can let "delay" be associated to space/shift, like: Option "AhmDelay" "65 102" # Delayed keys. Separate by white space Then the press of x (or any) following space/shift is "delayed", and completes after release of space/shift or x. There's a trade off. Whenever you want a real shift, you have to release the space/shift later. This feature is not (yet) satisfactory for the author. Maybe it should be treated as a modifier only if the key is pressed long enough (say 100ms), in addition to / instead of the press-release orders. More on keycodes ---------------- It's good to know that you can also tell keycodes by looking at /usr/share/X11/xkb/keycodes/evdev in order to customize the keyboard layout with XKB. For example that file says: <SPCE> = 65; // space ... <LFSH> = 50; // left shift Ok, but what's this? <AE02> = 11; Hm, if you use for example Italian layout, see /usr/share/X11/xkb/symbols/it. It has lines: xkb_symbols "basic" { ... key <AE02> { [ 2, quotedbl, twosuperior, dead_doubleacute ] }; ... } xkb_symbols "nodeadkeys" { // Modifies the basic italian layout to eliminate all dead keys ... key <AE02> { [ 2, quotedbl, twosuperior, doubleacute ] }; ... } Aha, so that key is basically "2". FAQ --- * Q: I need to input Shift+Space. How can I do it if my space is Space/Shift key? A: Simple. Turn both of the original Space and Shift into Space/Shift keys, for example. Author ====== Teika kazura <teika ahm-is-great at gmx ahm-is-great dot com> Delete "ahm-is-great" in the address. It's good *not* to trust authors you find on the Web. You may be reassured to know that I was a developer of Sawfish window manager: http://sawfish.wikia.com/wiki/User:Teika_kazura Bugs ==== Fixed bugs ---------- * In 2.6.3 ** Gtk widget double press issue. To push a gtk button, sometimes you had to press space/shift key twice, but this is fixed. If it doesn't work out-of-box, set "AhmPaddingInterval" option. (This "bug" is not the author's fault, but what's bad for users are bugs.=) ** Reset and Delayed key "Delay" and "Reset" are features introduced in 2.6.2. If a delayed key is pressed after a long enough period is passed (i.e. a reset is done), the press was ignored. It's fixed now. * In 2.6.2 ** Key release interference bug Suppose you press x, space/shift, release x, release space/shift. Probably you wanted "x ". But formerly, only "x" is sent. (More precisely, "x" + shift are sent. Don't confuse it with "AhmDelay".) ** Frozen key bug Probably ahm-2.6.0 has introduced a new bug which makes some keys irresponsive. The bug existed in theory, but the author has never experienced it actually. ** Memory leak Previous version had slight memory leaks (almost unnoticeable). ** (obsolete) keycode limit __This feature is deleted in 2.6.3__ X's keycode limit is 255, but linux input driver's keycode limit is 0x2ff. Now it accepts input codes > 255. * In 2.6.0 ** Double shift bug Suppose both key a and b are translated to shift. Press a, b, and release b. Then it should be 'B', but it used to emit lower b. It's because the release of shift was sent before b key press. Known bugs ---------- * Switching VT: If your Ctrl is a transmod key, when you switch from X to a virtual console with Ctrl + Alt + F1, and switch back to X with Alt + F1, Ctrl get frozen. This is mitigated with "reset" feature. It happens because Ctrl is pressed at the first switching, but the release is only sent to the VT, not to X, in particular to this driver. Not a bug --------- Many keyboards fail to send some combinations of key presses. For example, mine doesn't report Left-alt + space(Ctrl intended) + cursor-down nor alt + space + delete (whereas alt + space + up is dispatched!!) All normal symbol keys pressed with alt + space work. Keyboards with "n-key rollover" are the solution, and completely ok for this hack, but they may be expensive. (USB connection can't report 7 or more simultaneous presses, but it doesn't matter for us.) *** Limitations *** This driver is unaware of others, for example of synaptic driver. Suppose you press space/shift and the left click of notebook touchpad. It'll work as shift + click, but a space key event follows. (Timeout can give a workaround.) Future direction ================ Probably the author, Teika kazura, won't develop this hack any more as a fork of X evdev driver. Realistic solutions are to re-implement it in the user space. Then codes will be far smaller and much easier to read, and you'll seldom have to keep up with Xorg changes. Xcape (see below) does this, by using X Record extension and XTest extension. (X Record records inputs, and XTest synthesizes events. ) However, XTest and X-Record may not work in Wayland. Wish items ---------- Autorepeat support. For example, you press space/shift twice in a row, and/or hold it long enough, then it's turned to the press of space, rather than shift. Delay improvement. See the "Delay" section Two-way arguments: currently an original-translated pair is written as "65:50". It's better to allow "65:50m" or "50m:65", "m" meaning "modifier". "Dynamic configuration", or config changes on-the-fly may be good, for example enabling some keys only when you're using an input method. I don't know anything about socket or inter-process communication, so please tell me how to do it. (Space2Ctrl and Keydouble don't need this. Simply kill the process and run another.) See also this page for some ideas: http://www.ruska.it/michal/fork.html Bug reporting ------------- When you report a bug, don't forget to disable autorepeat by $ xset -r [<keycode>] It's better to make AhmResetTime big, and if you enable AhmDelay, set it big, too. I compile with -Wall -Wextra, and my code does not bring in any extra warning. Corner cases in press and release order --------------------------------------- There're many corner cases, and I don't know all. The option "AhmFreezeTT" is easy not only to reason, but also to code, but more complicated examples may not be so. More may be possible, by knowing which keys are modifiers. (This hack doesn't use any information which are modifiers. What's done is a simple translation.) You can get the required information by Xlib or XKB, but it'll be an inverted implementation, fetching the high-level part from the raw world. Or programmable configuration (together with timestamp support), something like an automaton, may help. But don't ask me it. I don't know how to design such logic nor to write a parser. Random bits =========== Will this patch speed up typing? -------------------------------- In my case, it didn't. But I (or my hands) feel far better and I can't do without this fork any more. It's much less tiring, so it may be more efficient if you use keyboard for long time in a day. In fact, this hack introduces some nicety. Options like delay and timeout are intended for the cure, but they bring in others. Warning: Health issue --------------------- This hack is likely to reduce the use of your pinkies, and the risk of their injury like RSI. However, overuse of keyboards can damage *any* digits and other parts of your hand, although pinkies are most vulnerable. Good keyboards -------------- If you can buy a Japanese keyboard, I recommend one. The Japanese keyboard is a "cheap Kinesis"; the space key is short, and there're keys around the space key which can be easily pressed with thumbs. (Have you ever heard of Kinesis Contoured Keyboard?) See for example http://en.wikipedia.org/wiki/Keyboard_layout But it's only the layout. I can't assure the overall quality. Of course it's better to try before you buy... "Realforce" keyboard made by Topre is unique with capacitive key switches whose touch is really soft. "HHK Professional" (HHK = Happy Hacking Keyboard) also uses Topre's switch. Kinesis contoured, Realforce and HHK Professional come with n-key rollover. (See also "not a bug" section above for "key rollover".) FYI: mine is OWL-KB86STD made by Owltech. It's cheap, and has cheap touch, but I like the layout. OWL-KB109BM(B)IIB has "Cherry mx brown switches", so may be good. See http://forums.gentoo.org/viewtopic.php?p=7019478#7019478 for more discussion. You can buy them from Amazon Japan. (I don't like Amazon hegemony, but they provide English interface. Many Japanese keyboards are sold at amazon.com, too.) Alternatives ============ * Xcape https://github.com/alols/xcape Xcape is independently written by Albin Olsson. Accepts configuration with key names in addition to keycodes. Obsolete alternatives --------------------- * Space2Ctrl and Keydouble Space2Ctrl by "r0adrunner" is minimal, only supports "Space to Ctrl", and not configurable. Written in C++. Keydouble by "baskerville" is a rewrite of Space2Ctrl in C. Has a bit less options than mine. https://github.com/r0adrunner/Space2Ctrl (Space2Ctrl) https://github.com/baskerville/keydouble (Keydouble) * actkbd: It works by direct access to /dev/input, but not updated since 2007. I don't think it's flexible enough. http://users.softlab.ntua.gr/~thkala/projects/actkbd/ * 窓使いの憂鬱 (Mado-tsukai no yū-utsu; meaning "Spleen of Windows Users") for Linux & Darwin: It's a port of a Windows key tuner software "窓使いの憂鬱", comparable to AutoHotkey. Japanese documentation only. The author is not reachable. Not maintained actively. It uses uinput. The last update was in Nov 2011. http://www42.tok2.com/home/negidakude/ History ======= News ---- * 2.10.3 (july 2016): * Merged upstream 2.10.3, which is 2.10.2 plus one bugfix, https://bugs.freedesktop.org/show_bug.cgi?id=95315 * 2.10.1 (feb 2016): * Merged upstream 2.10.1. * 2.9.2 (apr 2015): * Merged upstream 2.9.2. It also includes the fix of bug 84445, done in commit 8868f61: https://bugs.freedesktop.org/show_bug.cgi?id=84445 * 2.8.0 (jun 2013): * Merged upstream 2.8.0. More precisely, * There're two fix-up commits after 2.8.0 in the upstream. They're merged too. * In ahm-2.7.1, configure option "--without-mtdev" was added. But now it's deleted, and mtdev dependency is mandatory. * 2.7.3 (nov 2012): * Merged upstream 2.7.3. Ahm-2.7.2 was never released. * 2.7.1 (jun 2012): * Merged upstream 2.7.0. No any change in ahm per se, except doc. * An upstream bugfix of horizontal scroll, X.Org Bug 46205, is included. (The fix is published after the 2.7.0 release.) * Added an option to configure script "--without-mtdev". The upstream code always checks mtdev, and enable it when found. If you don't pass the above option, it falls back to the original behavior. This change, commit 371543edf0b, probably has to be reverted before merging upstream 2.8.0. The upstream suggests mtdev dependence will be forced in future versions. * Read also "Future direction" section in this README. * The hack version is 2.7.1, not 2.7.0, without much reason. * 2.6.4 (dec 2011): * Other device awareness When you press space/shift and a mouse button, the result used to be shift + click, ok, but also followed by an extra, unwanted space, as if the click hadn't happened. It's because each device ignored others. Now it's fixed, as long as the mouse is also handled by evdev driver. (Notebook touchpads are dealt by synaptics driver, so it's not fixed, and won't be fixed. Use AhmTimeout option as a workaround.) Thanks to the ArchLinux forum user "grimp3ur" for the idea. * 2.6.3 (nov 2011): * Bugs fixed Gtk button double press bug. Reset and delayed key bug. * Big keycode support is deleted. In 2.6.2, big keycode support was introduced, but it's deleted. loadkeys (1) command suffices. * 2.6.2 (oct 2011): * New features Long press cancellation (Option "AhmTimeout"), fast type fix (Option "AhmDelay"), successive transmod tuning (Option "AhmFreezeTT"), reset (Option "AhmResetTime") are implemented. Thanks to the ArchLinux forum user "bloom" for the idea of long press cancellation. * Bugs fixed Release interference bug, keycode limit bug, and 2 other minor bugs are fixed. * Documentation New sections: "Not a bug", "Corner cases", "Alternatives", "Source code". New bug item: "Switching VT". New wish items: "Dynamic configuration", "autorepeat support" * Feature deleted in later release. "Big keycode support" is introduced in 2.6.2, but deleted in 2.6.3. * 2.6.1 was never released. * 2.6.0 (apr 2011): Merged upstream 2.6.0. "Double shift bug" is fixed. * 2.5.1 (feb 2011): Minor documentation updates. * 2.5.0 (feb 2011): Initial release. Forked from upstream 2.5.0 = xf86-input-evdev-2.5.0. Background ---------- What was proposed originally was called "SandS" - stands for "Space and Shift" - which dates back to year 2001, by K. Kimura.[1] There's implementations in Mac and Win, and has a modest popularity in Japan still in year 2011. (K. Kimura has also contributed a lot to Japanese input methods.) In 2008 T. Matsuyama implemented it for X keyboard driver.[2] Then came a port to evdev driver by "jeneshicc".[3] But they lack generality; you can only use physical shift, alt, and space keys. My code is based on the last patch. I appreciate their work. [1] (Japanese) http://hp.vector.co.jp/authors/VA002116/ [2] (Japanese) http://dev.ariel-networks.com/Members/matsuyama/keyboard-customize [3] (Japanese): http://d.hatena.ne.jp/jeneshicc/20100306/1267843799 Space2Ctrl was (probably) written independently in 2011. Source code =========== Required knowledge ------------------ What's required is only C knowledge, none of X. I've added some comments, so it must be easy to understand. src/evdev.h ----------- Search for "ahm variables". In src/evdev.c, gcc __attribute__ is used. To support other compilers, it's defined as null when __GNUC__ is not defined. src/evdev.c ----------- * Parsing options Ahm options are parsed in function NewEvdevPreInit. Search for "parse ahm options". * Earlier event handling In the Xorg original code, keyboard events are handled by EvdevQueueKbdEvent. Ahm wraps it with AhmStep1 and AhmStep2, and WrapEvdevQueueKbdEvent. * Later event handling In the original code, events get really sent in EvdevPostQueuedEvents. To implement AhmPaddingInterval, this function is changed a bit, by queuing key events in ahm's own queue, and asynchronous timer is set. Timer related functions I've added are: AhmWakeupHandler, AhmBlockHandler, AhmRegisterTimers and AhmFinalise. License ======= Distributed under MIT License; Same as Xorg.
lambdaloop/at-home-modifier-evdev
It enables for example "shift/space dual role key." When SPC key is pressed alone, it's a space; but when pressed with another key, it's SHIFT. See wiki for more: https://gitlab.com/at-home-modifier/at-home-modifier-evdev/wikis/home
CNOASSERTION