diff --git a/.config/xmonad/xmonad.hs b/.config/xmonad/xmonad.hs index d44bd54..eac1568 100644 --- a/.config/xmonad/xmonad.hs +++ b/.config/xmonad/xmonad.hs @@ -2,7 +2,8 @@ import Data.Monoid import Data.Char (toLower) -import Control.Monad (forM_, liftM2, when) +import Control.Monad (forM_, join, liftM2, when) +import qualified Data.Map.Strict as M import Data.Maybe (isJust) import XMonad import XMonad.Actions.OnScreen (greedyViewOnScreen) @@ -25,6 +26,7 @@ import XMonad.Layout.ThreeColumns import qualified XMonad.StackSet as W import XMonad.Util.ClickableWorkspaces import XMonad.Util.EZConfig +import qualified XMonad.Util.ExtensibleState as XS import qualified XMonad.Util.Hacks as Hacks import XMonad.Util.Loggers import XMonad.Util.NamedActions @@ -38,6 +40,7 @@ main :: IO () main = xmonad . ewmhFullscreen + . setEwmhFullscreenHooks myFullscreenHook myUnfullscreenHook . setEwmhSwitchDesktopHook safeView . ewmh . docks @@ -415,6 +418,31 @@ myManageHook = -- Case-insensitive, as GTK4 and firejailed apps capitalise their class differently classIn names = (`elem` names) . map toLower <$> className +-- Fullscreen toggles: remember each window's float rect (Nothing if tiled) so leaving +-- fullscreen restores it instead of always sinking the window. +newtype PreFullscreen = PreFullscreen (M.Map Window (Maybe W.RationalRect)) + +instance ExtensionClass PreFullscreen where + initialValue = PreFullscreen M.empty + +myFullscreenHook :: ManageHook +myFullscreenHook = do + w <- ask + liftX $ do + old <- gets (M.lookup w . W.floating . windowset) + XS.modify (\(PreFullscreen m) -> PreFullscreen (M.insert w old m)) + doFullFloat + +-- Windows with no record (e.g. opened fullscreen) are sunk, as before. +myUnfullscreenHook :: ManageHook +myUnfullscreenHook = do + w <- ask + old <- liftX $ do + PreFullscreen m <- XS.get + XS.put (PreFullscreen (M.delete w m)) + pure (join (M.lookup w m)) + maybe doSink doRectFloat old + -- Handle event hook myHandleEventHook :: Event -> X All myHandleEventHook =