From e2fd3e4aa91c3d1f305eeac6cb1b419a9ec6e2c9 Mon Sep 17 00:00:00 2001 From: Daniele Fucini Date: Sat, 14 Nov 2026 19:43:37 +0100 Subject: [PATCH] xmonad: restore floating windows after leaving fullscreen Remember each window's float rect when it goes fullscreen and put it back on exit, instead of always sinking it (Viewnior after F5). Windows with no record are still sunk. --- .config/xmonad/xmonad.hs | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) 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 =