vanadium/xmonad: use event handling to set master pane count

This commit is contained in:
Primrose 2026-01-06 22:22:57 +01:00
parent e65e37d3a9
commit 084261c58e
Signed by: primrose
GPG key ID: 4E887A4CA9714ADA
3 changed files with 64 additions and 21 deletions

View file

@ -25,6 +25,7 @@ library
hs-source-dirs: lib hs-source-dirs: lib
exposed-modules: exposed-modules:
XMonad.Layout.Reflect.Message XMonad.Layout.Reflect.Message
XMonad.Layout.SetMasterNTall
Data.Char.Greek Data.Char.Greek
executable leanamonad executable leanamonad

View file

@ -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

View file

@ -16,7 +16,6 @@ import XMonad.Hooks.OnPropertyChange
import XMonad.Hooks.RefocusLast import XMonad.Hooks.RefocusLast
import XMonad.Hooks.StatusBar import XMonad.Hooks.StatusBar
import XMonad.Layout.FocusTracking import XMonad.Layout.FocusTracking
import XMonad.Layout.IfMax
import XMonad.Layout.Magnifier hiding (Toggle) import XMonad.Layout.Magnifier hiding (Toggle)
import qualified XMonad.Layout.Magnifier as Mag import qualified XMonad.Layout.Magnifier as Mag
import XMonad.Layout.NoBorders import XMonad.Layout.NoBorders
@ -24,6 +23,7 @@ import XMonad.Layout.Reflect
import XMonad.Layout.Reflect.Message import XMonad.Layout.Reflect.Message
import XMonad.Layout.Renamed import XMonad.Layout.Renamed
import XMonad.Layout.ResizableTile import XMonad.Layout.ResizableTile
import XMonad.Layout.SetMasterNTall
import XMonad.Layout.Spacing import XMonad.Layout.Spacing
import XMonad.Layout.ToggleLayouts import XMonad.Layout.ToggleLayouts
import qualified XMonad.StackSet as W import qualified XMonad.StackSet as W
@ -71,23 +71,16 @@ main =
myLayout = myLayout =
avoidStruts avoidStruts
$ smartBorders $ smartBorders
$ toggleLayouts (mag tallr) full $ toggleLayouts (magnifierOff tallr) full
where where
mag = magnifierOff
full = focusTracking Full full = focusTracking Full
mkTallrN n =
smartSpacingWithEdge 5
$ reflectMsg . reflectHoriz
$ ResizableTall n (1/10) (3/7) []
tallr = tallr =
renamed [ Replace "Tall" ] renamed [ Replace "Tall" ]
$ ifMax 3 (mkTallrN 1) $ smartSpacingWithEdge 5
$ ifMax 5 (mkTallrN 2) $ reflectMsg . reflectHoriz
$ ifMax 7 (mkTallrN 3) $ SetMasterNTall
$ mkTallrN 4 $ ResizableTall 1 (1/10) (3/7) []
isSioyek :: Query Bool isSioyek :: Query Bool
isSioyek = className =? "sioyek" isSioyek = className =? "sioyek"
@ -202,14 +195,33 @@ myEventHandleHook =
-- Imagine Spotify playing in the background, a track change would focus that workspace. -- 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 -- We prevent this by checking if the window is in the current workspace
onTitleChange onTitleChange
$ (windowIsInCurrentWorkspace -->) ( windowIsInCurrentWorkspace --> composeAll
$ composeAll
[ isSpotify --> doShiftAndGreedyView multimediaWS [ isSpotify --> doShiftAndGreedyView multimediaWS
, isYouTube --> doShiftAndGreedyView multimediaWS , isYouTube --> doShiftAndGreedyView multimediaWS
, isDiscord --> doShiftAndGreedyView chatWS , isDiscord --> doShiftAndGreedyView chatWS
, isWhatsApp --> doShiftAndGreedyView chatWS , isWhatsApp --> doShiftAndGreedyView chatWS
, isElement --> 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 :: WorkspaceId -> Query (Endo WindowSet)
doShiftAndGreedyView n = doF . go =<< ask doShiftAndGreedyView n = doF . go =<< ask