From 2776741c234a9ec57081c8c057cd2554ce380943 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Av=C3=A9?= Date: Thu, 7 May 2026 20:21:42 +0700 Subject: [PATCH] Automatically shorten titles if they get too long --- home/ags/files/Bar.tsx | 43 ++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/home/ags/files/Bar.tsx b/home/ags/files/Bar.tsx index cf03f0d..607491a 100644 --- a/home/ags/files/Bar.tsx +++ b/home/ags/files/Bar.tsx @@ -3,6 +3,7 @@ import app from "ags/gtk4/app"; import { createBinding, createState, For, With, Accessor } from "ags"; import { createPoll } from "ags/time"; import { subprocess, execAsync } from "ags/process"; +import Pango from "gi://Pango"; import Tray from "gi://AstalTray"; import { getIconName } from "./utils"; import Wp from "gi://AstalWp"; @@ -295,8 +296,24 @@ function Workspaces({ connector }: { connector: string }): JSX.Element { ); } -function shorten(title: string) { - return title.length > 40 ? title.slice(0, 20) + "..." : title; +const MAX_TOTAL_CHARS = 120; +const MIN_TITLE_CHARS = 10; +const OVERHEAD_PER_WINDOW = 5; // icon + padding + margin in character-width equivalents + +function computeTitleBudgets(wins: any[]): any[] { + const totalLength = wins.reduce((sum, w) => sum + (w.title || "").length, 0); + const count = wins.length; + const totalWithOverhead = totalLength + count * OVERHEAD_PER_WINDOW; + + let maxChars: number; + if (count === 0 || totalWithOverhead <= MAX_TOTAL_CHARS) { + maxChars = -1; + } else { + const charsAvailable = MAX_TOTAL_CHARS - count * OVERHEAD_PER_WINDOW; + maxChars = Math.max(MIN_TITLE_CHARS, Math.floor(charsAvailable / count)); + } + + return wins.map(w => ({ ...w, maxChars })); } function Clients({ connector }: { connector: string }): JSX.Element { @@ -311,18 +328,24 @@ function Clients({ connector }: { connector: string }): JSX.Element { {/* Generate a derived binding for windows, depending on the active workspace */} - wins.filter((w: any) => !w.title?.includes("rofi")) - .filter((w: any) => w.workspace_id === active_ws_for_monitor) - .sort((a: any, b: any) => { - const posA = a.layout?.pos_in_scrolling_layout?.[0] ?? 0; - const posB = b.layout?.pos_in_scrolling_layout?.[0] ?? 0; - return posA - posB; - }) + computeTitleBudgets( + wins.filter((w: any) => !w.title?.includes("rofi")) + .filter((w: any) => w.workspace_id === active_ws_for_monitor) + .sort((a: any, b: any) => { + const posA = a.layout?.pos_in_scrolling_layout?.[0] ?? 0; + const posB = b.layout?.pos_in_scrolling_layout?.[0] ?? 0; + return posA - posB; + }) + ) )}> {(win: any) => ( - )}