Commit bf9b2e7
fix(reconciler): dedupe ToggleSwitch.Toggled wiring via EventHandlerState (#113)
* fix(reconciler): dedupe ToggleSwitch.Toggled wiring via EventHandlerState
The wire-dedupe flag for ToggleSwitch.Toggled lived in
ConditionalWeakTable<FrameworkElement, PoolableWireFlags>, keyed by
managed RCW identity. WinRT projection can produce two RCWs over the
same underlying DependencyObject; each gets its own CWT entry, both
pass the dedupe check, and toggle.Toggled += subscribes the trampoline
twice. One IsOn change then fans into multiple user-callback invocations.
Symptom: EchoSuppress_ToggleSwitch_NoEchoCall flaked in ~8% of
full-suite selftest runs but never in isolation. The first subscription
consumed the BeginSuppress token; the second subscription saw counter=0
and invoked the user OnChanged with the value Reactor had just written.
Fix: store the trampoline on EventHandlerState (attached via
ReactorAttached.StateProperty, keyed by native DO identity) — the same
pattern already used for SizeChanged, PointerPressed, Tapped, etc. The
comment on GetOrCreateEventState (Reconciler.cs:2590) explicitly notes
this is the safe key.
Validation: 60/60 full-suite runs clean across two fix iterations
(baseline expected ~4.8 flakes at 8%).
Follow-up: PoolableWireFlags.ButtonClick / TextBoxTextChanged /
TextBoxSelectionChanged share the same CWT-by-RCW vulnerability and
should be migrated to EventHandlerState.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(reconciler): clarify which dedupe scheme covers which control
Address PR #113 review: the comment block above PoolableWireFlags
described the CWT approach as covering ToggleSwitch, but that's now
out of date — ToggleSwitch dedupes via EventHandlerState (DP keyed by
native DO identity). Spell out which scheme each control uses, point at
issue #114 for the planned migration of the remaining CWT entries, and
direct future contributors at the EventHandlerState pattern.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 6abe668 commit bf9b2e7
2 files changed
Lines changed: 22 additions & 12 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
675 | 675 | | |
676 | 676 | | |
677 | 677 | | |
678 | | - | |
679 | | - | |
680 | | - | |
681 | | - | |
682 | | - | |
| 678 | + | |
| 679 | + | |
| 680 | + | |
| 681 | + | |
683 | 682 | | |
684 | 683 | | |
685 | 684 | | |
686 | | - | |
687 | | - | |
688 | | - | |
689 | | - | |
| 685 | + | |
| 686 | + | |
| 687 | + | |
690 | 688 | | |
691 | 689 | | |
692 | 690 | | |
693 | 691 | | |
694 | 692 | | |
| 693 | + | |
695 | 694 | | |
696 | 695 | | |
697 | 696 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
360 | 360 | | |
361 | 361 | | |
362 | 362 | | |
363 | | - | |
364 | | - | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
365 | 376 | | |
366 | 377 | | |
367 | 378 | | |
368 | 379 | | |
369 | 380 | | |
370 | 381 | | |
371 | | - | |
372 | 382 | | |
373 | 383 | | |
374 | 384 | | |
| |||
2554 | 2564 | | |
2555 | 2565 | | |
2556 | 2566 | | |
| 2567 | + | |
2557 | 2568 | | |
2558 | 2569 | | |
2559 | 2570 | | |
| |||
0 commit comments