aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoruser <user@clank>2026-09-02 15:09:36 +0200
committeruser <user@clank>2026-09-02 15:09:36 +0200
commitcafa48e0a7e1eb48a783bfde6862c5fd82c7aede (patch)
tree8e7874fc9a26a0354154906fd9e6fd30e10fe197
parentweb: chore (diff)
downloadslosh-cafa48e0a7e1eb48a783bfde6862c5fd82c7aede.tar.gz
slosh-cafa48e0a7e1eb48a783bfde6862c5fd82c7aede.tar.xz
slosh-cafa48e0a7e1eb48a783bfde6862c5fd82c7aede.zip
attach tag: just the count, in theme colours
The +x+y offset goes -- 'N clients' says the thing that matters. The inverse-video chip goes with it: the tag now draws in attach_fg / attach_bg from the theme, defaulting to gray ink on the terminal's own background. Standing information, not an announcement.
-rw-r--r--config/config.kdl6
-rw-r--r--docs/slosh.512
-rw-r--r--include/app.h1
-rw-r--r--include/config.h4
-rw-r--r--src/app.c6
-rw-r--r--src/config.c7
-rw-r--r--src/server.c15
-rw-r--r--tests/test_session.py11
8 files changed, 36 insertions, 26 deletions
diff --git a/config/config.kdl b/config/config.kdl
index 7bca53f..3013858 100644
--- a/config/config.kdl
+++ b/config/config.kdl
@@ -882,6 +882,12 @@ theme {
// ── announcements ───────────────────────────────────────────────────────
toast_fg "#141418"
toast_bg "#7aa2f7"
+
+ // The "2 clients" tag when several terminals share the session. Muted by
+ // default -- standing information, not an announcement. attach_bg unset
+ // means the terminal's own background.
+ attach_fg "#45454a"
+ // attach_bg "#141418"
}
// ── keys ────────────────────────────────────────────────────────────────────
diff --git a/docs/slosh.5 b/docs/slosh.5
index dfa01d1..f0932af 100644
--- a/docs/slosh.5
+++ b/docs/slosh.5
@@ -153,11 +153,13 @@ Off, a new client displaces the previous one, which is the classic
\[dq]move my session here and close it there\[dq].
.TP
.BI attach_indicator\ bool
-When several clients are attached, each shows a tag in its own top-right
-corner: the viewer count, and on a cropped view its offset into the shared
-screen
-.RB ( \[dq]2\ clients\ +12+4\[dq] ),
-so a view being panned by somebody else's cursor says where it is.
+When several clients are attached, each shows a
+.RB ( \[dq]2\ clients\[dq] )
+tag in its own top-right corner, so a view being panned by somebody
+else's cursor is not a mystery. Its colours are the theme's
+.B attach_fg
+and
+.BR attach_bg .
.TP
.BI size_follows\ active\ |\ smallest\ |\ largest
Whose size the shared screen takes when several clients are attached.
diff --git a/include/app.h b/include/app.h
index f0928d7..6cf6886 100644
--- a/include/app.h
+++ b/include/app.h
@@ -64,6 +64,7 @@ size_t app_config_files(const char **out, size_t max);
* shared screen takes (SIZE_FOLLOWS_* in config.h). */
bool app_cfg_multi_attach(void);
bool app_cfg_attach_indicator(void);
+void app_cfg_attach_colors(color_t *fg, color_t *bg);
int app_cfg_size_follows(void);
/* What the config in force complained about while loading, or "". A complaint is
* not a failure -- an include that is not there, a shader nobody has heard of --
diff --git a/include/config.h b/include/config.h
index 2be60f5..69a017b 100644
--- a/include/config.h
+++ b/include/config.h
@@ -445,6 +445,10 @@ typedef struct {
/* announcements */
color_t toast_fg, toast_bg;
+ /* the multi-client tag ("2 clients", per-client top-right chrome). Muted
+ * by default: it is standing information, not an announcement. */
+ color_t attach_fg, attach_bg;
+
/* keys */
int prefix_key;
uint16_t prefix_mods;
diff --git a/src/app.c b/src/app.c
index b7af3d1..cc06924 100644
--- a/src/app.c
+++ b/src/app.c
@@ -98,6 +98,12 @@ bool app_cfg_attach_indicator(void) {
return CFG.attach_indicator;
}
+void app_cfg_attach_colors(color_t *fg, color_t *bg) {
+ ensure_config();
+ if (fg) *fg = CFG.attach_fg;
+ if (bg) *bg = CFG.attach_bg;
+}
+
int app_cfg_size_follows(void) {
ensure_config();
return CFG.size_follows;
diff --git a/src/config.c b/src/config.c
index 9c06983..2e3e662 100644
--- a/src/config.c
+++ b/src/config.c
@@ -662,6 +662,8 @@ static const struct {
{"rename_bg", offsetof(config_t, rename_bg)},
{"toast_fg", offsetof(config_t, toast_fg)},
{"toast_bg", offsetof(config_t, toast_bg)},
+ {"attach_fg", offsetof(config_t, attach_fg)},
+ {"attach_bg", offsetof(config_t, attach_bg)},
};
#define THEME_COLOR(c, i) ((color_t *)((char *)(c) + THEME_COLORS[i].off))
@@ -1054,6 +1056,11 @@ void config_defaults(config_t *c) {
c->toast_fg = ink;
c->toast_bg = accent;
+ /* Quiet on purpose: gray ink on the terminal's own background. The toast
+ * colours announce; this one merely mentions. */
+ c->attach_fg = dim;
+ c->attach_bg = (color_t){0};
+
c->prefix_key = GHOSTTY_KEY_A;
c->prefix_mods = MOD_CTRL;
diff --git a/src/server.c b/src/server.c
index 472fcdd..387fa7d 100644
--- a/src/server.c
+++ b/src/server.c
@@ -320,20 +320,15 @@ static void stamp_indicator(server_t *s, conn_t *c) {
if (!app_cfg_attach_indicator()) return;
size_t viewers = display_count(s);
if (viewers < 2) return;
- char tag[48];
- if (c->view_x || c->view_y)
- /* The crop's origin in the shared screen: "you are at +col+row of
- * something bigger", which is the disorienting case the tag exists for. */
- snprintf(tag, sizeof tag, " %zu clients +%u+%u ", viewers,
- (unsigned)c->view_x, (unsigned)c->view_y);
- else
- snprintf(tag, sizeof tag, " %zu clients ", viewers);
+ char tag[32];
+ snprintf(tag, sizeof tag, " %zu clients ", viewers);
size_t len = strlen(tag);
if (len >= c->view.cols) return; /* a view too narrow to say it in */
+ color_t fg, bg;
+ app_cfg_attach_colors(&fg, &bg);
uint16_t x0 = (uint16_t)(c->view.cols - len);
for (size_t i = 0; i < len; i++)
- screen_put_utf8(&c->view, (uint16_t)(x0 + i), 0, &tag[i], 1, (color_t){0},
- (color_t){0}, ATTR_DIM | ATTR_INVERSE);
+ screen_put_utf8(&c->view, (uint16_t)(x0 + i), 0, &tag[i], 1, fg, bg, 0);
}
static bool push_frame(server_t *s, conn_t *c) {
diff --git a/tests/test_session.py b/tests/test_session.py
index 4a5c7e7..7f22988 100644
--- a/tests/test_session.py
+++ b/tests/test_session.py
@@ -250,17 +250,6 @@ def main():
)
check("the last client to type owns the size", screen_size(name) == (80, 24))
- # Push the shared cursor below the small client's 12 rows: its view has
- # to pan down to follow, and the tag must say where it went.
- os.write(fd2, b"\n" * 20)
- drain(fd2)
- panned = drain(fd3)
- check(
- "a cropped view names its offset into the shared screen",
- b"clients +" in panned,
- repr(panned[-100:]),
- )
-
resize(pid3, fd3, 40, 10)
drain(fd3)
check(