The code was already using named methods (OnFloatButtonGroupOpenRequest/
OnFloatButtonGroupCloseRequest) with CompositeDisposable cleanup.
Update tracking doc to reflect actual state.
- Add OnClick/OnClose internal properties to NotificationCard to carry
per-notification callbacks without capturing local variables
- Replace PointerPressed lambda with static OnNotificationPointerPressed
(zero closure allocation, reads callback from card.OnClick)
- Replace NotificationClosed lambda with instance OnNotificationClosed
(accesses _items via 'this', no local variable capture)
- Update AtomUI_issues.md: mark 1.2 as fixed, remove from P8 list
Modal methods (ShowMessageBoxModalAsync, ShowMessageModalAsync,
ShowDialogModalAsync x2): OpenAsync() awaits dialog close, so cleanup
is moved after await tsc.Task — no Closed subscription needed.
Non-modal methods (ShowMessageBoxAsync, ShowMessageAsync,
ShowDialogAsync x2): OpenAsync() returns after dialog is shown, so
Closed lambda is retained as the only close notification point.
The lambda is harmless: Closed fires exactly once, dialog is removed
from parent and GC'd immediately after, releasing the closure.
- Update AtomUI_issues.md: mark 1.1 as fixed, remove from P3 list
- Delete performance_memory_leak.md (tracking moved to AtomUI_issues.md)
- INotifyTransitionCompleted interface now extends IDisposable
- AbstractNotifiableTransition<T>.Dispose() disposes Subject<bool> and nulls it
- NotifyTransitionCompleted() guards against null _subject (post-dispose)
- CompletedObservable throws ObjectDisposedException if accessed after Dispose
- AbstractMotion.RunTransitions: dispose all Transitions after await completes
(covers both normal completion and Task.Delay timeout path)
- AbstractMotion.ConfigureTransitions: dispose existing Transitions before Clear
to prevent Subject leaks when transitions are rebuilt
- Update performance_memory_leak.md: 32/39 fixed (82.1%), High 8/8 all done
Items is an internal ItemCollection owned by Form with identical lifetime.
The subscription cannot leak across lifetimes: when Form is GC'd, Items and
its event subscriptions are collected with it. Mark 3.4 as false positive in docs.
- Replace anonymous lambda with named method to allow precise -= unsubscription
- Prevents subscription leak when Items is replaced by an external CollectionView
- Update performance_memory_leak.md: 32/39 fixed (82.1%), Medium 16/19
- Mirror the same WeakCollectionChangedForwarder pattern applied to ListCollectionView (29452afe)
- Add IDisposable to DataGridCollectionView class declaration
- Add _collectionChangedForwarder field (WeakCollectionChangedForwarder?)
- Replace anonymous lambda subscription with forwarder in constructor
- Add Dispose() for eager cleanup
- Add WeakCollectionChangedForwarder nested class with self-unsubscribe on GC
- All Critical (P0) issues now fully resolved
- Update performance_memory_leak.md: 31/39 fixed (79.5%), Critical 7/7
- Add WeakCollectionChangedForwarder nested class: source holds strong ref to
forwarder, forwarder holds WeakReference<ListCollectionView> — prevents the
source collection from rooting the view
- Self-unsubscribes on next event after view is GC'd; no lingering delegate
- Keep IDisposable.Dispose() for eager cleanup when ItemsSource changes in ListView
- ListView: track _ownsCollectionView flag and call Dispose() on old view only
when we created it (not user-provided IListCollectionView)
- Remove OnDetachedFromVisualTree disposal to avoid breaking reattach scenarios
(tab switching, panel rebuilds, etc.) — WeakReference handles lifetime safely
- Update performance_memory_leak.md: mark 1.1 as fixed, progress 30/39 (76.9%)
- Always stop, unsubscribe, and null out old _delayTimer before creating new instance
- Prevents event handler accumulation when MinimumPopulateDelay changes
- Unify handling between Mentions and AbstractAutoComplete
- Fixes issue where timer event handlers would accumulate on rapid property changes
- StartActiveAnimation: dispose old CTS before creating new instance
- StopActiveAnimation: dispose CTS and set to null
- BuildActiveAnimation: dispose CTS before rebuilding animation
- Prevents WaitHandle and unmanaged resources from leaking during repeated animation start/stop cycles
- ColorSpectrum: convert CreateBitmapsAndColorMap to async Task with try-catch
- ColorSlider: convert UpdateBackground to async Task with IsAttachedToVisualTree check
- DataGrid: convert CopyToClipboard to async Task with exception handling
- SelectableTextBlock: convert Copy to async Task with IsAttachedToVisualTree check
- Keep original void methods for backward compatibility (fire-and-forget pattern)
- Add graceful exception handling to prevent app crashes
- Verify control is attached before updating UI after async operations
- Move PropertyChanged subscription from constructor to OnAttachedToVisualTree
- Add PropertyChanged unsubscription in OnDetachedFromVisualTree
- Ensure proper lifecycle management when Watermark is reattached to visual tree
- Prevent memory leaks from glyph event handlers
Also update performance_memory_leak.md:
- Mark 5.9 (Watermark glyph.PropertyChanged lambda) as fixed
- Add fix timestamp and implementation details
- Replace anonymous lambda with named method HandleShowTimerTick()
- Call StopTimer() at the beginning of StartShowTimer() to clean up old timer
- Use ValueTuple to safely extract control reference from timer Tag
- Prevent multiple parallel timers when mouse moves quickly
Also update performance_memory_leak.md:
- Mark 5.6 (ToolTip service global event subscription) as fixed
- Add fix timestamp and implementation details
- Add Dispose() call in HandleCleanupMarqueeAnimation() to release unmanaged resources
- Set CancellationTokenSource to null after disposal
- Ensure complete lifecycle management of CancellationTokenSource
Also update performance_memory_leak.md:
- Mark 5.4 (MarqueeLabel animation cleanup) as fixed
- Add fix timestamp and implementation details
- Remove 8 private event handler delegate fields (_alphaInputValueChangedHandler, etc.)
- Add 8 private methods to replace delegate fields (HandleAlphaInputValueChanged, etc.)
- Update OnApplyTemplate to use method references instead of delegate fields
- Avoid allocating new delegate objects on each OnApplyTemplate call
- Improve code clarity by using private methods for lambdas that don't capture closure variables
Also update performance_memory_leak.md:
- Mark 5.3 (CompositeDisposable) as fixed
- Update 3.7 fix description to reflect the actual implementation using private methods
- Add fix timestamp and details