libghostty als zweite Terminal-Engine integriert (Default ghostty, SwiftTerm Fallback)
- vendor/libghostty: vorgebaute macOS-libghostty.a (arm64) + Header + Build-Patches + README - Sources/CGhostty: C-Modul der libghostty-C-API - Sources/MiniTerm/Ghostty.swift: GhosttyApp + GhosttySurfaceView (Surface, Input, Größe, Fokus) - main.swift: Engine-Wahl per Info.plist MTEngine - Package.swift: CGhostty-Target + Link gegen libghostty + Frameworks - STATUS.md: Stand, Build-Weg (macOS-15-VM), offene Punkte
This commit is contained in:
+39
-10
@@ -20,6 +20,7 @@ struct AppConfig {
|
||||
let fontSize: CGFloat
|
||||
let fontName: String
|
||||
let windowTitle: String
|
||||
let engine: String // "ghostty" (Default) oder "swiftterm"
|
||||
|
||||
static func load() -> AppConfig {
|
||||
let info = Bundle.main.infoDictionary ?? [:]
|
||||
@@ -27,6 +28,9 @@ struct AppConfig {
|
||||
let cmd = ((info["MTCommand"] as? String) ?? "")
|
||||
.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
|
||||
let engine = ((info["MTEngine"] as? String) ?? "ghostty")
|
||||
.trimmingCharacters(in: .whitespacesAndNewlines).lowercased()
|
||||
|
||||
var workdir: String? = nil
|
||||
if let raw = info["MTWorkingDirectory"] as? String,
|
||||
!raw.trimmingCharacters(in: .whitespaces).isEmpty {
|
||||
@@ -46,7 +50,8 @@ struct AppConfig {
|
||||
workingDirectory: workdir,
|
||||
fontSize: CGFloat(size),
|
||||
fontName: fontName.isEmpty ? "Menlo" : fontName,
|
||||
windowTitle: title)
|
||||
windowTitle: title,
|
||||
engine: engine == "swiftterm" ? "swiftterm" : "ghostty")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,30 +60,54 @@ final class AppDelegate: NSObject, NSApplicationDelegate, LocalProcessTerminalVi
|
||||
private var window: NSWindow!
|
||||
private var terminalView: LocalProcessTerminalView!
|
||||
private var keyMonitor: Any?
|
||||
private var ghosttyApp: GhosttyApp?
|
||||
private var ghosttyView: GhosttySurfaceView?
|
||||
private let config = AppConfig.load()
|
||||
|
||||
func applicationDidFinishLaunching(_ notification: Notification) {
|
||||
let frame = NSRect(x: 0, y: 0, width: 900, height: 560)
|
||||
|
||||
terminalView = LocalProcessTerminalView(frame: frame)
|
||||
terminalView.processDelegate = self
|
||||
terminalView.font = resolvedFont()
|
||||
|
||||
installKeyMonitor()
|
||||
|
||||
window = NSWindow(
|
||||
contentRect: frame,
|
||||
styleMask: [.titled, .closable, .miniaturizable, .resizable],
|
||||
backing: .buffered,
|
||||
defer: false)
|
||||
window.title = config.windowTitle
|
||||
window.contentView = terminalView
|
||||
window.setFrameAutosaveName("MiniTermMain")
|
||||
window.center()
|
||||
window.makeKeyAndOrderFront(nil)
|
||||
window.makeFirstResponder(terminalView)
|
||||
|
||||
// Engine wählen. libghostty (GPU-Renderer) ist Default; SwiftTerm bleibt
|
||||
// als Fallback (auch wenn die libghostty-Init scheitert).
|
||||
if config.engine == "ghostty", let contentView = setupGhostty(frame: frame) {
|
||||
window.contentView = contentView
|
||||
window.makeKeyAndOrderFront(nil)
|
||||
window.makeFirstResponder(contentView)
|
||||
} else {
|
||||
setupSwiftTerm(frame: frame)
|
||||
}
|
||||
|
||||
setupMenu()
|
||||
}
|
||||
|
||||
private func setupGhostty(frame: NSRect) -> NSView? {
|
||||
guard let gapp = GhosttyApp() else {
|
||||
NSLog("libghostty-Init fehlgeschlagen – Fallback auf SwiftTerm")
|
||||
return nil
|
||||
}
|
||||
ghosttyApp = gapp
|
||||
let view = GhosttySurfaceView(ghostty: gapp, appConfig: config, frame: frame)
|
||||
ghosttyView = view
|
||||
return view
|
||||
}
|
||||
|
||||
private func setupSwiftTerm(frame: NSRect) {
|
||||
terminalView = LocalProcessTerminalView(frame: frame)
|
||||
terminalView.processDelegate = self
|
||||
terminalView.font = resolvedFont()
|
||||
installKeyMonitor()
|
||||
window.contentView = terminalView
|
||||
window.makeKeyAndOrderFront(nil)
|
||||
window.makeFirstResponder(terminalView)
|
||||
launchProcess()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user