From 59c603a55843e0cdd0760a4a20f1c642d1139349 Mon Sep 17 00:00:00 2001 From: Kyle Hickinson Date: Fri, 19 Jan 2024 16:21:47 -0500 Subject: [PATCH] Fix #8661: Always allow WebKit to load popup URLs before switching tabs There was a race condition on older devices that where WebKit would not load the popup URL before Brave attempted to select the tab. Selecting the tab would then attempt to restore it using the tab's current URL which would be `about:blank` since the web view had not made any requests yet. --- .../BVC+WKNavigationDelegate.swift | 10 ++++++++++ Sources/Brave/Frontend/Browser/TabManager.swift | 8 -------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Sources/Brave/Frontend/Browser/BrowserViewController/BVC+WKNavigationDelegate.swift b/Sources/Brave/Frontend/Browser/BrowserViewController/BVC+WKNavigationDelegate.swift index fdd5c182ea6..72d4f444943 100644 --- a/Sources/Brave/Frontend/Browser/BrowserViewController/BVC+WKNavigationDelegate.swift +++ b/Sources/Brave/Frontend/Browser/BrowserViewController/BVC+WKNavigationDelegate.swift @@ -1016,6 +1016,16 @@ extension BrowserViewController: WKUIDelegate { newTab.url = URL(string: "about:blank") toolbarVisibilityViewModel.toolbarState = .expanded + + // Wait until WebKit starts the request before selecting the new tab, otherwise the tab manager may + // restore it as if it was a dead tab. + var observation: NSKeyValueObservation? + observation = newTab.webView?.observe(\.url, changeHandler: { [weak self] webView, _ in + _ = observation // Silence write but not read warning + observation = nil + guard let self = self, let tab = self.tabManager[webView] else { return } + self.tabManager.selectTab(tab) + }) return newTab.webView } diff --git a/Sources/Brave/Frontend/Browser/TabManager.swift b/Sources/Brave/Frontend/Browser/TabManager.swift index cc5d92a00b6..df2cd8c781c 100644 --- a/Sources/Brave/Frontend/Browser/TabManager.swift +++ b/Sources/Brave/Frontend/Browser/TabManager.swift @@ -411,14 +411,6 @@ class TabManager: NSObject { @MainActor func addPopupForParentTab(_ parentTab: Tab, configuration: WKWebViewConfiguration) -> Tab { let popup = Tab(configuration: configuration, id: UUID(), type: parentTab.type, tabGeneratorAPI: tabGeneratorAPI) configureTab(popup, request: nil, afterTab: parentTab, flushToDisk: true, zombie: false, isPopup: true) - - // Wait momentarily before selecting the new tab, otherwise the parent tab - // may be unable to set `window.location` on the popup immediately after - // calling `window.open("")`. - DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) { - self.selectTab(popup) - } - return popup }