I am using left Alt as my primary modkey, but for certain application I would like to use Alt+keys as my bindings, and for that specific application I want left winkey to be my modkey.

It seems that logHook is the right place to plug this logic in, but I have troubles understanding, how to do it.

Greatly simplified, my configuration looks like

import qualified XMonad.StackSet as W
import XMonad
import XMonad.Hooks.DynamicLog

main = do
  -- some stuff
  xmonad $ defaultConfig {
      modMask = mod1Mask  -- left winkey = mod4Mask, left alt = mod1Mask
    , logHook = do
          dynamicLogWithPP pp


pp = dzenPP {
    -- more stuff

I could getName of current window in my logHook

winset <- gets windowset
let wname = fmap getName (W.peek winset) -- here I have some window identificator in Maybe

but I do not understand how to replace modMask in my main function, in defaultConfig, on the fly.

I would also be happy if on one workspace modkey will be different. Say, on workspaces 1 to 8 it is an Alt key, and on 9th it's left Winkey. This would do fine too, and I bet such solution can be easily modified to be based on currently focused window.


This failed. XMonad works as expected, but applications do not receive pressed keys. I mean, I use winkey as modKey on 5th workspace, and altkey on other workspaces. I used to switch workspaces with modKey+number. When I press Alt+2 on 5th workspace, XMonad does nothing (which is correct), and application does nothing (which is wrong). Chrome does not switch to 2nd tab, and so on.

Okay, so I managed to do it, using XMonad.Actions.PerWorkspaceKeys.

Related configuration:

import XMonad.Actions.PerWorkspaceKeys

workspaceModkeys = [ (mod1Mask, map show ([1..4] ++ [6..9])) -- use Alt as modkey on all workspaces
                   , (mod4Mask, ["5"])                       -- save 5th (use Win there)

modifiedKeysList conf =
  [ ((0,         xK_Return), spawn $ XMonad.terminal conf)  -- launch a terminal
  , ((shiftMask, xK_c     ), kill)  -- close focused window

unmodifiedKeys conf =
  [ ((0, xF86XK_AudioPlay ), spawn "mpc toggle")
  , ((0, xF86XK_AudioStop ), spawn "mpc stop")

keysList conf = concat (map modifyKey (modifiedKeysList conf)) ++ (unmodifiedKeys conf)

modifyKey :: ((KeyMask, KeySym), X()) -> [((KeyMask, KeySym), X())]
modifyKey k = map (f k) workspaceModkeys
    f ((mask, key), action) (mod, workspaces) = ((mask .|. mod, key), bindOn (map (\w -> (w, action)) workspaces))

myKeys conf = M.fromList $ keysList conf

main = xmonad $ defaultConfig {
  keys = myKeys

List modifiedKeys will use modifier (in this example — Winkey on 5th workspace, and left Alt on all others), list unmodifiedKeys is used as is.

Still might look into window-specific keys later, but I'm done for now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.