mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
Merge pull request #1285 from rytswd/wrap-around-split-focus
[WIP] Wrap around split focus
This commit is contained in:
@ -64,6 +64,25 @@ extension Ghostty {
|
||||
return node.preferredFocus(direction)
|
||||
}
|
||||
|
||||
/// When direction is either next or previous, return the first or last
|
||||
/// leaf. This can be used when the focus needs to move to a leaf even
|
||||
/// after hitting the bottom-right-most or top-left-most surface.
|
||||
/// When the direction is not next or previous (such as top, bottom,
|
||||
/// left, right), it will be ignored and no leaf will be returned.
|
||||
func firstOrLast(_ direction: SplitFocusDirection) -> Leaf? {
|
||||
// If there is no parent, simply ignore.
|
||||
guard let root = self.parent?.rootContainer() else { return nil }
|
||||
|
||||
switch (direction) {
|
||||
case .next:
|
||||
return root.firstLeaf()
|
||||
case .previous:
|
||||
return root.lastLeaf()
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
/// Close the surface associated with this node. This will likely deinitialize the
|
||||
/// surface. At this point, the surface view in this node tree can never be used again.
|
||||
func close() {
|
||||
@ -264,6 +283,37 @@ extension Ghostty {
|
||||
return weight
|
||||
}
|
||||
|
||||
/// Returns the top most parent, or this container. Because this
|
||||
/// would fall back to use to self, the return value is guaranteed.
|
||||
func rootContainer() -> Container {
|
||||
guard let parent = self.parent else { return self }
|
||||
return parent.rootContainer()
|
||||
}
|
||||
|
||||
/// Returns the first leaf from the given container. This is most
|
||||
/// useful for root container, so that we can find the top-left-most
|
||||
/// leaf.
|
||||
func firstLeaf() -> Leaf {
|
||||
switch (self.topLeft) {
|
||||
case .leaf(let leaf):
|
||||
return leaf
|
||||
case .split(let s):
|
||||
return s.firstLeaf()
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the last leaf from the given container. This is most
|
||||
/// useful for root container, so that we can find the bottom-right-
|
||||
/// most leaf.
|
||||
func lastLeaf() -> Leaf {
|
||||
switch (self.bottomRight) {
|
||||
case .leaf(let leaf):
|
||||
return leaf
|
||||
case .split(let s):
|
||||
return s.lastLeaf()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Hashable
|
||||
|
||||
func hash(into hasher: inout Hasher) {
|
||||
|
@ -152,7 +152,7 @@ extension Ghostty {
|
||||
/// The neighbors, used for navigation.
|
||||
let neighbors: SplitNode.Neighbors
|
||||
|
||||
/// The SplitNode that the leaf belongs to. This will be set to nil but when leaf is closed.
|
||||
/// The SplitNode that the leaf belongs to. This will be set to nil when leaf is closed.
|
||||
@Binding var node: SplitNode?
|
||||
|
||||
var body: some View {
|
||||
@ -247,9 +247,19 @@ extension Ghostty {
|
||||
// Determine our desired direction
|
||||
guard let directionAny = notification.userInfo?[Notification.SplitDirectionKey] else { return }
|
||||
guard let direction = directionAny as? SplitFocusDirection else { return }
|
||||
guard let next = neighbors.get(direction: direction) else { return }
|
||||
|
||||
// Find the next surface to move to. In most cases this should be
|
||||
// finding the neighbor in provided direction, and focus it. When
|
||||
// the neighbor cannot be found based on next or previous direction,
|
||||
// this would instead search for first or last leaf and focus it
|
||||
// instead, giving the wrap around effect.
|
||||
// When other directions are provided, this can be nil, and early
|
||||
// returned.
|
||||
guard let nextSurface = neighbors.get(direction: direction)?.preferredFocus(direction)
|
||||
?? node?.firstOrLast(direction)?.surface else { return }
|
||||
|
||||
Ghostty.moveFocus(
|
||||
to: next.preferredFocus(direction)
|
||||
to: nextSurface
|
||||
)
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user