- Add TerminalSurface class to own ghostty_surface_t lifecycle per tab - Use ZStack to keep all terminal views alive instead of recreating on switch - Add NSTextInputClient conformance to properly handle interpretKeyEvents - Add ghostty_surface_set_focus calls for proper focus management - Add doCommand(by:) override to silence unhandled key command beeps
75 lines
2.1 KiB
Swift
75 lines
2.1 KiB
Swift
import SwiftUI
|
|
import Foundation
|
|
|
|
class Tab: Identifiable, ObservableObject {
|
|
let id = UUID()
|
|
@Published var title: String
|
|
@Published var currentDirectory: String
|
|
let terminalSurface: TerminalSurface
|
|
|
|
init(title: String = "Terminal") {
|
|
self.title = title
|
|
self.currentDirectory = FileManager.default.homeDirectoryForCurrentUser.path
|
|
self.terminalSurface = TerminalSurface()
|
|
}
|
|
}
|
|
|
|
class TabManager: ObservableObject {
|
|
@Published var tabs: [Tab] = []
|
|
@Published var selectedTabId: UUID?
|
|
|
|
init() {
|
|
addTab()
|
|
}
|
|
|
|
func addTab() {
|
|
let newTab = Tab(title: "Terminal \(tabs.count + 1)")
|
|
tabs.append(newTab)
|
|
selectedTabId = newTab.id
|
|
}
|
|
|
|
func closeTab(_ tab: Tab) {
|
|
guard tabs.count > 1 else { return }
|
|
|
|
if let index = tabs.firstIndex(where: { $0.id == tab.id }) {
|
|
tabs.remove(at: index)
|
|
|
|
if selectedTabId == tab.id {
|
|
if index > 0 {
|
|
selectedTabId = tabs[index - 1].id
|
|
} else {
|
|
selectedTabId = tabs.first?.id
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func closeCurrentTab() {
|
|
guard let selectedId = selectedTabId,
|
|
let tab = tabs.first(where: { $0.id == selectedId }) else { return }
|
|
closeTab(tab)
|
|
}
|
|
|
|
func selectTab(_ tab: Tab) {
|
|
selectedTabId = tab.id
|
|
}
|
|
|
|
func selectNextTab() {
|
|
guard let currentId = selectedTabId,
|
|
let currentIndex = tabs.firstIndex(where: { $0.id == currentId }) else { return }
|
|
let nextIndex = (currentIndex + 1) % tabs.count
|
|
selectedTabId = tabs[nextIndex].id
|
|
}
|
|
|
|
func selectPreviousTab() {
|
|
guard let currentId = selectedTabId,
|
|
let currentIndex = tabs.firstIndex(where: { $0.id == currentId }) else { return }
|
|
let prevIndex = (currentIndex - 1 + tabs.count) % tabs.count
|
|
selectedTabId = tabs[prevIndex].id
|
|
}
|
|
|
|
func selectTab(at index: Int) {
|
|
guard index >= 0 && index < tabs.count else { return }
|
|
selectedTabId = tabs[index].id
|
|
}
|
|
}
|