fix(menu): #131 — size text menus in ch with a cap, not in % of the monitor
All checks were successful
Check / eval (push) Successful in 3m49s
All checks were successful
Check / eval (push) Successful in 3m49s
Bernardo saw Recovery ellipsize on a 2560x1440 external, which falsified the item's model (40% + Inter 11 → "only below 1920"). Real cause: text menus render through themes/<slug>/rofi.rasi, where boreal + neon-glass pinned width: 620px (fixed — a wide panel buys nothing) while seven used 40%, and the font is whatever that file says — mostly monospace, far wider than the Inter that was measured. The modelled combination ships in no theme. The insight: a menu must fit its longest label, which is a count of characters in the THEME's font — so the window must scale with the font, not the screen. 40% gives a 1366 panel 546px and a 2560 one 1024px for the same row, and a 14pt mono theme needs ~25% more room than an 11pt one on both; a percentage cannot see either fact. Rofi has the right unit (`ch` = width of one digit in the current font) and `calc( a min b )` to cap it, so every text menu — generated and all nine whole-swaps — is now `width: calc( 84ch min 65% )`. 84ch fits the longest row we ship (69 chars) plus icon and padding; the cap is Bernardo's condition (never sprawl on a low-res panel) and it is measured, not assumed. Verified on hardware, not by arithmetic: 84ch = 756px in GeistMono 11 and 924px in JetBrainsMono 14; `calc( 84ch min 300px )` → 300px, so the clamp really clamps. Screenshots at both ends — the real Recovery menu at 756px (29% of 2560) with every label complete, and the Acer worst case reproduced pixel-exactly (888px = 65% of 1366, JetBrainsMono 14) also complete. Grid views override width per-invocation and are untouched. checks.rofi-text-width guards the class, proven by pinning boreal back to 620px and watching it fail by name. Acer V3 queued for its own fontconfig. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
38
flake.nix
38
flake.nix
@@ -1473,6 +1473,44 @@
|
||||
in
|
||||
assert ok; pkgs.runCommand "nomarchy-waybar-swap-env" { } "touch $out";
|
||||
|
||||
# A text menu must fit its longest label, which is a count of
|
||||
# characters — so the picker has to be sized in the theme's own font
|
||||
# (`ch`), never in % of the monitor or fixed px (#131: boreal pinned
|
||||
# 620px and truncated Recovery on a 2560 panel; 40% themes truncate at
|
||||
# 1366 while looking fine at 2560, and a 14pt mono theme needs ~25%
|
||||
# more room than an 11pt one on both). The `min` cap is the other half
|
||||
# — without it a big font on a small panel sprawls across the screen.
|
||||
# Grid views (theme picker, drun) legitimately size by icons and
|
||||
# override width per-invocation; this only governs the base theme.
|
||||
rofi-text-width =
|
||||
let
|
||||
inherit (nixpkgs) lib;
|
||||
expect = cond: msg: lib.assertMsg cond "rofi-text-width: ${msg}";
|
||||
swaps = lib.filter
|
||||
(n: builtins.pathExists (./themes + "/${n}/rofi.rasi"))
|
||||
(builtins.attrNames (builtins.readDir ./themes));
|
||||
widthOf = name:
|
||||
let
|
||||
text = builtins.readFile (./themes + "/${name}/rofi.rasi");
|
||||
m = builtins.match ".*window[[:space:]]*\\{[^}]*width:[[:space:]]*([^;]+);.*" text;
|
||||
in
|
||||
if m == null then null else lib.head m;
|
||||
bad = lib.filter
|
||||
(name:
|
||||
let w = widthOf name; in
|
||||
w == null
|
||||
|| builtins.match ".*ch.*" w == null
|
||||
|| builtins.match ".*min.*" w == null)
|
||||
swaps;
|
||||
ok =
|
||||
expect (swaps != [ ])
|
||||
"fixture drift: no theme ships a rofi.rasi — the guard is checking nothing"
|
||||
&& expect (bad == [ ])
|
||||
("a whole-swap sizes its text menu without `ch` and a `min` cap, so it "
|
||||
+ "cannot fit its own font's labels: " + lib.concatStringsSep ", " bad);
|
||||
in
|
||||
assert ok; pkgs.runCommand "nomarchy-rofi-text-width" { } "touch $out";
|
||||
|
||||
# Docking artifact guard: default/no-profile Home Manager output
|
||||
# must still launch both hotplug watchers, put Rofi on the focused
|
||||
# monitor, expose the manual keyboard picker, and never ship the
|
||||
|
||||
Reference in New Issue
Block a user