I would like to remap the keys on my number pad so that they behave differently depending on how long the key is pressed. Here's an example:
If I hold the Numpad 9 key down for less than 300ms it will send the "previous tab" key command Ctrl+Tab
If I hold the Numpad 9 key down for 300-599ms it will send the "new tab" key command Ctrl+T
If I hold the Numpad 9 key down for 600-899ms it will send the "close tab/window" key command Ctrl+W
If I hold the Numpad 9 key down for more than 899ms, it does nothing in case I missed the time window I wanted.
On Windows I could do this with AutoHotKey and on OS X I could do this with ControllerMate, but I cannot find a tool on UNIX/Linux that allows key remapping based on how long a key is held.
If you are aware of a tool that can solve my problem, please make sure to provide a script or code sample that demonstrates the conditional key hold duration behavior I described above. It doesn't need to be the full code to solve my example, but it should be enough for me to repurpose it for my example.
Best Answer
I just wrote this in C:
Use
showkey -a
to get the bind keycode:Put the bind keycode 5 and its command(e.g. run
/tmp/.a.out
) in ~/.bashrc:Note that relevant keycode need to change in the source code too (the hex value can get from
sudo showkey -a
above too):Compile with (output to
/tmp/a.out
in my example):Demonstration:
Numpad 5, short press open new tab, medium press open gedit, and long press open gnome-terminal.
This is not direct applicable in any window on gnome desktop manager, but i think it should give you some idea how (hard) to implement it. It work in Virtual Console(Ctrl+Alt+N) too, and work in some terminal emulator (e.g. konsole, gnome-terminal, xterm).
p/s: I'm not a c programmer, so forgive me if this code is not optimized.
[UPDATE]
The previous answer only work in shell and required focus, so i think parse the /dev/input/eventX is the solution to work in entire X session.
I don't want to reinvent the wheel. I play around with
evtest
utility and modified the bottom part of evtest.c with my own code:Note that you should change the username (xiaobai is my username) part. And also the
if ( (ev[i].code == 76) ) {
is my Numpad 5 keycode, you might need to manually print the ev[i].code to double confirm. And of course you should change the video path too :)Compile and test it directly with (the `` part is in order to get the correct
/dev/input/eventN
):Note that
/by-id/
doesn't work in Fedora 24, so i change it to /by-path/. Kali no such problem.My desktop manager is gdm3:
So, i put this line in
/etc/gdm3/PostLogin/Default
to run this command as root on gdm startup (/etc/X11/Xsession.d/*
doesn't work):For unknown reason /
etc/gdm/PostLogin/Default
doesn't work on Fedora 24' gdm which give me "Permission denied" when check/tmp/l_gdmE
log. Manually run no problem though.Demonstration:
Numpad 5, instant-press (<=0.2 second) will be ignored, short-press (0.2 to 0.5 second) open
nautilus
, medium-press (0.5 to 1 second) openvlc
to play video, long-press (1 to 2 seconds) opengnome-terminal
, and timeout-press (2 seconds) opengedit
.I uploaded the full code(only one file) here.
[UPDATE again]
[1] Added multiple keys flow and fixed
notify-send
failed by defineDBUS_SESSION_BUS_ADDRESS
. [2] AddedXDG_CURRENT_DESKTOP
andGNOME_DESKTOP_SESSION_ID
to ensure konsole use gnome theme gui (Change it if you're not using gnome).I updated my code here.
Note that this code doesn't handle for combination keys flow, e.g. Ctrl+t.
UPDATE:
There's multiple device interfaces which the /dev/input/by-path/XXX-eventN entries sequence is random. So I change the command in
/etc/gdm3/PostLogin/Default
as below (Chesen
is my keyboard name, for your case, you should changed it togrep Razer
instead):You can try the eventN extract from
cat /proc/bus/input/devices | grep -i Razer -A 4
:In this example above, only
sudo cat /dev/input/event7
will print bizarre output when click the 12 digits on Razer mouse, which has the pattern "sysrq kbd leds event7" to use ingrep -P '^(?=.*sysrq)(?=.*leds)'
above (your pattern might vary).sudo cat /dev/input/event6
will print bizarre output only when click the middle up/down key. Whilesudo cat /dev/input/event5
will print bizarre output when move your mouse and scrolling the wheel.[Update: Support Replug keyboard cable to reload the program]
The following should be self-explanation: