13

I have an Asus laptop that has a special key that can be configured to launch any software (at least on Windows).

The general question is: how can I detect any key press (globally)?

Then, how can I detect when the user press this key?

Braiam
  • 35,991

3 Answers3

16

I typically will use xev to determine the key's scancode and then map it to whatever action I want using either xdotool or XBindKeys.

xev

$ xev | grep -A2 --line-buffered '^KeyRelease' \
    | sed -n '/keycode /s/^.*keycode \([0-9]*\).* (.*, \(.*\)).*$/\1 \2/p'

After running the above xev command you'll get a little white window that'll pop up. You'll want to put the mouse over this window and then press the problem key. The name of the key should be showing up in the terminal as you press the various keys.

Screenshot

                   ss of xev dialog

mapping the key to something useful

You can create shortcut key combinations that will launch commands using xbindkeys, for example. I've successfully been using XBindKeys on GNOME 3.8.4 for this very purpose.

My use has been modest but I like to create keyboard shortcuts for Nautilus to launch with certain directories opened.

Example

You'll need to first make sure the packages xbindkeys is installed.

Then you'll need to run the following command, one time only, to create a template xbindkeys configuration file.

$ xbindkeys --defaults > /home/saml/.xbindkeysrc

With the file created you can open it in a text editor and add a rule like this:

"nautilus --browser /home/saml/projects/path/to/some/dir"
  Mod4+shift + q

With the above change made we need to kill xbindkeys if it's already running and then restart it.

$ killall xbindkeys
$ xbindkeys

Now with this running any time I type Mod+Shift+Q Nautilus will open with the corresponding folder opened.

Using GNOME's Keyboard Applet

If you go through the settings (System SettingsKeyboard, select Shortcuts tab and add a new custom shortcut for your browser.

   ss #1

Using the steps 1-5 as in the diagram you could map a command to your special key as well.

slm
  • 369,824
  • Very useful. Is it possible to create a little C++ application do detect these key presses, like xev does? But it seems that xev doesn't detect my key presses globally. It only prints in console when the opened window is focused. – Ionică Bizău Mar 18 '14 at 14:39
  • Probably. xev is just to detect what the key's scan code is. xbindkeys will catch this key when pressed globally and do something when this happens. – slm Mar 18 '14 at 15:51
  • Is saml a typo (your username is sml)? :-) Also, I guess you mean xbindkeys --defaults > ~/.xbindkeysrc. Right? For the special button xev outputs 248 NoSymbol. I tried to set a nautilus start when NoSymbol is pressed but nothing is happening. I restarted xbindkeys process. – Ionică Bizău Mar 18 '14 at 19:41
  • In some cases (but not here it turns out), the key's scan code needs to be declared to the kernel. I thought we had a question about that but I can't find it now. – Gilles 'SO- stop being evil' Mar 18 '14 at 23:17
  • @IonicăBizău - no my username on my laptop is saml. My name is sam and I always suffix user accounts with an l to denote that it's local to the system. My username on SE sites is slm. These are my initials, which was traditionally what one would use to create user accounts on Unix. Or they'd use the first 2 letter from your 1st and middle names followed by 6 letters from your last name. – slm Mar 18 '14 at 23:23
  • @slm :-) Ok, and why aren't my key presses detected globally by killall? – Ionică Bizău Mar 19 '14 at 04:40
  • @IonicăBizău - killall kills the xbindkeys process. After killing it you're restarting xbindkeys. – slm Mar 19 '14 at 04:58
  • @slm I used Ubuntu built-in key shortcut settings and added a shortcut to my button. Can you add please this information in your answer? – Ionică Bizău Mar 21 '14 at 04:49
  • @IonicăBizău - see updates. – slm Mar 21 '14 at 05:22
  • Wow, the power button has its own key code! (XF86PowerOff) – Post Self Jun 14 '18 at 06:07
  • what if the scancode is empty? showkey --scancodes is empty for some of the new X1 thinkpad multimedia keys – Garen Vartanian Mar 01 '23 at 02:52
3

I'd like to post a summary of the various tools I've just tested.

I began with this google search: linux see what key is being pressed, which brought me to the following places. Since they are either closed or off-topic, right here is the most-logical choice to post my summary.

  1. [closed: off-topic] https://superuser.com/questions/248517/show-keys-pressed-in-linux
  2. [closed: duplicate] https://askubuntu.com/questions/1197651/ubuntu-show-what-keys-are-pressed-in-real-time
    1. [the "original", non-duplicate question] https://askubuntu.com/questions/30466/how-can-i-display-keyboard-shortcuts-as-i-press-them
  3. this very question here

Here is a bit of a summary of the best answers from each of those places. I need this info. so I can:

  1. detect stuck keys, which just happened, and
  2. work on HID keyboard microcontroller devices, which I do occasionally since I sell one.

Summary of various ways to detect key presses

Tested on Linux Ubuntu 20.04.

  1. screenkey

    # Install it
    sudo apt update 
    sudo apt install screenkey
    

    run it

    screenkey

    it now displays a massive black bar at the bottom of your main monitor

    whenever you press any key, showing all keys as they are pressed!

    kill it

    first, find its PID

    ps aux | grep screenkey

    Sample output:

    $ ps aux | grep screenkey

    gabriel 215523 2.9 0.3 972900 59364 ? Rl 10:27 0:00 /usr/bin/python3 /usr/bin/screenkey

    gabriel 215635 0.0 0.0 9040 2388 pts/0 S+ 10:27 0:00 grep --color=auto screenkey

    OR

    pgrep screenkey

    Sample output:

    $ pgrep screenkey

    215523

    now, kill that PID; ex:

    kill 215523

    Where I first learned about this tool: https://askubuntu.com/a/30468/327339

  2. sudo showkey

    # show numeric keycode key presses and releases (use Ctrl + C to exit)
    sudo showkey
    

    show hex scancodes (use Ctrl + C to exit)

    sudo showkey -s

    show ASCII keycodes, including the actual letter or character pressed,

    which is the most human-readable (use Ctrl + D to exit, NOT Ctrl + C!)

    sudo showkey -a

    Source:

    1. https://superuser.com/a/248568/425838
      1. My summary comment under the answer: https://superuser.com/questions/248517/show-keys-pressed-in-linux#comment2606625_248568
  3. https://www.keyboardtester.com/. Test your keys in the browser, and/or see if a key is stuck. Where I first learned about this tool: https://askubuntu.com/a/1197656/327339

  4. xev. When done using it, it takes two steps to kill it:

    1. Click out of your current terminal window to cause your terminal window to lose focus.
    2. Click back into your terminal window and press Ctrl + C.

    Sources:

    1. Where I first learned about this tool: https://askubuntu.com/a/1198027/327339
    2. See also: How to detect global key presses
  5. sudo evtest - a very low-level tool; appears to be what I need to work on USB HID devices (I think); works great!

    # Install it
    sudo apt update 
    sudo apt install evtest
    

    Run it

    First, find your keyboard /dev/input/event number manually

    sudo evtest

    Then, press Ctrl + C to kill it after it prints out all the events; you

    do NOT need to "Select the device event number" as it requests. Just hit

    Ctrl + C.

    Let's assume ours is "/dev/input/event4".

    now, run the grab command with the above event number path

    sudo su -c 'sleep 1; timeout -k5 10 evtest --grab /dev/input/event4'

    OR, if you know that sudo evtest only shows one output line with the

    word "keyboard" in it, you can script the above two steps with this one

    cmd like this. Notice that you can get a list of all input devices with

    cat /proc/bus/input/devices, as is done at the start of this cmd:

    input_event_num="$(cat /proc/bus/input/devices
    | grep -B 1 -A 10 -i "keyboard" | awk 'NR==6 {print $4}')";
    path_to_keyboard="/dev/input/$input_event_num";
    sudo su -c "sleep 1; timeout -k5 10 evtest --grab $path_to_keyboard"

    Source:

    1. https://askubuntu.com/a/1197742/327339
      1. See also the comments under this answer.

Other references:

  1. awk help: https://unix.stackexchange.com/a/89641/114401
  2. Where I learned about cat /proc/bus/input/devices: https://stackoverflow.com/a/15052092/4561887
  • 1
    When working on USB HID you may also want Wireshark. It's even lower level, as it lets you see actual HID packet exchange, and to easily dissect the packets. Beware of its bug 17014 though: it's only recently been fixed, so try to get the latest version of Wireshark. – Ruslan Dec 20 '21 at 22:52
-1

If you are unable to figure-out which keyboard keys are not working then you can use keyboardtester.org

It is simple to use.