diff options
| author | user <user@clank> | 2026-09-10 16:32:10 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-09-10 16:32:10 +0200 |
| commit | a2d08f4876226446c0052f033e8afea2f2ffbbf1 (patch) | |
| tree | ac77189b9c928939202adca4a43298730bccd8d2 /src | |
| parent | sidebar: the new-tab button says what it is, given a row to say it on (diff) | |
| download | slosh-a2d08f4876226446c0052f033e8afea2f2ffbbf1.tar.gz slosh-a2d08f4876226446c0052f033e8afea2f2ffbbf1.tar.xz slosh-a2d08f4876226446c0052f033e8afea2f2ffbbf1.zip | |
sidebar: statuses wear italic instead of an indent, and can wear colour
Three columns of indent is a fifth of a sixteen-column sidebar, spent
saying 'this belongs to the row above'. The slant says it in none: a
status now starts in the same column its tab's name starts in, and is
set in italic. That also survives the monochrome themes in contrib,
where a colour-only distinction would have had nothing to spend.
tab_status_fg / tab_status_bg are there for themes that do have colour
to spend. The fg follows tab_count when a theme does not name it -- the
same declared/derived split apply_scrolled makes -- so the six themes
in contrib get coherent status rows without a line added to any of
them. The bg is unset by default, because a band is opt-in and 'none'
is what a translucent terminal wants; the row is padded so a band that
*is* set covers the row rather than the words on it.
Two things fell out. The padding loop existed three times and is now
pad_cells. And cb_color wrote #000000 for an unset colour, so
quietly pinned attach_bg -- 'gray
ink on the terminal's own background', says its comment -- to a black
band. Unset colours are now written commented out, the same trick the
states block uses for what it wants re-derived rather than pinned.
Diffstat (limited to 'src')
| -rw-r--r-- | src/app_draw.c | 50 | ||||
| -rw-r--r-- | src/config.c | 23 |
2 files changed, 54 insertions, 19 deletions
diff --git a/src/app_draw.c b/src/app_draw.c index 54b8950..3b329bf 100644 --- a/src/app_draw.c +++ b/src/app_draw.c @@ -1783,6 +1783,17 @@ static bool tab_has_bell(tab_t *t) { return b.found; } +/* Spaces out to `w` cells, so a row's fill -- an active tab's, a drop + * target's, a themed status band's -- is the row and not the word sitting on + * it. Three copies of this loop wanted to exist; this is the one. */ +static void pad_cells(char *text, size_t cap, uint16_t w) { + size_t len = strlen(text); + while (cells(text) < w && len + 1 < cap) { + text[len++] = ' '; + text[len] = 0; + } +} + /* One tab's cell, wherever the strip lives. Paints the label at (x, y) under * the shared rules -- active weight, hover colour, the rename editor, the * bell, the drop target -- and registers the hit. `max_w` is 0 for the top @@ -1847,11 +1858,7 @@ static uint16_t draw_tab_cell(app_t *a, screen_t *s, size_t i, uint16_t x, while (len && (label[len] & 0xc0) == 0x80); /* whole UTF-8 sequences */ label[len] = 0; } - size_t len = strlen(label); - while (cells(label) < budget && len + 1 < sizeof label) { - label[len++] = ' '; - label[len] = 0; - } + pad_cells(label, sizeof label, budget); } bool active = i == a->cur; @@ -1930,13 +1937,7 @@ static void draw_newtab_button(app_t *a, screen_t *s, uint16_t x, uint16_t y, snprintf(btn, sizeof btn, " %s ", CFG.newtab_mark); /* Padded out on a sidebar row for the same reason a tab's label is: the * hover and the drop fill are the row, not the word sitting on it. */ - if (max_w) { - size_t len = strlen(btn); - while (cells(btn) < max_w && len + 1 < sizeof btn) { - btn[len++] = ' '; - btn[len] = 0; - } - } + if (max_w) pad_cells(btn, sizeof btn, max_w); uint16_t w = screen_text(s, x, y, btn, TAB_IDLE, NO_COLOR, 0); uint16_t hit_w = max_w ? max_w : w; if (ptr_on(a, x, y, hit_w, 1)) @@ -2126,18 +2127,29 @@ void draw_tab_sidebar(app_t *a, screen_t *s) { * one more status pretending the list is complete. */ bool more = ts.total > cap && j == (size_t)(cap - 1); char text[112]; + /* One leading space, which is the label's own -- a status starts in the + * column its tab's name starts in, rather than indented under it. + * + * It used to be three. Indentation is a fine way to say "this belongs + * to the row above" and a poor way to spend a sixteen-column sidebar, + * where three columns is a fifth of everything a status has to say + * itself in. The slant below says the same thing in none of them. */ if (more) { - snprintf(text, sizeof text, " \u2026"); + snprintf(text, sizeof text, " \u2026"); } else { - snprintf(text, sizeof text, " %s", ts.row[j].text); + snprintf(text, sizeof text, " %s", ts.row[j].text); fit_status(text, sizeof text, cw); } - /* Dim like the pane count: these are ambience until pointed at. The - * hover brightening doubles as the affordance that the row is a door; - * the hint under the pointer says where it leads. */ + pad_cells(text, sizeof text, cw); /* so a themed band covers the row */ + /* Italic, and ambient in colour: these are annotations until pointed + * at. The slant is what separates them from the labels, rather than a + * colour, because a monochrome theme has no colour to spare and would + * be left with none -- tab_status_fg/bg are there for themes that do. + * The hover brightening doubles as the affordance that the row is a + * door; the hint under the pointer says where it leads. */ bool hot = !more && ptr_on(a, cx, y, cw, 1); - screen_text(s, cx, y, text, hot ? TAB_HOVER : TAB_COUNT, NO_COLOR, - hot ? ATTR_BOLD : 0); + screen_text(s, cx, y, text, hot ? TAB_HOVER : TAB_STATUS_FG, + TAB_STATUS_BG, hot ? ATTR_BOLD : ATTR_ITALIC); if (!more) { char act[24]; snprintf(act, sizeof act, "find:%u", ts.row[j].pane); diff --git a/src/config.c b/src/config.c index cea9177..88b686f 100644 --- a/src/config.c +++ b/src/config.c @@ -640,6 +640,8 @@ static const struct { {"prefix_fg", offsetof(config_t, prefix_fg)}, {"prefix_bg", offsetof(config_t, prefix_bg)}, {"tab_count", offsetof(config_t, tab_count)}, + {"tab_status_fg", offsetof(config_t, tab_status_fg)}, + {"tab_status_bg", offsetof(config_t, tab_status_bg)}, {"status", offsetof(config_t, status)}, {"status_state", offsetof(config_t, status_state)}, {"finder_fg", offsetof(config_t, finder_fg)}, @@ -1031,6 +1033,10 @@ void config_defaults(config_t *c) { c->prefix_fg = ink; c->prefix_bg = accent; c->tab_count = dim; + /* Ambient, like the count: the slant is what separates a status from the + * label above it, so the colour does not have to. */ + c->tab_status_fg = dim; + c->tab_status_bg = (color_t){0}; /* none: the terminal's own background */ c->status = dim; c->status_state = bright; @@ -1526,6 +1532,16 @@ static void cb_chord(cfgbuf_t *b, int key, uint16_t mods) { } static void cb_color(cfgbuf_t *b, const char *name, color_t c) { + /* A colour that is not set is the terminal's own, and that has no spelling + * in a theme block -- parse_color takes #rrggbb and nothing else. So it is + * written commented out: the same trick the states block uses for what it + * wants re-derived rather than pinned. The dump still says the key exists, + * and `slosh --dump-config > config.kdl` does not quietly turn "none" into + * black, which is what writing #000000 here would have done. */ + if (!c.set) { + cb_add(b, " // %-19s (none: the terminal's own)\n", name); + return; + } cb_add(b, " %-22s \"#%02x%02x%02x\"\n", name, c.r, c.g, c.b); } @@ -2402,6 +2418,13 @@ static bool load_into(config_t *c, const char *path, int depth, char *err, complain(c, err, errcap, kdl_child(theme, THEME_COLORS[i].name)->line, "bad colour for %s: %s", THEME_COLORS[i].name, v); } + /* A theme that restyles the ambient chrome but has never heard of the + * sidebar's status rows gets coherent ones anyway: they follow tab_count, + * which is the same class of thing. Named explicitly, it wins -- the same + * declared/derived split apply_scrolled makes. Without this every theme in + * contrib would need a line adding to it to avoid one grey among another + * theme's greys. */ + if (!kdl_child(theme, "tab_status_fg")) c->tab_status_fg = c->tab_count; } /* After the theme, so the wash follows whatever scroll_bg the theme just * chose -- a config that wrote its own `scrolled` chain keeps it, whether |
