Skip to content

fix: avoid false idle reports from powerMonitor on macOS (naturalBreaks churn)#1798

Open
kyson-zhu-888 wants to merge 1 commit into
hovancik:trunkfrom
kyson-zhu-888:fix/macos-idle-false-report
Open

fix: avoid false idle reports from powerMonitor on macOS (naturalBreaks churn)#1798
kyson-zhu-888 wants to merge 1 commit into
hovancik:trunkfrom
kyson-zhu-888:fix/macos-idle-false-report

Conversation

@kyson-zhu-888

Copy link
Copy Markdown

What

On macOS 26 (Tahoe / Darwin 25), powerMonitor.getSystemIdleTime() reports false idle values — it oscillates between a few seconds and values above naturalBreaksInactivityResetTime, even during active use. Because NaturalBreaksManager.idleTime trusts powerMonitor.getSystemIdleTime() first and only falls back to the native node-desktop-idle-v2 when it returns 0, the inflated (non-zero) value means the accurate native source is never reached.

The oscillation makes _checkIdleTime() fire clearBreakScheduler (idle > reset time) and then naturalBreakFinished (idle < 20s) in rapid succession, every 1–2 minutes. Each naturalBreakFinished calls reset() on the planner, restarting the break countdown. Net effect: with naturalBreaks enabled, breaks never fire.

Fixes #1797.

Change

Use the native node-desktop-idle-v2 (IOHID) source directly on darwin; keep the existing behaviour on every other platform.

get idleTime () {
  if (this.usingNaturalBreaks) {
    if (process.platform === 'darwin') {
      return desktopIdle.getIdleTime() * 1000
    }
    return (powerMonitor.getSystemIdleTime() || desktopIdle.getIdleTime()) * 1000
  } else {
    return 0
  }
}

Why the native source is trustworthy

node-desktop-idle-v2 reads IOHID. Querying the same IOHID source directly is accurate:

$ ioreg -c IOHIDSystem | grep HIDIdleTime   # no input for 4s
109.899 s
$ sleep 4; ioreg -c IOHIDSystem | grep HIDIdleTime
113.979 s     # +4s, monotonic and correct

So only powerMonitor.getSystemIdleTime() misbehaves on this OS — likely a macOS 26 / Electron regression in the CGEventSource-backed idle API.

Testing

  • standard passes on the changed file.
  • Existing test/naturalBreaksManager.js still passes (it only asserts idleTime === 0 when natural breaks are off).
  • Patched into a local 1.21.0 build, naturalBreaks=true: monitored main.log for 5 minutes during active use → 0 idle-churn events (vs. one pause/resume pair every 1–2 min before). Breaks now schedule and fire correctly, and genuine idle periods still reset the countdown as intended.

Scope

Single-file, single-expression change, guarded by process.platform === 'darwin'. Non-macOS behaviour is unchanged. The powerMonitor event subscriptions in main.js (suspend/lock-screen/resume/unlock-screen) are unrelated and untouched.

powerMonitor.getSystemIdleTime() can report false idle values on macOS
(observed on macOS 26 / Darwin 25), oscillating between a few seconds and
values above naturalBreaksInactivityResetTime even during active use. Since
the inflated value is non-zero, the native fallback is never reached, causing
clearBreakScheduler/naturalBreakFinished churn that keeps resetting the break
countdown so breaks never fire.

Use the native node-desktop-idle-v2 (IOHID) source directly on darwin, which
ioreg HIDIdleTime confirms is accurate; keep existing behaviour elsewhere.

Refs hovancik#1797

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Jun 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 68.31%. Comparing base (888f1f1) to head (9e6c7af).
⚠️ Report is 15 commits behind head on trunk.

Files with missing lines Patch % Lines
app/utils/naturalBreaksManager.js 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##            trunk    #1798      +/-   ##
==========================================
+ Coverage   67.39%   68.31%   +0.91%     
==========================================
  Files          16       17       +1     
  Lines         506      527      +21     
==========================================
+ Hits          341      360      +19     
- Misses        165      167       +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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.

[Bug]: powerMonitor.getSystemIdleTime() reports false idle on macOS 26 (Darwin 25), breaking naturalBreaks (idle churn → breaks never fire)

2 participants