Skip to content

Commit d77ae21

Browse files
committed
fix: restore hosted inspector divider drag path
1 parent 8396885 commit d77ae21

2 files changed

Lines changed: 59 additions & 28 deletions

File tree

Sources/Panels/BrowserPanelView.swift

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5034,10 +5034,12 @@ struct WebViewRepresentable: NSViewRepresentable {
50345034
// Origin-only frame churn is common while the surrounding split layout
50355035
// settles. Reapplying the side-docked inspector at the same size fights
50365036
// WebKit's own dock layout and shows up as visible flicker.
5037-
if !isHostedInspectorSideDockActive() &&
5038-
!isHostedInspectorDividerDragActive &&
5039-
!hasStoredHostedInspectorWidthPreference {
5040-
captureHostedInspectorPreferredWidthFromCurrentLayout(reason: "host.layout.sameSize")
5037+
if !isHostedInspectorDividerDragActive {
5038+
if hasStoredHostedInspectorWidthPreference {
5039+
reapplyHostedInspectorDividerToStoredWidthIfNeeded(reason: "host.layout.sameSize")
5040+
} else if !isHostedInspectorSideDockActive() {
5041+
captureHostedInspectorPreferredWidthFromCurrentLayout(reason: "host.layout.sameSize")
5042+
}
50415043
}
50425044
updateHostedInspectorDockControlAvailabilityIfNeeded(reason: "host.layout.sameSize")
50435045
notifyGeometryChangedIfNeeded()
@@ -5049,7 +5051,9 @@ struct WebViewRepresentable: NSViewRepresentable {
50495051
lastHostedInspectorLayoutBoundsSize = bounds.size
50505052
if isHostedInspectorSideDockActive() {
50515053
layoutHostedInspectorSideDockIfNeeded(reason: "host.layout.sideDock")
5052-
} else if !hasStoredHostedInspectorWidthPreference {
5054+
} else if hasStoredHostedInspectorWidthPreference {
5055+
reapplyHostedInspectorDividerToStoredWidthIfNeeded(reason: "host.layout")
5056+
} else {
50535057
captureHostedInspectorPreferredWidthFromCurrentLayout(reason: "host.layout")
50545058
}
50555059
updateHostedInspectorDockControlAvailabilityIfNeeded(reason: "host.layout")
@@ -5127,26 +5131,24 @@ struct WebViewRepresentable: NSViewRepresentable {
51275131
return nil
51285132
}
51295133
if let hostedInspectorHit {
5130-
let isSideDockHit = isHostedInspectorSideDockHit(hostedInspectorHit)
51315134
if let nativeHit = nativeHostedInspectorHit(at: point, hostedInspectorHit: hostedInspectorHit) {
51325135
#if DEBUG
51335136
debugLogHitTest(stage: "hitTest.hostedInspectorNative", point: point, passThrough: false, hitView: nativeHit)
51345137
#endif
5135-
if !isSideDockHit ||
5136-
(nativeHit !== hostedInspectorHit.inspectorView &&
5137-
!hostedInspectorHit.inspectorView.isDescendant(of: nativeHit)) {
5138+
if nativeHit !== hostedInspectorHit.inspectorView &&
5139+
!hostedInspectorHit.inspectorView.isDescendant(of: nativeHit) {
51385140
return nativeHit
51395141
}
51405142
}
51415143
#if DEBUG
51425144
debugLogHitTest(
5143-
stage: isSideDockHit ? "hitTest.hostedInspectorManual" : "hitTest.hostedInspectorFallback",
5145+
stage: "hitTest.hostedInspectorManual",
51445146
point: point,
51455147
passThrough: false,
5146-
hitView: hostedInspectorHit.inspectorView
5148+
hitView: self
51475149
)
51485150
#endif
5149-
return isSideDockHit ? self : hostedInspectorHit.inspectorView
5151+
return self
51505152
}
51515153
let hit = super.hitTest(point)
51525154
#if DEBUG
@@ -5157,8 +5159,7 @@ struct WebViewRepresentable: NSViewRepresentable {
51575159

51585160
override func mouseDown(with event: NSEvent) {
51595161
let point = convert(event.locationInWindow, from: nil)
5160-
guard let hostedInspectorHit = hostedInspectorDividerHit(at: point),
5161-
isHostedInspectorSideDockHit(hostedInspectorHit) else {
5162+
guard let hostedInspectorHit = hostedInspectorDividerHit(at: point) else {
51625163
super.mouseDown(with: event)
51635164
return
51645165
}
@@ -5255,7 +5256,7 @@ struct WebViewRepresentable: NSViewRepresentable {
52555256
)
52565257
)
52575258
#endif
5258-
layoutHostedInspectorSideDockIfNeeded(reason: "drag.end")
5259+
reapplyHostedInspectorDividerToStoredWidthIfNeeded(reason: "drag.end")
52595260
}
52605261
super.mouseUp(with: event)
52615262
}
@@ -5492,9 +5493,9 @@ struct WebViewRepresentable: NSViewRepresentable {
54925493
guard let self else { return }
54935494
self.hostedInspectorReapplyWorkItem = nil
54945495
_ = self.promoteHostedInspectorSideDockFromCurrentLayoutIfNeeded()
5495-
if self.isHostedInspectorSideDockActive() {
5496+
if self.hasStoredHostedInspectorWidthPreference {
54965497
self.reapplyHostedInspectorDividerToStoredWidthIfNeeded(reason: reason)
5497-
} else if !self.hasStoredHostedInspectorWidthPreference {
5498+
} else {
54985499
self.captureHostedInspectorPreferredWidthFromCurrentLayout(reason: reason)
54995500
}
55005501
}
@@ -5555,7 +5556,6 @@ struct WebViewRepresentable: NSViewRepresentable {
55555556
private func reapplyHostedInspectorDividerToStoredWidthIfNeeded(reason: String) {
55565557
guard !isApplyingHostedInspectorLayout else { return }
55575558
guard let hit = hostedInspectorDividerCandidate() else { return }
5558-
guard isHostedInspectorSideDockHit(hit) else { return }
55595559
guard let preferredWidth = resolvedPreferredHostedInspectorWidth(in: hit.containerView.bounds) else {
55605560
return
55615561
}

cmuxTests/TerminalAndGhosttyTests.swift

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1510,6 +1510,34 @@ final class WindowTerminalHostViewTests: XCTestCase {
15101510

15111511
private final class BonsplitMockSplitDelegate: NSObject, NSSplitViewDelegate {}
15121512

1513+
private func makeHostedTerminalView(frame: NSRect) -> GhosttySurfaceScrollView {
1514+
let surfaceView = GhosttyNSView(frame: frame)
1515+
let hostedView = GhosttySurfaceScrollView(surfaceView: surfaceView)
1516+
hostedView.frame = frame
1517+
hostedView.autoresizingMask = [.width, .height]
1518+
return hostedView
1519+
}
1520+
1521+
private func assertHitFallsInsideHostedTerminal(
1522+
_ hitView: NSView?,
1523+
hostedView: GhosttySurfaceScrollView,
1524+
message: String,
1525+
file: StaticString = #filePath,
1526+
line: UInt = #line
1527+
) {
1528+
guard let hitView else {
1529+
XCTFail(message, file: file, line: line)
1530+
return
1531+
}
1532+
1533+
XCTAssertTrue(
1534+
hitView === hostedView || hitView.isDescendant(of: hostedView),
1535+
message,
1536+
file: file,
1537+
line: line
1538+
)
1539+
}
1540+
15131541
func testHostViewPassesThroughWhenNoTerminalSubviewIsHit() {
15141542
let host = WindowTerminalHostView(frame: NSRect(x: 0, y: 0, width: 200, height: 120))
15151543

@@ -1555,9 +1583,8 @@ final class WindowTerminalHostViewTests: XCTestCase {
15551583

15561584
let host = WindowTerminalHostView(frame: contentView.bounds)
15571585
host.autoresizingMask = [.width, .height]
1558-
let child = CapturingView(frame: host.bounds)
1559-
child.autoresizingMask = [.width, .height]
1560-
host.addSubview(child)
1586+
let hostedView = makeHostedTerminalView(frame: host.bounds)
1587+
host.addSubview(hostedView)
15611588
contentView.addSubview(host)
15621589

15631590
let dividerPointInSplit = NSPoint(
@@ -1575,7 +1602,11 @@ final class WindowTerminalHostViewTests: XCTestCase {
15751602
let contentPointInSplit = NSPoint(x: dividerPointInSplit.x + 40, y: splitView.bounds.midY)
15761603
let contentPointInWindow = splitView.convert(contentPointInSplit, to: nil)
15771604
let contentPointInHost = host.convert(contentPointInWindow, from: nil)
1578-
XCTAssertTrue(host.hitTest(contentPointInHost) === child)
1605+
assertHitFallsInsideHostedTerminal(
1606+
host.hitTest(contentPointInHost),
1607+
hostedView: hostedView,
1608+
message: "Terminal content should keep receiving hits after the divider region"
1609+
)
15791610
}
15801611

15811612
func testHostViewStopsSidebarPassThroughJustInsideTerminalContent() {
@@ -1609,9 +1640,8 @@ final class WindowTerminalHostViewTests: XCTestCase {
16091640

16101641
let host = WindowTerminalHostView(frame: contentView.bounds)
16111642
host.autoresizingMask = [.width, .height]
1612-
let child = CapturingView(frame: host.bounds)
1613-
child.autoresizingMask = [.width, .height]
1614-
host.addSubview(child)
1643+
let hostedView = makeHostedTerminalView(frame: host.bounds)
1644+
host.addSubview(hostedView)
16151645
contentView.addSubview(host)
16161646

16171647
let dividerPointInSplit = NSPoint(
@@ -1634,9 +1664,10 @@ final class WindowTerminalHostViewTests: XCTestCase {
16341664
x: dividerPointInHost.x + terminalSideOverlapWidth + 1,
16351665
y: dividerPointInHost.y
16361666
)
1637-
XCTAssertTrue(
1638-
host.hitTest(textSelectionPoint) === child,
1639-
"Once the pointer moves past the reduced terminal-side overlap, terminal content should win hit-testing"
1667+
assertHitFallsInsideHostedTerminal(
1668+
host.hitTest(textSelectionPoint),
1669+
hostedView: hostedView,
1670+
message: "Once the pointer moves past the reduced terminal-side overlap, terminal content should win hit-testing"
16401671
)
16411672
}
16421673
}

0 commit comments

Comments
 (0)