Repository navigation
Description
Describe the bug
On Windows Hub (OpenClaw Companion) v2026.7.1-2, the OpenClaw.Tray.WinUI process idles at ~100% of one CPU core continuously (even when the window is idle and nothing is happening). This makes dragging/moving the main window noticeably janky (UI/rendering thread is busy).
Evidence (measured on this machine)
OpenClaw.Tray.WinUI (PID 7948) CPU samples, idle, window open but not being interacted with:
sample 1: +3.17s CPU in 3s wall (≈106% of one core)
sample 2: +3.12s CPU in 3s wall (≈104% of one core)
sample 3: +3.12s CPU in 3s wall (≈104% of one core)
Meanwhile the OpenClaw Gateway node process is idle (~0% CPU), and overall system load is only ~10% with ~7 GB free RAM — so this is not a resource-starved machine; the WinUI app is burning a core on its own.
Expected behavior
When the window is idle (no messages streaming, no animation active), OpenClaw.Tray.WinUI CPU usage should be near 0%.
Actual behavior
The process continuously pegs one core (~100%+), causing window-drag jank and elevated power/heat.
Possible cause direction
Likely a WinUI3 rendering/layout busy-loop (animation, progress indicator, or layout-cycle) that never idles. Related work already exists in this repo: #1279 "fix(chat): coalesce Publish() bursts to prevent WinUI3 layout-cycle crash". A sustained single-core busy loop strongly suggests a render/layout effect that is scheduled unconditionally instead of only when needed.
Environment
- OS: Windows 10 Pro 22H2 (build 19045, x64)
- OpenClaw Companion (Windows Hub): v2026.7.1-2
- OpenClaw Gateway: 2026.8.1 (local, loopback bind)
- GPU: Intel UHD 630 (integrated) + virtual display adapters from remote-control software (GameViewer)
Repro
- Start OpenClaw Companion and let it idle (no chat activity, window visible).
- Observe CPU usage of
OpenClaw.Tray.WinUI— it stays at ~100% of one core. - Try dragging the main window — it lags/stutters.
Suggested fix
Ensure render/layout effects are only scheduled when the UI actually needs an update (e.g. coalesce/unschedule idle animations and progress updates), so the app idles at ~0% CPU when nothing is happening.
Metadata
Metadata
Assignees
Labels
Type
Fields
Priority
Activity
clawsweeper commentedon Sep 2, 2026
Codex review: keeping this open for maintainer follow-up; there is still a little grit to resolve. Reviewed September 4, 2026, 12:52 AM ET / 04:52 UTC.
Summary
Keep open for trace-driven maintainer investigation. Two users report the same severe idle CPU symptom on the released build, and current main contains no verified fix, but source inspection cannot safely attribute it to one callback or loop.
Reproducibility: no. high-confidence current-main reproduction is available. The released-build measurements are concrete and independently corroborated, but no current-main trace identifies the responsible work path.
Ways to help us reproduce this
Next step
The symptom is credible but no concrete current-main hot path is proven, and the existing no-new-fix-PR and maintainer-review signals appropriately prevent speculative automated repair.
Review details
Best possible solution:
Capture a Windows Performance Recorder or ETW trace while the default Connection page is visibly idle, identify the hot UI-thread stack, then make that exact source conditional or bounded and add focused regression coverage.
Do we have a high-confidence way to reproduce the issue?
No high-confidence current-main reproduction is available. The released-build measurements are concrete and independently corroborated, but no current-main trace identifies the responsible work path.
Is this the best way to solve the issue?
Unclear: conditional idle scheduling is the right likely direction, but copying the closed burst-update approach or disabling all timers would be unsafe without a hot-stack trace.
AGENTS.md: found and applied where relevant.
Remaining risk / open question:
Codex review notes: model internal, reasoning high; reviewed against c5105ab06a2f.
Label changes
Label justifications:
P1: Repeated reports describe ordinary desktop use consuming a full CPU core and degrading window responsiveness.impact:other: The supported impact is Windows desktop performance and power use, outside the more specific owned impact categories.Evidence reviewed
What I checked:
src/OpenClaw.Tray.WinUI/Services/WindowManager.cs:198, c5105ab06a2f)src/OpenClaw.Tray.WinUI/App.xaml.cs:671, c5105ab06a2f)src/OpenClaw.Tray.WinUI/Pages/ConnectionPage.xaml.cs:388, c5105ab06a2f)Likely related people:
src/OpenClaw.Tray.WinUI/Services/ManagedLocalGatewayAutoRepairMonitor.cs)How this review workflow works
@clawsweeper re-reviewcomments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.@clawsweeper re-reviewor@clawsweeper re-runon an open PR or issue to request a fresh review only.@clawsweeper reviewto request a fresh review only.@clawsweeper autofix,@clawsweeper automerge,@clawsweeper fix ci, or@clawsweeper address review.@clawsweeper explainto ask for more context, or@clawsweeper stopto stop active automation.Gubruce commentedon Sep 2, 2026
Added a closing-control experiment to prove the idle CPU burn is the app itself (not the remote-control/virtual-display environment, and not the gateway):
Before (idle, window open, no interaction):
OpenClaw.Tray.WinUI: ~104–106% of one core continuously (3 samples)After terminating
OpenClaw.Tray.WinUI:http://127.0.0.1:18789/) still returns HTTP 200.Conclusion: the idle CPU burn is caused entirely by the desktop app (
OpenClaw.Tray.WinUI) itself. It is independent of the GameViewer virtual-display/remote-control software present on this machine and independent of the gateway. It reproduces with the window simply open and idle.sslnv88 commentedon Sep 3, 2026
Yes, I'm having this issue too. It keeps using one CPU core. I was about to report it and saw similar problems, so I'm giving this a thumbs‑up!
Vivek-Rav commentedon Sep 13, 2026
Adding data from a second machine, plus what looks like a resolution path for this issue.
This is very likely a duplicate of #1325, and fixed in 2026.9.3.
On
2026.7.1.0(Windows 11 Pro 10.0.26200, Unpackaged install) I saw exactly the symptom described here: ~100% of one core sustained at idle, with the chat window never even opened, andWin32_PerfFormattedData_PerfProc_Threadputting thread 0 at 93–99%, ThreadState 2. Three concurringdotnet-stacksamples put the UI thread in the same non-terminating render loop that #1325 documents:One detail that may be worth recording against #1325: that issue notes the heap was "99.7% COM callable wrappers" but treats the growth as a consequence of the loop. The stack above shows what was allocating them —
LocalizationHelper.GetStringbuilds a fresh WinRTResourceContextRCW on every call, with no caching, and it is called once per string per render pass. A second thread was permanently inGC.RunFinalizers→WinRT.IObjectReference.Finalize(), which is the matching tell. So the loop drove the allocation rate, and the uncached localization lookup determined how expensive each iteration was. That also explains the reported coupling to transcript size: more tool-call cards means moreGetStringcalls per pass.(Possibly aggravated by Unpackaged installs, where MRT Core resolution is weakest —
TryGetValueAsStringcarries anout Exception, so it may have been throwing per lookup.)Evidence it is fixed: after updating to
2026.9.3(which shipsMicrosoft.UI.Reactor0.1.0-preview.14 via #1376), those frames are completely absent from fresh stack captures on the same machine — zero occurrences ofLocalizationHelper,ResourceContext, orReactorHostControl.RenderLoopacross three samples.Caveat, stated plainly: I cannot give you a clean idle-CPU measurement for the native chat on
2026.9.3to close this conclusively, because a separate regression in that build prevents the native chat from starting at all (the UI thread spins inInitialTailPositioner→StartBringItemIntoViewand no window is ever created). I have filed that separately as #1409. So: the loop this issue is about is gone from the stacks, but the surface it lived on cannot currently be exercised on the latest build.Suggest closing #1287 as a duplicate of #1325 once someone can confirm idle CPU on a build where the native chat runs.