Take the 2-minute tour ×

How can I set an action to occur on a key release in xmonad?

I don't like menu bars and panels. Instead of a panel like xmobar I want to have a full screen page of info, (time, currently selected window and workspace etc) appear when I hold down a key combo and then vanish when I let the keys go. I could code the info page application myself. I can set the info page to spawn on a key press.

I can not set anything to happen on a key release.

How can I set an action to occur on a key release?

I am considering extending xmonad myself to do this. I hope I don't have to though because it'd be really annoying.

share|improve this question
add comment

1 Answer

XMonad passes all received events, including KeyPress events, to the handleEventHook, so this code would be able to react on keyRelease events:

module KeyUp where

import Data.Monoid
import qualified Data.Map as M

import XMonad
import Control.Monad

keyUpEventHook :: Event -> X All
keyUpEventHook e = handle e >> return (All True)

keyUpKeys (XConf{ config = XConfig {XMonad.modMask = modMask} }) = M.fromList $ 
    [ ((modMask, xK_v), io (print "Hi")) ]

handle :: Event -> X ()
handle (KeyEvent {ev_event_type = t, ev_state = m, ev_keycode = code})
    | t == keyRelease = withDisplay $ \dpy -> do
        s  <- io $ keycodeToKeysym dpy code 0
        mClean <- cleanMask m
        ks <- asks keyUpKeys
        userCodeDef () $ whenJust (M.lookup (mClean, s) ks) id
handle _ = return ()

You would use it like that in your xmonad.hs file:

handleEventHook    = handleEventHook defaultConfig `mappend`
                     keyUpEventHook `mappend`

Unfortunately, this does not work yet: It will only react on KeyRelease events that have a corresponding entry in the regular keys configuration. This is due to grayKeys in XMonad.Main, grabbing only keys mentioned in keys. You can work-around this by defining a dummy action for every combination that you want to handle in KeyUp:

    , ((modMask              , xK_v     ), return ())
share|improve this answer
add comment

Your Answer


