Alt+Shift+Up/Down reorder the active tab within the overlay list

Move the active tab's slot in the tab order without switching the active
surface: the tab stays active and only its position changes, wrapping from
either end, and holding the chord keeps moving it via the same synthesized
repeat as cycling.  Only live tabs (a toplevel, not mid-close) count as
positions, mirroring cycle_tab.

The repeat latch is generalized with a repeat_kind so one timer serves both
cycle and reorder.  Ctrl+Shift+T inside the moved tab anchors right after
its new position (add_tab uses the active slot's index), which the new
test verifies.

Tests: 5x standalone + full suite 3x green (40 passed, 1 skipped).
This commit is contained in:
Andrew Hamilton 2026-08-17 10:45:21 +10:00
parent fb29f03dc0
commit 6677012a9a
3 changed files with 158 additions and 3 deletions

View file

@ -99,6 +99,8 @@ Notes:
| `Alt` (hold) | Show the tab-title overlay (centered) |
| `Alt+Up` | Previous tab (hold to keep cycling) |
| `Alt+Down` | Next tab (hold to keep cycling) |
| `Alt+Shift+Up` | Move the active tab earlier in the list |
| `Alt+Shift+Down` | Move the active tab later in the list |
| `Alt+Delete` | Close the active tab (SIGTERM, SIGKILL fallback) |
| `Ctrl+Shift+T` | Open a new terminal tab next to the current one |
@ -120,6 +122,13 @@ The tab-cycling hotkey only emits a physical press for the first tab switch;
repeats are synthesized, so holding `Alt+Up/Down` keeps stepping through
tabs while any other key stops it.
`Alt+Shift+Up/Down` reorder the overlay list instead of switching: the
active tab stays active, it just moves one position earlier or later in the
order. Moving off either end wraps around to the other end, and holding the
chord keeps moving it (same synthesized repeat as cycling). A `Ctrl+Shift+T`
inside the moved tab opens exactly where the reordered list says it should —
immediately right of the tab's new position.
`Alt+Delete` closes the active tab. The tab disappears immediately (the tab
to its right becomes active, or the left neighbor if it was the rightmost);
the client's process group gets a `SIGTERM`, escalated to `SIGKILL` after a