macOS: equalize splits when double tapping on SplitView divider (#9524)
Resolves Issue #8357 ### Implementation Following the existing `onResize` callback pattern in `TerminalSplitTreeView`, I added an `onEqualize` callback to `SplitView`. When a divider is double-tapped, the callback retrieves a surface from that `TerminalView`'s `SplitTree` and calls `splitEqualize` to equalize the entire tree. ### Context There is an existing PR #8364 that implements this feature but uses `focusedSurface`, which doesn't work for unfocused windows. Since that PR has been inactive for a few months after requested changes, I've implemented this alternative approach. Credit to @liby for that initial implementation! ### AI Usage I chatted with Claude Code in Plan mode to understand the relationship between surfaces and the split tree/split views, but I wrote all the code myself. ### Screenshot https://github.com/user-attachments/assets/0efd70ef-c90e-4b50-b853-b05e2ca2be67pull/9528/head
commit
84082c2b96
|
|
@ -21,6 +21,9 @@ struct SplitView<L: View, R: View>: View {
|
||||||
let left: L
|
let left: L
|
||||||
let right: R
|
let right: R
|
||||||
|
|
||||||
|
/// Called when the divider is double-tapped to equalize splits.
|
||||||
|
let onEqualize: () -> Void
|
||||||
|
|
||||||
/// The minimum size (in points) of a split
|
/// The minimum size (in points) of a split
|
||||||
let minSize: CGFloat = 10
|
let minSize: CGFloat = 10
|
||||||
|
|
||||||
|
|
@ -56,6 +59,9 @@ struct SplitView<L: View, R: View>: View {
|
||||||
split: $split)
|
split: $split)
|
||||||
.position(splitterPoint)
|
.position(splitterPoint)
|
||||||
.gesture(dragGesture(geo.size, splitterPoint: splitterPoint))
|
.gesture(dragGesture(geo.size, splitterPoint: splitterPoint))
|
||||||
|
.onTapGesture(count: 2) {
|
||||||
|
onEqualize()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.accessibilityElement(children: .contain)
|
.accessibilityElement(children: .contain)
|
||||||
.accessibilityLabel(splitViewLabel)
|
.accessibilityLabel(splitViewLabel)
|
||||||
|
|
@ -69,7 +75,8 @@ struct SplitView<L: View, R: View>: View {
|
||||||
dividerColor: Color,
|
dividerColor: Color,
|
||||||
resizeIncrements: NSSize = .init(width: 1, height: 1),
|
resizeIncrements: NSSize = .init(width: 1, height: 1),
|
||||||
@ViewBuilder left: (() -> L),
|
@ViewBuilder left: (() -> L),
|
||||||
@ViewBuilder right: (() -> R)
|
@ViewBuilder right: (() -> R),
|
||||||
|
onEqualize: @escaping () -> Void
|
||||||
) {
|
) {
|
||||||
self.direction = direction
|
self.direction = direction
|
||||||
self._split = split
|
self._split = split
|
||||||
|
|
@ -77,6 +84,7 @@ struct SplitView<L: View, R: View>: View {
|
||||||
self.resizeIncrements = resizeIncrements
|
self.resizeIncrements = resizeIncrements
|
||||||
self.left = left()
|
self.left = left()
|
||||||
self.right = right()
|
self.right = right()
|
||||||
|
self.onEqualize = onEqualize
|
||||||
}
|
}
|
||||||
|
|
||||||
private func dragGesture(_ size: CGSize, splitterPoint: CGPoint) -> some Gesture {
|
private func dragGesture(_ size: CGSize, splitterPoint: CGPoint) -> some Gesture {
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,10 @@ struct TerminalSplitSubtreeView: View {
|
||||||
},
|
},
|
||||||
right: {
|
right: {
|
||||||
TerminalSplitSubtreeView(node: split.right, onResize: onResize)
|
TerminalSplitSubtreeView(node: split.right, onResize: onResize)
|
||||||
|
},
|
||||||
|
onEqualize: {
|
||||||
|
guard let surface = node.leftmostLeaf().surface else { return }
|
||||||
|
ghostty.splitEqualize(surface: surface)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,9 @@ extension Ghostty {
|
||||||
InspectorViewRepresentable(surfaceView: surfaceView)
|
InspectorViewRepresentable(surfaceView: surfaceView)
|
||||||
.focused($inspectorFocus)
|
.focused($inspectorFocus)
|
||||||
.focusedValue(\.ghosttySurfaceView, surfaceView)
|
.focusedValue(\.ghosttySurfaceView, surfaceView)
|
||||||
|
}, onEqualize: {
|
||||||
|
guard let surface = surfaceView.surface else { return }
|
||||||
|
ghostty.splitEqualize(surface: surface)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue