aboutsummaryrefslogtreecommitdiff
path: root/src/Rahm/Desktop/Layout.hs
blob: f6fb49e026214c52ca1c463d1e68660858d383db (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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
module Rahm.Desktop.Layout
  ( myLayout,
    myLayoutList,
    nLayouts,
  )
where

import Rahm.Desktop.Layout.ConsistentMosaic
  ( MosaicWrap (..),
    expandPositionAlt,
    shrinkPositionAlt,
  )
import Rahm.Desktop.Layout.Flip (flippable)
import Rahm.Desktop.Layout.Hole (hole)
import Rahm.Desktop.Layout.List
  ( layoutList,
    layoutListLength,
    nil,
    (|:),
  )
import Rahm.Desktop.Layout.PinWindow (PinWindowLayout (PinWindowLayout))
import Rahm.Desktop.Layout.Pop (poppable)
import Rahm.Desktop.Layout.Redescribe (Describer (..), Redescribe (..))
import Rahm.Desktop.Layout.ReinterpretMessage (DoReinterpret (..), ReinterpretMessage (..))
import Rahm.Desktop.Layout.Rotate (rotateable)
import XMonad
  ( IncMasterN (..),
    Resize (..),
    SomeMessage (..),
    Tall (..),
    Window,
    fromMessage,
  )
import XMonad.Hooks.ManageDocks (avoidStruts)
import XMonad.Layout.Fullscreen (fullscreenFull)
import XMonad.Layout.LayoutModifier (ModifiedLayout (..))
import XMonad.Layout.MosaicAlt
  ( MosaicAlt (..),
  )
import XMonad.Layout.Spacing (Border (..), spacingRaw)
import XMonad.Layout.Spiral (spiral)

myLayout =
  fullscreenFull $
    PinWindowLayout $
      hole $
        avoidStruts myLayoutList

mySpacing = spacingRaw True (Border 5 5 5 5) True (Border 5 5 5 5) True

mods =
  mySpacing . poppable . flippable . rotateable

myLayoutList =
  layoutList $
    mods (reinterpretIncMaster $ spiral (6 / 7))
      |: mods (MosaicWrap $ modifyMosaic (MosaicAlt mempty :: MosaicAlt Window))
      |: mods (Redescribe UsingTall (Tall 1 (3 / 100) (1 / 2)))
      |: nil

nLayouts :: Int
nLayouts = layoutListLength myLayoutList

-- Mosaic doesn't have the concept of a "Master Space", so reinterpret messages
-- intended to modify the master space and instead have those messages expand
-- and shrink the current window.
--
-- "ForMosaic" is an instance of the Symbol kind. This is some neat type-system
-- hacking one can do in Haskell.
instance DoReinterpret "ForMosaic" where
  -- IncMaster message
  reinterpretMessage _ (fromMessage -> Just (IncMasterN n)) = do
    Just . SomeMessage
      <$> ( if n > 0
              then expandPositionAlt
              else shrinkPositionAlt
          )

  -- ResizeMaster message
  reinterpretMessage _ (fromMessage -> Just m) = do
    Just . SomeMessage
      <$> ( case m of
              Expand -> expandPositionAlt
              Shrink -> shrinkPositionAlt
          )

  -- Messages that don't match the above, just leave it unmodified.
  reinterpretMessage _ m = return (Just m)

instance DoReinterpret "IncMasterToResizeMaster" where
  reinterpretMessage _ (fromMessage -> Just (IncMasterN n)) =
    return $
      Just $
        if n > 0
          then SomeMessage Expand
          else SomeMessage Shrink
  reinterpretMessage _ m = return (Just m)

modifyMosaic :: l a -> ModifiedLayout (ReinterpretMessage "ForMosaic") l a
modifyMosaic = ModifiedLayout ReinterpretMessage

reinterpretIncMaster ::
  l a -> ModifiedLayout (ReinterpretMessage "IncMasterToResizeMaster") l a
reinterpretIncMaster = ModifiedLayout ReinterpretMessage

data UsingTall = UsingTall deriving (Read, Show)

instance Describer UsingTall Tall where
  newDescription _ (Tall mast _ _) _ = "Tall(" ++ show mast ++ ")"