Skip to content

Dismiss the low battery warning once the charger is back - #10900

Open
yamz8 wants to merge 1 commit into
omacom:quattrofrom
yamz8:fix/battery-low-notification-lingers
Open

Dismiss the low battery warning once the charger is back#10900
yamz8 wants to merge 1 commit into
omacom:quattrofrom
yamz8:fix/battery-low-notification-lingers

Conversation

@yamz8

@yamz8 yamz8 commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

The problem

Hit a 10% battery warning, plugged the charger in, and the toast stayed on screen.

omarchy-battery-low sends the warning at -u critical, and durationFor() in shell/plugins/notifications/Service.qml returns 0 for critical urgency — critical popups never expire, so the -t 30000 on that send is ignored by design. The battery service resets its own notifiedLowBattery flag when you plug in, but nothing takes the toast off screen, so a stale "Time to recharge!" sits there until dismissed by hand.

The fix

Let the service dismiss the warning it sent, once the battery stops being low.

  • BatteryModel.shouldWarnLowBattery() gains a clear flag for the recovery transition (was notified, no longer low). The level < 0 early return folds into the same expression, so a battery that disappears also clears.
  • Service.qml calls a new clearLowBatteryWarning(), which runs omarchy-notification-dismiss "Time to recharge!". onOnBatteryChanged already triggers checkBattery(), so it fires the moment the charger lands rather than on the next 30s tick.
  • A comment in bin/omarchy-battery-low ties the headline to lowBatterySummary so the two don't drift.

Dismissing moves the toast to notification history rather than deleting it, so there's still a record that it fired.

I kept the dismissal keyed on the summary rather than tracking the notification id via omarchy-notification-send -p: the id would have to survive a shell restart in PersistentProperties and could collide with a reused id, for no real gain.

Testing

test/shell.d/battery-test.sh covers the new flag with three added cases — charger plugged in, never-warned, and battery removed. ./test/shell and ./test/cli pass; config-test.sh and locate-test.sh fail identically on an unmodified checkout (plocate packaging and a UnicodeDecodeError), unrelated to this change.

Verified in the running UI per agents/skills/visual-verification.md: sent the real toast, confirmed it on screen, ran the dismissal, confirmed it gone.

🤖 Generated with Claude Code

https://claude.ai/code/session_01V7sx1LYXKQrhFwchbfqPwz

The low battery toast is sent at critical urgency, and the shell never
expires critical popups, so plugging in left a stale "Time to recharge!"
warning on screen until it was dismissed by hand.

Track the recovery transition in the battery model and have the service
dismiss its own warning when the battery stops being low.

Two paths would otherwise leave the toast stranded for good, since each
clears the notified flag without ever taking the toast down:

  - Dismissing by summary only matches toasts the server already has, so
    plugging in while omarchy-battery-low is still posting would dismiss
    nothing. Defer the clear until the warning process has exited.
  - PersistentProperties only spans in-process QML reloads, but a critical
    popup is restored from disk across a full restart. Clear on the first
    check after startup rather than trusting the flag alone.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V7sx1LYXKQrhFwchbfqPwz
@yamz8
yamz8 force-pushed the fix/battery-low-notification-lingers branch from db2854c to c4f19a2 Compare September 8, 2026 23:40
@yamz8

yamz8 commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

Pushed an amended commit (c4f19a21) closing two ways the toast could still be stranded permanently — both share the shape that the notified flag gets cleared without the toast ever coming down, so nothing retries:

  • The clear could outrun the warning it dismisses. sendLowBatteryWarning and clearLowBatteryWarning spawn independent processes. Plugging in a few hundred ms after the 30s timer fires means the dismissal runs against a popup model that doesn't hold the toast yet, matches nothing, and omarchy-battery-low posts the critical toast afterwards. The clear now defers until warningProcess has exited, following the pendingPowerSource idiom already in the file.
  • A shell restart restores the toast but not the flag. PersistentProperties only spans in-process QML reloads (shell/plugins/notifications/Service.qml:61-64), while a duration-0 critical popup "always survives restarts" (NotificationLogic.js:384-386) and is re-appended to popupModel on startup. So omarchy-restart-shell around the plug-in event — an update or theme change — left the restored toast up for good. shouldWarnLowBattery takes a firstCheck argument and clears on the first check after startup rather than trusting the flag alone.

Two more test cases cover the restart path (clears when restored, still warns when it genuinely starts up low); 12 assertions pass.

One verification caveat worth stating plainly: my earlier check exercised omarchy-notification-dismiss against the installed shell at /usr/share/omarchy, so the dismissal mechanism is confirmed end-to-end, but the modified QML itself has not been loaded by a running shell on my machine. It parses under qmlformat, and qmllint's only complaints about the new onExited handlers are the same ones it raises for the existing powerProfileProcess.onExited. The model logic is fully unit-tested either way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant