Skip to content

fix: InteractiveViewer failing to render when alignment is set - #6887

Merged
FeodorFitsner merged 7 commits into
mainfrom
fix/interactive-viewer-alignment
Sep 26, 2026
Merged

FeodorFitsner merged 7 commits into
mainfrom
fix/interactive-viewer-alignment

Conversation

@ndonkoHenri

@ndonkoHenri ndonkoHenri commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Problem

InteractiveViewer passed its alignment property to Flutter's InteractiveViewer(alignment:) unparsed. Control.get<T> infers T from the parameter and returns the wire value, an {x, y} map, as is, so any alignment failed the cast in build():

type '_Map<dynamic, dynamic>' is not a subtype of type 'Alignment?'

Flutter then replaced the viewer with its error widget, a grey box in release builds, and the message only reached Python as page.on_error. JS web builds omit that implicit cast (dart2js -O4), so there the map reached Transform and the viewer painted nothing, raising a NoSuchMethodError for every frame or pointer event that touched it. 0.28.x parsed the value with parseAlignment; the parser was lost in the 1.0 rewrite, so this has been broken since 0.80.0.

Fixes #6744

Changes

  • Dart: read alignment with getAlignment.
  • Docstring: alignment was described as the position of the content. Flutter passes it to Transform.alignment, so it is the origin the content is scaled around and never moves the content. The docstring now says so and points to Container.alignment for positioning, and notes that gestures and the pan() limits assume a top-left origin.
  • Changelog entry.

Not in this PR: making alignment position the content instead (by wrapping it in Align), and hardening Control.get<T> so a mistyped value fails with the control and property name. #6684 was the same cast bug in GestureDetector.

Testing

  • A widget test that builds the viewer from a MessagePack-shaped Control tree reproduced the cast error on main and passed with the fix. It also checked that the parsed value reaches Flutter's InteractiveViewer and that nothing is passed when alignment is unset. The existing packages/flet tests pass.
  • The issue's sample: the published 1.0.1 macOS client showed the grey box and the cast error above, and a JS web build of main an empty viewer. A web client built from this branch renders the content with no page.on_error reports.
  • The docstring's note, measured with the fix in a 900×650 viewer with alignment=Alignment.CENTER: one wheel tick moves the point under the pointer by about (-47, -34) px, and at 2.5× the pan limits are off by (-675, -487) px; with no alignment both are exact. zoom(2) scales around the center, but pan() then stops short of one edge.
  • flutter analyze, dart format and ruff.

Test code

import flet as ft


def main(page: ft.Page):
    page.add(
        ft.InteractiveViewer(
            content=ft.Text("InteractiveViewer child", size=40, color=ft.Colors.RED),
            width=900,
            height=650,
            alignment=ft.Alignment(0, 0),
        )
    )


ft.run(main)

Summary by Sourcery

Fix InteractiveViewer alignment handling and improve diagnostics and documentation for reused desktop clients and the audio example.

Bug Fixes:

  • Fix InteractiveViewer rendering failures when its alignment property is set by correctly converting the alignment value before passing it to Flutter.

Enhancements:

  • Clarify that InteractiveViewer.alignment controls the transformation origin rather than content placement, including the implications for gestures and panning.

Documentation:

  • Document the warning shown when a desktop client from a previous build is used and how to switch back to the standard client.

Chores:

  • Add a warning identifying desktop clients reused from platform build directories.
  • Clarify the audio playback example metadata to describe local asset playback and provide setup guidance.

InteractiveViewer handed the raw property value, a {x, y} map, to
Flutter's InteractiveViewer(alignment:). On native and wasm clients the
implicit cast in Control.get threw a TypeError while building, so the
viewer was replaced by Flutter's error box. JS web builds skip that
check, so the map reached Transform and the viewer painted nothing,
raising a NoSuchMethodError on every frame or pointer event over it.
Read it with getAlignment, as before the 1.0 rewrite.

The docstring described alignment as the position of the content. In
Flutter it is the origin of the zoom transform: it never moves the
content, and gestures and the pan() limits assume a top-left origin.
Document that, and point to Container.alignment for positioning.

@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.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

@ndonkoHenri
ndonkoHenri requested a balanced review from Copilot September 24, 2026 19:24
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Deploying flet-website-v2 with  Cloudflare Pages  Cloudflare Pages

Latest commit: 0ff1ca0
Status: ✅  Deploy successful!
Preview URL: https://530e609e.flet-website-v2.pages.dev
Branch Preview URL: https://fix-interactive-viewer-align.flet-website-v2.pages.dev

View logs

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.

Copilot review overview

🟡 Changes recommended

The regression test described in the PR is absent from the changes.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Fixes InteractiveViewer rendering failures by parsing alignment into Flutter’s expected type and clarifying its transformation semantics.

Changes:

  • Parse wire-format alignment values with getAlignment.
  • Clarify alignment behavior and limitations.
  • Add a 1.0.2 changelog entry.
File Description
CHANGELOG.md Records the bug fix.
packages/​flet/​lib/​src/​controls/​interactive_viewer.dart Parses alignment values correctly.
sdk/​python/​packages/​flet/​src/​flet/​controls/​core/​interactive_viewer.py Documents alignment semantics.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/flet/lib/src/controls/interactive_viewer.dart
ndonkoHenri and others added 3 commits September 25, 2026 13:14
The docs page shows only main.py, so code copied from it fails without
the example's assets/viper.mp3. The example intro now points at that
file and at using a URL for src instead. The project description no
longer calls the track remote.
A client found in build/<platform> is launched ahead of the standard
one. On Windows and Linux this was never logged, and on macOS only
with -v, so a client built before an extension was added went
unnoticed: calls to that extension just timed out. All three
platforms now log a warning with the client's path, which is shown
without -v.
@FeodorFitsner
FeodorFitsner merged commit 0d34cca into main Sep 26, 2026
2 of 102 checks passed
@FeodorFitsner
FeodorFitsner deleted the fix/interactive-viewer-alignment branch September 26, 2026 19:49
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.

bug: Interactive Viewer renders grey text when passed alignment

3 participants