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.
This commit is contained in:
Daniele Fucini committed 2026-11-14 19:43:37 +01:00
1 parent 4a96319bb2
commit e2fd3e4aa9
1 file changed
+29 -1
+29 -1
View File
@@ -2,7 +2,8 @@
import Data.Monoid import Data.Monoid
import Data.Char (toLower) 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 Data.Maybe (isJust)
import XMonad import XMonad
import XMonad.Actions.OnScreen (greedyViewOnScreen) import XMonad.Actions.OnScreen (greedyViewOnScreen)
@@ -25,6 +26,7 @@ import XMonad.Layout.ThreeColumns
import qualified XMonad.StackSet as W import qualified XMonad.StackSet as W
import XMonad.Util.ClickableWorkspaces import XMonad.Util.ClickableWorkspaces
import XMonad.Util.EZConfig import XMonad.Util.EZConfig
import qualified XMonad.Util.ExtensibleState as XS
import qualified XMonad.Util.Hacks as Hacks import qualified XMonad.Util.Hacks as Hacks
import XMonad.Util.Loggers import XMonad.Util.Loggers
import XMonad.Util.NamedActions import XMonad.Util.NamedActions
@@ -38,6 +40,7 @@ main :: IO ()
main = main =
xmonad xmonad
. ewmhFullscreen . ewmhFullscreen
. setEwmhFullscreenHooks myFullscreenHook myUnfullscreenHook
. setEwmhSwitchDesktopHook safeView . setEwmhSwitchDesktopHook safeView
. ewmh . ewmh
. docks . docks
@@ -415,6 +418,31 @@ myManageHook =
-- Case-insensitive, as GTK4 and firejailed apps capitalise their class differently -- Case-insensitive, as GTK4 and firejailed apps capitalise their class differently
classIn names = (`elem` names) . map toLower <$> className 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 -- Handle event hook
myHandleEventHook :: Event -> X All myHandleEventHook :: Event -> X All
myHandleEventHook = myHandleEventHook =