blob: 9415dc2cccb40f03418a541f5deb8e2c611166f8 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
module Rahm.Desktop.Swap
( SwapBuddy (..),
getSwapBuddy,
recordSwap,
swapWindows,
removeSwapBuddy,
)
where
import Control.Monad (forM_, void)
import Data.Default (Default (..))
import Data.Map (Map)
import qualified Data.Map as Map
import Rahm.Desktop.Common
import Rahm.Desktop.Hooks.WindowChange
import Rahm.Desktop.Logger
import qualified Rahm.Desktop.StackSet as SS
import XMonad (ExtensionClass (..), Window, X, withWindowSet, StateExtension (PersistentExtension), windows)
import qualified XMonad.Util.ExtensibleState as XS
import Data.Maybe (maybeToList)
newtype SwapBuddy = SwapBuddy
{ swapBuddies :: Map Window Window
}
deriving (Read, Show)
instance Default SwapBuddy where
def = SwapBuddy Map.empty
instance ExtensionClass SwapBuddy where
initialValue = def
extensionType = PersistentExtension
-- | Record a swap pairing between two windows.
-- The buddy relationship is bidirectional: w1's buddy becomes w2 and vice versa.
recordSwap :: Window -> Window -> X ()
recordSwap w1 w2 = do
XS.modify $ \sw@(SwapBuddy m) ->
SwapBuddy $ Map.insert w1 w2 $ Map.insert w2 w1 m
logs Debug "Recorded swap pairing: %s <-> %s" (show w1) (show w2)
-- | Get the current (most recent) swap buddy for a window.
getSwapBuddy :: Window -> X (Maybe Window)
getSwapBuddy w = do
SwapBuddy m <- XS.get
return (Map.lookup w m)
-- | Swap windows between two lists.
-- Each window in w1s is swapped with the corresponding window in w2s.
-- Both windows in each pair become each other's swap buddy.
swapWindows :: [Window] -> [Window] -> X ()
swapWindows ws1 ws2 = do
windows $ SS.swapWindows (zip ws1 ws2)
mapM_ (uncurry recordSwap) (zip ws1 ws2)
-- | Clean up all swap buddy entries for a given window.
-- Should be called when a window is killed or moves to hidden workspace.
removeSwapBuddy :: Window -> X ()
removeSwapBuddy w = do
SwapBuddy m <- XS.get
let buddy = Map.lookup w m
cleaned = foldr Map.delete (Map.delete w m) (maybeToList buddy)
XS.put $ SwapBuddy cleaned
logs Debug "Removed swap buddy for window: %s" (show w)
|