diff --git a/include/ghostty.h b/include/ghostty.h index 42cfc5a42..bf13500c8 100644 --- a/include/ghostty.h +++ b/include/ghostty.h @@ -351,6 +351,8 @@ typedef struct { typedef enum { GHOSTTY_SPLIT_DIRECTION_RIGHT, GHOSTTY_SPLIT_DIRECTION_DOWN, + GHOSTTY_SPLIT_DIRECTION_LEFT, + GHOSTTY_SPLIT_DIRECTION_UP, } ghostty_action_split_direction_e; // apprt.action.GotoSplit diff --git a/macos/Sources/Ghostty/Ghostty.SplitNode.swift b/macos/Sources/Ghostty/Ghostty.SplitNode.swift index e5a86b4ca..361af1e1b 100644 --- a/macos/Sources/Ghostty/Ghostty.SplitNode.swift +++ b/macos/Sources/Ghostty/Ghostty.SplitNode.swift @@ -253,6 +253,15 @@ extension Ghostty { bottomRight.parent = self } + // Move the top left node to the bottom right and vice versa, + // preserving the size. + func swap() { + let topLeft: SplitNode = self.topLeft + self.topLeft = bottomRight + self.bottomRight = topLeft + self.split = 1 - self.split + } + /// Resize the split by moving the split divider in the given /// direction by the given amount. If this container is not split /// in the given direction, navigate up the tree until we find a diff --git a/macos/Sources/Ghostty/Ghostty.TerminalSplit.swift b/macos/Sources/Ghostty/Ghostty.TerminalSplit.swift index fa8335416..6d288b434 100644 --- a/macos/Sources/Ghostty/Ghostty.TerminalSplit.swift +++ b/macos/Sources/Ghostty/Ghostty.TerminalSplit.swift @@ -220,13 +220,21 @@ extension Ghostty { // Determine our desired direction guard let directionAny = notification.userInfo?["direction"] else { return } guard let direction = directionAny as? ghostty_action_split_direction_e else { return } - var splitDirection: SplitViewDirection + let splitDirection: SplitViewDirection + let swap: Bool switch (direction) { case GHOSTTY_SPLIT_DIRECTION_RIGHT: splitDirection = .horizontal - + swap = false + case GHOSTTY_SPLIT_DIRECTION_LEFT: + splitDirection = .horizontal + swap = true case GHOSTTY_SPLIT_DIRECTION_DOWN: splitDirection = .vertical + swap = false + case GHOSTTY_SPLIT_DIRECTION_UP: + splitDirection = .vertical + swap = true default: return @@ -240,6 +248,12 @@ extension Ghostty { // See moveFocus comment, we have to run this whenever split changes. Ghostty.moveFocus(to: container.bottomRight.preferredFocus(), from: node!.preferredFocus()) + + // If we are swapping, swap now. We do this after our focus event + // so that focus is in the right place. + if swap { + container.swap() + } } /// This handles the event to move the split focus (i.e. previous/next) from a keyboard event.