Хук фокуса XMonad

Я хотел бы настроить XMonad так, чтобы определенная функция IO () оценивалась всякий раз, когда окно находится в фокусе, чтобы я мог изменять некоторые аспекты среды в зависимости от того, какое окно это было. Кажется, я не могу найти ничего об этом в документах, но я уверен, что он существует, поэтому, вероятно, я ищу неправильное ключевое слово.


person Anschel Schaffer-Cohen    schedule 26.04.2014    source источник
comment
Вы пытаетесь выполнить действие, когда в фокусе находится конкретное окно или когда фокусируется любое окно? Последнее намного сложнее первого (я не знаком ни с одним модулем, дающим так называемый хук фокуса).   -  person cassandracomar    schedule 26.04.2014
comment
Когда конкретное окно сфокусировано, было бы хорошо, если бы я также мог что-то сделать, когда оно не сфокусировано.   -  person Anschel Schaffer-Cohen    schedule 27.04.2014


Ответы (3)


Ближе всего, вероятно, logHook :: !(X ()) в XConfig. Вы можете получить сфокусированное окно и запустить действие IO для обновления среды, но этот хук описывается как «действие, выполняемое при изменении набора окон», поэтому ваш updateEnv может вызываться несколько раз подряд с одним и тем же окном. ID (например, когда вы меняете окна, не меняя фокуса).

myLogHook = gets (peek . windowset) >>= liftIO . updateEnv
  where
    updateEnv :: Maybe Window -> IO ()
    updateEnv = undefined
person raymonad    schedule 26.04.2014
comment
Я думаю, это то, что я хочу; Я проголосую и приму его, как только у меня будет время убедиться, что он работает. - person Anschel Schaffer-Cohen; 28.04.2014

Возможно, вы захотите настроить handleEventHook.

Что-то вроде этого :

myEventHook e@(CrossingEvent {ev_event_type=t, ev_window=win}) 
        | t == enterNotify = do 
                   something with win
                   return $ All True
        | t == leaveNotify = do 
                   something else
                   return $ All True
        | otherwise = return $ All True
person Leiaz    schedule 26.04.2014
comment
Поскольку CrossingEvent привязаны к указателю мыши, это ничего не делает, когда вы используете клавиатуру для изменения фокуса, если только вы не используете что-то вроде XMonad.Actions.UpdatePointer, чтобы заставить указатель следовать. - person raymonad; 27.04.2014
comment
@raymonad focusIn/focusOut были бы правильными событиями, но получить их не представляется возможным (я пытался с AnyEvent). Я не знаю почему. - person Leiaz; 27.04.2014
comment
@Leiaz Я думаю, вам нужно изменить clientMask, который использует XMonad. (xmonad.org/docu). Конечно, есть способ добавить к нему focusChangeMask, но я не могу понять, как это сделать. - person anthonybrice; 02.04.2015

Благодаря предыдущим вариантам я построил свой. @Leiza, я нашел, как использовать clientMask:

import XMonad
-- import Data.Monoid (All(..))
import Control.Monad (when)
...
hook :: Event -> X All
hook (AnyEvent {ev_event_type = et}) = do
  when (et == focusOut) $
    <action>
  return (All True)
hook _ = return (All True)
...
main = do
...
  clientMask = focusChangeMask .|. clientMask def
...

@Leiza была права, для меня CrossingEvents не работает должным образом.

person PRESFIL    schedule 22.09.2020