6

I have a numpad connected via USB and my goal is to be able to remap keys on that numpad so they can run custom commands or be mapped to other key combinations.

I have this in my .xbindkeysrc file:

~ $ cat .xbindkeysrc
"xte 'keydown Super_L' 'key Left' 'keyup Super_L'"
  m:0x10 + c:79 + Release
  Mod2 + KP_Home

This remaps the NUM 7 key (which normally prints 7) to Super_L + Left Arrow. That's great and it works, BUT FOR ALL KEYBOARDS, while my goal is to make it work only for the numpad.

Been searching how to do it, but the closest I got was to use xinput set-button-map. Unfortunately, this seems to only work for devices like mouses. I like tried fetching what the button map is for the numpad with xinput get-button-map [device id] but it just prints numbers from 1 to 7 and I definitely have more buttons on my keypad, so it doesn't necessarily make sense.

Any advice?

orion3
  • 201
  • 3
  • 7

2 Answers2

4

Consider using https://github.com/rvaiya/keyd. It was written for this purpose and works across the entire system.

curious
  • 49
  • 1
  • 2
    [Brevity is acceptable, but fuller explanations are better](https://unix.stackexchange.com/help/how-to-answer). – Kusalananda Jul 28 '21 at 08:09
2

Find the deviceID first, using xinput list

$ xinput list

⎣ Virtual core keyboard
...
↳   USB Keyboard     id=19  [slave  keyboard (3)]

key mapping per device/keyboard

(This will only map keys. See below for mapping scripts to keys)

setxkbmap has the option to target a specific device (keyboard).

Then query the setxkbmap config to see your device settings (I will use '19'):

$ setxkbmap -device 19 -print
xkb_keymap {
    xkb_keycodes  { include "evdev+aliases(qwerty)" };
    xkb_types     { include "complete"  };
    xkb_compat    { include "complete"  };
    xkb_symbols   { include "pc+us(euro)+us(intl):2+inet(evdev)"    };
    xkb_geometry  { include "pc(pc105)" };
};

The symbols is what we're looking for; these can be found in ls /usr/share/X11/xkb/symbols. The arguments refer to a subsection in the file, for example xkb_symbols "intl" {

To add any of the available options like for example, rupeesign, you could do setxkbmap -device 19 -option rupeesign:4

to reset the options, use setxkbmap -device 19 -option without further arguments.

However, you want some custom configuration, and that is a bit more tricky, because simply adding a custom file in that folder and using it does not work.

So create some folders and create a tempfile with the current config.

mkdir -p ~/.config/xkb/symbols
cd ~/.config/xkb 
setxkbmap -device 19 -print > tempfile.txt
touch symbols/mysymbol

Edit tempfile.txt so it contains mysymbol(mymapping)

...
xkb_symbols   { include "pc+us(euro)+us(intl):2+inet(evdev)+mysymbol(mymapping)"   

Edit symbol/mysymbol any way you want, see /usr/share/X11/xkb/symbols for examples. This one adds a Bitcoin symbol to num 7 key .

partial
xkb_symbols "mymapping" {
    key <AE07> { [  7,   &,   U20BF ]  };

};

Now, finally, to activate this mapping, use xkbcomp ( note -i 19 to set the device)

xkbcomp -i 19 -I$HOME/.config/xkb tempfile.txt $DISPLAY

(This will probably show some warning messages, but it still works)

Mapping keys to start a script

There is a tool for mapping key to a script: actkbd

install:

$ git clone https://github.com/thkala/actkbd 
$ cd actkb
$ make 
$ sudo make install

Then find the devicename for your keyboard in /dev/input/, in my case it is /dev/input/by-id/usb-_USB_Keyboard-event-kbd

You should now have a config file /etc/actkbd.conf containing some examples, can all be all be removed. Here are some more practical examples

# 'a' starts gedit
30:::gedit
# 'shift+7' starts a custom script. (keynumber 8 for some reason)
42+8:::/home/me/myscript.py

To find the keynumber (or keycombination), use the 's' option:

$ actkbd -d /dev/input/by-id/usb-_USB_Keyboard-event-kbd -s

After your configuration in /etc/actkbd.conf, start the program (use -D for background mode )

$ actkbd -d /dev/input/by-id/usb-_USB_Keyboard-event-kbd
Alex
  • 148
  • 5
  • No need for creating all those dirs - `xkbcomp` works in both directions; simply `xkbcomp -i 19 $DISPLAY foo.xkb`, edit `foo.xkb`, `xkbcomp -i 19 foo.xkb $DISPLAY` should do. It even works in a single shot `xkbcomp -i dev $DISPLAY - | some_filter | xkbcomp -i dev - $DISPLAY`, though the xkb format is too "structured" for awk or sed. –  Aug 17 '19 at 14:19
  • @mosvy you're right, that returns the full layout (~2000lines), but might not be as easy to edit for anyone new to the format. – Alex Aug 17 '19 at 14:46
  • I tried following your instructions, this is the error I'm getting when trying to run: `xkbcomp -i...` `Can't find file "evdev" for keycodes include Exiting Abandoning keycodes file "(null)"` – orion3 Aug 19 '19 at 13:23
  • I also get this error even if I don't change tempfile.txt and am trying to load it as is. – orion3 Aug 19 '19 at 13:31