1package core
2
3import (
4 "reflect"
5 "slices"
6 "testing"
7)
8
9func TestMoveWindowInColumn(t *testing.T) {
10 for _, o := range []Overflow{OverflowScroll, OverflowFixed} {
11 w := workspace()
12 w.Overflow = o
13 w.Columns = []Column{{Windows: []WindowID{1, 2, 3}, Focus: 1}}
14 w.Apply(ActionMoveWindowUp)
15 if !slices.Equal(w.Columns[0].Windows, []WindowID{2, 1, 3}) || w.Columns[0].Focus != 0 {
16 t.Fatal(o, w.Columns)
17 }
18 // Top end: nothing moves.
19 w.Apply(ActionMoveWindowUp)
20 if !slices.Equal(w.Columns[0].Windows, []WindowID{2, 1, 3}) || w.Columns[0].Focus != 0 {
21 t.Fatal(o, w.Columns)
22 }
23 w.Apply(ActionMoveWindowDown)
24 w.Apply(ActionMoveWindowDown)
25 if !slices.Equal(w.Columns[0].Windows, []WindowID{1, 3, 2}) || w.Columns[0].Focus != 2 {
26 t.Fatal(o, w.Columns)
27 }
28 w.Apply(ActionMoveWindowDown)
29 if id, _ := w.Focused(); id != 2 || w.Columns[0].Focus != 2 {
30 t.Fatal(o, w.Columns)
31 }
32 }
33}
34
35func TestMoveWindowReleasesSlot(t *testing.T) {
36 w := workspace()
37 w.Columns = []Column{{Windows: []WindowID{1, 2}, Slot: 7}}
38 w.Apply(ActionMoveWindowDown)
39 if w.Columns[0].Slot != 0 || !slices.Equal(w.Columns[0].Windows, []WindowID{2, 1}) {
40 t.Fatal(w.Columns)
41 }
42 // A window moving into row 0 takes the place of the slot window: the
43 // slot is released too.
44 w = workspace()
45 w.Columns = []Column{{Windows: []WindowID{1, 2}, Slot: 7, Focus: 1}}
46 w.Apply(ActionMoveWindowUp)
47 if w.Columns[0].Slot != 0 {
48 t.Fatal(w.Columns)
49 }
50 // Rows below keep it.
51 w = workspace()
52 w.Columns = []Column{{Windows: []WindowID{1, 2, 3}, Slot: 7, Focus: 1}}
53 w.Apply(ActionMoveWindowDown)
54 if w.Columns[0].Slot != 7 {
55 t.Fatal(w.Columns)
56 }
57}
58
59func TestMoveWindowOnFloat(t *testing.T) {
60 w := workspace()
61 w.Columns = []Column{{Windows: []WindowID{1, 2}}}
62 w.AddFloating(3, 20, 20)
63 w.Apply(ActionMoveWindowDown)
64 if !slices.Equal(w.Columns[0].Windows, []WindowID{1, 2}) {
65 t.Fatal(w.Columns)
66 }
67}
68
69// set-column-width +N/-N moves cells with no cycle, and a column never
70// goes below one cell.
71func TestSetColumnWidth(t *testing.T) {
72 w := workspace()
73 w.SetOutput(1000, 800)
74 w.SetGaps(10)
75 w.SetMaxColumns(4)
76 w.Overflow = OverflowFixed
77 w.AddWindow(1)
78 w.AddWindow(2)
79 before := w.columnWidth(w.Focus)
80 w.Apply("set-column-width +1")
81 if w.Columns[w.Focus].Cells != 3 || w.columnWidth(w.Focus) <= before {
82 t.Fatal(w.Columns, w.columnWidth(w.Focus), before)
83 }
84 // No donor is left: the width stays, it does not cycle back.
85 w.Apply("set-column-width +1")
86 if w.Columns[0].Cells != 1 || w.Columns[1].Cells != 3 {
87 t.Fatal(w.Columns)
88 }
89 w.Apply("set-column-width -1")
90 if w.Columns[0].Cells != 2 || w.Columns[1].Cells != 2 || w.columnWidth(w.Focus) != before {
91 t.Fatal(w.Columns, w.columnWidth(w.Focus), before)
92 }
93 for range 5 {
94 w.Apply("set-column-width -1")
95 }
96 if w.Columns[1].Cells != 1 || w.Columns[0].Cells != 3 {
97 t.Fatal(w.Columns)
98 }
99 w.Apply("set-column-width +2")
100 if w.Columns[1].Cells != 3 || w.Columns[0].Cells != 1 {
101 t.Fatal(w.Columns)
102 }
103}
104
105func TestSetColumnWidthScroll(t *testing.T) {
106 w := workspace()
107 w.SetOutput(1000, 800)
108 w.SetMaxColumns(4)
109 w.Overflow = OverflowScroll
110 w.AddWindow(1)
111 w.AddWindow(2)
112 w.Apply("set-column-width +1")
113 if w.Columns[w.Focus].Cells != 3 {
114 t.Fatal(w.Columns)
115 }
116 for range 5 {
117 w.Apply("set-column-width +1")
118 }
119 if w.Columns[w.Focus].Cells != 4 {
120 t.Fatal("grows up to max-columns", w.Columns)
121 }
122 for range 9 {
123 w.Apply("set-column-width -1")
124 }
125 if w.Columns[w.Focus].Cells != 1 {
126 t.Fatal("never below one cell", w.Columns)
127 }
128}
129
130func TestSetColumnWidthUnmaximizes(t *testing.T) {
131 for _, a := range []Action{"set-column-width +1", "set-column-width -1", ActionCycleColumnWidth} {
132 w := workspace()
133 w.SetOutput(1000, 800)
134 w.SetMaxColumns(4)
135 w.AddWindow(1)
136 w.ToggleFullWidth()
137 w.Apply(a)
138 if w.Columns[0].FullWidth {
139 t.Fatalf("%s: still maximized", a)
140 }
141 }
142}
143
144func TestColumnEditsUnderFullscreen(t *testing.T) {
145 w := workspace()
146 w.SetOutput(1000, 800)
147 w.Columns = []Column{{Windows: []WindowID{1, 2}, Cells: 1}}
148 w.SetFullscreen(1, true)
149 w.Apply("set-column-width -1")
150 w.Apply(ActionCycleColumnWidth)
151 w.Apply(ActionMoveWindowDown)
152 c := w.Columns[0]
153 if c.Cells != 1 || !slices.Equal(c.Windows, []WindowID{1, 2}) {
154 t.Fatal(c)
155 }
156}
157
158func TestSetColumnWidthFixedPastMax(t *testing.T) {
159 w := workspace()
160 w.Overflow = OverflowFixed
161 for id := WindowID(1); id <= 3; id++ {
162 w.AddWindow(id)
163 }
164 w.Apply("set-column-width +1")
165 w.Apply("set-column-width -1")
166 w.Apply(ActionCycleColumnWidth)
167 for _, c := range w.Columns {
168 if c.Cells != 0 {
169 t.Fatal(w.Columns)
170 }
171 }
172}
173
174func TestMoveWorkspace(t *testing.T) {
175 m := monitor()
176 m.AddWindow(1)
177 m.FocusNumber(2)
178 m.AddWindow(2)
179 m.FocusNumber(3)
180 m.AddWindow(3)
181 // [1:{1}] [2:{2}] [3:{3}] [4:{}]
182 m.Apply(ActionMoveWorkspacePrev)
183 if !reflect.DeepEqual(windows(m), [][]WindowID{{1}, {3}, {2}, {}}) || m.Active != 1 {
184 t.Fatal(windows(m), m.Active)
185 }
186 m.Apply(ActionMoveWorkspacePrev)
187 m.Apply(ActionMoveWorkspacePrev)
188 if !reflect.DeepEqual(windows(m), [][]WindowID{{3}, {1}, {2}, {}}) || m.Active != 0 {
189 t.Fatal(windows(m), m.Active)
190 }
191 m.Apply(ActionMoveWorkspaceNext)
192 m.Apply(ActionMoveWorkspaceNext)
193 // Never past the trailing empty workspace.
194 m.Apply(ActionMoveWorkspaceNext)
195 if !reflect.DeepEqual(windows(m), [][]WindowID{{1}, {2}, {3}, {}}) || m.Active != 2 {
196 t.Fatal(windows(m), m.Active)
197 }
198 // The trailing empty workspace does not move.
199 m.FocusNumber(4)
200 m.Apply(ActionMoveWorkspacePrev)
201 if !reflect.DeepEqual(windows(m), [][]WindowID{{1}, {2}, {3}, {}}) || m.Active != 3 {
202 t.Fatal(windows(m), m.Active)
203 }
204}
205
206func TestMoveWorkspaceHidden(t *testing.T) {
207 m := named(monitor(), NamedWorkspace{Name: "dev"})
208 m.AddWindow(1)
209 m.FocusNumber(2)
210 m.AddWindow(2)
211 m.ToggleNamed("dev")
212 m.Apply(ActionMoveWorkspacePrev)
213 if !reflect.DeepEqual(windows(m), [][]WindowID{{1}, {2}, {}}) {
214 t.Fatal(windows(m))
215 }
216}