Skip to content

chore: bump Flutter to 3.47.7 and render desktop with Impeller - #6916

Merged
FeodorFitsner merged 34 commits into
flet-1.1.0from
chore/bump-flutter-3.47.5
Oct 9, 2026
Merged

FeodorFitsner merged 34 commits into
flet-1.1.0from
chore/bump-flutter-3.47.5

Conversation

@ndonkoHenri

@ndonkoHenri ndonkoHenri commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

Builds on the merged #6914 and targets flet-1.1.0. Both ship in Flet 1.1.0.

Summary

This bumps the bundled Flutter from 3.44.8 to 3.47.7 and makes desktop apps render with Impeller, Flutter 3.47's default, with a --no-impeller opt-out.

The pin is 3.47.7 rather than an earlier 3.47:

The Dart code needs no API changes. The earlier SDK migration required no framework API replacements. Material and Cupertino are frozen upstream, and all Dart packages analyze with no new errors or warnings.

Changes

  • SDK pin: .fvmrc → 3.47.7. Flutter 3.47 replaced several exact SDK package pins with caret ranges, so client/pubspec.lock moves intl, matcher, meta, test_api and vector_math.
  • analysis_options.yaml (21 files, including the flet-shadcn-ui extension from flet-1.1.0):
    • Flutter 3.47 has a new AnalysisOptionsMigration that writes an analyzer.exclude block on every flutter pub get / flutter test. This PR pre-applies the same block.
    • Without it, flutter test leaves packages/flet with a modified file, and CI's dart pub publish --dry-run exits 65. Every release job depends on that step.
    • The migration only checks that the patterns are present, so it leaves the files alone afterwards.
  • Podfiles:
    • This PR drops the post_install deployment-target clamps from fix(build): raise macOS and iOS deployment targets for Xcode 27 #6914. Flutter 3.47's podhelper.rb now deletes IPHONEOS_DEPLOYMENT_TARGET < 15 and MACOSX_DEPLOYMENT_TARGET < 12 from every pod.
    • client/ios/Podfile.lock picks up the new Podfile checksum and the Flutter pod checksum. The pod changes because its generated podspec now declares iOS 15.
  • Desktop renders with Impeller, with an opt-out:
  • flet-shadcn-ui text field context menus: Flutter 3.47 shows a text field's context menu in the root overlay without the themes between the field and the Navigator (Fix SelectableText crash with inline lambda contextMenuBuilder flutter/flutter#184990). The extension provides its ShadTheme only around each control, so right-clicking or long-pressing an Input, Textarea, InputOTP or TimePicker threw "ShadTheme.of() called with a context that does not contain a ShadTheme" and covered the window with an error box.
    • Input and Textarea now build shadcn_ui's menu inside the field's ShadTheme.
    • InputOTP and TimePicker take no contextMenuBuilder, so their native menu is off.
  • Android: Gradle 9.3.1, AGP 8.13.2, KGP 2.3.21 (were 8.14 / 8.11.1 / 2.2.20):
    • 3.47.5 moved its error floor to exactly the old pins, and every build printed three "support will soon be dropped" warnings.
    • AGP 8.13.2 bundles R8 8.13.19, the minimum Google lists for Kotlin 2.3. Kotlin 2.4 needs R8 9.1.29 (AGP 9). KGP 2.2.x is documented only up to Gradle 8.14.
    • AGP 9 itself is blocked by file_picker 11 and device_info_plus 12.4.
    • Gradle 9 also runs on JDK 25, which crashed Gradle 8.14. Only the AGP warning remains.
    • kotlin.incremental=false in the client and in flet-cli's default gradle.properties for generated projects. KGP 2.3 compiles through the Build Tools API by default, and its incremental cache fails on Windows when the pub cache and the app are on different drives, as on GitHub's Windows runners. [tool.flet.android.gradle_properties] can turn it back on.
  • Canvas: the Dart side defaults the QuadraticTo weight to 1, as Python does. It fell back to 0, a conic that is a straight line; Flutter 3.44 still dashed it as a curve, but 3.47 handles it correctly, so dashed paths built from QuadraticTo lost their curves.
  • Docs:
    • A new Renderer section in the publish docs, the FLET_NO_IMPELLER environment variable, Windows and Linux troubleshooting rows, and the macOS Info.plist and Android meta-data resolution orders.
    • Semantics.heading_level / header: on iOS, VoiceOver's header trait now comes from the heading level (iOS a11y sets header trait based on heading level flutter/flutter#186916).
    • SemanticsService.high_contrast: the list of platforms that report it is corrected.
    • The 1.1.0 macOS 12 / iOS 15 guide is updated for Flutter 3.47. Custom templates build without the Podfile step, and macOS 11 / iOS 13–14 need Flet 1.0.4 or earlier.
    • FilePicker page: the client-action section no longer swallows the upload subsections, and the examples' intros come from their metadata.
  • textfield.dart: super parameters, the only new analyzer diagnostic on Dart 3.13.
  • Changelog: entries under 1.1.0.

Testing

Environment: macOS 27 / Xcode 27.0, JDK 17 unless noted. The results below were recorded on Flutter 3.47.5 and the previous patch pin. These builds and runtime tests have not been rerun on 3.47.7.

  • packages/flet: flutter test passes (91 on the previous patch pin). Then dart pub publish --dry-run exits 0 on a clean tree; without the analysis_options.yaml change it exits 65.
  • Extensions (20, including flet-shadcn-ui): CI's flutter pub get + dart analyze loop exits 0, and no files are rewritten.
  • client:
    • flutter build macos --debug, flutter build ios --simulator --debug, and flutter build apk --debug and --release succeed with no FLUTTER_XCODE_* overrides.
    • The release APK is shrunk by R8 8.13.19 with no Kotlin metadata warnings. Every Pods target resolves to 12.0 / 15.0 without the clamps.
    • ./gradlew assembleDebug succeeds on JDK 25.
  • Renderer, release macOS client (also checked on the previous patch pin):
    • With FLET_NO_IMPELLER unset or 0, it logs Using the Impeller rendering backend (MetalSDF).
    • With 1 or TRUE, it logs Using the Skia rendering backend (Metal). This also holds when it is launched through open -n, as flet run does.
    • No icudtl.dat errors.
  • flet build from the in-repo template:
    • macos, renderer: a default build has no FLTEnableImpeller key and renders with Impeller, or with Skia when FLET_NO_IMPELLER=1. A --no-impeller build has FLTEnableImpeller=false and renders with Skia. The rendered Windows and Linux runners and the Android manifest carry the expected values.
    • ios-simulator (flet_build_test, all extensions except flet-shadcn-ui, which came with flet-1.1.0): the app renders in the simulator. Flutter migrates the template to the UIScene lifecycle at build time.
    • apk: release build, R8 8.13.19.
    • web: the Pyodide app renders in the browser.
  • flet-cli: 435 tests pass.
  • Icons: generate_icons.py --verify against the previous patch pin reports 0 failures, including flet-shadcn-ui's Lucide set.
  • flet-shadcn-ui context menus: a widget test through the extension's Input, Textarea, InputOTP and TimePicker controls (macOS right-click, Android long-press) threw the ShadTheme error in all 8 cases before the fix and in none after. Input and Textarea show their copy/paste menu.
  • R8 repro: a minimal app that keeps kotlin.Metadata prints 24 R8 "kotlin metadata" warnings on AGP 8.11.1 + KGP 2.4.0, and none on AGP 8.13.2 + KGP 2.3.21.
  • Docs: yarn build passes with no broken links or anchors.

Not covered locally:

  • Windows and Linux. The runner changes were checked against the 3.47.5 embedder sources. CI compiles them, and the on-device flet test workflow now runs the counter app with Impeller on Windows and Linux runners.
  • Android runtime on a device.
  • The macOS integration goldens, which CI runs (with Skia, through the conftest.py default).

Follow-ups

  • Impeller goldens: regenerate the integration goldens with Impeller, then drop the FLET_NO_IMPELLER default from the conftest.py files.
  • Impeller on real hardware: check Windows, Linux and an Intel Mac by hand, including transparent windows, WebView and Video. Linux anti-aliasing and most of the issues above are fixed in Flutter 3.50.
  • AGP 9: needs file_picker ≥ 12 and the win32-6 plugin set (device_info_plus 13, package_info_plus 10, share_plus 13, wakelock_plus 1.8). This has to land before the next Flutter bump, which will likely reject AGP 8.

Summary by Sourcery

Upgrade Flet to Flutter 3.47.7 and make Impeller the default renderer while providing configurable Skia fallbacks across supported platforms.

New Features:

  • Add Impeller renderer selection to Flet builds and desktop runs, with Skia opt-outs through CLI flags, project configuration, and environment variables.
  • Support renderer configuration across desktop and Android templates while warning for unsupported iOS and web overrides.

Bug Fixes:

  • Fix shadcn-ui text-field context menus under Flutter 3.47.
  • Correct Canvas quadratic path defaults for Flutter 3.47 rendering behavior.

Enhancements:

  • Upgrade the bundled Flutter SDK to 3.47.7 and align Android tooling with Gradle 9.3.1, AGP 8.13.2, and Kotlin 2.3.21.
  • Update desktop and mobile build templates for Flutter 3.47 deployment-target handling and improve cross-platform build compatibility.
  • Apply Flutter analyzer migration exclusions across client, package, extension, and template projects.
  • Update accessibility metadata and text-field code for Flutter/Dart 3.13 compatibility.

Build:

  • Update Flutter and Android build toolchain versions and disable Kotlin incremental compilation by default for generated projects.

Documentation:

  • Document renderer selection, Impeller troubleshooting, configuration precedence, environment variables, and updated platform compatibility requirements.
  • Improve FilePicker example metadata and documentation organization.

Tests:

  • Keep integration screenshot tests on Skia until Impeller goldens are regenerated.

Chores:

  • Record the Flutter upgrade and renderer behavior changes in the changelogs.

Xcode 27 fails builds whose macOS deployment target is below 12.0. The template and client pinned 11.0, and Flutter 3.44.8 generates the FlutterMacOS pod at 10.15. Raise the Podfile platform and the Xcode project to 12.0, and let pods below 12.0 inherit the platform, as Flutter 3.47's podhelper does.
Xcode 27 fails builds whose iOS deployment target is below 15.0. The template and client pinned 13.0, and Flutter 3.44.8 generates the Flutter pod at 13.0. Raise the Podfile platform and the Xcode project to 15.0, let pods below 15.0 inherit the platform, and drop the stale MinimumOSVersion that Flutter strips from AppFrameworkInfo.plist anyway.
Raising the deployment targets is a breaking change under the compatibility policy, so add a 1.0.4 breaking-change guide and register it in the index, the sidebar and the release notes. The release notes also gain the missing 1.0.1-1.0.3 entries. The macOS and iOS publish pages now state the minimum OS version, and the changelog entry links the guide.
Raising the minimum macOS and iOS versions drops support for macOS 11
and iOS 13-14, so it ships in the 1.1.0 minor release instead of the
1.0.4 patch, together with the Flutter 3.47 bump, whose engine requires
the same minimums.

Move the changelog entry to 1.1.0 and the breaking-change guide from
v1-0-4 to v1-1-0, and update the breaking-changes index, the sidebar
and the release notes. Flet 1.0.4 becomes the last release for macOS 11
and iOS 13-14.
Flutter 3.47 adds a migration that runs on every `flutter pub get`,
`flutter test` and build. It inserts an `analyzer.exclude` block into
the `analysis_options.yaml` of any package that depends on Flutter.
On CI, `flutter test` in packages/flet would then leave a modified
checked-in file, and `dart pub publish --dry-run` fails with exit code
65. Every release job depends on that step.

Add the same block the migration writes, placed after `include:` the
way Flutter's own app template does it: `build/**` for packages/flet,
flet_integration_test and the extension packages, plus the six platform
directories for the client and the `flet build` template. The
migration only checks that each pattern is present, so it leaves these
files alone afterwards. The excludes are valid on older SDKs too.
Flutter 3.47 replaces several exact SDK package pins with caret ranges.
The client lock picks up the versions they now require: intl 0.20.3,
matcher 0.12.20, meta 1.19.0, test_api 0.7.12 and vector_math 2.4.3.
On Flutter 3.47, flutter_additional_ios_build_settings and
flutter_additional_macos_build_settings delete IPHONEOS_DEPLOYMENT_TARGET
below 15 and MACOSX_DEPLOYMENT_TARGET below 12 from every pod, whether or
not it depends on Flutter, so each pod inherits the Pods project value.
The post_install clamps added for Xcode 27 on 3.44.8 now repeat that
work and can go.

Verified on Xcode 27 with clean client builds (macos --debug,
ios --simulator --debug): every Pods target ends up at 12.0 / 15.0 and
both builds succeed without FLUTTER_XCODE_* overrides.

client/ios/Podfile.lock picks up the new Podfile checksum and the
Flutter pod checksum, which changes because 3.47's generated Flutter
podspec declares iOS 15.0.
Flutter 3.47 makes Impeller the default renderer on macOS, Windows and
Linux. The Flet desktop client already opts out on macOS
(FLTEnableImpeller=false, after blank windows on Intel Macs in #3557),
but apps built with `flet build` and the Windows and Linux clients would
switch to Impeller with the SDK bump. Upstream still has open Impeller
issues on these platforms (flutter#185394 crash on foreground on macOS,
flutter#191538 flicker on Intel Macs, flutter#191353 slower on Windows,
flutter#192915 flicker in Linux VMs), and Impeller hasn't been tested
with Flet on real Windows/Linux hardware.

Keep every desktop lane on Skia, as on Flutter 3.44:
- Windows client and template runner: set_impeller_switch(Disabled).
- Linux client and template runner: fl_dart_project_set_enable_impeller.
- macOS apps: flet-cli adds FLTEnableImpeller=false to the Info.plist
  defaults, so `[tool.flet.macos.info]` or
  `--info-plist FLTEnableImpeller=true` still switches a built app to
  Impeller.

FLUTTER_ENGINE_SWITCHES=--enable-impeller still enables Impeller in
debug builds. Release builds ignore that variable.
On iOS, Flutter 3.47 sets VoiceOver's header trait from the heading
level, not from the header flag (flutter#186916). Android already did
this, so both mobile screen readers now announce a heading only when
`heading_level` is set. Describe that on `Semantics.heading_level` and
`Semantics.header`.

Flutter 3.47 also reports `high_contrast` on Android API 34+, not only
on iOS (flutter#182263).
The Dart 3.13 linter reports use_super_parameters for this constructor. It was the only new analyzer diagnostic in packages/flet on Flutter 3.47.5. The behavior is unchanged: replacementString keeps the super constructor's '' default.
Flutter 3.47.5 raised its Android dependency floors: Gradle 8.14, AGP
8.11.1 and KGP 2.2.20, the versions both Android lanes pin, are now
the lowest it accepts, and each build printed three "support will soon
be dropped" warnings. The next Flutter release will likely reject them.

Move the client and the `flet build` template to the newest combination
that is supported end to end without AGP 9:
- Gradle wrapper 9.3.1, Flutter's template default.
- KGP 2.3.21. KGP 2.2.x is documented only up to Gradle 8.14, and
  Kotlin 2.4 class files need R8 9.1.29 or later.
- AGP 8.13.2, the last 8.x release. Its bundled R8 8.13.19 is the
  minimum Google lists for Kotlin 2.3. With AGP 8.11.1 (R8 8.11.18) and
  Kotlin 2.4, R8 couldn't parse Kotlin metadata and printed a warning
  per class whenever kotlin.Metadata was kept.
Flutter 3.47.5's AGP/Gradle and AGP/KGP compatibility checks accept
this combination.

AGP 9 isn't usable yet: file_picker 11 and device_info_plus 12.4 fail to
build with either android.builtInKotlin setting. Only the AGP warning
remains.

Gradle 9.1+ also runs on JDK 25, which crashed Gradle 8.14 with
"IllegalArgumentException: 25.0.2".

Verified: client `flutter build apk --debug` and `--release` (R8 8.13.19,
no Kotlin metadata warnings), and `./gradlew assembleDebug` on JDK 25.
On Flutter 3.47, a custom build template no longer needs the Podfile
post_install step: Flutter's migrators raise the deployment targets of
the generated project during the build, and podhelper.rb drops lower
targets from every pod. Custom templates keep building on Xcode 27, and
the Podfile `platform` and project.pbxproj changes only remove that
migration step.

Staying on macOS 11 or iOS 13-14 needs Flet 1.0.4 or earlier, because
the Flutter 3.47 engine itself requires macOS 12 and iOS 15.

@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 added this pull request to stack #6917 October 4, 2026 22:23
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Deploying flet-website-v2 with  Cloudflare Pages  Cloudflare Pages

Latest commit: 3704d8a
Status: ✅  Deploy successful!
Preview URL: https://e5c435ec.flet-website-v2.pages.dev
Branch Preview URL: https://chore-bump-flutter-3-47-5.flet-website-v2.pages.dev

View logs

@FeodorFitsner FeodorFitsner added this to the 1.1.0 milestone Oct 7, 2026
ndonkoHenri and others added 10 commits October 7, 2026 21:37
The "Picking files with a client action" section sat between the Usage
intro and its "Uploading files" and "Upload storage" subsections, so
both rendered as children of the client-action section. Move it to just
before Examples, where the Clipboard, Share and UrlLauncher pages put
theirs.

The "Pick and upload files" and "Pick text content" examples kept
hand-written headings and intros, which duplicated the headings the
remark plugin injects from each example's metadata, and the intros
rendered above the injected heading. Move the intros into `docs_intro`
and drop the hand-written headings.
`Path.QuadraticTo` defaults `w` to 1 in Python, and the serializer
omits a field that equals its default, so a plain quadratic curve
reaches the client without `w`. The Dart side fell back to a weight of
0. A conic with weight 0 is a straight line between its end points.
Flutter 3.44 measured and dashed such conics as curves anyway, but
Flutter 3.47 handles them correctly, so dashed paths built from
`QuadraticTo` lost their curves (`test_draw_dashed_path_with_fill`
dropped to 87.9% similarity).

Fall back to 1, the same default as Python.
Kotlin Gradle plugin 2.3 compiles through the Build Tools API by
default (`kotlin.compiler.runViaBuildToolsApi` defaults to true; it
was false in 2.2.20). Its incremental cache stores every source path
relative to the Android project. On Windows, when the pub cache and
the app sit on different drives (C: and D: on GitHub's Windows
runners), there is no relative path. Compiling a plugin such as
battery_plus then fails with "Could not close incremental caches ...
this and base files have different roots", which broke every
apk-windows and aab-windows job.

Set `kotlin.incremental=false` in the client and in flet-cli's default
gradle.properties for generated projects. The plugin modules are small
and Gradle still skips unchanged ones, so builds barely slow down.
`[tool.flet.android.gradle_properties]` can turn it back on.
Desktop apps and the flet run client now use Flutter 3.47's default
renderer, Impeller. The client and template runners switch to Skia when
FLET_NO_IMPELLER is true at startup; release engines ignore Flutter's own
engine-switch variables, and on macOS the runner replaces the private
FlutterDartProject.enableImpeller getter only when asked.

flet run --no-impeller (or impeller = false in pyproject) sets the variable
for the client it opens. flet build/debug/test get --impeller/--no-impeller
with [tool.flet(.<platform>)].impeller: the template runners bake it in on
Windows and Linux, macOS gets FLTEnableImpeller=false and Android the
EnableImpeller=false meta-data.

Integration tests keep rendering with Skia until the goldens are
regenerated.
3.47.6 fixes Windows release apps hanging while waiting on a timer
(flutter/flutter#192513) and moves to Dart 3.13.5. The client lock and the
generated icon lists don't change.
@ndonkoHenri ndonkoHenri changed the title chore: bump Flutter to 3.47.5 chore: bump Flutter to 3.47.6 and render desktop with Impeller Oct 8, 2026
…ployment-targets

# Conflicts:
#	CHANGELOG.md
#	website/docs/updates/release-notes.md
…r-3.47.5

# Conflicts:
#	CHANGELOG.md
#	client/pubspec.lock
#	packages/flet/CHANGELOG.md
Flutter 3.47's AnalysisOptionsMigration writes this block on every pub get,
as for the other extensions in this branch.
Flutter 3.47 shows a text field's context menu in the root overlay without
the themes between the field and the Navigator. flet_shadcn_ui provides its
ShadTheme only around each control, so right-clicking or long-pressing an
Input, Textarea, InputOTP or TimePicker threw "ShadTheme.of() called with a
context that does not contain a ShadTheme" and covered the window with an
error box.

Input and Textarea build shadcn_ui's menu inside the field's ShadTheme.
InputOTP and TimePicker take no contextMenuBuilder, so their native menu is
turned off.
Regenerating the lock after the merge had moved flutter_shaders and
theme_extensions_builder_annotation, which Flutter 3.47 doesn't require.
@ndonkoHenri
ndonkoHenri removed this pull request from stack #6917 October 8, 2026 22:00
@ndonkoHenri
ndonkoHenri added this pull request to stack #6934 October 8, 2026 22:01
Base automatically changed from fix/xcode-27-deployment-targets to flet-1.1.0 October 9, 2026 18:28
@FeodorFitsner FeodorFitsner changed the title chore: bump Flutter to 3.47.6 and render desktop with Impeller chore: bump Flutter to 3.47.7 and render desktop with Impeller Oct 9, 2026
@FeodorFitsner
FeodorFitsner merged commit 864e545 into flet-1.1.0 Oct 9, 2026
64 of 130 checks passed
@FeodorFitsner
FeodorFitsner deleted the chore/bump-flutter-3.47.5 branch October 9, 2026 19:27
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.

2 participants