Fix browser pane video fullscreen
This commit is contained in:
parent
6ff81579d9
commit
e935eb57d3
4 changed files with 97 additions and 6 deletions
|
|
@ -2759,6 +2759,8 @@ final class WindowBrowserPortal: NSObject {
|
|||
let webViewId = ObjectIdentifier(webView)
|
||||
let anchorId = ObjectIdentifier(anchorView)
|
||||
let previousEntry = entriesByWebViewId[webViewId]
|
||||
let shouldPreserveExternalFullscreenHost =
|
||||
webView.cmuxIsManagedByExternalFullscreenWindow(relativeTo: window)
|
||||
let containerView = ensureContainerView(
|
||||
for: previousEntry ?? Entry(
|
||||
webView: nil,
|
||||
|
|
@ -2833,7 +2835,16 @@ final class WindowBrowserPortal: NSObject {
|
|||
}
|
||||
#endif
|
||||
|
||||
if webView.superview !== containerView {
|
||||
if shouldPreserveExternalFullscreenHost {
|
||||
#if DEBUG
|
||||
dlog(
|
||||
"browser.portal.reparent.skip web=\(browserPortalDebugToken(webView)) " +
|
||||
"reason=fullscreenExternalHost super=\(browserPortalDebugToken(webView.superview)) " +
|
||||
"container=\(browserPortalDebugToken(containerView)) " +
|
||||
"state=\(String(describing: webView.fullscreenState))"
|
||||
)
|
||||
#endif
|
||||
} else if webView.superview !== containerView {
|
||||
#if DEBUG
|
||||
dlog(
|
||||
"browser.portal.reparent web=\(browserPortalDebugToken(webView)) " +
|
||||
|
|
@ -3097,10 +3108,22 @@ final class WindowBrowserPortal: NSObject {
|
|||
hostView.addSubview(containerView, positioned: .above, relativeTo: nil)
|
||||
refreshReasons.append("syncAttachContainer")
|
||||
}
|
||||
let shouldPreserveExternalFullscreenHost =
|
||||
webView.cmuxIsManagedByExternalFullscreenWindow(relativeTo: window)
|
||||
let shouldPreserveExternalHostForHiddenEntry =
|
||||
!shouldPreserveExternalFullscreenHost &&
|
||||
!entry.visibleInUI &&
|
||||
webView.superview !== containerView
|
||||
if shouldPreserveExternalHostForHiddenEntry {
|
||||
if shouldPreserveExternalFullscreenHost {
|
||||
#if DEBUG
|
||||
dlog(
|
||||
"browser.portal.reparent.skip web=\(browserPortalDebugToken(webView)) " +
|
||||
"reason=fullscreenExternalHost super=\(browserPortalDebugToken(webView.superview)) " +
|
||||
"container=\(browserPortalDebugToken(containerView)) " +
|
||||
"state=\(String(describing: webView.fullscreenState))"
|
||||
)
|
||||
#endif
|
||||
} else if shouldPreserveExternalHostForHiddenEntry {
|
||||
#if DEBUG
|
||||
dlog(
|
||||
"browser.portal.reparent.skip web=\(browserPortalDebugToken(webView)) " +
|
||||
|
|
|
|||
|
|
@ -2192,6 +2192,7 @@ final class BrowserPanel: Panel, ObservableObject {
|
|||
}
|
||||
}
|
||||
}
|
||||
@Published private(set) var isElementFullscreenActive: Bool = false
|
||||
private var searchNeedleCancellable: AnyCancellable?
|
||||
let portalAnchorView = BrowserPortalAnchorView(frame: .zero)
|
||||
private struct PortalHostLease {
|
||||
|
|
@ -2478,6 +2479,7 @@ final class BrowserPanel: Panel, ObservableObject {
|
|||
|
||||
// Enable developer extras (DevTools)
|
||||
configuration.preferences.setValue(true, forKey: "developerExtrasEnabled")
|
||||
configuration.preferences.isElementFullscreenEnabled = true
|
||||
|
||||
// Enable JavaScript
|
||||
configuration.defaultWebpagePreferences.allowsContentJavaScript = true
|
||||
|
|
@ -3064,6 +3066,27 @@ final class BrowserPanel: Panel, ObservableObject {
|
|||
}
|
||||
webViewObservers.append(progressObserver)
|
||||
|
||||
let fullscreenObserver = webView.observe(\.fullscreenState, options: [.initial, .new]) { [weak self] webView, _ in
|
||||
let isElementFullscreenActive = webView.cmuxIsElementFullscreenActiveOrTransitioning
|
||||
let fullscreenState = webView.fullscreenState
|
||||
Task { @MainActor in
|
||||
guard let self, self.isCurrentWebView(webView, instanceID: observedWebViewInstanceID) else { return }
|
||||
self.isElementFullscreenActive = isElementFullscreenActive
|
||||
BrowserWindowPortalRegistry.refresh(
|
||||
webView: webView,
|
||||
reason: "fullscreenStateChanged"
|
||||
)
|
||||
#if DEBUG
|
||||
dlog(
|
||||
"browser.fullscreen.state panel=\(self.id.uuidString.prefix(5)) " +
|
||||
"web=\(ObjectIdentifier(webView)) state=\(String(describing: fullscreenState)) " +
|
||||
"active=\(isElementFullscreenActive ? 1 : 0)"
|
||||
)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
webViewObservers.append(fullscreenObserver)
|
||||
|
||||
NotificationCenter.default.publisher(for: .ghosttyDefaultBackgroundDidChange)
|
||||
.sink { [weak self] notification in
|
||||
guard let self else { return }
|
||||
|
|
|
|||
|
|
@ -5774,6 +5774,13 @@ struct WebViewRepresentable: NSViewRepresentable {
|
|||
host.clearLocalInlineCallbacks()
|
||||
}
|
||||
|
||||
private static func shouldPreserveExternalFullscreenHost(
|
||||
for webView: WKWebView,
|
||||
relativeTo expectedWindow: NSWindow?
|
||||
) -> Bool {
|
||||
webView.cmuxIsManagedByExternalFullscreenWindow(relativeTo: expectedWindow)
|
||||
}
|
||||
|
||||
private static func localInlineTransferRoot(for webView: WKWebView) -> NSView? {
|
||||
var current = webView.superview
|
||||
var last: NSView?
|
||||
|
|
@ -5874,7 +5881,12 @@ struct WebViewRepresentable: NSViewRepresentable {
|
|||
guard let host = nsView as? HostContainerView else { return false }
|
||||
let slotView = host.ensureLocalInlineSlotView()
|
||||
let isAlreadyInLocalHost = host.containsManagedLocalInlineContent(webView)
|
||||
let didAttachWebViewToLocalHost = !isAlreadyInLocalHost
|
||||
let shouldPreserveExternalFullscreenHost = Self.shouldPreserveExternalFullscreenHost(
|
||||
for: webView,
|
||||
relativeTo: host.window
|
||||
)
|
||||
let didAttachWebViewToLocalHost =
|
||||
!isAlreadyInLocalHost && !shouldPreserveExternalFullscreenHost
|
||||
|
||||
let coordinator = context.coordinator
|
||||
coordinator.desiredPortalVisibleInUI = false
|
||||
|
|
@ -5919,6 +5931,16 @@ struct WebViewRepresentable: NSViewRepresentable {
|
|||
return false
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
if shouldPreserveExternalFullscreenHost {
|
||||
dlog(
|
||||
"browser.localHost.reparent.skip web=\(Self.objectID(webView)) " +
|
||||
"reason=fullscreenExternalHost host=\(Self.objectID(host)) " +
|
||||
"slot=\(Self.objectID(slotView)) state=\(String(describing: webView.fullscreenState))"
|
||||
)
|
||||
}
|
||||
#endif
|
||||
|
||||
let preferredAttachedWidthState = panel.preferredAttachedDeveloperToolsWidthState()
|
||||
host.setPreferredHostedInspectorWidth(
|
||||
width: preferredAttachedWidthState.width,
|
||||
|
|
@ -5971,7 +5993,7 @@ struct WebViewRepresentable: NSViewRepresentable {
|
|||
host.setHostedInspectorFrontendWebView(webView.cmuxInspectorFrontendWebView())
|
||||
host.scheduleHostedInspectorDockConfigurationSync(reason: "localInline.update.async")
|
||||
}
|
||||
} else {
|
||||
} else if !shouldPreserveExternalFullscreenHost {
|
||||
panel.consumeAttachedDeveloperToolsManualCloseIfNeeded()
|
||||
host.scheduleHostedInspectorDockConfigurationSync(reason: "localInline.update")
|
||||
}
|
||||
|
|
@ -5985,7 +6007,7 @@ struct WebViewRepresentable: NSViewRepresentable {
|
|||
details: Self.attachContext(webView: webView, host: host)
|
||||
)
|
||||
#endif
|
||||
return true
|
||||
return !shouldPreserveExternalFullscreenHost
|
||||
}
|
||||
|
||||
private func updateUsingWindowPortal(_ nsView: NSView, context: Context, webView: WKWebView) -> Bool {
|
||||
|
|
@ -5993,6 +6015,10 @@ struct WebViewRepresentable: NSViewRepresentable {
|
|||
host.prepareForWindowPortalHosting()
|
||||
host.setLocalInlineSlotHidden(true)
|
||||
host.releaseHostedWebViewConstraints()
|
||||
let shouldPreserveExternalFullscreenHost = Self.shouldPreserveExternalFullscreenHost(
|
||||
for: webView,
|
||||
relativeTo: host.window
|
||||
)
|
||||
|
||||
let coordinator = context.coordinator
|
||||
let paneDropContext = currentPaneDropContext()
|
||||
|
|
@ -6188,7 +6214,7 @@ struct WebViewRepresentable: NSViewRepresentable {
|
|||
details: Self.attachContext(webView: webView, host: host)
|
||||
)
|
||||
#endif
|
||||
return portalHostAccepted
|
||||
return portalHostAccepted && !shouldPreserveExternalFullscreenHost
|
||||
}
|
||||
|
||||
func updateNSView(_ nsView: NSView, context: Context) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,25 @@ import ObjectiveC
|
|||
import UniformTypeIdentifiers
|
||||
import WebKit
|
||||
|
||||
extension WKWebView {
|
||||
var cmuxIsElementFullscreenActiveOrTransitioning: Bool {
|
||||
switch fullscreenState {
|
||||
case .notInFullscreen:
|
||||
return false
|
||||
case .enteringFullscreen, .inFullscreen, .exitingFullscreen:
|
||||
return true
|
||||
@unknown default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func cmuxIsManagedByExternalFullscreenWindow(relativeTo expectedWindow: NSWindow?) -> Bool {
|
||||
guard cmuxIsElementFullscreenActiveOrTransitioning else { return false }
|
||||
guard let expectedWindow else { return true }
|
||||
return window !== expectedWindow
|
||||
}
|
||||
}
|
||||
|
||||
struct BrowserImageCopyPasteboardPayload {
|
||||
let imageData: Data
|
||||
let mimeType: String?
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue