是否可以切换 XMonad.Hooks.EwmhDesktops.fullscreenEventHook?

问题描述

我使用 Xmonad 作为窗口管理器。为了自动处理全屏窗口,我使用 XMonad.Hooks.EwmhDesktops.fullscreenEventHook。并将其放入我的配置中:

,handleEventHook = handleEventHook def <+> docksEventHook <+> XMonad.Hooks.EwmhDesktops.fullscreenEventHook 

我希望能够通过键绑定来切换它。因此,认情况下,全屏窗口会占据整个屏幕,但是当我关闭 EwmhDesktops.fullscreenEventHook 时,它仅在窗口占据的“平铺”空间中是全屏的。

完整配置为 here

解决方法

将状态添加到 XMonad 本身是非常困难的,因此我们必须使用 IORef 作为外部状态。首先,我们将创建一个全屏事件挂钩,它检查来自 IORef 的布尔值,并且仅在为真时才运行实际的事件挂钩:

toggleableFullscreen :: IORef Bool -> Event -> X All
toggleableFullscreen ref evt =
    io (readIORef ref) >>= \isOn ->
        if isOn
            then XMonad.Hooks.EwmhDesktops.fullscreenEventHook evt
            else return (All True)

这使用 io :: IO a -> X aIO monad 提升为 X monad。现在,在我们的主函数中,我们想用 newIORef 构造 IORef

main = do
    fullscreenRef <- newIORef True -- default to being on
    -- rest of main goes here

现在,我们还将编辑 main 的 handleEventHook 行,以将 toggleableFullscreen 与传入的 fullscreenRef 一起使用:

,handleEventHook = handleEventHook def <+> docksEventHook <+> toggleableFullscreen fullscreenRef

到此,事件挂钩部分就完成了。现在我们需要一种方法来切换它。 myKeys 函数也需要将 fullscreenRef 作为参数接收,因此您必须将其添加到:

myKeys fullscreenRef conf@(XConfig {XMonad.modMask = modm}) = M.fromList $
    -- rest of myKeys

(这是您配置的第 125 行)

然后,您必须添加一个使用 modifyIORef 切换 IORef 的新键绑定(假设为 mod+shift+f):

,((modm .|. shiftMask,xK_f),io (modifyIORef fullscreenRef not))

然后,在您的主函数中,将 fullscreenRef 传递到 myKeys

,keys = myKeys fullscreenRef

(第 400 行)

并删除整个块,因为您不使用它(并且它不会进行类型检查):

defaults = def {
      -- simple stuff
        terminal           = myTerminal,focusFollowsMouse  = myFocusFollowsMouse,clickJustFocuses   = myClickJustFocuses,borderWidth        = myBorderWidth,modMask            = myModMask,workspaces         = myWorkspaces,normalBorderColor  = myNormalBorderColor,focusedBorderColor = myFocusedBorderColor,-- key bindings
        keys               = myKeys,mouseBindings      = myMouseBindings,-- hooks,layouts
        layoutHook         = myLayout,manageHook         = myManageHook,handleEventHook    = myEventHook,logHook            = myLogHook,startupHook        = myStartupHook
    }

(第 446-467 行)

然后,重新启动 xmonad,您应该可以使用 mod+shift+f 切换全屏事件挂钩。