Как изменить modMask в Xmonad, когда сфокусировано определенное окно или определенная рабочая область?

Как изменить modMask в Xmonad, когда сфокусировано определенное окно или определенная рабочая область?

Я использую левую клавишу Alt в качестве основной клавиши моддера, но для некоторых приложений я хотел бы использовать Alt+клавиши в качестве привязок, и для этого конкретного приложения я хочу, чтобы левая клавиша подмигивания была моей клавишей моддера.

Кажется, logHook — подходящее место для подключения этой логики, но мне трудно понять, как это сделать.

Если сильно упростить, то моя конфигурация выглядит так:

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
}

Я мог бы получить Имя текущего окна в моем logHook

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

но я не понимаю, как заменить modMask в моей основной функции, в defaultConfig, на лету.

Я также был бы рад, если бы на одном рабочем пространстве modkey был другим. Скажем, на рабочих пространствах с 1 по 8 это клавиша Alt, а на 9-м — левая Winkey. Это тоже было бы неплохо, и я уверен, что такое решение можно легко модифицировать, чтобы оно основывалось на текущем окне в фокусе.

решение1

Это не удалось. XMonad работает как и ожидалось, но приложения не получают нажатые клавиши. Я имею в виду, что я использую winkey как modKey на 5-м рабочем пространстве и altkey на других рабочих пространствах. Я раньше переключал рабочие пространства с помощью modKey+number. Когда я нажимаю Alt+2 на 5-м рабочем пространстве, XMonad ничего не делает (что правильно), и приложение ничего не делает (что неправильно). Chrome не переключается на 2-ю вкладку и т. д.


Хорошо, мне удалось это сделать, используяXMonad.Действия.PerWorkspaceKeys.

Сопутствующая конфигурация:

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
  where
    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
}

Список modifiedKeys будет использовать модификатор (в этом примере — Winkey на 5-м рабочем пространстве и левый Alt на всех остальных), список unmodifiedKeys используется как есть.

Возможно, позже я займусь клавишами, специфичными для окон, но на данный момент я закончил.

Связанный контент