fix(app): #348 — cursor switches ride a process-lifetime native cache; the per-flip Win32 handle leak is closed
Silk's per-mouse ICursor recreates the native Win32 cursor on every Image assignment; a per-frame cursor alternation (the pick cursor flickering between kinds while hovering an ANIMATED NPC — exactly the stand-at-a-vendor posture) allocated a fresh USER handle each flip until CreateCursor died with "Not enough memory" and took the render loop with it (vendor-gate.log, exit 82 — surfaced as one clean stack by #343's fix, as designed). GlfwCursorCache restores retail's own shape: each distinct MediaDescCursor is created ONCE for the process lifetime (glfwCreateCursor, rejected media cached as permanent misses) and switching is an O(1) zero-allocation glfwSetCursor. The AP-72 missing-art standard-cursor fallback rides the same cache (Arrow/Hand/Crosshair/IBeam; anything else keeps the Silk path). Graphical hosts attach after the native window exists; tests and windowless hosts keep the Silk path untouched. RetailCursorManager's dedup and PlanApplication logic are unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
c721830e71
commit
9d3df5f627
5 changed files with 245 additions and 1 deletions
|
|
@ -996,6 +996,9 @@ public sealed class GameWindow :
|
|||
_retailChatVm = retained.Chat;
|
||||
_characterSheetProvider = retained.CharacterSheet;
|
||||
_frameScreenshots = retained.Screenshots;
|
||||
// #348: cursor switches ride a process-lifetime native cache
|
||||
// instead of Silk's recreate-per-assignment path.
|
||||
retained.Runtime.AttachNativeCursorWindow(_window?.Native?.Glfw ?? 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue