Skip to content

windows-reactor improvements - #4782

Merged
kennykerr merged 5 commits into
masterfrom
reactor-improvements
Aug 5, 2026
Merged

windows-reactor improvements#4782
kennykerr merged 5 commits into
masterfrom
reactor-improvements

Conversation

@kennykerr

@kennykerr kennykerr commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Fixes #4778 - preserves realized controls and row-local state during keyed TemplatedList reorders.

Fixes #4776 - adds typed lightweight resource overrides with correct ownership, replacement, and removal.

Fixes #4772 - adds window-relative pointer coordinates, pointer capture, and capture-loss/cancellation callbacks.

Fixes #4771 - adds NavigationView pane-open and actual display-mode change callbacks.

Fixes #4720 - adds native BitmapIcon and PathIcon support while retaining full-color ImageIcon support.

Also fixes lifecycle exit transitions and clears stale native TabViewItem identity when an item key is removed.

Address keyed list identity, typed resources, pointer input, responsive navigation, icon elements, lifecycle transitions, and tab item identity.

Copilot-Session: 49930c97-f37c-46b7-b60e-fb4b9d1b5320

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves windows-reactor reconciliation correctness and WinUI integration by fixing keyed list identity handling, adding typed resource overrides, expanding pointer input support (including capture), making NavigationView state callbacks reflect actual dependency property values, broadening icon element support, and implementing enter/exit lifecycle transitions via WinUI Composition implicit animations.

Changes:

  • Preserve realized controls during equal-length keyed templated-list reorders (state follows keys; positional fallback for missing/duplicate keys).
  • Add typed element resource overrides (tracked key ownership + correct removal) and expand pointer/navigation/tab identity behaviors.
  • Implement lifecycle enter/exit transitions using implicit show/hide composition animations (including animation groups for combined opacity + scale).

Reviewed changes

Copilot reviewed 46 out of 46 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
docs/crates/windows-reactor.md Documents new reactor behaviors: keyed reorder identity, typed resources, pointer capture/window coords, navigation state callbacks, icon kinds, and lifecycle transitions.
docs/crates/windows-composition.md Updates composition docs to mention animation groups and their use for combined implicit animations.
crates/tools/reactor/src/test.txt Adds WinUI members needed by new icon/navigation/pointer behaviors to the reactor tool test surface list.
crates/tools/reactor/src/base.txt Extends the reactor base binding set for BitmapIcon/PathIcon, pointer capture events, ElementCompositionPreview implicit animations, and NavigationView DP observation.
crates/tools/composition/src/composition.txt Adds CompositionAnimationGroup and CreateAnimationGroup/Add to composition tool inputs.
crates/tests/libs/reactor/tests/templated_list.rs Adds coverage for keyed reorder behavior (move realized controls, boundary behavior, duplicate-key fallback).
crates/tests/libs/reactor/tests/templated_list_mutate.rs Adds perf/behavior coverage ensuring key comparison work stays proportional to realized rows.
crates/tests/libs/reactor/tests/resources.rs Adds unit tests for typed heterogeneous resource overrides and correct clearing semantics.
crates/tests/libs/reactor/tests/pointer_handlers.rs Extends handler bundle tests for capture lost/canceled and capture-on-press configuration; validates new pointer fields.
crates/tests/libs/reactor/tests/icon_bindings.rs Updates icon tests for BitmapIcon rendering mode and adds PathIcon data coverage.
crates/tests/libs/reactor/tests/controls_shell.rs Adds structural tests for tab key clearing and navigation state callbacks.
crates/tests/libs/reactor/tests/animation.rs Updates animation tests to validate lifecycle transition registration/clearing and precedence vs property animations.
crates/tests/libs/reactor/src/lib.rs Extends RecordingBackend with SetElementTransitions op and a navigation display-mode event injector for tests.
crates/tests/libs/reactor_selftest/src/registry.rs Registers new selftest fixtures for typed resources, tab key clearing, navigation callbacks, keyed list state, icon subclasses, and exit transitions.
crates/tests/libs/reactor_selftest/src/fixtures/pointer_input.rs Updates pointer injection fixture to validate window-relative coords and pointer capture behavior.
crates/tests/libs/reactor_selftest/src/fixtures/interactions.rs Expands icon interaction fixture to validate native icon subclasses and adds an exit-transition interaction fixture.
crates/tests/libs/reactor_selftest/src/fixtures/controls.rs Adds selftest fixtures validating resource override ownership/clearing, tab tag clearing, navigation DP-observed callbacks, and keyed list state behavior.
crates/tests/libs/reactor_selftest/src/bindings.rs Regenerates selftest WinUI bindings needed for new pointer capture, DP observation, and icon support.
crates/tests/libs/composition/src/live.rs Adds a live test asserting animation groups accept multiple animations.
crates/samples/reactor/samples/examples/tab_view_item_key.rs Adds a sample demonstrating TabItem::with_key identity and correct clearing on key removal.
crates/samples/reactor/samples/examples/responsive_navigation.rs Adds a sample demonstrating pane-open and display-mode callbacks driven by real DP state.
crates/samples/reactor/samples/examples/pointer_resize.rs Adds a sample demonstrating stable window-relative drag deltas plus pointer capture for resize handles.
crates/samples/reactor/samples/examples/lightweight_resources.rs Adds a sample demonstrating typed lightweight resource overrides and clearing.
crates/samples/reactor/samples/examples/keyed_list_reorder.rs Adds a sample demonstrating keyed reorder preserving per-row component state.
crates/samples/reactor/samples/examples/icon_elements.rs Extends icon sample to cover BitmapIcon and PathIcon in addition to existing icon kinds.
crates/samples/reactor/samples/examples/exit_transition.rs Adds a sample demonstrating exit transitions where the logical subtree is removed immediately but the visual persists during the hide animation.
crates/libs/reactor/src/widgets/tab_view.rs Documents TabItem::with_key as the stable identity for close requests.
crates/libs/reactor/src/widgets/navigation_view.rs Adds on_pane_open_changed and on_display_mode_changed widget event bindings.
crates/libs/reactor/src/widgets/icon.rs Expands Icon to include Bitmap and Path variants and adds constructors (notably bitmap_icon and path).
crates/libs/reactor/src/style.rs Introduces typed resource values (ResourceValue, ResourceBuilder, CornerRadius) and extends pointer handler configuration/state.
crates/libs/reactor/src/reconciler/widget_dispatch.rs Fixes TabView item key updates to clear native identity when the optional key is removed.
crates/libs/reactor/src/reconciler/templated.rs Implements keyed realized-row remapping for equal-length reorders and refines update-skipping behavior.
crates/libs/reactor/src/reconciler.rs Wires lifecycle transitions into reconciliation; ensures resource updates can clear stale keys; adds transition diffing on updates.
crates/libs/reactor/src/lib.rs Re-exports NavigationViewDisplayMode.
crates/libs/reactor/src/element.rs Adds pointer capture configuration/callbacks and introduces resource_overrides plus typed resources.
crates/libs/reactor/src/bindings.rs Regenerates reactor WinUI bindings to support new DP observation, pointer capture, and icon types.
crates/libs/reactor/src/backend/winui/mod.rs Implements DP observers for navigation state callbacks, typed resource ownership/removal, pointer capture lifecycle, and element lifecycle transitions via implicit animations.
crates/libs/reactor/src/backend/winui/convert.rs Adds BitmapIcon and PathIcon construction (with attribute escaping + regression test).
crates/libs/reactor/src/backend/mod.rs Updates PropValue::Resources to typed values; adds navigation display-mode event handler support; adds backend hook for element transitions.
crates/libs/reactor/readme.md Updates crate readme with new typed resources, pointer window coords/capture, navigation callbacks, lifecycle transitions, tab identity, and expanded icon examples.
crates/libs/composition/src/lib.rs Re-exports CompositionAnimationGroup.
crates/libs/composition/src/compositor.rs Adds create_animation_group helper.
crates/libs/composition/src/bindings.rs Regenerates composition bindings to include animation groups and compositor creation APIs.
crates/libs/composition/src/bindings_lifted.rs Regenerates lifted bindings to include animation groups for WinUI hosting scenarios.
crates/libs/composition/src/animation.rs Adds CompositionAnimationGroup wrapper with add and (reactor) as_host.
crates/libs/composition/readme.md Documents animation groups as a core capability.

Comment thread crates/libs/reactor/src/widgets/icon.rs
@kennykerr
kennykerr merged commit a48e42e into master Aug 5, 2026
35 checks passed
@kennykerr
kennykerr deleted the reactor-improvements branch August 5, 2026 11:57
Tam1SH added a commit to Tam1SH/windows-rs that referenced this pull request Aug 5, 2026
Squashed history of local fork work whose functionality either matches
or is superseded by upstream's own merged fixes (PR microsoft#4764 SVG/icon
support, PR microsoft#4782 keyed-list reorder / pointer capture / NavigationView
pane events) - those commits' actual code effect is fully gone from
this diff since it now equals origin/master exactly. What remains is
only what upstream doesn't have yet:

- TextBlock.TextTrimming: SetTextTrimming was a dead usize vtable slot
  with no safe wrapper; adds the TextTrimming type, a real wrapper,
  Prop::TextTrimming wiring, and TextBlock::single_line_ellipsis().
  Filed upstream, not yet addressed.
- Multiple ControlId component-instance tracking + force-rerender of
  dirty-descendant ancestors (memoised_ancestor_dirty_descendant.rs).
- Passthrough-component ControlId collision fix
  (passthrough_component_control_id_collision.rs, ISSUE draft included).
- templated_list_keyed_reorder.rs kept as a regression suite against
  upstream's remap_keyed_realized_rows - 2/3 tests pass as-is; the
  third (reorder_with_added_and_removed_key_mounts_and_unmounts_correctly)
  is #[ignore]d with an explanation: upstream's remap bails to a
  positional (non-keyed) fallback the instant any old key has no home
  in the new set, silently reusing a surviving row's native content for
  an unrelated key instead of destroying/remounting it. Not fixed here.
- drag_repro.rs sample, ISSUE draft notes for the above.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Tam1SH added a commit to Tam1SH/windows-rs that referenced this pull request Aug 5, 2026
Squashed history of local fork work whose functionality either matches
or is superseded by upstream's own merged fixes (PR microsoft#4764 SVG/icon
support, PR microsoft#4782 keyed-list reorder / pointer capture / NavigationView
pane events) - those commits' actual code effect is fully gone from
this diff since it now equals origin/master exactly. What remains is
only what upstream doesn't have yet:

- TextBlock.TextTrimming: SetTextTrimming was a dead usize vtable slot
  with no safe wrapper; adds the TextTrimming type, a real wrapper,
  Prop::TextTrimming wiring, and TextBlock::single_line_ellipsis().
  Filed upstream, not yet addressed.
- Multiple ControlId component-instance tracking + force-rerender of
  dirty-descendant ancestors (memoised_ancestor_dirty_descendant.rs).
- Passthrough-component ControlId collision fix
  (passthrough_component_control_id_collision.rs, ISSUE draft included).

Dropped from the earlier version of this squash after review:
- drag_repro.rs sample - upstream's own pointer_resize.rs (added by
  microsoft#4782) is a strict superset, built on the real capture API.
- templated_list_keyed_reorder.rs - upstream's templated_list.rs
  (also microsoft#4782) already covers keyed-reorder/swap/duplicate-key
  scenarios with its own tests; ours was redundant except for one
  #[ignore]d gap (add+remove-in-the-same-update loses key identity via
  the positional fallback) that has no upstream equivalent test yet -
  tracked outside this repo rather than kept as dead weight here.
- ISSUE-DRAFT-svg-icon-support-request.md,
  ISSUE-templated-list-key-ignored-on-reorder.md - both describe
  problems microsoft#4764/microsoft#4782 already fixed upstream.
- ISSUE-pointer-capture-and-resubscription.md trimmed to only its
  still-unfixed half: upstream's set_pointer_handlers still does a
  full revoke+resubscribe on every render, which silently ends an
  in-progress .capture_pointer_on_press() capture mid-drag. The other
  half (no capture API at all) is exactly what microsoft#4782 added.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Tam1SH added a commit to Tam1SH/windows-rs that referenced this pull request Aug 5, 2026
Squashed history of local fork work whose functionality either matches
or is superseded by upstream's own merged fixes (PR microsoft#4764 SVG/icon
support, PR microsoft#4782 keyed-list reorder / pointer capture / NavigationView
pane events) - those commits' actual code effect is fully gone from
this diff since it now equals origin/master exactly. What remains is
only what upstream doesn't have yet:

- TextBlock.TextTrimming: SetTextTrimming was a dead usize vtable slot
  with no safe wrapper; adds the TextTrimming type, a real wrapper,
  Prop::TextTrimming wiring, and TextBlock::single_line_ellipsis().
  Filed upstream, not yet addressed.
- Multiple ControlId component-instance tracking + force-rerender of
  dirty-descendant ancestors (memoised_ancestor_dirty_descendant.rs).
- Passthrough-component ControlId collision fix
  (passthrough_component_control_id_collision.rs, ISSUE draft included).

Dropped from the earlier version of this squash after review:
- drag_repro.rs sample - upstream's own pointer_resize.rs (added by
  microsoft#4782) is a strict superset, built on the real capture API.
- templated_list_keyed_reorder.rs - upstream's templated_list.rs
  (also microsoft#4782) already covers keyed-reorder/swap/duplicate-key
  scenarios with its own tests; ours was redundant except for one
  #[ignore]d gap (add+remove-in-the-same-update loses key identity via
  the positional fallback) that has no upstream equivalent test yet -
  tracked outside this repo rather than kept as dead weight here.
- ISSUE-DRAFT-svg-icon-support-request.md,
  ISSUE-templated-list-key-ignored-on-reorder.md - both describe
  problems microsoft#4764/microsoft#4782 already fixed upstream.
- ISSUE-pointer-capture-and-resubscription.md trimmed to only its
  still-unfixed half: upstream's set_pointer_handlers still does a
  full revoke+resubscribe on every render, which silently ends an
  in-progress .capture_pointer_on_press() capture mid-drag. The other
  half (no capture API at all) is exactly what microsoft#4782 added.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Tam1SH added a commit to Tam1SH/windows-rs that referenced this pull request Aug 5, 2026
Squashed history of local fork work whose functionality either matches
or is superseded by upstream's own merged fixes (PR microsoft#4764 SVG/icon
support, PR microsoft#4782 keyed-list reorder / pointer capture / NavigationView
pane events) - those commits' actual code effect is fully gone from
this diff since it now equals origin/master exactly. What remains is
only what upstream doesn't have yet:

- TextBlock.TextTrimming: SetTextTrimming was a dead usize vtable slot
  with no safe wrapper; adds the TextTrimming type, a real wrapper,
  Prop::TextTrimming wiring, and TextBlock::single_line_ellipsis().
  Filed upstream, not yet addressed.
- Multiple ControlId component-instance tracking + force-rerender of
  dirty-descendant ancestors (memoised_ancestor_dirty_descendant.rs).
- Passthrough-component ControlId collision fix
  (passthrough_component_control_id_collision.rs, ISSUE draft included).

Dropped from the earlier version of this squash after review:
- drag_repro.rs sample - upstream's own pointer_resize.rs (added by
  microsoft#4782) is a strict superset, built on the real capture API.
- templated_list_keyed_reorder.rs - upstream's templated_list.rs
  (also microsoft#4782) already covers keyed-reorder/swap/duplicate-key
  scenarios with its own tests; ours was redundant except for one
  #[ignore]d gap (add+remove-in-the-same-update loses key identity via
  the positional fallback) that has no upstream equivalent test yet -
  tracked outside this repo rather than kept as dead weight here.
- ISSUE-DRAFT-svg-icon-support-request.md,
  ISSUE-templated-list-key-ignored-on-reorder.md - both describe
  problems microsoft#4764/microsoft#4782 already fixed upstream.
- ISSUE-pointer-capture-and-resubscription.md trimmed to only its
  still-unfixed half: upstream's set_pointer_handlers still does a
  full revoke+resubscribe on every render, which silently ends an
  in-progress .capture_pointer_on_press() capture mid-drag. The other
  half (no capture API at all) is exactly what microsoft#4782 added.
- icon_elements.rs's added module doc comment - not worth carrying.
- NavigationView.on_pane_closed/on_pane_opened - upstream's
  on_pane_open_changed(bool) (also microsoft#4782, closes microsoft#4771) is a strict
  superset; the discrete Closed/Opened callbacks added nothing a
  `if open`/`if !open` branch on the bool callback doesn't already
  cover. Event::PaneOpened variant removed with it; Event::PaneClosed
  stays (SplitView has its own unrelated use of it).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment