aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authoruser <user@clank>2026-08-14 16:18:04 +0200
committeruser <user@clank>2026-08-14 16:18:04 +0200
commitb0e42c5ff20098fc2fa5f44cbb28cc4f7b1e11e6 (patch)
treea972d8446a1f812d19ccb2fa12e6d1a12cc3f099 /src
parentsl0ppty: a tab is laid out or it is a list, never half of each (diff)
downloadslosh-b0e42c5ff20098fc2fa5f44cbb28cc4f7b1e11e6.tar.gz
slosh-b0e42c5ff20098fc2fa5f44cbb28cc4f7b1e11e6.tar.xz
slosh-b0e42c5ff20098fc2fa5f44cbb28cc4f7b1e11e6.zip
sl0ppty: a row in the stack lights up under the pointer
Once a tab is a list, its rows are what you are picking from, and until now they gave no sign of being pickable at all — a flat rule that looked the same whether the mouse was on it or on the other side of the screen. Lit immediately rather than on dwell. The dwell that keeps a split guide from flashing as the pointer crosses a border is exactly wrong here: this is feedback about where the pointer *is*, not an action being armed, and a list you are scanning has to track the mouse continuously or it feels broken. The finder's language for "this is the row", a solid bar, rather than a brighter rule. FRAME_FOCUS would have read as "this pane is focused", which is a different claim and one a collapsed row cannot make. Hovering deliberately does not open the row. focus: already ignored everything but a press, so this needed no guard — but it is the property worth keeping and now has a test: a list that opened panes as the mouse crossed it would shuffle under you while you read it. Clicking is still what opens one. The lit row is decided from the same rect that is registered as the row's hit, in the same function, so what lights up and what would be clicked cannot drift apart.
Diffstat (limited to 'src')
-rw-r--r--src/app.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/src/app.c b/src/app.c
index bf463c9..ace5119 100644
--- a/src/app.c
+++ b/src/app.c
@@ -1584,9 +1584,30 @@ static void draw_collapsed(app_t *a, screen_t *s, node_t *n) {
status && *status ? " · " : "", status && *status ? status : "");
line[r.w < sizeof line ? r.w : sizeof line - 1] = 0;
- for (uint16_t x = r.x; x < r.x + r.w; x++)
- screen_text(s, x, r.y, "─", FRAME_IDLE, NO_COLOR, 0);
- screen_text(s, r.x, r.y, line, FRAME_IDLE, NO_COLOR, 0);
+ /* Once a tab is a list, its rows are what you are picking from, and a row
+ * under the pointer should say so. Immediate rather than on dwell: this is
+ * feedback about where the pointer *is*, not an action being armed, and a
+ * list you are scanning should track the mouse continuously — the dwell that
+ * stops a guide from flashing would only make this feel broken.
+ *
+ * Tested against the rect registered as the hit two lines below, so the row
+ * that lights up and the row that would be clicked are the same row by
+ * construction. A drag already owns the pointer and says nothing here. */
+ bool hot = a->ptr_valid && a->drag.kind == DRAG_NONE && a->ptr_y == r.y &&
+ a->ptr_x >= r.x && a->ptr_x < r.x + r.w;
+
+ /* The finder's language for "this is the row": a solid bar, not a brighter
+ * rule. FRAME_FOCUS would have read as "this pane is focused", which is a
+ * different claim and one this row cannot make. */
+ if (hot)
+ for (uint16_t x = r.x; x < r.x + r.w; x++)
+ screen_text(s, x, r.y, " ", BTN_FG, BTN_BG, 0);
+ else
+ for (uint16_t x = r.x; x < r.x + r.w; x++)
+ screen_text(s, x, r.y, "─", FRAME_IDLE, NO_COLOR, 0);
+
+ screen_text(s, r.x, r.y, line, hot ? BTN_FG : FRAME_IDLE,
+ hot ? BTN_BG : NO_COLOR, hot ? ATTR_BOLD : 0);
char action[48];
snprintf(action, sizeof action, "focus:%u", leaf->id);