fix(core): leave a pushed cascade column that moved away in place
restoreBand names the pushed column across the workspace before looking in the adjacent band, so a column moved farther away has no stand-in.
- commit
- 1b76e21847ee2d273303a58bc91f2940d20b8897
- author
- brice · · 2026-10-16 17:02 UTC
- parent
- d4c54ab
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
2 files · +22 -5
M internal/core/cascade.go +8 -5
| @@ -445,12 +445,15 @@ func (w *Workspace) restoreBand() bool { | |||
| 445 | 445 | if rev { | |
| 446 | 446 | e = ids[len(ids)-1-k] | |
| 447 | 447 | } | |
| 448 | - | i := -1 | |
| 449 | - | for _, v := range e { | |
| 450 | - | if i = slices.IndexFunc(bands[nb], func(c Column) bool { return c.Windows[0] == v }); i >= 0 { | |
| 451 | - | break | |
| 452 | - | } | |
| 448 | + | // The column is named across the workspace first: one that | |
| 449 | + | // moved farther away stays there, with no stand-in. | |
| 450 | + | head := slices.IndexFunc(e, func(v WindowID) bool { | |
| 451 | + | return slices.ContainsFunc(w.Columns, func(c Column) bool { return c.Windows[0] == v }) | |
| 452 | + | }) | |
| 453 | + | if head < 0 { | |
| 454 | + | continue | |
| 453 | 455 | } | |
| 456 | + | i := slices.IndexFunc(bands[nb], func(c Column) bool { return c.Windows[0] == e[head] }) | |
| 454 | 457 | if i < 0 { | |
| 455 | 458 | continue | |
| 456 | 459 | } | |
| @@ -445,12 +445,15 @@ func (w *Workspace) restoreBand() bool { | |||||
| 445 | if rev { | 445 | if rev { | ||
| 446 | e = ids[len(ids)-1-k] | 446 | e = ids[len(ids)-1-k] | ||
| 447 | } | 447 | } | ||
| 448 | - | i := -1 | 448 | + | // The column is named across the workspace first: one that |
| 449 | - | for _, v := range e { | 449 | + | // moved farther away stays there, with no stand-in. |
| 450 | - | if i = slices.IndexFunc(bands[nb], func(c Column) bool { return c.Windows[0] == v }); i >= 0 { | 450 | + | head := slices.IndexFunc(e, func(v WindowID) bool { |
| 451 | - | break | 451 | + | return slices.ContainsFunc(w.Columns, func(c Column) bool { return c.Windows[0] == v }) |
| 452 | - | } | 452 | + | }) |
| 453 | + | if head < 0 { | |||
| 454 | + | continue | |||
| 453 | } | 455 | } | ||
| 456 | + | i := slices.IndexFunc(bands[nb], func(c Column) bool { return c.Windows[0] == e[head] }) | |||
| 454 | if i < 0 { | 457 | if i < 0 { | ||
| 455 | continue | 458 | continue | ||
| 456 | } | 459 | } | ||
M internal/core/cascade_bands_test.go +14 -0
| @@ -236,6 +236,20 @@ func TestCascadeRestoreBandMemory(t *testing.T) { | |||
| 236 | 236 | w.ToggleFullWidth() | |
| 237 | 237 | wantBands(t, w, []WindowID{1, 2, 3}, []WindowID{4, 5}) | |
| 238 | 238 | }) | |
| 239 | + | t.Run("a pushed column moved away has no stand-in", func(t *testing.T) { | |
| 240 | + | c, w := cascadeMovesCore(t, 5, 4, false) // {1 2 3 4} {5} | |
| 241 | + | w.FocusID(4) | |
| 242 | + | w.ConsumeOrExpel(-1) // {1 2 3/4} {5} | |
| 243 | + | w.FocusID(2) | |
| 244 | + | w.ToggleFullWidth() // {1} {2*} {3/4 5} | |
| 245 | + | w.FocusID(4) | |
| 246 | + | w.ConsumeOrExpel(-1) // {1} {2*} {4 3 5} | |
| 247 | + | w.FocusID(3) | |
| 248 | + | c.applyAction(ActionMoveWindowDown) // {1} {2*} {4 5} {3} | |
| 249 | + | w.FocusID(2) | |
| 250 | + | w.ToggleFullWidth() | |
| 251 | + | wantBands(t, w, []WindowID{1, 2}, []WindowID{4, 5}, []WindowID{3}) | |
| 252 | + | }) | |
| 239 | 253 | t.Run("first window of a pushed column closed", func(t *testing.T) { | |
| 240 | 254 | _, w := cascadeMovesCore(t, 4, 3, false) // {1 2 3} {4} | |
| 241 | 255 | w.FocusID(4) | |
| @@ -236,6 +236,20 @@ func TestCascadeRestoreBandMemory(t *testing.T) { | |||||
| 236 | w.ToggleFullWidth() | 236 | w.ToggleFullWidth() | ||
| 237 | wantBands(t, w, []WindowID{1, 2, 3}, []WindowID{4, 5}) | 237 | wantBands(t, w, []WindowID{1, 2, 3}, []WindowID{4, 5}) | ||
| 238 | }) | 238 | }) | ||
| 239 | + | t.Run("a pushed column moved away has no stand-in", func(t *testing.T) { | |||
| 240 | + | c, w := cascadeMovesCore(t, 5, 4, false) // {1 2 3 4} {5} | |||
| 241 | + | w.FocusID(4) | |||
| 242 | + | w.ConsumeOrExpel(-1) // {1 2 3/4} {5} | |||
| 243 | + | w.FocusID(2) | |||
| 244 | + | w.ToggleFullWidth() // {1} {2*} {3/4 5} | |||
| 245 | + | w.FocusID(4) | |||
| 246 | + | w.ConsumeOrExpel(-1) // {1} {2*} {4 3 5} | |||
| 247 | + | w.FocusID(3) | |||
| 248 | + | c.applyAction(ActionMoveWindowDown) // {1} {2*} {4 5} {3} | |||
| 249 | + | w.FocusID(2) | |||
| 250 | + | w.ToggleFullWidth() | |||
| 251 | + | wantBands(t, w, []WindowID{1, 2}, []WindowID{4, 5}, []WindowID{3}) | |||
| 252 | + | }) | |||
| 239 | t.Run("first window of a pushed column closed", func(t *testing.T) { | 253 | t.Run("first window of a pushed column closed", func(t *testing.T) { | ||
| 240 | _, w := cascadeMovesCore(t, 4, 3, false) // {1 2 3} {4} | 254 | _, w := cascadeMovesCore(t, 4, 3, false) // {1 2 3} {4} | ||
| 241 | w.FocusID(4) | 255 | w.FocusID(4) | ||