diff --git a/tabbed-wlroots.c b/tabbed-wlroots.c index 47c03da..2b261e8 100644 --- a/tabbed-wlroots.c +++ b/tabbed-wlroots.c @@ -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,