From 0b68fc62139cc98b1163699ab635d0d6e8f11cd8 Mon Sep 17 00:00:00 2001 From: Eduardo Speroni Date: Mon, 14 Sep 2026 15:01:16 -0300 Subject: [PATCH] fix(android): back press navigates nested frames with history again Scope the activity's back press to the topmost frame of its window instead of handing the root view to Frame.goBack(). goBack(frame) only walks up to ancestors, so passing the root frame skipped nested frames that still had history and finished the activity. --- packages/core/ui/frame/frame-common.spec.ts | 27 +++++++++++++++++++++ packages/core/ui/frame/index.android.ts | 4 +-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/packages/core/ui/frame/frame-common.spec.ts b/packages/core/ui/frame/frame-common.spec.ts index a2096eb19b..f7deba3d47 100644 --- a/packages/core/ui/frame/frame-common.spec.ts +++ b/packages/core/ui/frame/frame-common.spec.ts @@ -127,6 +127,33 @@ describe('FrameBase.goBack', () => { expect(frameStack).toEqual([only]); }); + + it("navigates a nested frame with history when given the window's topmost frame", () => { + const window = createWindow('a'); + const root = createFrameInWindow(window); + const nested = createFrame(true); + nested.parent = root; + nested._nativeWindow = window; + _pushInFrameStack(nested); + + expect(FrameBase.goBack(FrameBase.topmost(window))).toBe(true); + + expect(isNavigatingBack(nested)).toBe(true); + expect(isNavigatingBack(root)).toBe(false); + }); + + it('does not reach a nested frame with history when given its root frame', () => { + const window = createWindow('a'); + const root = createFrameInWindow(window); + const nested = createFrame(true); + nested.parent = root; + nested._nativeWindow = window; + _pushInFrameStack(nested); + + expect(FrameBase.goBack(root)).toBe(false); + + expect(isNavigatingBack(nested)).toBe(false); + }); }); /** diff --git a/packages/core/ui/frame/index.android.ts b/packages/core/ui/frame/index.android.ts index 9638b5272a..d98f76ab91 100644 --- a/packages/core/ui/frame/index.android.ts +++ b/packages/core/ui/frame/index.android.ts @@ -779,7 +779,7 @@ if (SDK_VERSION >= 33) { // In the case of Frame, use this callback only if it was overridden, since the original will cause navigation issues if (!viewArgs.cancel && (view.onBackPressed === Frame.prototype.onBackPressed || !view.onBackPressed())) { - callSuper = view instanceof Frame ? !Frame.goBack(view) : true; + callSuper = view instanceof Frame ? !Frame.goBack(Frame.topmost(nativeWindow)) : true; } } } @@ -1031,7 +1031,7 @@ export class ActivityCallbacksImplementation implements AndroidActivityCallbacks // In the case of Frame, use this callback only if it was overridden, since the original will cause navigation issues if (!viewArgs.cancel && (view.onBackPressed === Frame.prototype.onBackPressed || !view.onBackPressed())) { - callSuper = view instanceof Frame ? !Frame.goBack(view) : true; + callSuper = view instanceof Frame ? !Frame.goBack(Frame.topmost(nativeWindow)) : true; } if (callSuper) {