Skip to content

feat(desktop): add prevent-sleep settings toggle - #93

Merged
deepagent-ai merged 2 commits into
deepagent-ltd:devfrom
thomas-yanga:feat/desktop-prevent-sleep-toggle
Jul 26, 2026
Merged

feat(desktop): add prevent-sleep settings toggle#93
deepagent-ai merged 2 commits into
deepagent-ltd:devfrom
thomas-yanga:feat/desktop-prevent-sleep-toggle

Conversation

@thomas-yanga

Copy link
Copy Markdown
Contributor

Issue for this PR

Closes #

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

The desktop app calls powerSaveBlocker.start("prevent-app-suspension") unconditionally at launch, so the system never idle-sleeps while the app is running,
and there is no user-facing way to opt out.

This PR adds a "Prevent system sleep" switch under a new Power section in General settings (desktop only):

  • Main: the preventSleep value is persisted in the settings store. The default stays enabled (only an explicit false opts out), so existing installs
    keep the historical always-on behavior. A set-prevent-sleep IPC handler starts/stops the blocker live and broadcasts the change to all windows; startup reads
    the stored value instead of always starting the blocker.
  • Preload / renderer / app: bridges get/setPreventSleepEnabled through the platform context, mirroring the existing pinchZoom wiring, and adds the
    switch to the settings UI.
  • i18n: translates the new section and row across all 18 locales.
  • The persisted-setting resolution lives in prevent-sleep.ts, an Electron-free module (same split as close-to-tray.ts), so the default-on semantics are
    unit-testable.

The toggle takes effect immediately; no restart is required.

How did you verify your code works?

  • Unit tests for the setting resolution (unset → on, any non-false value → on, explicit false → off); all 87 desktop package tests pass.
  • Added test:prevent-sleep-smoke, a Playwright-driven dynamic test that launches the real built app, clicks the actual Settings switch, and asserts against
    macOS pmset -g assertions:
    1. default launch registers NoIdleSleepAssertion
    2. disabling the toggle releases the assertion while the app keeps running
    3. the disabled state persists across a relaunch (no assertion)
    4. re-enabling registers the assertion again
  • Wired the smoke into CI as a new desktop-smoke (macos) job in test.yml (kept out of the unit matrix since it needs a window server and a prior desktop
    build).
  • Typecheck (desktop + app), lint, and i18n parity all pass.

Screenshots / recordings

Recorded locally during development; can attach a recording of the toggle flipping pmset assertions on/off if helpful.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

The desktop app unconditionally started a powerSaveBlocker at launch with
no user-facing way to opt out. Add a "Prevent system sleep" switch under
a new Power section in General settings (desktop only).

- main: persist preventSleep in the settings store; default stays enabled
  (only explicit false opts out) so existing installs keep the historical
  always-on behavior; set-prevent-sleep IPC starts/stops the blocker live
  and broadcasts to all windows
- preload/renderer/app: bridge get/setPreventSleepEnabled through the
  platform context, mirroring the pinchZoom pattern
- i18n: translate the new section and row across all 18 locales
- tests: unit-cover the persisted-setting resolution (Electron-free, same
  split as close-to-tray); add prevent-sleep-smoke, a Playwright-driven
  dynamic test that clicks the real Settings switch and asserts macOS
  pmset NoIdleSleepAssertion across default-on, disable, relaunch
  persistence, and re-enable
- ci: run the smoke in a new desktop-smoke (macos) job in test.yml

Signed-off-by: thomas-yanga <odie_majere@outlook.com>
The generic store-set/store-delete/store-clear IPCs could write the
preventSleep key in the settings store without starting/stopping the
powerSaveBlocker, desyncing the persisted setting from the running
blocker (a string "false" even resolved back to enabled on next
launch).

- store-set: reject writes to the preventSleep key; the dedicated
  set-prevent-sleep IPC is now the single write path
- store-delete/store-clear: after touching the settings store,
  re-sync the blocker via syncPowerSaveBlocker() so the reset to the
  default-on behavior takes effect immediately

Verified with the macOS prevent-sleep smoke (4/4) plus a Playwright
guard check: rejected store-set leaves the assertion running, and
store-delete/store-clear restore the NoIdleSleepAssertion.

Signed-off-by: thomas-yanga <odie_majere@outlook.com>
@deepagent-ai
deepagent-ai merged commit b080201 into deepagent-ltd:dev Jul 26, 2026
4 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants