From 084261c58ebd58080e4121e43221f28f59bce0a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9ana=20=E6=B1=9F?= Date: Tue, 6 Jan 2026 22:22:57 +0100 Subject: [PATCH] vanadium/xmonad: use event handling to set master pane count --- .../vanadium/home/xmonad/leanamonad.cabal | 1 + .../lib/XMonad/Layout/SetMasterNTall.hs | 30 +++++++++++ .../vanadium/home/xmonad/xmonad.hs | 54 +++++++++++-------- 3 files changed, 64 insertions(+), 21 deletions(-) create mode 100644 nix/configurations/vanadium/home/xmonad/lib/XMonad/Layout/SetMasterNTall.hs diff --git a/nix/configurations/vanadium/home/xmonad/leanamonad.cabal b/nix/configurations/vanadium/home/xmonad/leanamonad.cabal index bfe56163..9fd30e3b 100644 --- a/nix/configurations/vanadium/home/xmonad/leanamonad.cabal +++ b/nix/configurations/vanadium/home/xmonad/leanamonad.cabal @@ -25,6 +25,7 @@ library hs-source-dirs: lib exposed-modules: XMonad.Layout.Reflect.Message + XMonad.Layout.SetMasterNTall Data.Char.Greek executable leanamonad diff --git a/nix/configurations/vanadium/home/xmonad/lib/XMonad/Layout/SetMasterNTall.hs b/nix/configurations/vanadium/home/xmonad/lib/XMonad/Layout/SetMasterNTall.hs new file mode 100644 index 00000000..a08f7742 --- /dev/null +++ b/nix/configurations/vanadium/home/xmonad/lib/XMonad/Layout/SetMasterNTall.hs @@ -0,0 +1,30 @@ +{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} + +-- Wraps ResizableTall, allows setting master count to a number directly +module XMonad.Layout.SetMasterNTall + ( SetMasterNTall(..) + , SetMasterN(..) + ) where + +import XMonad +import qualified XMonad.StackSet as W +import XMonad.Layout.ResizableTile + +-- Message +data SetMasterN = SetMasterN Int +instance Message SetMasterN + +-- Layout +newtype SetMasterNTall a = SetMasterNTall { unSetMasterNTall :: ResizableTall a } + deriving (Read, Show) + +instance LayoutClass SetMasterNTall a where + runLayout (W.Workspace t l s) = + let ws' = W.Workspace t (unSetMasterNTall l) s + in (fmap . fmap . fmap) SetMasterNTall . runLayout ws' + + handleMessage (SetMasterNTall l@(ResizableTall _n0 d f s)) mess + | Just (SetMasterN n) <- fromMessage mess = pure $ Just $ SetMasterNTall $ ResizableTall n d f s + | otherwise = (fmap . fmap) SetMasterNTall . handleMessage l $ mess + + description (SetMasterNTall l) = description l diff --git a/nix/configurations/vanadium/home/xmonad/xmonad.hs b/nix/configurations/vanadium/home/xmonad/xmonad.hs index 84756b09..e5c8ad57 100644 --- a/nix/configurations/vanadium/home/xmonad/xmonad.hs +++ b/nix/configurations/vanadium/home/xmonad/xmonad.hs @@ -16,7 +16,6 @@ import XMonad.Hooks.OnPropertyChange import XMonad.Hooks.RefocusLast import XMonad.Hooks.StatusBar import XMonad.Layout.FocusTracking -import XMonad.Layout.IfMax import XMonad.Layout.Magnifier hiding (Toggle) import qualified XMonad.Layout.Magnifier as Mag import XMonad.Layout.NoBorders @@ -24,6 +23,7 @@ import XMonad.Layout.Reflect import XMonad.Layout.Reflect.Message import XMonad.Layout.Renamed import XMonad.Layout.ResizableTile +import XMonad.Layout.SetMasterNTall import XMonad.Layout.Spacing import XMonad.Layout.ToggleLayouts import qualified XMonad.StackSet as W @@ -71,23 +71,16 @@ main = myLayout = avoidStruts $ smartBorders - $ toggleLayouts (mag tallr) full + $ toggleLayouts (magnifierOff tallr) full where - mag = magnifierOff - full = focusTracking Full - mkTallrN n = - smartSpacingWithEdge 5 - $ reflectMsg . reflectHoriz - $ ResizableTall n (1/10) (3/7) [] - tallr = renamed [ Replace "Tall" ] - $ ifMax 3 (mkTallrN 1) - $ ifMax 5 (mkTallrN 2) - $ ifMax 7 (mkTallrN 3) - $ mkTallrN 4 + $ smartSpacingWithEdge 5 + $ reflectMsg . reflectHoriz + $ SetMasterNTall + $ ResizableTall 1 (1/10) (3/7) [] isSioyek :: Query Bool isSioyek = className =? "sioyek" @@ -202,14 +195,33 @@ myEventHandleHook = -- Imagine Spotify playing in the background, a track change would focus that workspace. -- We prevent this by checking if the window is in the current workspace onTitleChange - $ (windowIsInCurrentWorkspace -->) - $ composeAll - [ isSpotify --> doShiftAndGreedyView multimediaWS - , isYouTube --> doShiftAndGreedyView multimediaWS - , isDiscord --> doShiftAndGreedyView chatWS - , isWhatsApp --> doShiftAndGreedyView chatWS - , isElement --> doShiftAndGreedyView chatWS - ] + ( windowIsInCurrentWorkspace --> composeAll + [ isSpotify --> doShiftAndGreedyView multimediaWS + , isYouTube --> doShiftAndGreedyView multimediaWS + , isDiscord --> doShiftAndGreedyView chatWS + , isWhatsApp --> doShiftAndGreedyView chatWS + , isElement --> doShiftAndGreedyView chatWS + ] + ) + <> setMasterNEventHandleHook + +setMasterNEventHandleHook :: Event -> X All +setMasterNEventHandleHook ev = + let adjustMasterCount :: X () + adjustMasterCount = do + count <- gets $ length . W.integrate' . W.stack . W.workspace . W.current . windowset + if count <= 3 then sendMessage (SetMasterN 1) + else if count <= 5 then sendMessage (SetMasterN 2) + else if count <= 7 then sendMessage (SetMasterN 3) + else pure () + in do + case ev of + MapRequestEvent{} -> adjustMasterCount + ConfigureEvent{} -> adjustMasterCount + DestroyWindowEvent {} -> adjustMasterCount + _ -> pure () + + pure (All True) doShiftAndGreedyView :: WorkspaceId -> Query (Endo WindowSet) doShiftAndGreedyView n = doF . go =<< ask