diff --git a/include/cst_version.h b/include/cst_version.h index 4fcf0b5..d515a16 100644 --- a/include/cst_version.h +++ b/include/cst_version.h @@ -3,7 +3,7 @@ #define CST_VERSION_MAJOR 1 #define CST_VERSION_MINOR 0 -#define CST_VERSION_PATCH 1 +#define CST_VERSION_PATCH 2 #define CST_VERSION_STR_(x) #x #define CST_VERSION_STR(x) CST_VERSION_STR_(x) diff --git a/src/tui.c b/src/tui.c index 7331c7b..5ee0a08 100644 --- a/src/tui.c +++ b/src/tui.c @@ -2791,8 +2791,28 @@ static void draw_hermit_badge(WINDOW *win, int y, int x, const tui_t *t) { return; } } - const char *b = hermit_mini_badge(st, t->spin, g_ascii); - draw_ansi_at(win, y, x, (int)strlen(b), b, CP_TOOL, 0, 0); + /* Compact topbar mark — avoid wide ║║ which reads as an orange slab. */ + const char *b; + if (g_ascii) { + b = (st == HERMIT_ST_CODING) ? ">_" : "<>"; + } else { + switch (st) { + case HERMIT_ST_QUESTION: + b = "◇?"; + break; + case HERMIT_ST_ERROR: + b = "◇!"; + break; + case HERMIT_ST_CODING: + b = ">_"; + break; + default: + b = "◇"; + break; + } + } + (void)t; + draw_ansi_at(win, y, x, 2, b, CP_TOOL, 0, 0); } static const char *const TIPS[] = { @@ -2971,7 +2991,7 @@ static void draw_side(tui_t *t) { char line[512]; int bottom = h - 3; /* where + version */ - /* SEAT — local role + instance + short realm fp */ + /* SEAT — role on one line; instance + realm indented under it */ draw_ansi_at(s, y++, x, mw, "seat", CP_SIDE_MUTED, 0, 0); { char sid[64] = {0}; @@ -2980,21 +3000,28 @@ static void draw_side(tui_t *t) { const char *role = !sess ? "logged-out" : chair ? "chair" : "member"; int pair = !sess ? CP_SIDE_MUTED : chair ? CP_SIDE_SUCCESS : CP_SIDE_PRIMARY; - int dx = x + draw_ansi_at(s, y, x, 2, seat_pulse_dot(t), pair, 0, 0); - snprintf(line, sizeof(line), "%s", role); - dx += draw_ansi_at(s, y, dx + 1, mw - (dx + 1 - x), line, pair, 1, 0); + int dx = x; + dx += draw_ansi_at(s, y, dx, 2, seat_pulse_dot(t), pair, 0, 0); + dx += draw_ansi_at(s, y, dx, 1, " ", pair, 0, 0); + draw_ansi_at(s, y, dx, mw - (dx - x), role, pair, 1, 0); y++; + int ix = x + 2; /* align under role text, past the pulse */ + int imw = mw - 2; + if (imw < 6) { + ix = x; + imw = mw; + } if (!sid[0]) cst_parliament_default_instance(sid, sizeof(sid)); if (sid[0] && y < bottom) { - size_t fit = utf8_fit_cols(sid, strlen(sid), mw); + size_t fit = utf8_fit_cols(sid, strlen(sid), imw); snprintf(line, sizeof(line), "%.*s", (int)fit, sid); - draw_ansi_at(s, y++, x, mw, line, CP_SIDE_MUTED, 0, 0); + draw_ansi_at(s, y++, ix, imw, line, CP_SIDE_MUTED, 0, 0); } char fp[9]; if (realm_fp_short(fp) == 0 && y < bottom) { snprintf(line, sizeof(line), "realm %.8s", fp); - draw_ansi_at(s, y++, x, mw, line, CP_SIDE_MUTED, 0, 0); + draw_ansi_at(s, y++, ix, imw, line, CP_SIDE_MUTED, 0, 0); } } y++; @@ -3301,27 +3328,56 @@ static void draw_topbar(tui_t *t) { if (hexish) title = "New session"; } - /* Hermit badge + title + model. Role lives only in the Seat Deck. */ + /* Badge + brand + title on the left; model then seat chip on the right. */ int x = 1; draw_hermit_badge(w, 0, x, t); - x += 4; + x += 3; x += draw_ansi_at(w, 0, x, 6, "Hermit", CP_TOPBAR_ACCENT, 1, 0); x += draw_ansi_at(w, 0, x, 1, " ", CP_TOPBAR_MUTED, 0, 0); - int model_room = 0; + + char seat_chip[48] = ""; + int seat_w = 0; + { + char sid[64] = {0}; + int sess = cst_parliament_session_ok(sid, sizeof(sid)); + int chair = sess && cst_parliament_is_chair(); + if (cst_parliament_is_active()) { + snprintf(seat_chip, sizeof(seat_chip), "%s %s", + seat_pulse_dot(t), + !sess ? "login" : chair ? "chair" : "member"); + seat_w = utf8_cols(seat_chip, strlen(seat_chip)) + 2; + } + } char mid[160] = ""; + int model_room = 0; if (cfg) { snprintf(mid, sizeof(mid), "%.40s%s%.20s", cfg->model, cfg->provider[0] ? " · " : "", cfg->provider); model_room = utf8_cols(mid, strlen(mid)) + 2; } - int title_max = bw - x - 1 - model_room; + int title_max = bw - x - 1 - model_room - seat_w; if (title_max < 8) title_max = 8; size_t tfit = utf8_fit_cols(title, strlen(title), title_max); snprintf(left, sizeof(left), "%.*s", (int)tfit, title); x += draw_ansi_at(w, 0, x, bw - x, left, CP_TOPBAR, 1, 0); - if (mid[0] && x + 2 < bw) - draw_ansi_at(w, 0, x + 2, bw - (x + 2), mid, CP_TOPBAR_MUTED, 0, 0); + int right = bw - 1; + if (seat_chip[0]) { + int sw = utf8_cols(seat_chip, strlen(seat_chip)); + int sx = right - sw; + if (sx > x + 2) { + int pair = strstr(seat_chip, "chair") ? CP_TOPBAR_ACCENT : CP_TOPBAR_MUTED; + draw_ansi_at(w, 0, sx, sw, seat_chip, pair, 0, 0); + right = sx - 2; + } + } + if (mid[0] && x + 2 < right) { + int mw = utf8_cols(mid, strlen(mid)); + int mx = right - mw; + if (mx < x + 2) + mx = x + 2; + draw_ansi_at(w, 0, mx, right - mx + 1, mid, CP_TOPBAR_MUTED, 0, 0); + } wrefresh(w); } @@ -3698,8 +3754,10 @@ static void layout(tui_t *t) { t->todo_rows = 1 + (total < TODO_PANEL_MAX ? total : TODO_PANEL_MAX); t->log_x = 1; t->log_y = topbar; + /* Topbar spans the full width so the sidebar does not leave a dead + * hole next to "Hermit …" in the top-right corner. */ if (topbar) - t->header = tui_newwin(1, mw, 0, 0); + t->header = tui_newwin(1, t->cols, 0, 0); int log_h = t->in_y - 1 - t->todo_rows - t->log_y; if (log_h < 1) { t->todo_rows = 0; @@ -3709,8 +3767,9 @@ static void layout(tui_t *t) { if (t->todo_rows) t->todow = tui_newwin(t->todo_rows, mw - 2, t->log_y + log_h, 1); t->status = tui_newwin(1, mw - 2, t->rows - 1, 1); + /* Sidebar starts under the topbar, aligned with the transcript. */ if (t->side_w) - t->side = tui_newwin(t->rows, t->side_w, 0, mw); + t->side = tui_newwin(t->rows - topbar, t->side_w, topbar, mw); } t->input = tui_newwin(t->in_h, t->in_w, t->in_y, t->in_x); if (HAS_COLOR()) {