From 07e82294f073050cf319afd27ce38f1efde1b500 Mon Sep 17 00:00:00 2001 From: Tomas Janousek Date: Sun, 23 Oct 2022 23:14:19 +0100 Subject: [PATCH] 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 --- XMonad/Hooks/EwmhDesktops.hs | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/XMonad/Hooks/EwmhDesktops.hs b/XMonad/Hooks/EwmhDesktops.hs index 85b27e68bc..c4161aa8f3 100644 --- a/XMonad/Hooks/EwmhDesktops.hs +++ b/XMonad/Hooks/EwmhDesktops.hs @@ -40,6 +40,10 @@ module XMonad.Hooks.EwmhDesktops ( -- $customActivate setEwmhActivateHook, + -- ** Fullscreen + -- $customFullscreen + setEwmhFullscreenHooks, + -- ** @_NET_DESKTOP_VIEWPORT@ -- $customManageDesktopViewport disableEwmhManageDesktopViewport, @@ -106,6 +110,8 @@ data EwmhDesktopsConfig = -- ^ configurable workspace rename (see 'XMonad.Hooks.StatusBar.PP.ppRename') , activateHook :: ManageHook -- ^ configurable handling of window activation requests + , fullscreenHooks :: (ManageHook, ManageHook) + -- ^ configurable handling of fullscreen state requests , manageDesktopViewport :: Bool -- ^ manage @_NET_DESKTOP_VIEWPORT@? } @@ -115,6 +121,7 @@ instance Default EwmhDesktopsConfig where { workspaceSort = getSortByIndex , workspaceRename = pure pure , activateHook = doFocus + , fullscreenHooks = (doFullFloat, doSink) , manageDesktopViewport = True } @@ -235,6 +242,22 @@ setEwmhWorkspaceRename f = XC.modifyDef $ \c -> c{ workspaceRename = f } setEwmhActivateHook :: ManageHook -> XConfig l -> XConfig l 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 -- Setting @_NET_DESKTOP_VIEWPORT@ is typically desired but can lead to a -- confusing workspace list in polybar, where this information is used to @@ -472,7 +495,12 @@ fullscreenStartup = setFullscreenSupported -- Note this is not included in 'ewmh'. {-# DEPRECATED fullscreenEventHook "Use ewmhFullscreen instead." #-} 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 wmstate <- getAtom "_NET_WM_STATE" 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 (action == add || (action == toggle && not isFull)) $ do 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 chWstate $ delete (fi fullsc) - windows $ W.sink win + windows . appEndo =<< runQuery unFullscreenHook win return $ All True -fullscreenEventHook _ = return $ All True +fullscreenEventHook' _ _ = return $ All True setNumberOfDesktops :: (Integral a) => a -> X () setNumberOfDesktops n = withDisplay $ \dpy -> do