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
This commit is contained in:
@@ -7,6 +7,7 @@ import Quickshell.Bluetooth
|
||||
import Quickshell.Io
|
||||
import Quickshell.Services.Pipewire
|
||||
import QtQuick
|
||||
import qs.config
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
@@ -146,11 +147,38 @@ Singleton {
|
||||
// Running out is not ambient. Published at a priority Do Not Disturb does
|
||||
// not silence, because the one notification you must not miss is the one
|
||||
// saying the machine is about to stop.
|
||||
//
|
||||
// And then, unless told otherwise, the machine is put to sleep: a suspend
|
||||
// at the urgent threshold preserves the session for days, a hard cut at
|
||||
// 0% preserves nothing. The grace timer is what makes the warning above
|
||||
// readable and the action cancelable -- plugging in during it stands
|
||||
// everything down.
|
||||
Timer {
|
||||
id: criticalSuspend
|
||||
interval: 15000
|
||||
onTriggered: {
|
||||
if (Battery.critical && !Battery.acOnline
|
||||
&& DesktopPreferences.get("batteryCriticalAction") === "suspend")
|
||||
Quickshell.execDetached(["systemctl", "suspend"]);
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Battery
|
||||
function onAcOnlineChanged(): void {
|
||||
if (Battery.acOnline)
|
||||
criticalSuspend.stop();
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Battery
|
||||
function onCriticalChanged(): void {
|
||||
if (!root.powerInitialized || !Battery.critical)
|
||||
return;
|
||||
if (!Battery.acOnline
|
||||
&& DesktopPreferences.get("batteryCriticalAction") === "suspend")
|
||||
criticalSuspend.restart();
|
||||
StatusEvents.publish({
|
||||
key: "battery-critical",
|
||||
glyph: "\u{F0083}",
|
||||
|
||||
Reference in New Issue
Block a user