aboutsummaryrefslogtreecommitdiffstats
path: root/src/input.c
diff options
context:
space:
mode:
authoruser <user@clank>2026-08-15 20:10:27 +0200
committeruser <user@clank>2026-08-15 20:10:27 +0200
commitbd84065613df44f131476d4b66fd39b2c76da801 (patch)
tree9ee09027b05cea7f5210bef184b578cd62579ff7 /src/input.c
parentsl0ppty: answer the terminal when it is asked how big it is (diff)
downloadslosh-bd84065613df44f131476d4b66fd39b2c76da801.tar.gz
slosh-bd84065613df44f131476d4b66fd39b2c76da801.tar.xz
slosh-bd84065613df44f131476d4b66fd39b2c76da801.zip
sl0ppty: make the finder a modal, and a picker worth using
It was a bare coloured rectangle painted over whatever pane it landed on: no border, no title, no scrim, no way out you could see. It read as output from the program underneath rather than as a window in front of it, which is the one thing an overlay has to get right. It is now a modal like the cheatsheet -- same frame, same scrim, same close button in the place a pane keeps one -- differing in the way that matters: the cheatsheet is read, so any key dismisses it, while this one is used, so it keeps the keyboard until it is answered. The list was the other half of the problem. It showed `1:` for a tab with no name, which looks like something failed to load; a row for a pane with no purpose was three columns of nothing; there was no mark for the pane you are already in, no count, and nothing to say a list had more below the tenth row -- so a list that scrolled looked like a list that ended. An empty result was an empty box, which reads as a broken finder rather than a wrong query. Now: a query field that looks like one (so it shows where the typing goes before you type), the current pane marked, tab/title/purpose told apart by weight, the row under the pointer lit, "N of M" in the footer, arrows for what is off each end, and "no pane matches that" when there is nothing. Keys, because a picker in this shape is reached for by hands that already know one: C-n/C-p, tab/shift-tab, home/end, page up/down, C-u to clear the query, and wrapping at both ends -- one press of Up for the last entry is worth more in a short list than overshoot protection. Backspace deleted a *byte*, so one press through a multi-byte character left the rest of it in the query; it deletes a character now, the way the rename editor already did. The finder owns the pointer as well as the keyboard: a press that is not on one of its rows dismisses it and stops there, rather than also landing on the layout behind and focusing the pane you were clicking away from. Found on the way: CSI Z (shift+tab) was not parsed at all, so it reached neither a binding nor the program in the pane -- every terminal sends back-tab that way, and it is the one chord whose shift lives in the final byte rather than in a modifier param.
Diffstat (limited to 'src/input.c')
-rw-r--r--src/input.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/src/input.c b/src/input.c
index 75da2fd..04dc0b5 100644
--- a/src/input.c
+++ b/src/input.c
@@ -351,6 +351,16 @@ static size_t parse_one(input_parser_t *p, input_cb_t cb, void *ud) {
return i + 1;
}
+ /* Back-tab. Every terminal sends shift+tab as CSI Z rather than as tab
+ * with a modifier param, so it is the one chord whose shift lives in
+ * the final byte -- and a picker that walks its list with tab is
+ * useless without it. */
+ if (final == 'Z') {
+ emit_key(cb, ud, GHOSTTY_KEY_TAB, (uint16_t)(mods | MOD_SHIFT), action,
+ NULL, 0, 0);
+ return i + 1;
+ }
+
int key = final_key(final);
if (key != GHOSTTY_KEY_UNIDENTIFIED) {
emit_key(cb, ud, key, mods, action, NULL, 0, 0);