Fix embedded FletApp back gesture exiting host app#6715
Open
FeodorFitsner wants to merge 2 commits into
Open
Conversation
A system/edge-swipe back landing on an embedded FletApp (an app rendered inside another Flet app via FletApp, e.g. a gallery host running example apps in-process) closed the whole host app instead of navigating back. Root cause is Android's predictive-back path, not the legacy didPopRoute path: each WidgetsApp (MaterialApp/CupertinoApp) listens for NavigationNotification and, by default, calls SystemNavigator.setFrameworkHandlesBack(canHandlePop) and stops the notification. The embedded app's single-view Navigator reports canHandlePop=false, so the embedded WidgetsApp told the OS the framework does not handle back AND swallowed the notification before it could reach the host Navigator (which would have re-reported canHandlePop=true since it can pop the embedding view). The OS then finished the activity. Fix, for an embedded page (backend.controlId != null): - Override onNavigationNotification to return false so the notification bubbles to the host, whose Navigator re-reports canHandlePop=true and whose WidgetsApp calls setFrameworkHandlesBack(true). - Chain a ChildBackButtonDispatcher to the host Router (instead of the default RootBackButtonDispatcher) so that once the back actually reaches didPopRoute, an unhandled back propagates from the embedded Router to the host Router, which pops the view embedding the FletApp. This also preserves correct precedence for multi-view embedded apps (they pop their own inner view first).
Deploying flet-website-v2 with
|
| Latest commit: |
6338ec9
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://be7247ef.flet-website-v2.pages.dev |
| Branch Preview URL: | https://fix-embedded-back-navigation.flet-website-v2.pages.dev |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A system/edge-swipe back gesture that lands on an embedded
FletApp(an app rendered inside another Flet app viaFletApp— e.g. a gallery host running example apps in-process) closed the whole host app instead of navigating back.Root cause
This is Android's predictive-back path, not the legacy
didPopRoutepath.Every
WidgetsApp(MaterialApp/CupertinoApp) listens forNavigationNotification, and its default handler both callsSystemNavigator.setFrameworkHandlesBack(canHandlePop)and stops the notification. The embedded example's single-viewNavigatorreportscanHandlePop: false, so the embeddedWidgetsApp:Navigator— which would have re-reportedcanHandlePop: true, since it can pop the view embedding the app.The OS then finished the activity → the app exits.
didPopRoutenever fired.Fix
For an embedded page (
backend.controlId != null), inpackages/flet/lib/src/controls/page.dart:onNavigationNotification: (_) => false— don't runWidgetsApp's default handler; let the notification bubble to the host, whoseNavigatorre-reportscanHandlePop: trueand whoseWidgetsAppcallssetFrameworkHandlesBack(true). This is what stops the OS from finishing the activity.ChildBackButtonDispatcherchained to the hostRouter(instead of the defaultRootBackButtonDispatcher) — so once back actually reachesdidPopRoute, an unhandled back propagates from the embeddedRouterto the hostRouter, which pops the view embedding theFletApp. This also preserves correct precedence for multi-view embedded apps: they pop their own inner view first, then fall through to the host.Non-embedded (root) pages are unaffected:
onNavigationNotificationstaysnull(default handler) and no child dispatcher is created.Testing
NavigationNotificationcombining logic (Navigator) and the dispatcher fall-through (BackButtonDispatcher/ChildBackButtonDispatcher).flutter analyzeclean.Notes
This makes an embedded app defer back-reporting to its host, which is correct for the only way
FletAppembeds today (inside another Flet app with its ownNavigator).Summary by Sourcery
Ensure embedded Flet apps delegate system back handling to their host so edge-swipe back navigates within the host instead of exiting the entire app.
Bug Fixes:
Documentation: