Skip to content

fix(desktop): stop Windows silent freeze when window is occluded (#83420) - #83540

Closed
HexLab98 wants to merge 2 commits into
NousResearch:mainfrom
HexLab98:fix/83420-windows-occluded-freeze
Closed

fix(desktop): stop Windows silent freeze when window is occluded (#83420)#83540
HexLab98 wants to merge 2 commits into
NousResearch:mainfrom
HexLab98:fix/83420-windows-occluded-freeze

Conversation

@HexLab98

@HexLab98 HexLab98 commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Summary

  • On Windows only, re-enable Chromium's occluded-window opt-out (disable-backgrounding-occluded-windows + CalculateNativeWinOcclusion) so an idle minimized/covered Hermes window cannot stall the UI task runner with no error.
  • Pulse setBackgroundThrottling(false) on chat-window show / restore / focus so a return from occlusion can wake the scheduler even if it wedged while hidden.
  • Keep stream-scoped throttling: do not restore process-wide disable-background-timer-throttling or a static backgroundThrottling: false (those caused the idle ~20% CPU burn).

Fixes #83420

Test plan

  • cd apps/desktop && npx vitest run electron/stream-throttle.test.ts electron/windows-occlusion-flags.test.ts
  • On Windows 11 Desktop (remote gateway ok): idle chat, minimize or fully cover with another app for ≥30s, restore — composer stays usable, no process kill needed, first taskbar restore click works
  • Confirm idle minimized CPU stays reasonable vs the old always-unthrottled path

Idle chat windows were returning to Chromium's occluded-window path, which
on Windows can park the browser main thread on a WaitableEvent with no wake
(NousResearch#83420). Restore the Windows-only occlusion opt-out and pulse unthrottle
on show/restore/focus, without bringing back process-wide timer opt-outs.
Regression coverage for NousResearch#83420: win32-only Chromium switches and the
show/restore/focus wake pulse that restarts idle throttling safely.
daltino

This comment was marked as resolved.

@alt-glitch alt-glitch added type/bug Something isn't working P1 High — major feature broken, no workaround comp/desktop Electron desktop app (apps/desktop/*) platform/windows Native Windows-specific behavior or breakage sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows labels Aug 11, 2026
@egilewski

Copy link
Copy Markdown
Contributor

suggesting changes

windows-occlusion-flags.ts adds disable-features=CalculateNativeWinOcclusion without preserving the current disable-features value. Electron/Chromium treat switches as keyed: with Electron 40.10.2 launched as --disable-features=ExistingFeature, the effective value was ExistingFeature before this append and only CalculateNativeWinOcclusion afterward. The workaround therefore silently re-enables every other feature that the launcher or Electron had disabled.

Please read and merge the existing comma-separated value, de-duplicate CalculateNativeWinOcclusion, and add a regression test that starts with another disabled feature and proves both remain effective.

Security evidence:

  • trust boundary: Electron's main process constructs Chromium's effective command line before app readiness; existing disabled features can come from the launcher or Electron.
  • source/sink/invariant: windowsOcclusionCommandLineSwitches('win32') emits a new disable-features value and main.ts forwards it directly to app.commandLine.appendSwitch; adding the occlusion workaround must preserve every feature already disabled.
  • current-main reproduction: current main has no occlusion helper or replacement append; its existing stream-throttle tests pass (5 passed).
  • PR-head or patch-replay validation: exact head 36380c3fda and the clean replay on current main both pass the 27 focused tests, TypeScript, and the full Electron suite (1,017 and 1,041 tests respectively).
  • positive/negative cases: the added tests prove the intended Windows flags and non-Windows no-op, but Electron 40.10.2 changed an initial effective value of ExistingFeature to only CalculateNativeWinOcclusion after the new append pattern.
  • residual bypass search: the helper has no path that reads, merges, or de-duplicates a pre-existing disable-features value, and no test starts with one.
  • reviewer validation: the replacement behavior was reproduced independently against the PR's locked Electron version.

Not checked:

  • Windows 11 end-to-end freeze reproduction
  • Idle minimized CPU
  • CodeRabbit review

Signed: GPT-5.6-sol-xhigh in Codex

@marcatmadu

Copy link
Copy Markdown

Windows 11 reporter of #83420 here — I can run the manual occlusion test from your test plan (minimize/fully cover ≥30s, restore, first taskbar click) on the exact build, with renderer logging + a crash dump if it still stalls. Say the word once the requested change lands.

@marcatmadu

Copy link
Copy Markdown

Just checking in on #83540 — any ETA on the requested change (merging the disable-features switch instead of overwriting)? The Windows 11 test offer from #83420 still stands: I can run the occlusion test (minimize/fully cover ≥30s, restore, first taskbar click) with renderer logging + crash dump as soon as a new head is pushed.

@marcatmadu

Copy link
Copy Markdown

Windows 11 test result: freeze reproduces on this PR (head 36380c3fd)

Tested the current head on Windows 11 (the same machine that produced dumps #6/#7 on the #82832 build). The silent freeze still occurs — the occlusion flags alone do not fix this stall.

What was tested

Log evidence

  • Renderer log is clean — no clamp-flood (useClientLookup: Clamped stale index is absent), unlike the pre-fix builds that had 914+ clamp messages/day
  • The occlusion flags therefore eliminated the clamp-flood symptom, but the underlying stall survived
  • Full crash dump collected (32 threads, 812 MB, Hermes9.dmp) — matches the stalled-task-runner signature from dumps Fix VM instance sharing across tasks #6/some cleanups #7

Takeaway

The disable-backgrounding-occluded-windows + CalculateNativeWinOcclusion + throttle-pulse approach does not reach the stall. The renderer's UI task runner still wedges when the window returns from occlusion. This suggests the scheduler-level lost-wakeup (threads parked on base::WaitableEvent instead of the Windows message queue) originates deeper than the occlusion-throttling flags — likely in Chromium's task runner / scheduler layer, potentially tied to the renderer process's event binding under Electron 43/40 on Windows.

The dumps and logs are available if anyone wants to inspect.

@teknium1

Copy link
Copy Markdown
Contributor

Thanks @HexLab98 for the careful work here — the platform-scoped helper, the wake() pulse design, and the test coverage were all well built. Closing this after empirical validation, though:

  • The original reporter of [Bug]: Hermes Desktop silently freezes on Windows when the window is hidden/occluded - stalled task runner (no error, no exception) #83420 (@marcatmadu) tested this PR's exact head (36380c3fd, Electron 43.2.0, Windows 11 — the same machine that produced the earlier crash dumps) and the silent freeze still reproduces within ~2 minutes of occlusion. The flags eliminated the useClientLookup clamp-flood side symptom, but the stalled-task-runner signature (threads parked on base::WaitableEvent, dump Hermes9.dmp) is unchanged — the stall lives deeper, likely in Chromium's scheduler layer, and disable-backgrounding-occluded-windows + CalculateNativeWinOcclusion don't reach it.
  • @egilewski's review finding is also real and unaddressed: appending disable-features=CalculateNativeWinOcclusion replaces any pre-existing disable-features value rather than merging it, silently re-enabling every other feature the launcher or Electron had disabled.

Merging this would close #83420 without fixing it (and add a flag-clobbering regression), so we're keeping the issue open for the deeper scheduler-level investigation. If a future fix wants the occlusion opt-out as defense-in-depth alongside a real fix for the wedged task runner, the helper structure here is a good starting point and we'd welcome a follow-up that merges the disable-features value. Credit to @HexLab98 for the investigation and to @marcatmadu for the exceptional on-head verification with dumps.

@teknium1 teknium1 closed this Aug 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/desktop Electron desktop app (apps/desktop/*) P1 High — major feature broken, no workaround platform/windows Native Windows-specific behavior or breakage sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Hermes Desktop silently freezes on Windows when the window is hidden/occluded - stalled task runner (no error, no exception)

6 participants