-
tray: the gearbox gets the one face PLN actually looks at · b893a06d
PLN, 2026-08-21: "i dont use the webui most of the time, tray indicator is the only ui i use for parvagues gear bro". The gearbox shipped with an engine, a CLI and a web panel — and its one everyday surface still said Silent/Cool/Standard/ Extreme/Normal, still wrote governor/EPP/platform_profile itself through `sudo perf-audio`, and was DISABLED at login. So the surface he uses was the one surface that had not moved. What this does * tools/bridge/gearbox.py — the client both faces speak. Names the three gears and the three trims once, reads the persisted state unprivileged, and builds the argv for a switch. rig.py's gear() now delegates to it, so the tray and the web panel cannot drift on what a gear is called. * perf-tray.py — the mode list is gone. In its place: gear (off/standard/ aggressive) and trim (quiet/auto/cool) as two INLINE radio blocks under their own headers, because the separation is the design. A reader who sees one flat list keeps believing there is a single "how fast" dial and that quiet and cool are two words for it; two headers teach the model every time the menu opens. * It no longer writes any thermal knob itself. Switching goes `sudo -n` to the arbiter, which is the point — a tray reaching around it would rebuild the four-writer mess GEARBOX.md removed, in one click. * The desired-mode bookkeeping is gone with it. The gearbox persists the gear and re-asserts it from a udev hook on power-source changes and a system-sleep hook on resume; a second bookkeeper in the tray could only ever disagree. * The checked gear is read from the FILE, never inferred from sysfs. Inference (perf.detect_mode) cannot tell a deliberate gear from power-profiles-daemon having moved the same knobs, which it does by design since the gearbox cooperates with ppd rather than masking it. * "Gear ▸" (the apps and services) is now "Rig ▸": gear is the thermal lever now, and the web panel already calls that collection the rig. * perf-tray.service was never tracked — it lived only in ~/.config. Now in the repo, so the unit and the script it runs can no longer drift apart. The icon carries the lever, so it reads with the menu shut Width = gear, colour = trim, drawn as the badge's border. One element for two axes because the panel renders this at ~22 px and any design with two separate marks turns to mush there. Width is the cue that has to survive a dark room and a peripheral glance ("am I in the gig gear?" is the mid-set question), so gear gets shape and trim, which is set-and-forget, gets colour. Off draws no ring: a bare badge is the honest picture of nothing steering the machine. First attempt used 2 px / 5 px, which looked right in a mockup and VANISHED on the panel — 64→22 px scaling turns a 2 px stroke into 0.7 px of grey. Rendering every combination at 20/24/32 px before believing it gave 6 px / 11 px, and then forced the temperature numeral and the sparkline to shrink with the ring, since an 11 px border over a 30 px numeral clips the digits at exactly the size where aggressive is the gear whose temperature you most want to read. Verified on hardware, through the real menu over its D-Bus interface (Plasma's own protocol), not by calling the Python directly: * live tooltip reads "gear: Standard · Cool · cap 15/35W" * the menu exports two radio groups, correctly checked, headers live * clicking Aggressive -> GEAR=aggressive, RAPL 45 W / 115 W * clicking Standard -> GEAR=standard, back to 15/35 W * clicking Cool -> TRIM=cool, fans 0 -> ~2900 rpm * a CLI-side gear change is picked up by the tray within one refresh * enabled and running under graphical-session.target, so it survives logout Harness caveat worth writing down: the very FIRST dbusmenu Event sent to a never-opened menu landed on the wrong item (asked for Aggressive, got trim Auto). Every subsequent one mapped exactly, from both dbus-send and gdbus. Reading it as provisional ids on a menu Qt has not yet had to show — a human cannot click an item without opening the menu first, which is what the later probes did. 18 tests for gearbox.py (79 in the bridge suite, all green). They defend two things, neither arithmetic: the sudoers contract (the argv IS a security boundary — `--trim cool` must stay two words, and `performance`/`--boot`, both real helper verbs, must never be reachable from a face that only knows gears), and the honest-unset rule (never-engaged is not the same state as off, which is why off had to become an explicit gear).PLN (Algolia) authoredb893a06d
| Name |
Last commit
|
Last update |
|---|---|---|
| .. | ||
| tests | Loading commit data... | |
| ui | Loading commit data... | |
| .gitignore | Loading commit data... | |
| README.md | Loading commit data... | |
| bridge.py | Loading commit data... | |
| gearbox.py | Loading commit data... | |
| launchers.py | Loading commit data... | |
| midimon.py | Loading commit data... | |
| midistream.py | Loading commit data... | |
| parvagues-bridge.desktop | Loading commit data... | |
| parvagues-bridge.service | Loading commit data... | |
| perf.py | Loading commit data... | |
| rig.py | Loading commit data... | |
| server.py | Loading commit data... | |
| surface.py | Loading commit data... |