Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/518 - new tab on macos #526

Closed

Conversation

anthony-bernardo
Copy link

@anthony-bernardo anthony-bernardo commented Oct 2, 2023

I refactor the way the alert is receiving notification, because with NotificationCenter (if there were opened tabs) the alert were displayed in each tabs

TODO:

  • Squash commit before merge

Fixes #518

Copy link
Member

@automactic automactic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like your solution to resolving issue around external url alerts, but I don't think the open link in new tab stuff always works reliably

Not that it's your fault or anything -- a lot of swiftui stuff are very new, and to be frank buggy. My position on "Open in new tab" is: if it doesn't result in a good and (mostly) bug free experience, let's disable it

@@ -37,6 +37,7 @@ class BrowserViewModel: NSObject, ObservableObject,

// MARK: - Properties

@Published var openExternalLinkURL = URL(string: "")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall I think this is a good solution on resolving the problem where alerts are displayed in all windows. It keeps the state local, and I am not a fan of the notifications either

I have two feedback:

  • why not use an optional URL, and have nil when when there isn't an external URL to open?
  • (nit) let's use the same variable name here and inside ExternalLinkHandler, I suggest use externalLinkURL everywhere

@@ -179,7 +180,7 @@ class BrowserViewModel: NSObject, ObservableObject,
} else if url.isKiwixURL {
decisionHandler(.allow)
} else if url.scheme == "http" || url.scheme == "https" {
NotificationCenter.default.post(name: .externalLink, object: nil, userInfo: ["url": url])
self.openExternalLinkURL = url
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self.openExternalLinkURL = url
openExternalLinkURL = url

@@ -38,7 +38,7 @@ struct BrowserTab: View {
.focusedSceneValue(\.browserViewModel, browser)
.focusedSceneValue(\.canGoBack, browser.canGoBack)
.focusedSceneValue(\.canGoForward, browser.canGoForward)
.modifier(ExternalLinkHandler())
.modifier(ExternalLinkHandler(externalURL: $browser.openExternalLinkURL))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fairly sure there is another usage of ExternalLinkHandler on a iOS specific view, could you change that as well?

@@ -179,7 +180,7 @@ class BrowserViewModel: NSObject, ObservableObject,
} else if url.isKiwixURL {
decisionHandler(.allow)
} else if url.scheme == "http" || url.scheme == "https" {
NotificationCenter.default.post(name: .externalLink, object: nil, userInfo: ["url": url])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you remove this as well? (I don't think we need this anymore, right?)

https://github.com/kiwix/apple/blob/fa397a905f95b946e1cf6b55328771b101bb91f8/SwiftUI/Patches.swift#L65

@@ -11,12 +11,11 @@ import SwiftUI
import Defaults

struct ExternalLinkHandler: ViewModifier {
@Binding var externalURL: URL?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@Binding var externalURL: URL?
@Binding var externalLinkURL: URL?

(following the 2nd feedback from above)

@@ -28,8 +27,10 @@ struct ExternalLinkHandler: ViewModifier {
}

func body(content: Content) -> some View {
content.onReceive(externalLink) { notification in
guard let url = notification.userInfo?["url"] as? URL else { return }
content.onChange(of: externalURL, perform: { _ in
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: could you write this in the style of

content.onChange(of: externalURL) {
    ...
}

@@ -179,7 +180,7 @@ class BrowserViewModel: NSObject, ObservableObject,
} else if url.isKiwixURL {
decisionHandler(.allow)
} else if url.scheme == "http" || url.scheme == "https" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are introducing isExternalLink on URL, could you change this line to use that variable instead?

currentWindow.addTabbedWindow(newWindow, ordered: .above)

// open url in new tab
NotificationCenter.openURL(newUrl, inNewTab: true)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
NotificationCenter.openURL(newUrl, inNewTab: true)
NotificationCenter.openURL(newUrl)

Context: inNewTab is for iOS / iPadOS only, it doesn't do anything for Mac, so I suggest removing it

Comment on lines +412 to +419
guard let currentWindow = NSApp.keyWindow,
let windowController = currentWindow.windowController else { return nil }
windowController.newWindowForTab(nil)
guard let newWindow = NSApp.keyWindow, currentWindow != newWindow else { return nil }
currentWindow.addTabbedWindow(newWindow, ordered: .above)

// open url in new tab
NotificationCenter.openURL(newUrl, inNewTab: true)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works well most of the times, but not always. The issue I think is @Environment(\.controlActiveState) var controlActiveState is supposed to tell us which window is key, and only the key window should respond to the open URL notification, but there sometimes can be multiple key windows.

https://github.com/kiwix/apple/blob/fa397a905f95b946e1cf6b55328771b101bb91f8/App/App_macOS.swift#L141-L143

I am not an AppKit expert, but I was under the impression only one window can become key at a time, since only one window is supposed to be able to receive keyboard event

You can reproduce the issue with (on macOS 14):

  • using right click, open in new window to open stay 4 tabs
  • go to the 2nd tab, right click on something, and open in new window
  • multiple windows responds to the notification
    • with the additional problem that the newly opened window having the incorrect title (haven't investigated why)
Screenshot 2023-10-07 at 10 06 27 AM

@kelson42
Copy link
Contributor

@anthony-bernardo Thank you for your work here. This PR has been superseeded by #536.

@kelson42 kelson42 closed this Nov 20, 2023
This pull request was closed.
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.

Non functional "Open Link in New Window"
3 participants