Skip to content

Preserve ResponsiveRow child state across Row/Wrap layout switches#6663

Merged
FeodorFitsner merged 2 commits into
flet-0.86from
fix-responsive-row-state-preservation
Jul 9, 2026
Merged

Preserve ResponsiveRow child state across Row/Wrap layout switches#6663
FeodorFitsner merged 2 commits into
flet-0.86from
fix-responsive-row-state-preservation

Conversation

@FeodorFitsner

@FeodorFitsner FeodorFitsner commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Description

ResponsiveRowControl.build() returns a Row when the resolved col values fit within columns and a Wrap when they don't. When a window resize crosses a breakpoint, the widget type at that slot changes, so Flutter's reconciliation unmounts the whole child subtree and inflates a new one — destroying any Flutter State below (video players, WebViews, scroll positions, focus).

This PR keys each child's ControlWidget with a GlobalObjectKey tied to its Control model identity. Since Dart-side Control instances are patched in place, the key is stable across rebuilds with no cache, and Flutter re-parents the existing elements into the new Row/Wrap within the same frame — child state now survives breakpoint changes.

This also fixes a latent bug on the same line: the ResponsiveRowControl's own widget key was passed to every child's ControlWidget, which would produce duplicate-key errors if ever non-null.

Verification

Scripted repro with a scrollable Column inside ResponsiveRow (scroll offset lives in Flutter State, same class of state as a video player's): scroll to 300, resize the window 900→500 px across the MD breakpoint, probe with scroll_to(delta=5).

Before (0.86 client): offset resets to 0 on every Row↔Wrap flip (probe lands at 5).
After: offset is preserved (probe lands at 305, and 310 after flipping back).

Related issues

Fixes #6661

Summary by Sourcery

Preserve ResponsiveRow children’s widget state when switching between Row and Wrap layouts by stabilizing their identity-based keys.

Bug Fixes:

  • Prevent loss of state in ResponsiveRow children (e.g., scroll positions, media players) when layout flips between Row and Wrap at breakpoints.
  • Fix a latent duplicate-key issue by no longer reusing the ResponsiveRowControl widget key for each child ControlWidget.

Enhancements:

  • Key each ResponsiveRow child ControlWidget with a GlobalObjectKey derived from its Control model to maintain element identity across layout changes.

Key each child's ControlWidget with a GlobalObjectKey tied to its Control
identity so Flutter re-parents existing elements when the layout flips
between Row and Wrap on a breakpoint change, instead of unmounting and
re-inflating the subtree. Stateful descendants (video players, WebViews,
scroll positions) now survive window resizes across breakpoints.

Fixes #6661

@sourcery-ai sourcery-ai Bot 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.

We've reviewed this pull request using the Sourcery rules engine

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 9, 2026

Copy link
Copy Markdown

Deploying flet-website-v2 with  Cloudflare Pages  Cloudflare Pages

Latest commit: 2886465
Status: ✅  Deploy successful!
Preview URL: https://268d8446.flet-website-v2.pages.dev
Branch Preview URL: https://fix-responsive-row-state-pre.flet-website-v2.pages.dev

View logs

@FeodorFitsner FeodorFitsner merged commit 889b5e0 into flet-0.86 Jul 9, 2026
100 of 107 checks passed
@FeodorFitsner FeodorFitsner deleted the fix-responsive-row-state-preservation branch July 9, 2026 03:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant