Xbindkeys – Run Program on Key Press Without Interrupting Event

xbindkeysxdotool

Is it possible to bind a (global) key press to some command and still not disrupt the key press from completing? What I mean is, if I try the bindkey solution posted elsewhere here:

# In file: ~/.xbindkeysrc
# Bind key 'q' to running 'some_command'
"some_command"
  q

then the key press 'q' never completes as it otherwise would do: i.e., never prints the character 'q' on the terminal, for example.

Using xdotool to send a 'q' key press like this:

# In file: ~/.xbindkeysrc
# Bind key 'q' to running 'some_command'
"some_command && xdotool key q"
  q

results in loop since the 'q' key press executed by xdotool will execute another 'some_command' via the binding.

To be a little clearer, I want the key press 'q' to execute as it normally does and in addition execute some external command. The solution above replaces the 'q' key press event with executing some external command. The problem is that if that external command also simulates a 'q' key press, then the binding re-launches the external command and I get stuck in an infinite loop.

Best Answer

OK, so I will post a solution that I've found, but maybe someone else has a better one. Following an answer presented here, I can see all the keys pressed by running

xinput test <keyboad_id>

in a terminal. It's then just a simple case of piping the output of that command into a program that watches for strings like "key release 24" (the output when 'q' is released on my keyboard) and which will then do whatever you like when it does match this string.

For example, we can catch a press of the 'q' key and make a sound like this:

xinput test <keyboard_id> | while read in ; do
  [[ $in = "key press   24" ]] && aplay /usr/share/sounds/purple/alert.wav
done

We can then, obviously, watch for other inputs as well and run something else if desired.

Related Question