Skip to content

Commit

Permalink
Fix video fullscreen exit crash (#295)
Browse files Browse the repository at this point in the history
* Fix crash on fullscreen exit

* fix resizing

* trying to fix Xcode 13.0 compatibility

* Xcode 13.1 fix

* Unit tests fixed for macOS 12

* fix tab switching

* Fix window closing when video playing in full screen

* cleanup

Co-authored-by: Tomas Strba <[email protected]>
  • Loading branch information
2 people authored and jonathanKingston committed Feb 25, 2022
1 parent 15a809b commit e306ea6
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 15 deletions.
54 changes: 41 additions & 13 deletions DuckDuckGo/BrowserTab/View/BrowserTabViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ final class BrowserTabViewController: NSViewController {
@IBOutlet weak var errorMessageLabel: NSTextField!
@IBOutlet weak var hoverLabel: NSTextField!
@IBOutlet weak var hoverLabelContainer: NSView!
weak var webView: WebView?
private weak var webView: WebView?
private weak var webViewContainer: NSView?

var tabViewModel: TabViewModel?

Expand Down Expand Up @@ -76,6 +77,18 @@ final class BrowserTabViewController: NSViewController {
subscribeToErrorViewState()
}

override func viewDidAppear() {
NotificationCenter.default.addObserver(self,
selector: #selector(windowWillClose(_:)),
name: NSWindow.willCloseNotification,
object: self.view.window)
}

@objc
private func windowWillClose(_ notification: NSNotification) {
self.removeWebViewFromHierarchy()
}

private func subscribeToSelectedTabViewModel() {
selectedTabViewModelCancellable = tabCollectionViewModel.$selectedTabViewModel
.sink { [weak self] selectedTabViewModel in
Expand All @@ -100,6 +113,18 @@ final class BrowserTabViewController: NSViewController {
show(tabContent: tabViewModel?.tab.content)
}

private func removeWebViewFromHierarchy(webView: WebView? = nil,
container: NSView? = nil) {
guard let webView = webView ?? self.webView,
let container = container ?? self.webViewContainer
else { return }

// close fullscreenWindowController when closing tab in FullScreen mode
webView.fullscreenWindowController?.close()
webView.removeFromSuperview()
container.removeFromSuperview()
}

private func addWebViewToViewHierarchy(_ webView: WebView) {
// This code should ideally use Auto Layout, but in order to enable the web inspector, it needs to use springs & structs.
// The line at the bottom of this comment is the "correct" method of doing this, but breaks the inspector.
Expand All @@ -109,7 +134,12 @@ final class BrowserTabViewController: NSViewController {

webView.frame = view.bounds
webView.autoresizingMask = [.width, .height]
view.addSubview(webView)

let container = NSView(frame: view.bounds)
container.autoresizingMask = [.width, .height]
view.addSubview(container)
container.addSubview(webView)
self.webViewContainer = container

// Make sure this is on top
view.addSubview(hoverLabelContainer)
Expand All @@ -127,25 +157,20 @@ final class BrowserTabViewController: NSViewController {
addWebViewToViewHierarchy(newWebView)
}

func removeOldWebView(_ oldWebView: WebView?) {
if let oldWebView = oldWebView, view.subviews.contains(oldWebView) {
oldWebView.removeFromSuperview()
}
}

guard let tabViewModel = tabViewModel else {
self.tabViewModel = nil
removeOldWebView(webView)
removeWebViewFromHierarchy()
return
}

guard self.tabViewModel !== tabViewModel else { return }

let oldWebView = webView
let webViewContainer = webViewContainer
displayWebView(of: tabViewModel)
subscribeToUrl(of: tabViewModel)
self.tabViewModel = tabViewModel
removeOldWebView(oldWebView)
removeWebViewFromHierarchy(webView: oldWebView, container: webViewContainer)
}

func subscribeToUrl(of tabViewModel: TabViewModel) {
Expand All @@ -167,13 +192,17 @@ final class BrowserTabViewController: NSViewController {
}
}

func makeWebViewFirstResponder() {
self.webView?.makeMeFirstResponder()
}

private func setFirstResponderIfNeeded() {
guard webView?.url != nil else {
return
}

DispatchQueue.main.async { [weak self] in
self?.webView?.makeMeFirstResponder()
self?.makeWebViewFirstResponder()
}
}

Expand Down Expand Up @@ -229,7 +258,7 @@ final class BrowserTabViewController: NSViewController {
preferencesViewController.removeCompletely()
bookmarksViewController.removeCompletely()
if includingWebView {
self.webView?.removeFromSuperview()
self.removeWebViewFromHierarchy()
}
}

Expand Down Expand Up @@ -373,7 +402,6 @@ extension BrowserTabViewController: TabDelegate {

func closeTab(_ tab: Tab) {
guard let index = tabCollectionViewModel.tabCollection.tabs.firstIndex(of: tab) else {

return
}
tabCollectionViewModel.remove(at: index)
Expand Down
9 changes: 9 additions & 0 deletions DuckDuckGo/BrowserTab/View/WebView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -170,4 +170,13 @@ final class WebView: WKWebView {
inspectorPerform("showResources")
}

var fullscreenWindowController: NSWindowController? {
guard let fullscreenWindowController = self.window?.windowController,
fullscreenWindowController.className.contains("FullScreen")
else {
return nil
}
return fullscreenWindowController
}

}
2 changes: 1 addition & 1 deletion DuckDuckGo/Main/View/MainViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ final class MainViewController: NSViewController {
switch selectedTabViewModel.tab.content {
case .homepage, .onboarding, .none: navigationBarViewController.addressBarViewController?.addressBarTextField.makeMeFirstResponder()
case .url:
browserTabViewController.webView?.makeMeFirstResponder()
browserTabViewController.makeWebViewFirstResponder()
case .preferences: browserTabViewController.preferencesViewController.view.makeMeFirstResponder()
case .bookmarks: browserTabViewController.bookmarksViewController.view.makeMeFirstResponder()
}
Expand Down
2 changes: 1 addition & 1 deletion DuckDuckGo/Statistics/PixelEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ extension Pixel {
}

case navigation(kind: NavigationKind, source: NavigationAccessPoint)

case serp

case suggestionsDisplayed(hasBookmark: HasBookmark, hasFavorite: HasFavorite, hasHistoryEntry: HasHistoryEntry)
Expand Down

0 comments on commit e306ea6

Please sign in to comment.