From 8eb672badac5aeda2dc798b3a3b62792cfe5ce6b Mon Sep 17 00:00:00 2001 From: Bernardo Magri Date: Sun, 12 Jul 2026 08:15:08 +0100 Subject: [PATCH] fix(waybar): carry tray-menu counter-rules in the bar stylesheet itself MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The e8658fe cure (USER-priority gtk.css counter-rules) verified in a plain GTK app but not in the real Waybar-hosted nm-applet menu: Waybar adds its provider at GTK_STYLE_PROVIDER_PRIORITY_USER as well (src/client.cpp), and in practice its rules win the tie against ~/.config/gtk-3.0/gtk.css on GTK 3.24 — reproduced by injecting the bar stylesheet above USER priority: arrow, checkmark and separator all vanish, matching the live menu exactly. The only placement that wins at ANY provider priority is inside the same stylesheet: after each '*' reset, restore the CSS-sized menu nodes (menuitem arrow 16px, check/radio 14px, separator 1px line) and give menus a text face instead of the bar's glyph font. Applied to boreal + executive-slate waybar.css and waybar.nix generatedStyle; stylix.nix comment corrected (its rules now cover ordinary GTK apps only). Ground truth checked over D-Bus first: nm-applet exports per-network Wi-Fi icons as dbusmenu icon-data, and with gtk-menu-images=1 the connected network's icon already renders in the live menu — the remaining loss was arrows/checks/separators, all CSS-box nodes. Co-Authored-By: Claude Fable 5 --- modules/home/stylix.nix | 12 ++++++------ modules/home/waybar.nix | 21 ++++++++++++++++----- themes/boreal/waybar.css | 24 ++++++++++++++++++++---- themes/executive-slate/waybar.css | 23 +++++++++++++++++++---- 4 files changed, 61 insertions(+), 19 deletions(-) diff --git a/modules/home/stylix.nix b/modules/home/stylix.nix index 0f537b2..bc8cd11 100644 --- a/modules/home/stylix.nix +++ b/modules/home/stylix.nix @@ -70,13 +70,13 @@ in } /* Submenu disclosure arrows need no icon remap: pan-end-symbolic resolves via Papirus-Dark's breeze-dark inheritance. The - "invisible arrow" bug is Waybar's process-wide stylesheet: + "invisible arrow" bug was Waybar's process-wide stylesheet: its `* { min-height: 0; }` reset also hits the SNI tray menus - Waybar hosts and collapses the arrow node. This file loads at - USER priority (~/.config/gtk-3.0/gtk.css), which outranks any - waybar.css (APPLICATION priority) — restore the arrow's box - here, exactly like the check/radio rule below already does - for the same collapse. */ + Waybar hosts and collapses arrow/check nodes. NB: this file + CANNOT fix that — Waybar adds its provider at USER priority + too and wins the tie in practice (GTK 3.24, observed), so + every waybar.css carries its own menu counter-rules. The + rules here cover menus in ordinary GTK apps only. */ menu menuitem arrow, .menu menuitem arrow, .context-menu menuitem arrow { min-width: 16px; min-height: 16px; diff --git a/modules/home/waybar.nix b/modules/home/waybar.nix index f80deb2..1e4afca 100644 --- a/modules/home/waybar.nix +++ b/modules/home/waybar.nix @@ -382,17 +382,28 @@ let ${colorDefs} /* NB: this `*` reset reaches the SNI tray menus Waybar hosts too - (its stylesheet applies process-wide) — the menu-side damage - (collapsed arrows/checks) is undone by USER-priority counter-rules - in stylix.nix, which outrank any waybar.css. Do NOT scope this to - window#waybar: the id's specificity would beat the class rules - below (pills, workspaces) and wreck the bar. */ + (its stylesheet applies process-wide, at a priority user gtk.css + cannot out-rank). The menu block right below undoes the damage — + keep the two in sync. Do NOT scope `*` to window#waybar instead: + the id's specificity would beat the class rules below and wreck + the bar. Whole-swap theme waybar.css files carry the same pair. */ * { font-family: "${t.fonts.ui}", "${t.fonts.mono}"; font-size: ${toString t.fonts.size}pt; min-height: 0; } + /* Tray menus: undo the `*` reset — same stylesheet, higher + specificity. Arrows/checks/separators are CSS-sized nodes; + min-height 0 makes them invisible. */ + menu menuitem arrow { min-width: 16px; min-height: 16px; } + menu check, menu radio { min-width: 14px; min-height: 14px; } + menu separator { + min-height: 1px; + margin: 5px 0; + background: alpha(@text, 0.15); + } + window#waybar { background: alpha(@base, 0.85); color: @text; diff --git a/themes/boreal/waybar.css b/themes/boreal/waybar.css index 56ebdf0..e89b764 100644 --- a/themes/boreal/waybar.css +++ b/themes/boreal/waybar.css @@ -23,10 +23,12 @@ @define-color warn #E6C384; @define-color bad #E2818A; -/* NB: this `*` reset reaches the SNI tray menus Waybar hosts too — the - menu-side damage (collapsed arrows) is undone by USER-priority rules in - stylix.nix. Do NOT scope it to window#waybar: the id's specificity would - beat the class rules below (pills) and wreck the bar. */ +/* NB: this `*` reset reaches the SNI tray menus Waybar hosts too (its + stylesheet applies process-wide, at a priority user gtk.css cannot + out-rank). The menu block right below undoes the damage — keep the two + in sync. Do NOT scope `*` to window#waybar instead: the id's + specificity would beat the class rules below (pills) and wreck the + bar. */ * { /* Mono Nerd face for status glyphs (tight right bearings on the proportional Symbols face make icon+percentage collide). */ @@ -38,6 +40,20 @@ min-height: 0; } +/* ── Tray menus (nm-applet & co live in Waybar's process) ───────────── + Undo the `*` reset for them: same stylesheet, higher specificity. + Arrows/checks are CSS-sized nodes — min-height 0 makes them invisible; + separators die the same way; the bar's mono face reads wrong in text + menus. */ +menu { font-family: "Inter", sans-serif; } +menu menuitem arrow { min-width: 16px; min-height: 16px; } +menu check, menu radio { min-width: 14px; min-height: 14px; } +menu separator { + min-height: 1px; + margin: 5px 0; + background: alpha(@text, 0.15); +} + /* The bar itself is invisible — the pills float over the wallpaper. */ window#waybar { background: transparent; diff --git a/themes/executive-slate/waybar.css b/themes/executive-slate/waybar.css index 4e5040f..bb28c5f 100644 --- a/themes/executive-slate/waybar.css +++ b/themes/executive-slate/waybar.css @@ -21,10 +21,11 @@ @define-color warn #DBA85A; @define-color bad #D06B71; -/* NB: this `*` reset reaches the SNI tray menus Waybar hosts too — the - menu-side damage (collapsed arrows) is undone by USER-priority rules in - stylix.nix. Do NOT scope it to window#waybar: the id's specificity would - beat the class rules below and wreck the bar. */ +/* NB: this `*` reset reaches the SNI tray menus Waybar hosts too (its + stylesheet applies process-wide, at a priority user gtk.css cannot + out-rank). The menu block right below undoes the damage — keep the two + in sync. Do NOT scope `*` to window#waybar instead: the id's + specificity would beat the class rules below and wreck the bar. */ * { /* Mono Nerd face first for status glyphs: proportional "Symbols Nerd Font" has tight right bearings that make icon+percentage collide. */ @@ -36,6 +37,20 @@ min-height: 0; } +/* ── Tray menus (nm-applet & co live in Waybar's process) ───────────── + Undo the `*` reset for them: same stylesheet, higher specificity. + Arrows/checks are CSS-sized nodes — min-height 0 makes them invisible; + separators die the same way; the glyph-first face reads wrong in text + menus. */ +menu { font-family: "Inter", sans-serif; } +menu menuitem arrow { min-width: 16px; min-height: 16px; } +menu check, menu radio { min-width: 14px; min-height: 14px; } +menu separator { + min-height: 1px; + margin: 5px 0; + background: alpha(@text, 0.15); +} + /* Solid bar, crisp edge against the content below. */ window#waybar { background: @base;