I have a new Macbook Pro and I installed Arch Linux on it. One thing I want to be able to do is use the media keys to seek through a track (in mpd) and goto the next or previous track. This is possible on OSX with iTunes so I assume it's not fundamentally impossible. Using xev only shows Key Press and Key Release events. Holding a key just seems to cycle through those two events rapidly.

So what I want to be able to do is:

  • go to next mpd track when XF86AudioNext key is pressed; or
  • seek through the current mpd track when XF86AudioNext key is held down

and of course the same (but in the other direction) for the XF86AudioPrev key.

It seems like this is only possible through some advanced scripting. Hopefully one of you can point me in the right direction.

Edit: Interestingly showkey doesn't cycle between Press and Release when holding a key down. Rather it just shows a bunch of Press events for the duration of which the key is held down and a final Release event when it's finally let go.

Another interesting thing I just noticed is that when disabling the autorepeat using xset then xev will only show a single Key Press event no matter how long the key is held down and a single Key Release event when it's let go. On the otherahnd showkey's output doesn't change. It shows a bunch of Key Press event and a final Key Release when it's let go.

There's probably a way to use that to script what I want to do but sxhkd the hotkey tool I'm using appears to follow the xev way. So is Xbindkeys.

2 Answers 2


No, there's no KeyHold event, only KeyPress and KeyRelease. KeyPress is sent when the key is pressed, and sent again after a certain amount of time. The time can be configured with xset r (there are two times: time to first repeat, and time to subsequent repeats). A KeyRelease event is sent when the key is actually released (it is not sent while the key is being held).

If an application wishes to react to a held key, it needs to note the initial key press, then react either after a set time or after a new KeyPress event, assuming it hasn't received a KeyRelease in the meantime. Reacting to held keys is highly unusual in the Unix GUI world, so there's a self-perpetuating circle of applications not doing it and programming frameworks not offering an easy way to do it.

XKB allows some keys to be configured as non-repeatable; those keys will only generate an initial KeyPress and a final KeyRelease. I don't know where this is done in the configuration. With those keys, only the KeyPress+timeout strategy will work, not the second-KeyPress strategy.

Neither xbindkeys nor sxhkd make this easy. While they allow an action to be bound to key release events, they don't make it easy to relate the key press and the key release, so it's difficult to program the logic “do this X ms after key press, but only if the key hasn't been released yet” + “do this on key release, but only if the hold event hasn't been fired yet”. I don't know of any other similar framework that makes this easy.


While there is no simple solution in X11, one could instead read the device outputs from the kernel which does have a "keyheld" event.  *more info from kernel.org*

This is an example output from /dev/input/event#   (# varies between devices)

Event: time 1677080541.072921, type 4 (EV_MSC), code 4 (MSC_SCAN), value 9d
Event: time 1677080541.072921, type 1 (EV_KEY), code 97 (KEY_RIGHTCTRL), value 1
Event: time 1677080541.072921, -------------- SYN_REPORT ------------
Event: time 1677080541.319094, type 4 (EV_MSC), code 4 (MSC_SCAN), value 9d
Event: time 1677080541.319094, type 1 (EV_KEY), code 97 (KEY_RIGHTCTRL), value 2
Event: time 1677080541.319094, -------------- SYN_REPORT ------------
Event: time 1677080541.348759, type 4 (EV_MSC), code 4 (MSC_SCAN), value 9d
Event: time 1677080541.348759, type 1 (EV_KEY), code 97 (KEY_RIGHTCTRL), value 2
Event: time 1677080541.348759, -------------- SYN_REPORT ------------
Event: time 1677080541.379604, type 4 (EV_MSC), code 4 (MSC_SCAN), value 9d
Event: time 1677080541.379604, type 1 (EV_KEY), code 97 (KEY_RIGHTCTRL), value 0

The output goes from 1 (key press), 2 (key held), and then 0 (key release)

By monitoring the output from /dev/input/event# a simple script I made can run commands to emulate the seek and next behavior (using "playerctl position 5+" and "playerctl next"). Here is the github branch.

  • Nice addition :-) I'd suggest editing it a bit, just by changing "more info" to "more info at kernel.org" for clarity. BTW "necroing" isn't a concept here - this is almost 7y old question, in that time things can well change making old answers... well, old :-) Commented Mar 4, 2023 at 22:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .