macos: use SurfaceConfiguration everywhere instead of bare c struct

This commit is contained in:
Mitchell Hashimoto
2023-10-03 22:00:56 -07:00
parent 140afb395f
commit d5299fec25
6 changed files with 56 additions and 23 deletions

View File

@ -12,7 +12,7 @@ struct PrimaryView: View {
let focusedSurfaceWrapper: FocusedSurfaceWrapper
// If this is set, this is the base configuration that we build our surface out of.
let baseConfig: ghostty_surface_config_s?
let baseConfig: Ghostty.SurfaceConfiguration?
// We need access to our window to know if we're the key window to determine
// if we show the quit confirmation or not.

View File

@ -24,7 +24,7 @@ class PrimaryWindow: NSWindow {
return true
}
static func create(ghostty: Ghostty.AppState, appDelegate: AppDelegate, baseConfig: ghostty_surface_config_s? = nil) -> PrimaryWindow {
static func create(ghostty: Ghostty.AppState, appDelegate: AppDelegate, baseConfig: Ghostty.SurfaceConfiguration? = nil) -> PrimaryWindow {
let window = PrimaryWindow(
contentRect: NSRect(x: 0, y: 0, width: 800, height: 600),
styleMask: getStyleMask(renderDecoration: ghostty.windowDecorations),

View File

@ -94,7 +94,7 @@ class PrimaryWindowManager {
ghostty.newWindow(surface: surface)
}
func addNewWindow(withBaseConfig config: ghostty_surface_config_s? = nil) {
func addNewWindow(withBaseConfig config: Ghostty.SurfaceConfiguration? = nil) {
guard let controller = createWindowController(withBaseConfig: config) else { return }
controller.showWindow(self)
guard let newWindow = addManagedWindow(windowController: controller)?.window else { return }
@ -103,7 +103,7 @@ class PrimaryWindowManager {
@objc private func onNewWindow(notification: SwiftUI.Notification) {
let configAny = notification.userInfo?[Ghostty.Notification.NewSurfaceConfigKey]
let config = configAny as? ghostty_surface_config_s
let config = configAny as? Ghostty.SurfaceConfiguration
self.addNewWindow(withBaseConfig: config)
}
@ -128,19 +128,19 @@ class PrimaryWindowManager {
guard let window = surfaceView.window else { return }
let configAny = notification.userInfo?[Ghostty.Notification.NewSurfaceConfigKey]
let config = configAny as? ghostty_surface_config_s
let config = configAny as? Ghostty.SurfaceConfiguration
self.addNewTab(to: window, withBaseConfig: config)
}
private func addNewTab(to window: NSWindow, withBaseConfig config: ghostty_surface_config_s? = nil) {
private func addNewTab(to window: NSWindow, withBaseConfig config: Ghostty.SurfaceConfiguration? = nil) {
guard let controller = createWindowController(withBaseConfig: config, cascade: false) else { return }
guard let newWindow = addManagedWindow(windowController: controller)?.window else { return }
window.addTabbedWindow(newWindow, ordered: .above)
newWindow.makeKeyAndOrderFront(nil)
}
private func createWindowController(withBaseConfig config: ghostty_surface_config_s? = nil, cascade: Bool = true) -> PrimaryWindowController? {
private func createWindowController(withBaseConfig config: Ghostty.SurfaceConfiguration? = nil, cascade: Bool = true) -> PrimaryWindowController? {
guard let appDelegate = NSApplication.shared.delegate as? AppDelegate else { return nil }
let window = PrimaryWindow.create(ghostty: ghostty, appDelegate: appDelegate, baseConfig: config)

View File

@ -282,7 +282,7 @@ extension Ghostty {
guard let surface = self.surfaceUserdata(from: userdata) else { return }
NotificationCenter.default.post(name: Notification.ghosttyNewSplit, object: surface, userInfo: [
"direction": direction,
Notification.NewSurfaceConfigKey: config,
Notification.NewSurfaceConfigKey: SurfaceConfiguration(from: config),
])
}
@ -434,12 +434,12 @@ extension Ghostty {
_ = alert.runModal()
return
}
NotificationCenter.default.post(
name: Notification.ghosttyNewTab,
object: surface,
userInfo: [
Notification.NewSurfaceConfigKey: config
Notification.NewSurfaceConfigKey: SurfaceConfiguration(from: config),
]
)
}
@ -451,7 +451,7 @@ extension Ghostty {
name: Notification.ghosttyNewWindow,
object: surface,
userInfo: [
Notification.NewSurfaceConfigKey: config
Notification.NewSurfaceConfigKey: SurfaceConfiguration(from: config),
]
)
}

View File

@ -7,7 +7,7 @@ extension Ghostty {
/// split direction by splitting the terminal.
struct TerminalSplit: View {
let onClose: (() -> Void)?
let baseConfig: ghostty_surface_config_s?
let baseConfig: SurfaceConfiguration?
@Environment(\.ghosttyApp) private var app
@ -118,7 +118,7 @@ extension Ghostty {
@Published var surface: SurfaceView
/// Initialize a new leaf which creates a new terminal surface.
init(_ app: ghostty_app_t, _ baseConfig: ghostty_surface_config_s?) {
init(_ app: ghostty_app_t, _ baseConfig: SurfaceConfiguration?) {
self.app = app
self.surface = SurfaceView(app, baseConfig)
}
@ -132,7 +132,7 @@ 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, baseConfig: ghostty_surface_config_s? = nil) {
init(from: Leaf, baseConfig: SurfaceConfiguration? = nil) {
self.app = from.app
// Initially, both topLeft and bottomRight are in the "nosplit"
@ -197,7 +197,7 @@ extension Ghostty {
@State private var node: SplitNode
@State private var requestClose: Bool = false
let onClose: (() -> Void)?
let baseConfig: ghostty_surface_config_s?
let baseConfig: SurfaceConfiguration?
/// Keeps track of whether we're in a zoomed split state or not. If one of the splits we own
/// is in the zoomed state, we clear our body since we expect a zoomed split to overlay
@ -209,7 +209,7 @@ extension Ghostty {
init(app: ghostty_app_t,
zoomedSurface: Binding<SurfaceView?>,
onClose: (() ->Void)? = nil,
baseConfig: ghostty_surface_config_s? = nil) {
baseConfig: SurfaceConfiguration? = nil) {
self.onClose = onClose
self.baseConfig = baseConfig
self._zoomedSurface = zoomedSurface
@ -395,7 +395,7 @@ extension Ghostty {
private func onNewSplit(notification: SwiftUI.Notification) {
let configAny = notification.userInfo?[Ghostty.Notification.NewSurfaceConfigKey]
let config = configAny as? ghostty_surface_config_s
let config = configAny as? SurfaceConfiguration
// Determine our desired direction
guard let directionAny = notification.userInfo?["direction"] else { return }

View File

@ -184,6 +184,41 @@ extension Ghostty {
view.sizeDidChange(size)
}
}
/// The configuration for a surface. For any configuration not set, defaults will be chosen from
/// libghostty, usually from the Ghostty configuration.
struct SurfaceConfiguration {
/// Explicit font size to use in points
var fontSize: UInt16? = nil
/// Explicit working directory to set
var workingDirectory: String? = nil
init() {}
init(from config: ghostty_surface_config_s) {
self.fontSize = config.font_size
self.workingDirectory = String.init(cString: config.working_directory, encoding: .utf8)
let blah = workingDirectory!
AppDelegate.logger.warning("OPEN from=\(blah)")
}
/// Returns the ghostty configuration for this surface configuration struct. The memory
/// in the returned struct is only valid as long as this struct is retained.
func ghosttyConfig(view: SurfaceView) -> ghostty_surface_config_s {
var config = ghostty_surface_config_new()
config.userdata = Unmanaged.passUnretained(view).toOpaque()
config.nsview = Unmanaged.passUnretained(view).toOpaque()
config.scale_factor = NSScreen.main!.backingScaleFactor
if let fontSize = fontSize { config.font_size = fontSize }
if let workingDirectory = workingDirectory {
config.working_directory = (workingDirectory as NSString).utf8String
}
return config
}
}
/// The NSView implementation for a terminal surface.
class SurfaceView: NSView, NSTextInputClient, ObservableObject {
@ -221,7 +256,7 @@ extension Ghostty {
case pendingHidden
}
init(_ app: ghostty_app_t, _ baseConfig: ghostty_surface_config_s?) {
init(_ app: ghostty_app_t, _ baseConfig: SurfaceConfiguration?) {
self.markedText = NSMutableAttributedString()
// Initialize with some default frame size. The important thing is that this
@ -230,12 +265,10 @@ extension Ghostty {
super.init(frame: NSMakeRect(0, 0, 800, 600))
// Setup our surface. This will also initialize all the terminal IO.
var surface_cfg = baseConfig ?? ghostty_surface_config_new()
surface_cfg.userdata = Unmanaged.passUnretained(self).toOpaque()
surface_cfg.nsview = Unmanaged.passUnretained(self).toOpaque()
surface_cfg.scale_factor = NSScreen.main!.backingScaleFactor
var surface_cfg = baseConfig ?? SurfaceConfiguration()
var surface_cfg_c = surface_cfg.ghosttyConfig(view: self)
guard let surface = ghostty_surface_new(app, &surface_cfg) else {
guard let surface = ghostty_surface_new(app, &surface_cfg_c) else {
self.error = AppError.surfaceCreateError
return
}