#2014 Pool NativeUI widgets instead of abandoning their frames - #2017
Merged
TimothyLuke merged 1 commit intoAug 24, 2026
Merged
Conversation
…ames
Release() only hid a widget's frame -- and WoW frames can never be
destroyed -- so every editor redraw abandoned its entire widget set:
+238 widgets per version click, forever. Long sessions accumulated
thousands of dead frames and megabytes of unreclaimable state, and the
collector dragged an ever-growing graph for the rest of the session.
AceGUI pooled widgets for exactly this reason; the rewrite dropped it.
Widgets are plain tables of closures over their own frame, so the SAME
table is reused. UI:Create hands out a banked widget when one exists;
Release banks poolable types. The reset contract, each part of which
covers a real bug found in testing:
* every key added after construction is removed (caller decorations
and wrapped methods must not survive into the next life)
* callbacks/children become fresh tables
* frame scripts recorded at construction are restored on every
subframe the widget exposes
* regions and child frames callers created directly on the widget's
frame are hidden on reuse -- the key sweep cannot see those, and
without this a reused frame keeps rendering its previous life
(header rows bleeding into macro blocks, doubled counters, dead
scrollbars intercepting the mouse wheel)
* a double Release cannot bank the same widget twice
Only the 13 high-churn leaf/container types pool; windows, scroll
frames, tab groups and the tree keep their old behaviour. Kill switch
for diagnostics: /run GSE_NoWidgetPool = true and /reload.
Best merged with TimothyLuke#2013: pooled reuse of macro edit boxes is what makes
the scrollbar re-show race there common.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This was referenced Aug 24, 2026
Pooled widgets keep their previous life's styling, art and frame flags (regression from #2014)
#2018
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #2014
Release()only hid a widget's frame — and WoW frames can never be destroyed — so every editor redraw abandoned its entire widget set: measured +238 widgets per version click, permanently. Long sessions accumulate thousands of dead frames and megabytes of unreclaimable state. AceGUI pooled widgets for exactly this reason; the NativeUI rewrite dropped it.Widgets are plain tables of closures over their own frame, so the same table is reused:
UI:Createhands out a banked widget when one exists;Releasebanks poolable types. The reset contract — every part of which covers a real bug found during soak testing:callbacks/childrenbecome fresh tables;Releasecannot bank the same widget twice.Only the 13 high-churn leaf/container types pool; windows, scroll frames, tab groups and the tree keep their old behaviour. Diagnostics kill switch:
/run GSE_NoWidgetPool = true+/reload.Best merged together with #2013 — pooled reuse of macro edit boxes is what makes the scrollbar re-show race fixed there common.
Testing
luac -pclean.🤖 Generated with Claude Code