aba2d16ffa58eaf1895d6aaa3cdab4f6e27fb604
4
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
9530e32326 |
Give a laptop its first week: the keys, the lid, the battery's endgame
The audit's fourth tier -- what a Framework owner reaches for in the first week and found missing. The power button stops being an instant, unconfirmed poweroff: a shipped logind drop-in tells the daemon to stand down and the compositor binds the key to the power menu, the way GNOME turns it into a question. Holding it still hard-cuts through firmware. change-settings restarts logind so the change applies without waiting for a boot, and the Power page says what the button does now. The function row fills in: F10 (XF86RFKill) toggles airplane mode through a new panama-osd verb that blocks or unblocks every radio and says which way it went; F9 (XF86Display) opens the Displays page, the honest action until mirroring exists. And the lid becomes a switch bind: closing a docked lid turns the internal panel off so nothing renders inside a closed shell and no workspace strands on an invisible output, and opening it restores the panel with the mode and scale chosen in Settings. panama-lid owns both decisions; undocked machines suspend via logind before any of it matters. The battery gets an endgame. On battery the screen dims to 30% two-thirds of the way to blanking -- GNOME's single largest idle battery saver -- and restores exactly the level it saved. At the urgent threshold the machine suspends after a fifteen-second grace, cancelled by plugging in, because a suspend preserves the session for days and a hard cut at 0% preserves nothing; "Only warn" remains a choice on the Power page. Hibernate joins the power menu, but only where logind answers CanHibernate with yes -- an entry that fails silently is worse than none. And brightness stops being two code paths: the Displays page now embeds the same control the quick-settings panel uses, so the built-in backlight and DDC/CI monitors share one surface that withdraws itself where neither exists. The lid contract narrows to what its principle protects -- a HandleLidSwitch drop-in -- so deliberate policy for other keys can ship. Claude-Session: https://claude.ai/code/session_01Epx9ZC1gwm81K3jm9x9CKh |
||
|
|
bc6d63b70f |
Let the idle timings know whether you are plugged in
An idle screen costs a screen on wall power and the rest of your afternoon on battery, so they should not be the same number. hypridle has no concept of a power source -- one config, one set of timeouts -- so rather than maintaining two configs and swapping them, panama-idle builds the single config from whichever key set applies, and IdleLock rebuilds it when the charger comes or goes. That runs through the same 400ms debounce a settings change uses, so a loose charger cannot restart hypridle in a loop. The battery keys fall back to their AC counterparts rather than to the schema defaults. Without that, unplugging would silently override a deliberately long timing with a shipped short one, which is the kind of thing you would notice only by losing work. A machine with no battery reads none of it and generates exactly what it generated before. The contract pins that alongside the two obvious directions, and was checked by sabotaging the detection to confirm it fails rather than passing vacuously. |
||
|
|
3c359f3f7e |
Notice the battery, and the machine it is or is not in
Panama had no idea whether it was running on a laptop. No upower, no battery, no lid, no AC: hypridle.conf says "This is a desktop" in its own header, and that was true of the code as well as the machine. panama-hw answers hardware questions one at a time, exits 0 or 1, and prints nothing, so scripts, services and contracts all ask the same way. The definition the rest of the laptop work hangs on is one line: clamshell is lid-closed AND an external monitor. A machine with no mains supply at all reports as being on wall power, because a desktop cannot run out of it. The battery service follows Vitals: sysfs through FileView, an availability flag, and no subprocess on the timer. Globbing is the one thing QML cannot do -- a battery is BAT0 or BAT1 or CMB0, mains is AC or ADP1 or ACAD -- so panama-battery resolves the names once and the shell reads the files directly after. Nothing falls back to a plausible zero: a desktop shows no indicator, no card, and no charge limit control where the firmware has no ceiling. Also repairs two contracts that were already failing and had not been noticed, because only the full suite runs them. The dependency scanner treated line-initial variable assignments, case labels, comments and heredoc bodies as commands, and `count`, `host`, `cancel` and `import` are all real binaries on Fedora, so `command -v` could not filter them out. It now drops comments and heredoc bodies and requires a command to be followed by whitespace. Verified it still catches a genuinely undeclared dependency rather than passing quietly. The launcher command contract had not been told about the fourteen commands added earlier today. |
||
|
|
e1faaf7a76 |
Drop the extension, and give the test suite a front door
Phase 6, the last of the fresh-install spec. 159 scripts lose their .sh: 110 contracts, 47 Vicinae commands, 2 compositor contracts. A shebang and the executable bit already select the interpreter. The extension only ever added something that had to stay in sync, and the rename proved the point twice over in the space of an hour. The spec's stated risk was Vicinae's script discovery. One script was renamed and reloaded on its own before the other 46 followed; it came back as scripts:panama.capture and all 47 resolve. What the probe turned up instead is that the extension was never only a filename: Vicinae's command IDs embed it, so every ID changed. Nothing in this repository refers to them, so nothing breaks. The only trace is Vicinae's metadata.json, whose visited map had two Panama entries that are now orphaned -- two commands lost their usage ranking and will earn it back. Worth knowing before anyone renames these again on a machine that has a keybind pointing at one. Rewriting the references by exact filename missed two things it structurally could not see: a name built from a variable, settings-$page.sh, and a glob, -name '*.sh'. Both were in the contract that counts the generated commands, which promptly reported 47 expected and 0 found. The mechanical part of a rename is the part that looks finished. The three subcommands. panama doctor fronts a health check that already existed and already ran at the end of every install but could not be reached from a terminal. panama upgrade re-runs the installer from anywhere. panama test runs the suite, which had no entry point at all -- 121 files that were the main safety net in this repository and were invisible in it. Writing that runner found three tests nothing was running. calendar_agenda_bridge_test, home_assistant_bridge_test and kdeconnect_bridge_test are unittest suites without the executable bit, so no contract invoked them and the first draft of the runner skipped them silently. All three pass, and have passed unobserved for weeks. The runner collects *_test.py as well now, because a runner with a blind spot is worse than no runner for the same reason a dependency checker with one is: it reports PASS. Six worktrees pruned. Each was re-checked rather than trusted to the spec's list, and two needed it: panama-commands is not on feat/panama-commands but on feat/gnome-tweaks-parity, and fix/panama-displays-review reads [ahead 3] -- ahead of its remote, not of main, with every commit patch-equivalent to landed work. roadmap-completion stays; it has five commits that are genuinely unlanded. The branches are left alone: pruning a worktree costs nothing, deleting a branch is a decision. 121 contracts pass. Claude-Session: https://claude.ai/code/session_01NvgBuSWB5sE43yWmg21ozj |