X.H.EwmhDesktops: Add (un)fullscreen hooks

Fairly straightforward, just add two hooks for (un)fullscreening. There
are multiple motivations for this:

* Users are calling for unfullscreened windows to revert back to their
  original location if they were floating.

* XMonad.Layout.Fullscreen uses some deprecated exports from
  XMonad.Hooks.EwmhDesktops and reimplements fullscreenEventHook.

This commit only adds the hooks. Neither of the motivations are dealt
with yet, so the docs are a bit terse still.

Related: https://github.com/xmonad/xmonad-contrib/issues/456
Related: https://github.com/xmonad/xmonad-contrib/issues/394
Related: https://github.com/xmonad/xmonad-contrib/pull/626
This commit is contained in:
Tomas Janousek 2022-10-23 23:14:19 +01:00
parent 815a595b46
commit 2dcc3a92e7

View File

@ -40,6 +40,10 @@ module XMonad.Hooks.EwmhDesktops (
-- $customActivate -- $customActivate
setEwmhActivateHook, setEwmhActivateHook,
-- ** Fullscreen
-- $customFullscreen
setEwmhFullscreenHooks,
-- ** @_NET_DESKTOP_VIEWPORT@ -- ** @_NET_DESKTOP_VIEWPORT@
-- $customManageDesktopViewport -- $customManageDesktopViewport
disableEwmhManageDesktopViewport, disableEwmhManageDesktopViewport,
@ -106,6 +110,8 @@ data EwmhDesktopsConfig =
-- ^ configurable workspace rename (see 'XMonad.Hooks.StatusBar.PP.ppRename') -- ^ configurable workspace rename (see 'XMonad.Hooks.StatusBar.PP.ppRename')
, activateHook :: ManageHook , activateHook :: ManageHook
-- ^ configurable handling of window activation requests -- ^ configurable handling of window activation requests
, fullscreenHooks :: (ManageHook, ManageHook)
-- ^ configurable handling of fullscreen state requests
, manageDesktopViewport :: Bool , manageDesktopViewport :: Bool
-- ^ manage @_NET_DESKTOP_VIEWPORT@? -- ^ manage @_NET_DESKTOP_VIEWPORT@?
} }
@ -115,6 +121,7 @@ instance Default EwmhDesktopsConfig where
{ workspaceSort = getSortByIndex { workspaceSort = getSortByIndex
, workspaceRename = pure pure , workspaceRename = pure pure
, activateHook = doFocus , activateHook = doFocus
, fullscreenHooks = (doFullFloat, doSink)
, manageDesktopViewport = True , manageDesktopViewport = True
} }
@ -235,6 +242,22 @@ setEwmhWorkspaceRename f = XC.modifyDef $ \c -> c{ workspaceRename = f }
setEwmhActivateHook :: ManageHook -> XConfig l -> XConfig l setEwmhActivateHook :: ManageHook -> XConfig l -> XConfig l
setEwmhActivateHook h = XC.modifyDef $ \c -> c{ activateHook = h } setEwmhActivateHook h = XC.modifyDef $ \c -> c{ activateHook = h }
-- $customFullscreen
-- When a client sends a @_NET_WM_STATE@ request to add/remove/toggle the
-- @_NET_WM_STATE_FULLSCREEN@ state, 'ewmhFullscreen' uses a pair of hooks to
-- make the window fullscreen and revert its state. The default hooks are
-- stateless: windows are fullscreened by turning them into fullscreen floats,
-- and reverted by sinking them into the tiling layer. This behaviour can be
-- configured by supplying a pair of 'ManageHook's to 'setEwmhFullscreenHooks'.
-- | Set (replace) the hooks invoked when clients ask to add/remove the
-- $_NET_WM_STATE_FULLSCREEN@ state. The defaults are 'doFullFloat' and
-- 'doSink'.
setEwmhFullscreenHooks :: ManageHook -> ManageHook -> XConfig l -> XConfig l
setEwmhFullscreenHooks f uf = XC.modifyDef $ \c -> c{ fullscreenHooks = (f, uf) }
-- $customManageDesktopViewport -- $customManageDesktopViewport
-- Setting @_NET_DESKTOP_VIEWPORT@ is typically desired but can lead to a -- Setting @_NET_DESKTOP_VIEWPORT@ is typically desired but can lead to a
-- confusing workspace list in polybar, where this information is used to -- confusing workspace list in polybar, where this information is used to
@ -472,7 +495,12 @@ fullscreenStartup = setFullscreenSupported
-- Note this is not included in 'ewmh'. -- Note this is not included in 'ewmh'.
{-# DEPRECATED fullscreenEventHook "Use ewmhFullscreen instead." #-} {-# DEPRECATED fullscreenEventHook "Use ewmhFullscreen instead." #-}
fullscreenEventHook :: Event -> X All fullscreenEventHook :: Event -> X All
fullscreenEventHook (ClientMessageEvent _ _ _ dpy win typ (action:dats)) = do fullscreenEventHook = XC.withDef . fullscreenEventHook'
fullscreenEventHook' :: Event -> EwmhDesktopsConfig -> X All
fullscreenEventHook'
ClientMessageEvent{ev_event_display = dpy, ev_window = win, ev_message_type = typ, ev_data = action:dats}
EwmhDesktopsConfig{fullscreenHooks = (fullscreenHook, unFullscreenHook)} = do
managed <- isClient win managed <- isClient win
wmstate <- getAtom "_NET_WM_STATE" wmstate <- getAtom "_NET_WM_STATE"
fullsc <- getAtom "_NET_WM_STATE_FULLSCREEN" fullsc <- getAtom "_NET_WM_STATE_FULLSCREEN"
@ -489,14 +517,14 @@ fullscreenEventHook (ClientMessageEvent _ _ _ dpy win typ (action:dats)) = do
when (managed && typ == wmstate && fi fullsc `elem` dats) $ do when (managed && typ == wmstate && fi fullsc `elem` dats) $ do
when (action == add || (action == toggle && not isFull)) $ do when (action == add || (action == toggle && not isFull)) $ do
chWstate (fi fullsc:) chWstate (fi fullsc:)
windows $ W.float win $ W.RationalRect 0 0 1 1 windows . appEndo =<< runQuery fullscreenHook win
when (action == remove || (action == toggle && isFull)) $ do when (action == remove || (action == toggle && isFull)) $ do
chWstate $ delete (fi fullsc) chWstate $ delete (fi fullsc)
windows $ W.sink win windows . appEndo =<< runQuery unFullscreenHook win
return $ All True return $ All True
fullscreenEventHook _ = return $ All True fullscreenEventHook' _ _ = return $ All True
setNumberOfDesktops :: (Integral a) => a -> X () setNumberOfDesktops :: (Integral a) => a -> X ()
setNumberOfDesktops n = withDisplay $ \dpy -> do setNumberOfDesktops n = withDisplay $ \dpy -> do