mirror of
https://github.com/xmonad/xmonad-contrib.git
synced 2025-05-19 03:20:21 -07:00
108 lines
4.2 KiB
Haskell
108 lines
4.2 KiB
Haskell
-----------------------------------------------------------------------------
|
|
-- |
|
|
-- Module : XMonad.Hooks.DebugKeyEvents
|
|
-- Copyright : (c) 2011 Brandon S Allbery <allbery.b@gmail.com>
|
|
-- License : BSD
|
|
--
|
|
-- Maintainer : Brandon S Allbery <allbery.b@gmail.com>
|
|
-- Stability : unstable
|
|
-- Portability : unportable
|
|
--
|
|
-- A debugging module to track key events, useful when you can't tell whether
|
|
-- xmonad is processing some or all key events.
|
|
-----------------------------------------------------------------------------
|
|
|
|
module XMonad.Hooks.DebugKeyEvents (-- * Usage
|
|
-- $usage
|
|
debugKeyEvents
|
|
) where
|
|
|
|
import XMonad.Core
|
|
import XMonad.Operations (cleanMask)
|
|
|
|
import Graphics.X11.Xlib
|
|
import Graphics.X11.Xlib.Extras
|
|
|
|
import Control.Monad.State (gets)
|
|
import Data.Bits
|
|
import Data.List (intercalate)
|
|
import Data.Monoid
|
|
import Numeric (showHex)
|
|
import System.IO (hPutStrLn
|
|
,stderr)
|
|
|
|
-- $usage
|
|
-- Add this to your handleEventHook to print received key events to the
|
|
-- log (the console if you use @startx@/@xinit@, otherwise usually
|
|
-- @~/.xsession-errors@).
|
|
--
|
|
-- > , handleEventHook = debugKeyEvents
|
|
--
|
|
-- If you already have a handleEventHook then you should append it:
|
|
--
|
|
-- > , handleEventHook = ... <+> debugKeyEvents
|
|
--
|
|
-- Logged key events look like:
|
|
--
|
|
-- @keycode 53 sym 120 (0x78, "x") mask 0x0 () clean 0x0 ()@
|
|
--
|
|
-- The @mask@ and @clean@ indicate the modifiers pressed along with
|
|
-- the key; @mask@ is raw, and @clean@ is what @xmonad@ sees after
|
|
-- sanitizing it (removing @numberLockMask@, etc.)
|
|
--
|
|
-- For more detailed instructions on editing the logHook see:
|
|
--
|
|
-- "XMonad.Doc.Extending#The_log_hook_and_external_status_bars"
|
|
|
|
-- | Print key events to stderr for debugging
|
|
debugKeyEvents :: Event -> X All
|
|
debugKeyEvents (KeyEvent {ev_event_type = t, ev_state = m, ev_keycode = code})
|
|
| t == keyPress =
|
|
withDisplay $ \dpy -> do
|
|
sym <- io $ keycodeToKeysym dpy code 0
|
|
msk <- cleanMask m
|
|
nl <- gets numberlockMask
|
|
io $ hPutStrLn stderr $ intercalate " " ["keycode"
|
|
,show code
|
|
,"sym"
|
|
,show sym
|
|
," ("
|
|
,hex sym
|
|
," \""
|
|
,keysymToString sym
|
|
,"\") mask"
|
|
,hex m
|
|
,"(" ++ vmask nl m ++ ")"
|
|
,"clean"
|
|
,hex msk
|
|
,"(" ++ vmask nl msk ++ ")"
|
|
]
|
|
return (All True)
|
|
debugKeyEvents _ = return (All True)
|
|
|
|
-- | Convenient showHex variant
|
|
hex :: (Integral n, Show n) => n -> String
|
|
hex v = "0x" ++ showHex v ""
|
|
|
|
-- | Convert a modifier mask into a useful string
|
|
vmask :: KeyMask -> KeyMask -> String
|
|
vmask numLockMask msk = intercalate " " $
|
|
reverse $
|
|
fst $
|
|
foldr vmask' ([],msk) masks
|
|
where
|
|
masks = map (\m -> (m,show m)) [0..toEnum (bitSize msk - 1)] ++
|
|
[(numLockMask,"num" )
|
|
,( lockMask,"lock" )
|
|
,(controlMask,"ctrl" )
|
|
,( shiftMask,"shift")
|
|
,( mod5Mask,"mod5" )
|
|
,( mod4Mask,"mod4" )
|
|
,( mod3Mask,"mod3" )
|
|
,( mod2Mask,"mod2" )
|
|
,( mod1Mask,"mod1" )
|
|
]
|
|
vmask' _ a@( _,0) = a
|
|
vmask' (m,s) (ss,v) | v .&. m == m = (s:ss,v .&. complement m)
|
|
vmask' _ r = r
|