Truncate overlay rows so the menu stays narrower than the window

This commit is contained in:
Andrew Hamilton 2026-08-15 10:28:14 +10:00
parent 0b00cded7e
commit 726838bfbc

View file

@ -1089,6 +1089,44 @@ static int overlay_text_width(const char *s) {
return w;
}
/* Copy `src` into `out`, truncated so that its on-screen width plus a
trailing "..." fits within `max_px`. Uses the same advance rules as
overlay_text_width(). Falls back to an empty string when even one dot
won't fit. */
static void fit_text(const char *src, int max_px, char *out, int out_sz)
{
const char *dots = "...";
int dot_w = 0;
for (const unsigned char *p = (const unsigned char *)dots; *p; p++) {
int c = *p;
if (c < 32 || c > 126) { dot_w += 4; continue; }
dot_w += host.overlay_glyphs[c - 32].adv;
}
out[0] = '\0';
if (!src || max_px < dot_w || out_sz <= 1) return;
int w = 0;
size_t n = 0;
const unsigned char *p;
for (p = (const unsigned char *)src; *p; p++) {
int c = *p;
int adv = (c < 32 || c > 126) ? 4 : host.overlay_glyphs[c - 32].adv;
if (w + adv + dot_w > max_px)
break;
if (n + 1 >= (size_t)out_sz)
break;
out[n++] = (char)c;
w += adv;
}
if (*p) {
if (n + 4 < (size_t)out_sz) {
memcpy(out + n, dots, 3);
n += 3;
}
}
out[n] = '\0';
}
static void draw_tab_overlay(void) {
if (!host.overlay_visible || server.num_apps < 1) return;
@ -1114,6 +1152,9 @@ static void draw_tab_overlay(void) {
}
if (n_rows == 0) return;
int avail_w = host.width - 2 * margin - 2 * boxpad;
if (max_row_w > avail_w) max_row_w = avail_w;
int box_w = max_row_w + 2 * boxpad;
int box_h = n_rows * row_h + 2 * boxpad;
if (box_w > host.width - 2 * margin) box_w = host.width - 2 * margin;
@ -1135,8 +1176,15 @@ static void draw_tab_overlay(void) {
}
int ry = box_y + boxpad + row * row_h;
bool active = app->toplevel == server.active;
char row_text[512];
int budget = max_row_w - icon_sz - icon_gap;
if (budget < 0) budget = 0;
fit_text(title, budget, row_text, sizeof(row_text));
int text_w = overlay_text_width(row_text);
if (active) {
int hw = icon_sz + icon_gap + overlay_text_width(title) + 4;
int hw = icon_sz + icon_gap + text_w + 4;
int max_hw = box_w - 2 * boxpad + 4;
if (hw > max_hw) hw = max_hw;
draw_rect(box_x + boxpad - 2, ry - 1, hw, row_h,
0.24f, 0.36f, 0.60f, 0.9f);
}
@ -1156,7 +1204,7 @@ static void draw_tab_overlay(void) {
draw_rect(ix + 3, iy + 3, icon_sz - 6, icon_sz - 6,
0.07f, 0.07f, 0.09f, 1.0f);
}
draw_text(title, ix + icon_sz + icon_gap,
draw_text(row_text, ix + icon_sz + icon_gap,
ry + (row_h - host.overlay_font_h) / 2,
active ? 1.0f : 0.72f,
active ? 1.0f : 0.72f,