diff --git a/include/ghostty.h b/include/ghostty.h index 9a627e11d..bcaba1eac 100644 --- a/include/ghostty.h +++ b/include/ghostty.h @@ -252,7 +252,7 @@ typedef const ghostty_config_t (*ghostty_runtime_reload_config_cb)(void *); typedef void (*ghostty_runtime_set_title_cb)(void *, const char *); typedef const char* (*ghostty_runtime_read_clipboard_cb)(void *, ghostty_clipboard_e); typedef void (*ghostty_runtime_write_clipboard_cb)(void *, const char *, ghostty_clipboard_e); -typedef void (*ghostty_runtime_new_split_cb)(void *, ghostty_split_direction_e); +typedef void (*ghostty_runtime_new_split_cb)(void *, ghostty_split_direction_e, ghostty_surface_config_s); typedef void (*ghostty_runtime_new_tab_cb)(void *, ghostty_surface_config_s); typedef void (*ghostty_runtime_new_window_cb)(void *, ghostty_surface_config_s); typedef void (*ghostty_runtime_close_surface_cb)(void *, bool); diff --git a/macos/Sources/Features/Primary Window/PrimaryWindowManager.swift b/macos/Sources/Features/Primary Window/PrimaryWindowManager.swift index 4280877c0..343a77918 100644 --- a/macos/Sources/Features/Primary Window/PrimaryWindowManager.swift +++ b/macos/Sources/Features/Primary Window/PrimaryWindowManager.swift @@ -105,7 +105,7 @@ class PrimaryWindowManager { } @objc private func onNewWindow(notification: SwiftUI.Notification) { - let configAny = notification.userInfo?[Ghostty.Notification.NewWindowKey] + let configAny = notification.userInfo?[Ghostty.Notification.NewSurfaceConfigKey] let config = configAny as? ghostty_surface_config_s self.addNewWindow(withBaseConfig: config) @@ -130,7 +130,7 @@ class PrimaryWindowManager { guard let surfaceView = notification.object as? Ghostty.SurfaceView else { return } guard let window = surfaceView.window else { return } - let configAny = notification.userInfo?[Ghostty.Notification.NewTabKey] + let configAny = notification.userInfo?[Ghostty.Notification.NewSurfaceConfigKey] let config = configAny as? ghostty_surface_config_s self.addNewTab(to: window, withBaseConfig: config) diff --git a/macos/Sources/Ghostty/AppState.swift b/macos/Sources/Ghostty/AppState.swift index 51ff9db0a..7643b7d0d 100644 --- a/macos/Sources/Ghostty/AppState.swift +++ b/macos/Sources/Ghostty/AppState.swift @@ -60,7 +60,7 @@ extension Ghostty { set_title_cb: { userdata, title in AppState.setTitle(userdata, title: title) }, read_clipboard_cb: { userdata, loc in AppState.readClipboard(userdata, location: loc) }, write_clipboard_cb: { userdata, str, loc in AppState.writeClipboard(userdata, string: str, location: loc) }, - new_split_cb: { userdata, direction in AppState.newSplit(userdata, direction: direction) }, + new_split_cb: { userdata, direction, surfaceConfig in AppState.newSplit(userdata, direction: direction, config: surfaceConfig) }, new_tab_cb: { userdata, surfaceConfig in AppState.newTab(userdata, config: surfaceConfig) }, new_window_cb: { userdata, surfaceConfig in AppState.newWindow(userdata, config: surfaceConfig) }, close_surface_cb: { userdata, processAlive in AppState.closeSurface(userdata, processAlive: processAlive) }, @@ -164,10 +164,11 @@ extension Ghostty { // MARK: Ghostty Callbacks - static func newSplit(_ userdata: UnsafeMutableRawPointer?, direction: ghostty_split_direction_e) { + static func newSplit(_ userdata: UnsafeMutableRawPointer?, direction: ghostty_split_direction_e, config: ghostty_surface_config_s) { guard let surface = self.surfaceUserdata(from: userdata) else { return } NotificationCenter.default.post(name: Notification.ghosttyNewSplit, object: surface, userInfo: [ "direction": direction, + Notification.NewSurfaceConfigKey: config, ]) } @@ -275,7 +276,7 @@ extension Ghostty { name: Notification.ghosttyNewTab, object: surface, userInfo: [ - Notification.NewTabKey: config + Notification.NewSurfaceConfigKey: config ] ) } @@ -287,7 +288,7 @@ extension Ghostty { name: Notification.ghosttyNewWindow, object: surface, userInfo: [ - Notification.NewWindowKey: config + Notification.NewSurfaceConfigKey: config ] ) } diff --git a/macos/Sources/Ghostty/Ghostty.SplitView.swift b/macos/Sources/Ghostty/Ghostty.SplitView.swift index a3e224139..553ede47f 100644 --- a/macos/Sources/Ghostty/Ghostty.SplitView.swift +++ b/macos/Sources/Ghostty/Ghostty.SplitView.swift @@ -82,13 +82,13 @@ extension Ghostty { /// A container is always initialized from some prior leaf because a split has to originate /// from a non-split value. When initializing, we inherit the leaf's surface and then /// initialize a new surface for the new pane. - init(from: Leaf) { + init(from: Leaf, baseConfig: ghostty_surface_config_s? = nil) { self.app = from.app // Initially, both topLeft and bottomRight are in the "nosplit" // state since this is a new split. self.topLeft = .noSplit(from) - self.bottomRight = .noSplit(.init(app, nil)) + self.bottomRight = .noSplit(.init(app, baseConfig)) } } @@ -254,6 +254,9 @@ extension Ghostty { } private func onNewSplit(notification: SwiftUI.Notification) { + let configAny = notification.userInfo?[Ghostty.Notification.NewSurfaceConfigKey] + let config = configAny as? ghostty_surface_config_s + // Determine our desired direction guard let directionAny = notification.userInfo?["direction"] else { return } guard let direction = directionAny as? ghostty_split_direction_e else { return } @@ -270,7 +273,7 @@ extension Ghostty { } // Setup our new container since we are now split - let container = SplitNode.Container(from: leaf) + let container = SplitNode.Container(from: leaf, baseConfig: config) // Depending on the direction, change the parent node. This will trigger // the parent to relayout our views. diff --git a/macos/Sources/Ghostty/Package.swift b/macos/Sources/Ghostty/Package.swift index b0ca3d560..7a09fd872 100644 --- a/macos/Sources/Ghostty/Package.swift +++ b/macos/Sources/Ghostty/Package.swift @@ -64,6 +64,9 @@ extension Ghostty { } extension Ghostty.Notification { + /// Used to pass a configuration along when creating a new tab/window/split. + static let NewSurfaceConfigKey = "com.mitchellh.ghostty.newSurfaceConfig" + /// Posted when a new split is requested. The sending object will be the surface that had focus. The /// userdata has one key "direction" with the direction to split to. static let ghosttyNewSplit = Notification.Name("com.mitchellh.ghostty.newSplit") @@ -81,11 +84,9 @@ extension Ghostty.Notification { /// New tab. Has base surface config requested in userinfo. static let ghosttyNewTab = Notification.Name("com.mitchellh.ghostty.newTab") - static let NewTabKey = ghosttyNewTab.rawValue /// New window. Has base surface config requested in userinfo. static let ghosttyNewWindow = Notification.Name("com.mitchellh.ghostty.newWindow") - static let NewWindowKey = ghosttyNewWindow.rawValue /// Toggle fullscreen of current window static let ghosttyToggleFullscreen = Notification.Name("com.mitchellh.ghostty.toggleFullscreen") diff --git a/src/apprt/embedded.zig b/src/apprt/embedded.zig index adae5b09c..fc1a22ed2 100644 --- a/src/apprt/embedded.zig +++ b/src/apprt/embedded.zig @@ -57,7 +57,7 @@ pub const App = struct { /// Create a new split view. If the embedder doesn't support split /// views then this can be null. - new_split: ?*const fn (SurfaceUD, input.SplitDirection) callconv(.C) void = null, + new_split: ?*const fn (SurfaceUD, input.SplitDirection, apprt.Surface.Options) callconv(.C) void = null, /// New tab with options. new_tab: ?*const fn (SurfaceUD, apprt.Surface.Options) callconv(.C) void = null, @@ -236,7 +236,8 @@ pub const Surface = struct { return; }; - func(self.opts.userdata, direction); + const options = self.newSurfaceOptions(); + func(self.opts.userdata, direction, options); } pub fn close(self: *const Surface, process_alive: bool) void {