Merge remote-tracking branch 'origin/main' into task-browser-page-pushed-up
# Conflicts: # cmuxTests/CmuxWebViewKeyEquivalentTests.swift
This commit is contained in:
commit
e35e1cd94c
2 changed files with 78 additions and 1 deletions
|
|
@ -1530,6 +1530,12 @@ final class BrowserPaneDropTargetView: NSView {
|
|||
|
||||
final class WindowBrowserSlotView: NSView {
|
||||
override var isOpaque: Bool { false }
|
||||
override var isHidden: Bool {
|
||||
didSet {
|
||||
guard isHidden, !oldValue, let window else { return }
|
||||
yieldOwnedFirstResponderIfNeeded(in: window, reason: "slotHidden")
|
||||
}
|
||||
}
|
||||
private let paneDropTargetView = BrowserPaneDropTargetView(frame: .zero)
|
||||
private let dropZoneOverlayView = BrowserDropZoneOverlayView(frame: .zero)
|
||||
private var searchOverlayHostingView: NSHostingView<BrowserSearchOverlay>?
|
||||
|
|
@ -1571,6 +1577,13 @@ final class WindowBrowserSlotView: NSView {
|
|||
nil
|
||||
}
|
||||
|
||||
override func viewWillMove(toWindow newWindow: NSWindow?) {
|
||||
if newWindow == nil, let currentWindow = window {
|
||||
yieldOwnedFirstResponderIfNeeded(in: currentWindow, reason: "slotWillLeaveWindow")
|
||||
}
|
||||
super.viewWillMove(toWindow: newWindow)
|
||||
}
|
||||
|
||||
override func layout() {
|
||||
super.layout()
|
||||
paneDropTargetView.frame = bounds
|
||||
|
|
@ -1739,6 +1752,23 @@ final class WindowBrowserSlotView: NSView {
|
|||
return window.makeFirstResponder(nil)
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
private func yieldOwnedFirstResponderIfNeeded(in window: NSWindow, reason: String) -> Bool {
|
||||
guard let firstResponder = window.firstResponder,
|
||||
let owningView = firstResponder.browserPortalOwningView,
|
||||
owningView === self || owningView.isDescendant(of: self) else {
|
||||
return false
|
||||
}
|
||||
#if DEBUG
|
||||
dlog(
|
||||
"browser.slot.firstResponder.yield reason=\(reason) " +
|
||||
"slot=\(browserPortalDebugToken(self)) " +
|
||||
"responder=\(String(describing: type(of: firstResponder)))"
|
||||
)
|
||||
#endif
|
||||
return window.makeFirstResponder(nil)
|
||||
}
|
||||
|
||||
func pinHostedWebView(_ webView: WKWebView) {
|
||||
guard webView.superview === self else { return }
|
||||
|
||||
|
|
|
|||
|
|
@ -2434,7 +2434,9 @@ final class BrowserSessionHistoryRestoreTests: XCTestCase {
|
|||
|
||||
@MainActor
|
||||
final class BrowserDeveloperToolsVisibilityPersistenceTests: XCTestCase {
|
||||
private final class WKInspectorProbeView: NSView {}
|
||||
private final class WKInspectorProbeView: NSView {
|
||||
override var acceptsFirstResponder: Bool { true }
|
||||
}
|
||||
|
||||
private final class FakeInspector: NSObject {
|
||||
private(set) var attachCount = 0
|
||||
|
|
@ -11697,6 +11699,51 @@ final class BrowserWindowPortalLifecycleTests: XCTestCase {
|
|||
)
|
||||
}
|
||||
|
||||
func testHidingBrowserSlotYieldsOwnedInspectorFirstResponder() {
|
||||
let window = NSWindow(
|
||||
contentRect: NSRect(x: 0, y: 0, width: 520, height: 320),
|
||||
styleMask: [.titled, .closable],
|
||||
backing: .buffered,
|
||||
defer: false
|
||||
)
|
||||
defer { window.orderOut(nil) }
|
||||
realizeWindowLayout(window)
|
||||
guard let contentView = window.contentView else {
|
||||
XCTFail("Expected content view")
|
||||
return
|
||||
}
|
||||
|
||||
let slot = WindowBrowserSlotView(frame: NSRect(x: 40, y: 24, width: 260, height: 180))
|
||||
contentView.addSubview(slot)
|
||||
|
||||
let inspectorContainer = NSView(frame: slot.bounds)
|
||||
inspectorContainer.autoresizingMask = [.width, .height]
|
||||
let inspectorView = WKInspectorProbeView(frame: inspectorContainer.bounds)
|
||||
inspectorView.autoresizingMask = [.width, .height]
|
||||
inspectorContainer.addSubview(inspectorView)
|
||||
slot.addSubview(inspectorContainer)
|
||||
contentView.layoutSubtreeIfNeeded()
|
||||
|
||||
XCTAssertTrue(
|
||||
window.makeFirstResponder(inspectorView),
|
||||
"Precondition failed: inspector probe should become first responder"
|
||||
)
|
||||
XCTAssertTrue(window.firstResponder === inspectorView)
|
||||
|
||||
slot.isHidden = true
|
||||
|
||||
XCTAssertFalse(
|
||||
window.firstResponder === inspectorView,
|
||||
"Hiding a browser slot should yield any owned inspector responder before it goes off-screen"
|
||||
)
|
||||
if let firstResponderView = window.firstResponder as? NSView {
|
||||
XCTAssertFalse(
|
||||
firstResponderView === slot || firstResponderView.isDescendant(of: slot),
|
||||
"Hiding a browser slot should not leave first responder inside the hidden slot"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func testHiddenPortalSyncDoesNotStealLocallyHostedDevToolsWebViewDuringResize() {
|
||||
let window = NSWindow(
|
||||
contentRect: NSRect(x: 0, y: 0, width: 520, height: 320),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue