diff options
| author | Craig Jennings <c@cjennings.net> | 2026-06-19 11:27:48 -0400 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-06-19 11:27:48 -0400 |
| commit | be766471a40e6239540c35b25384508bb2864c79 (patch) | |
| tree | a9c50fff3270226f38c8243b9451c82fafc49a62 | |
| parent | 895062022679fe73e28147fafd7e8402357147b5 (diff) | |
| download | archsetup-be766471a40e6239540c35b25384508bb2864c79.tar.gz archsetup-be766471a40e6239540c35b25384508bb2864c79.zip | |
A spike disproved the CSS / state-file approach. GTK3 has no display:none, so native modules go invisible but hold their space, and the bar never reflows. The mechanism is config-swap plus a SIGUSR2 reload, driven through an active config copied into XDG_RUNTIME_DIR so the toggle never rewrites the stowed canonical config.
The spec locks the base sets (left: menu + workspaces; right: date + worldclock + tray), keeps the two sides independent, and stays host-agnostic: the base set is constant, the full set is whatever each host already defines. Spec and spike findings live under working/.
| -rw-r--r-- | todo.org | 5 | ||||
| -rw-r--r-- | working/collapsible-waybar-sides/collapsible-waybar-sides-spec.org | 120 | ||||
| -rw-r--r-- | working/collapsible-waybar-sides/spike-findings.org | 42 |
3 files changed, 164 insertions, 3 deletions
@@ -105,10 +105,9 @@ Implementation notes (to flesh out when picked up): waybar =custom= module(s) wi :END: Let either side of the waybar collapse horizontally to a minimal base set, toggled by a click. Each collapsible side carries a small triangle / arrowhead pointing toward the screen edge it collapses into (away from center). Clicking it collapses that side to its base set and flips the arrow to point back toward center; clicking again restores the full side. Same shape-changes-with-state idea as the auto-dim indicator. -- *Right-side base set* (proposed): the date/time, optionally plus the systray. Everything else on the right (sysmonitor group, netspeed, pulseaudio, the toggles) hides. -- *Left-side base set*: TBD (workspaces only, or menu + workspaces). +Spec ready (2026-06-19): [[file:working/collapsible-waybar-sides/collapsible-waybar-sides-spec.org]]. Spike settled the mechanism: [[file:working/collapsible-waybar-sides/spike-findings.org]]. -Implementation notes: waybar has no native per-side collapse, so this is custom. Options to explore: (a) swap between a full and a collapsed waybar config on click via a signal/exec, (b) rewrite the modules array and reload (heavy), (c) a state file the modules read to hide/show a group via CSS. Likely a state file (=$XDG_RUNTIME_DIR=) + per-side toggle scripts + a targeted waybar refresh, mirroring the existing custom-module + signal pattern. Lives in the dotfiles repo (=hyprland/.config/waybar/= + =hyprland/.local/bin/=). TDD the toggle scripts per the dotfiles suite. +Decisions locked: right base set = date + worldclock + tray; left base set = menu + workspaces; per-side independent; host-agnostic (base set constant, full set is each host's existing config). Mechanism = config-swap + SIGUSR2 reload via an active-config copy in =$XDG_RUNTIME_DIR= (the CSS/state-file approach was disproven — GTK3 can't reflow-hide native modules). Lives in =~/.dotfiles/hyprland/=. Next: implement per the spec (TDD the toggle + arrow scripts). ** TODO [#B] Network-manager dropdown, nmcli-backed with GPG-stored secrets :waybar:network: :PROPERTIES: diff --git a/working/collapsible-waybar-sides/collapsible-waybar-sides-spec.org b/working/collapsible-waybar-sides/collapsible-waybar-sides-spec.org new file mode 100644 index 0000000..b9ddc0d --- /dev/null +++ b/working/collapsible-waybar-sides/collapsible-waybar-sides-spec.org @@ -0,0 +1,120 @@ +#+TITLE: Collapsible waybar sides — implementation spec +#+AUTHOR: Craig Jennings & Claude +#+DATE: 2026-06-19 + +* Goal +Let each side of the waybar collapse to a minimal base set with a click, and +expand again with another click. Each side carries a small arrowhead that points +toward the screen edge when expanded (click to collapse outward) and flips to +point toward center when collapsed (click to expand). Left and right collapse +independently. + +This is dotfiles work (=~/.dotfiles=, =hyprland/= tier). Tracked by the +=Collapsible waybar sides= task in archsetup =todo.org=. + +* Decisions (locked 2026-06-19) +- *Mechanism*: config-swap + =killall -SIGUSR2 waybar=. NOT state-file + CSS — + the spike proved CSS can't collapse native modules (they go invisible but hold + their space; GTK3 has no =display:none=). See [[file:spike-findings.org]]. +- *Right base set*: =custom/date=, =custom/worldclock=, =tray= (plus the right + arrow). Tray reflows cleanly and survives the reload (spike-confirmed). +- *Left base set*: =custom/menu=, =hyprland/workspaces= (plus the left arrow). +- *Per-side*: left and right toggle independently, each with its own arrow. +- *Per-host*: host-agnostic. The base set is constant; the full set is whatever + each host's config already defines. ratio (no battery/touchpad/airplane) needs + no special-casing — collapse hides whatever modules that host has. Build once. + +* Architecture + +** The active-config indirection (the core piece) +=~/.config/waybar/config= is a stow symlink into the dotfiles, so the toggle +can't rewrite it in place (that would edit the repo). Instead: + +1. *Canonical* config: the committed dotfiles config. Always holds the FULL + module arrays. Read-only source of truth. Unchanged by this feature except + for adding the two arrow modules and their definitions. +2. *Active* config: a generated copy at =$XDG_RUNTIME_DIR/waybar/config=. This is + what waybar loads (=waybar -c=). The toggle rewrites its =modules-left= / + =modules-right= between full and base. +3. *Launch change* (hyprland.conf exec-once): before launching waybar, generate + the active config from the canonical (initial state = expanded/full), then + =waybar -c "$XDG_RUNTIME_DIR/waybar/config" -s <style>=. + +The style.css stays shared (canonical, stowed) — only the config (module arrays) +needs the runtime copy. + +** Toggle scripts +=waybar-collapse <side>= where side ∈ {left, right}: +1. Read per-side state from =$XDG_RUNTIME_DIR/waybar/<side>.state= (expanded | + collapsed; absent = expanded). +2. Flip it. +3. Regenerate the active config's =modules-<side>= array: + - expanded → the canonical full array for that side. + - collapsed → the base set for that side (constant in the script) with the + arrow module included. +4. Write the new state file. +5. =killall -SIGUSR2 waybar=. + +The full array is read from the canonical config each time, so the script never +loses it and stays correct as modules are added/removed upstream. The base set is +the only constant the script hardcodes (or reads from a tiny sidecar). + +** Arrow modules +Two custom modules, =custom/arrow-left= and =custom/arrow-right=, each an exec +script (=waybar-arrow left= / =waybar-arrow right=) that: +- Reads the side's state file. +- Emits the glyph: expanded → points outward (left side ◀ toward left edge, + right side ▶ toward right edge); collapsed → points inward (left ▶, right ◀). +- =on-click= runs =waybar-collapse <side>=. + +The arrow is always in the base set (it's the expand control), so it's present in +both states. Place the left arrow as the LAST module in =modules-left= (innermost, +nearest center) and the right arrow as the FIRST module in =modules-right= +(innermost), so each arrow sits at the inner edge of its side and the collapse +pulls outward away from it. (Confirm placement during implementation — the glyph +direction and module order must agree so the arrow visually points the right way.) + +** State + reload +- State dir: =$XDG_RUNTIME_DIR/waybar/= (per-boot, ephemeral — collapse state + resets on logout, which is fine). +- Reload is =SIGUSR2= (full waybar reload). Cost: brief flicker, module state + resets, tray re-registers. Acceptable for a click action; spike confirmed tray + survives. This cost is per-toggle, never idle. + +* Files (all in =~/.dotfiles/hyprland/=) +- =.local/bin/waybar-collapse= — the toggle (reads canonical, writes active, + signals). New. +- =.local/bin/waybar-arrow= — the arrow module exec (state → glyph + class). New. +- =.local/bin/waybar-active-config= — generates the active config from canonical + at login (used by exec-once and reused by waybar-collapse to resolve the full + arrays). New. (Or fold generation into waybar-collapse + a one-shot init call.) +- =.config/waybar/config= — add =custom/arrow-left= / =custom/arrow-right= module + defs + place them in the arrays. Edit. +- =.config/hypr/hyprland.conf= — exec-once: generate active config, then + =waybar -c "$XDG_RUNTIME_DIR/waybar/config"=. Edit. +- Optional keybinds: =$mod+[= / =$mod+]= to collapse left/right without the mouse. + +* TDD plan (per the dotfiles suite) +- =tests/waybar-collapse/=: full↔base array rewrite against a fixture canonical + config; expanded→collapsed→expanded round-trips to the original arrays; state + file flips; base set always includes the arrow; SIGUSR2 sent (fake killall). + Use a fake canonical config + temp =$XDG_RUNTIME_DIR=, fake killall on PATH + (same harness style as tests/waybar-toggle). +- =tests/waybar-arrow/=: state → correct glyph + class for each side and state; + missing state file = expanded glyph (fail-safe). +- JSON validity of the generated active config (parse it back). + +* Open / to-confirm during implementation +- Exact arrow glyphs (nerd-font triangles) and that order-vs-direction agree. +- Whether to keep =hyprland/window= (the title) out of the left base set — it's + long and variable-width; collapsing the left should drop it (it's not in the + base set, so it hides — correct). +- Animation: none (waybar doesn't animate width; the collapse snaps). Accepted. + +* Risks +- Reload flicker on every toggle. Mitigation: none needed unless it annoys in use. +- If a future module is added to the canonical config, it lands in the full set + automatically (good) but the author should decide if it belongs in a base set. +- $XDG_RUNTIME_DIR active config must exist before waybar starts; the exec-once + ordering must generate it first. waybar-toggle (the crash-relaunch path, mod+B) + must also point at the active config, not the canonical — update it to match. diff --git a/working/collapsible-waybar-sides/spike-findings.org b/working/collapsible-waybar-sides/spike-findings.org new file mode 100644 index 0000000..4d45ed1 --- /dev/null +++ b/working/collapsible-waybar-sides/spike-findings.org @@ -0,0 +1,42 @@ +#+TITLE: Collapsible waybar — spike findings (mechanism) +#+DATE: 2026-06-18 + +* Question +Which mechanism actually collapses a waybar side to a base set, given the right +side is a mix of native modules (group/sysmonitor, pulseaudio, pulseaudio#mic, +idle_inhibitor, tray) and custom exec modules? + +* Method +Two transient waybar instances against /tmp copies of the live config, captured +with grim (live bar briefly down, restored after). Variants in this dir: +- spike-style-csshide.css : option (c) — CSS-hide the native modules + (min-width:0; padding:0; margin:0; opacity:0) on #sysmonitor #pulseaudio + #idle_inhibitor. +- spike-config-collapsed.json : option (b) — modules-right rewritten to the base + set [tray, custom/date, custom/worldclock]. + +* Result +- *CSS-hide (option c): FAILS.* sysmonitor and pulseaudio rendered invisible but + held their space — a gap remained where they were, no reflow. GTK3 has no + =display:none=, and opacity/zero-size leaves the label's intrinsic width. The + right side ends up ragged and half-collapsed, not narrowed. Not viable for the + native modules. +- *Config-swap (option b): WORKS.* The collapsed config reflowed the right side + tight to tray + date, everything else fully gone, no gaps. Hides native and + custom modules alike. Tray icons survived the swap. + +* Decision +Mechanism is config-swap + =killall -SIGUSR2 waybar= (reload), NOT the state-file ++ CSS approach the original task leaned toward. The original "heavy" label on +option (b) is the cost of a full reload (brief flicker, module state resets, tray +re-registers) — acceptable, and the only approach that actually collapses a mixed +module set. + +* Implications for the spec +- Don't maintain two static configs (drift-prone). A toggle script rewrites the + active config's modules-left / modules-right between the full set and the base + set, then SIGUSR2. Base sets defined once; collapsed set is the base set, full + set is restored from the canonical module list. +- Per-side state in $XDG_RUNTIME_DIR; the arrow module reads it to pick its + direction. Arrow lives IN the base set (always visible, it's the expand control). +- Reload cost is per-toggle, not idle — fine for a click action. |
