Skip to content

fix(classic): Windows freeze, glass, caption, and silent death - #86

Draft
StephenSHorton wants to merge 23 commits into
mainfrom
cursor/classic-memory-windows-freeze-8321
Draft

StephenSHorton wants to merge 23 commits into
mainfrom
cursor/classic-memory-windows-freeze-8321

Conversation

@StephenSHorton

@StephenSHorton StephenSHorton commented Oct 3, 2026 •

Copy link
Copy Markdown
Owner

Head is 8a211fe.

Idle Grok spinner

The pane/tab busy glyph spun for every Grok chat, including idle ones waiting for input.

Cause: Grok leaves a braille spinner in the OSC window title after a turn. busy() treated that leftover titleBusy flag as in-progress work, so the strip never stopped. ConPTY resize already ignored titleBusy (“Grok spinners never clear”).

Fix: The spinner follows an explicit agent report (working), a running Warp-bar/foreground command, or recent PTY output. A stale title frame is not work.

Also on this PR

  • bac1d53: disable no-op Win11 Blur / Rim sliders in Settings.
  • eea6262: never run DWM glass mid title-bar drag.
  • c67fd3f: HostBackdrop glass + 24-bit color-key + 7px resize.

Leave PR #85 as-is.

Open in Web Open in Cursor 

cursoragent and others added 3 commits October 3, 2026 23:12
Cap CSI 2026 syncBuf, OSC 8 capture, and OSC 99 accumulation so agent
floods cannot grow without bound. Drain inBuf in 256KiB UI slices, retry
Mac job-queue drops instead of wedging bytesMsg, and treat an in-flight
ConPTY Write as hot so ResizePseudoConsole cannot overlap it.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
Real-machine logs on PR #86 showed a freeze with flat ~41 MB RSS and a
live WM_CLOSE path, so memory was not the hang. The Win32 present path
used a device bitmap plus a 25 Hz blink/rain flood; on mixed NVIDIA+AMD
adapters that can stall DWM while the process still handles close.

Switch the backbuffer to a system-memory DIB, coalesce blinks, cap rain
to ~14 fps, auto-disable ambient after slow paints, and add a UI-thread
watchdog (plus SUZURI_SAFE_MODE / frame-timing) so the next freeze dumps
goroutine stacks.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
@cursor cursor Bot changed the title fix(classic): bound PTY memory and stop Windows/Mac freezes on charm-ui fix(classic): bound PTY memory and stop Windows dual-GPU UI stall Oct 3, 2026
The watchdog dump on 7b0eb25 showed the UI thread spinning in
WM_MOUSELEAVE → trackCaptionHover → TrackMouseEvent. The leave handler
cleared captionLeaveTrk and then called trackCaptionHover(-1,-1), which
re-armed TME_LEAVE. With the cursor already outside the client — or over
HTCAPTION on the custom title bar — Windows posts another WM_MOUSELEAVE
immediately. That loop starves paint and input while WM_CLOSE still works.

This is the same title-bar hover code that shipped in 0.9.160 / 0.9.161.
Leave now only clears hover; TrackMouseEvent is armed from client moves
and refused for negative coordinates.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
@cursor cursor Bot changed the title fix(classic): bound PTY memory and stop Windows dual-GPU UI stall fix(classic): bound PTY memory and stop Windows WM_MOUSELEAVE freeze Oct 4, 2026
…otices

The custom title strip still sat under a DWM caption because the first
WM_NCCALCSIZE ran before the HWND was registered, glass-off cleared the
frame extend, and caption buttons returned HTCLIENT. Re-apply
SWP_FRAMECHANGED after register, keep a 1px DWM extend for the shadow,
round Win11 corners, and return HTMAXBUTTON/HTMINBUTTON/HTCLOSE so Snap
Layouts and system caption clicks work. Leave handlers still never
re-arm TrackMouseEvent.

Rain was capped at ~14 fps from the dual-GPU guess. Tie it back to the
25 fps blink clock and only auto-disable ambient on genuinely slow
presents (150ms×3 or 400ms).

Notice cards were a 2× bitmap shown too large on Stephen's desktop.
Size the layered window from monitor DPI, host font, and a 36% window
cap, then StretchBlt 1:1 into that dest.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
@cursor cursor Bot changed the title fix(classic): bound PTY memory and stop Windows WM_MOUSELEAVE freeze fix(classic): Windows freeze, custom caption, rain fps, notice size Oct 4, 2026
Default-view rain was stuck on the input-only paint path after the first
frames (skipAmbientFrame turned rain ticks into bar-only blits, then
markShellDirty only every 240ms). Settings is a dim modal so it always
full-painted the matrix. Drive rain from a display-paced frame loop
capped at 60 fps, and never take the input-only shortcut while ambient
or Settings is up.

DWM has no blur radius, so the slider only flipped Mica vs Acrylic and
looked dead. Map 0 / 1–39 / 40–80 to Mica / Acrylic / Tabbed and push
an acrylic frost alpha on every step so empty chroma-key cells actually
show a changing backdrop through the custom caption.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
@cursor cursor Bot changed the title fix(classic): Windows freeze, custom caption, rain fps, notice size fix(classic): Windows freeze, caption, rain fps, glass blur Oct 4, 2026
9f5b3a2 stacked ACCENT_ENABLE_ACRYLICBLURBEHIND on Mica/Tabbed with
AccentFlags=0, so DWM ignored the packed tint and washed the holes with
the Windows accent color. Win11 now uses SYSTEMBACKDROP only; Win10 uses
Flags=2 and a theme-void AABBGGRR tint.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
@cursor cursor Bot changed the title fix(classic): Windows freeze, caption, rain fps, glass blur fix(classic): Windows freeze, caption, rain fps, glass backdrop Oct 4, 2026
cursoragent and others added 5 commits October 4, 2026 23:02
HostBackdrop Mica/Acrylic/Tabbed jumped at 40 (Tabbed is much darker)
and went solid — often light gray — when inactive. Use one Flags=2
accent-acrylic for every blur step, frost alpha 20–196, re-apply on
WM_ACTIVATE/WM_NCACTIVATE, and pin caption/border to the theme void.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
Win11 rounded corners came from DWMWCP_ROUND in applyWindowChromeFrame.
Force DWMWCP_DONOTROUND on create, glass toggle, and activate so DWM
cannot put the rounding back. Shadow and custom caption stay.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
Min/max/close were a thin GDI stamp plus a half-step/theme shadow copy.
Draw each icon once with the X's stroke and a soft coverage fringe,
DPI-scale the 46dip buttons, and skip NCUAH caption redraw so DWM
cannot stamp a second glyph. Hover and press still lighten/darken.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
The doubled min/max/close were DWM caption sprites (HTMIN/MAX/CLOSE
plus TITLEBARINFOEX). Those hit codes now map to HTCLIENT and DWM's
button rects are marked invisible. Bell/coffee/min/max/close all
rasterize from one Lucide-style 24px stroke set with the X's weight
and AA. Strip cells no longer emit 🔔/☕. One paint per slot per frame.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
de25fe7 died ~31s after launch with no panic, no WER, no crash file.
WM_NCACTIVATE/WM_ACTIVATE were calling DwmExtend/SetAccent on the
same stack; those APIs re-enter WndProc and can overflow the native
callback. Unfocused full paints then jumped 20-40x (rain + grok-fork
+ SetPixel icons + DWM) before the process vanished.

Never touch DWM composition from NCACTIVATE; post a coalesced glass
refresh; abort nested WndProc past depth 12; blit caption ink as one
DIB; do not toast from WM_PAINT; log GDI/USER counts; write every
exit reason to the crash trail (os.Exit, VEH, console-ctrl, WM_QUIT).

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
@cursor cursor Bot changed the title fix(classic): Windows freeze, caption, rain fps, glass backdrop fix(classic): Windows freeze, glass, caption, and silent death Oct 5, 2026
cursoragent and others added 11 commits October 5, 2026 01:00
A grok-fork build flood while alt-tabbed ingested 256KiB chunks and
InvalidateRect'd every one. Those full GDI presents (rain + alt-screen
+ glass) jumped to 150-376ms; the child/ConPTY exit did not take the
host down. Unfocused ingest still drains so the pipe does not block,
but presents are capped at 10fps and rain drops while PTY is hot.

Crash trail: VEH+UEF write code/addr/module (+ Go stack except on
overflow), WER LocalDumps under HKCU, 5s heartbeat (heap/GDI/handles/
paint ms), unclean-previous-session detect, log rotate at 2MiB, and a
reason on WM_CLOSE/ENDSESSION/QUIT/DESTROY/os.Exit.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
VEH/UEF now record AV read/write, a native backtrace, and the Go
stack. WER LocalDumps is registered for both suzuri.exe and the
actual image name. SetCrashOutput is labeled as throw/fatal (not
only panic). Warn/error log lines fsync. Recovered panics and
WM_QUIT write the crash trail.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
SetDIBitsToDevice of a 32-bit caption stamp onto the sysmem DIB
backbuffer marked it alpha-aware. DWM color-key holes then became
opaque black and every later GDI call on that DC jumped from ~10ms
to 150–3692ms. Restore SetPixel for caption ink, blit images as
24-bit, and keep default-bg / theme-void cells as glass holes.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
DwmExtend top=-1 gave DWM a caption band, so native min/max/close
drew on top of ours even after remapping those hits to HTCLIENT.

Match WT: cyTopHeight=0 (sides/bottom still sheet-of-glass), NCCALCSIZE
eats the caption, never DwmDefWindowProc. HTMAXBUTTON stays for Snap
Layouts; min/close stay HTCLIENT. Caption ink is a 24-bit DIB BitBlt.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
d2c7da8 set DwmExtend top=0 so DWM would not stamp caption sprites.
Accent-acrylic color-key needs -1 on every side; BLACK_BRUSH holes
then went solid black even at an idle prompt.

Extend is a full sheet again. WS_SYSMENU/MINIMIZEBOX/MAXIMIZEBOX come
off so DWM has no caption buttons; we still draw ours and handle
SC_MINIMIZE/MAXIMIZE/RESTORE/CLOSE. WS_CAPTION|THICKFRAME stay.

The paint-stall rain guard no longer assigns ShellAmbient=none, so
persistWindowPlacement cannot write that into config.json. Toast:
"rain paused for this session".

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
…icons

The input panel used the shell's 4px left inset, so glass showed as a
strip beside the dark bar. Flush the panel (and a leftover bottom
hairline) to the client edges; text still has its inner pad.

Caption/bell/coffee glyphs were a 2/5 strip box (~10px at 96 DPI) —
too small for the thick stroke. Same stroke and AA, box +25% so all
five match Windows Terminal's optical size.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
Two stacked causes: (1) SWP_FRAMECHANGED after DwmExtend dropped the
sheet-of-glass, so BLACK_BRUSH in the client was opaque black and only
a frame sliver showed the desktop. (2) frost mapped blur 36 → alpha 99
on a black HC void tint — accent acrylic reads as a solid dark slab.

Extend after FRAMECHANGED and log S_OK. Remap frost so blur 0 is clear,
blur 36 stays under 64, and the slider frosts smoothly. Lift #000 void
in GradientColor RGB so the color key stays the holes, not the tint.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
63a9568 logged extend_ok and frost=50 but the desktop never showed:
HostBackdrop was forced to None and accent acrylic does not compose
after WS_SYSMENU is stripped. Restore the pre-PR86 Mica/Acrylic
backdrop, keep accent off on Win11 when veil=0, and present a 24-bit
backbuffer so RGB(0,0,0) stays the color key.

NCCALCSIZE no longer calls DefWindowProc (that mixed caption insets
with a 7px padded frame and made height alternate 1399/1392). Top
stays put; only L/R/bottom take the resize border. SUZURI_GLASS_DEBUG=1
logs a sample void pixel plus accent/extend return codes.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
Title-bar drag sends WA_CLICKACTIVE then ENTERSIZEMOVE. The posted
wmSuzuriGlassRefresh was dispatched inside the modal drag loop,
pushGlassBackdrop stalled ~2s, and the second drag AV'd in ntdll.

Do not PostMessage or call DwmExtend/SetAccent/HostBackdrop while
inSizeMove. WA_CLICKACTIVE and NCACTIVATE during a drag only set a
deferred flag; flush after EXITSIZEMOVE (posted, not on that stack).
Keep the WndProc depth abort and crash trail.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
Win11 HostBackdrop (veil=0) ignores Blur — Desktop Acrylic has no
point radius. Show the row as idle with 'Windows controls frost' and
ignore left/right. Rim is macOS-only on GDI, so it shows 'macOS only'.

Blur stays live on macOS, Windows 10, and Win11 when Veil > 0 (accent
acrylic, frost follows the slider). Drag-crash deferral is already on
this branch (eea6262).

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
Grok leaves a braille spinner in the OSC title after a turn.
busy() treated that leftover as in-progress work, so the pane/tab
glyph never stopped. ConPTY resize already ignored titleBusy for
the same reason.

The strip spinner now follows an explicit agent report, a running
Warp-bar/foreground command, or recent PTY output — not a stale
title frame. Idle Grok waiting for input stays quiet.

Co-authored-by: Stephen Horton <StephenSHorton@users.noreply.github.com>
@StephenSHorton
StephenSHorton changed the base branch from classic/charm-ui to main October 20, 2026 18:36

This branch has not been deployed

No deployments
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.

2 participants