Skip to content

feat(keep-awake): optionally block lid switch suspend while active#2816

Draft
sweenu wants to merge 1 commit into
AvengeMedia:masterfrom
sweenu:feat/keep-awake-lid-inhibitor
Draft

feat(keep-awake): optionally block lid switch suspend while active#2816
sweenu wants to merge 1 commit into
AvengeMedia:masterfrom
sweenu:feat/keep-awake-lid-inhibitor

Conversation

@sweenu

@sweenu sweenu commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Problem

Keep awake only speaks the Wayland idle-inhibit protocol (an IdleInhibitor on the bar surface) plus gating DMS's own IdleMonitors. On laptops where suspend is triggered by closing the lid — a logind hardware event (HandleLidSwitch=) — keep awake has no effect: no Wayland idle inhibitor can suppress lid handling, so the machine suspends anyway.

Solution

New setting idleInhibitLidSwitch (default off). While keep awake is active, the DMS daemon takes a block-mode handle-lid-switch logind inhibitor via the existing m.inhibit() D-Bus helper, and releases it when keep awake ends or the daemon shuts down. logind always honors handle-lid-switch locks regardless of LidSwitchIgnoreInhibited=, so this works without any logind config changes.

The inhibitor is deliberately scoped to handle-lid-switch only (not sleep): a block-mode sleep inhibitor would also make explicit suspend from the power menu fail while keep awake is on.

Note: with the lid action blocked, the internal panel stays on when the lid is closed — logind's suspend was what turned it off. Users who want the panel dark can add a compositor lid-switch bind (e.g. Hyprland bindl = , switch:on:Lid Switch, exec, hyprctl dispatch dpms off eDP-1); that's compositor territory, so intentionally out of scope here.

Changes

core (API v27 → v28):

  • loginctl.setLidInhibitorEnabled method (params: enabled)
  • Manager.SetLidInhibitorEnabled() — idempotent acquire/release under its own mutex, mirroring the sleep inhibitor
  • Released in Manager.Close()
  • Handler tests: param validation, no-op disable, missing manager object, acquire-once/release with a mocked D-Bus fd

quickshell:

  • idleInhibitLidSwitch in SettingsSpec.js + SettingsData.qml (default off)
  • SessionService.syncLidInhibitor() — sends the daemon request, gated on loginctlAvailable + API ≥ 28; synced on keep-awake enable/disable, setting change, and daemon reconnect (re-establishes the inhibitor if dms restarts while keep awake is on)
  • Toggle "Keep awake blocks lid switch" in Settings → Power & Sleep, next to "Lock before suspend" (visible when loginctl is available)
  • Regenerated settings_search_index.json

Testing

  • go build ./..., go vet, gofmt clean; full loginctl test suite passes incl. 4 new tests; all pre-commit hooks pass
  • Verified end-to-end on a Hyprland laptop (NixOS, HandleLidSwitch=suspend-then-hibernate) running this branch:
    • keep awake on → systemd-inhibit --list shows DankMaterialShell … handle-lid-switch … Keep awake … block
    • keep awake off → lock released (only the pre-existing sleep/delay lock remains); re-enable re-acquires it
    • with keep awake on, physically closing the lid does not suspend the machine; without it, lid-close suspends as before

🤖 Generated with Claude Code

Keep awake only speaks the Wayland idle-inhibit protocol (plus gating
DMS's own IdleMonitors), so on laptops where suspend is triggered by
closing the lid - a logind hardware event - it has no effect.

Add an idleInhibitLidSwitch setting (default off). While keep awake is
active, the DMS daemon now takes a block-mode handle-lid-switch logind
inhibitor via the existing D-Bus inhibit helper, released when keep
awake ends or the daemon shuts down. logind always honors
handle-lid-switch locks regardless of LidSwitchIgnoreInhibited.

The inhibitor is scoped to handle-lid-switch only, not sleep, so
explicit suspend from the power menu keeps working while keep awake
is on.

New loginctl.setLidInhibitorEnabled API method (bumps API to v28);
the shell syncs it on keep-awake toggle, setting change, and daemon
reconnect. Toggle lives in Settings > Power next to lock-before-suspend.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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