Skip to content

feat(recording): throttle screenshot capture while idle (fixes #286)#311

Open
praxstack wants to merge 2 commits into
JerryZLiu:mainfrom
praxstack:pr2-idle-capture-throttle
Open

feat(recording): throttle screenshot capture while idle (fixes #286)#311
praxstack wants to merge 2 commits into
JerryZLiu:mainfrom
praxstack:pr2-idle-capture-throttle

Conversation

@praxstack

@praxstack praxstack commented Jul 7, 2026

Copy link
Copy Markdown

fixes #286

what

after 2 minutes without keyboard/mouse input, screenshot capture slows from the default 10s cadence to 30s — cutting idle-period disk writes and analysis cost by ~3x. adds a "Slow down capture when idle" toggle in Settings > Recording privacy (default on).

why throttle, not pause

a hard pause was my first instinct but it's wrong: IdleBatchClassifier needs screenshots with idle readings actually present to produce an "Idle" timeline card (95% coverage, no gap >30s). stop capturing entirely and idle periods become a silent gap instead of an Idle card — worse than today.

why 30s, not something bigger

idleSecondsAtCapture is seconds-since-last-input, not seconds-since-last-screenshot. a brief activity blip mid-idle-stretch (checking your phone, a stray mouse jiggle) resets that clock for the next screenshot, so the worst case leaves (throttle_interval - 1) seconds of the previous gap uncovered. at 60s (what I tried first) that's up to 59s — nearly double IdleBatchClassifier's 30s limit, silently kicking the whole batch out of idle classification into full LLM processing. 30s is the largest value where the worst case (29s) still stays under the limit — verified exhaustively across every blip timing, not just spot-checked.

IdleCaptureIntervalTests.testWorstCaseBlipDuringIdleStaysWithinClassifierGapLimit reproduces IdleBatchClassifier's actual coverage math and fails against the original 60s value (confirmed by testing it before fixing it).

tests

xcodebuild -project Dayflow/Dayflow.xcodeproj -scheme Dayflow -destination 'platform=macOS' test
** TEST SUCCEEDED **

19/19 pass (11 pre-existing, 8 new).

verification gap (being upfront)

I did not launch the built app to visually confirm the new Settings toggle renders — the real /Applications/Dayflow.app was already running on this machine and I didn't want a second instance conflicting on the shared database/UserDefaults. The #Preview block for the modified view builds and links cleanly (__preview.dylib compiles with no errors), which confirms the code is well-formed, but I haven't rendered it interactively. Happy to follow up with a screenshot if useful.


Follow-up hardening pass (2026-07-08)

Added 5 tests (no production code change) covering surfaces the original tests left out: IdleCapturePreferences default-on + persist/re-read round-trip, the disabled-preference gate the recorder relies on, and RecordingPrivacySettingsViewModel reflecting the persisted value at init + writing through on toggle. Full DayflowTests suite green.

praxstack added 2 commits July 8, 2026 02:08
…Liu#286)

After 2 minutes without keyboard/mouse input, reduce screenshot capture
from the default 10s cadence to 30s — cutting idle-period disk writes
and JPEG encode/analysis cost by 3x, per issue JerryZLiu#286's request to reduce
capture frequency (esp. during inactivity).

This throttles rather than pauses: ScreenRecorder's state machine is
unchanged (still .capturing throughout), only the capture timer's
interval adapts. A hard pause was considered and rejected — it would
starve IdleBatchClassifier of the screenshots it needs to produce an
"Idle" timeline card, turning idle periods into silent gaps instead.

The 30s throttled interval is not an arbitrary choice: idleSecondsAtCapture
measures time-since-last-INPUT, not time-since-last-screenshot, so a brief
activity blip mid-idle-stretch resets that clock for the next screenshot.
Exhaustively verified (IdleCaptureIntervalTests.swift) that 30s is the
largest interval where a worst-case blip still can't leave more than
IdleBatchClassifier's 30s uncovered-gap limit exposed — a 60s interval,
tried first, fails this by nearly 2x and would silently kick affected
batches out of idle classification into full LLM processing, defeating
the whole point of the throttle.

Adds a "Slow down capture when idle" toggle in Settings > Recording
privacy (default on).

Tests: 19/19 pass (11 pre-existing + 8 new), including a regression test
that reproduces IdleBatchClassifier's real coverage-gap math and fails
against the original (incorrect) 60s value.
Follow-up hardening pass. The original PR's tests covered the pure interval
math (IdleCaptureInterval) but not the persistence/UI surfaces. Adds 5 tests:
- defaults-to-enabled when unset (feature ships on; a fresh install must throttle)
- persist-disabled + re-read, and re-enable round-trip
- disabled-preference contract the recorder's effectiveScreenshotInterval gate relies on
- RecordingPrivacySettingsViewModel reflects the persisted value at init and
  writes through on toggle change

All pass; full DayflowTests suite green; no production code changed.
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.

[Feature Request] Change screen capture interval length

1 participant