macOS: SurfaceView should implement Identifiable
This has no meaningful functionality yet, it was one of the paths I was looking at for #8505 but didn't pursue further. But I still think that this makes more sense in general for the macOS app and will likely be more useful later.pull/8506/head
parent
e6d60dee07
commit
fe3dab9467
|
|
@ -937,7 +937,7 @@ class AppDelegate: NSObject,
|
|||
func findSurface(forUUID uuid: UUID) -> Ghostty.SurfaceView? {
|
||||
for c in TerminalController.all {
|
||||
for view in c.surfaceTree {
|
||||
if view.uuid == uuid {
|
||||
if view.id == uuid {
|
||||
return view
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ struct TerminalEntity: AppEntity {
|
|||
/// Returns the view associated with this entity. This may no longer exist.
|
||||
@MainActor
|
||||
var surfaceView: Ghostty.SurfaceView? {
|
||||
Self.defaultQuery.all.first { $0.uuid == self.id }
|
||||
Self.defaultQuery.all.first { $0.id == self.id }
|
||||
}
|
||||
|
||||
@MainActor
|
||||
|
|
@ -46,7 +46,7 @@ struct TerminalEntity: AppEntity {
|
|||
|
||||
@MainActor
|
||||
init(_ view: Ghostty.SurfaceView) {
|
||||
self.id = view.uuid
|
||||
self.id = view.id
|
||||
self.title = view.title
|
||||
self.workingDirectory = view.pwd
|
||||
if let nsImage = ImageRenderer(content: view.screenshot()).nsImage {
|
||||
|
|
@ -80,7 +80,7 @@ struct TerminalQuery: EntityStringQuery, EnumerableEntityQuery {
|
|||
@MainActor
|
||||
func entities(for identifiers: [TerminalEntity.ID]) async throws -> [TerminalEntity] {
|
||||
return all.filter {
|
||||
identifiers.contains($0.uuid)
|
||||
identifiers.contains($0.id)
|
||||
}.map {
|
||||
TerminalEntity($0)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import AppKit
|
||||
|
||||
/// SplitTree represents a tree of views that can be divided.
|
||||
struct SplitTree<ViewType: NSView & Codable> {
|
||||
struct SplitTree<ViewType: NSView & Codable & Identifiable> {
|
||||
/// The root of the tree. This can be nil to indicate the tree is empty.
|
||||
let root: Node?
|
||||
|
||||
|
|
@ -127,6 +127,13 @@ extension SplitTree {
|
|||
root: try root.insert(view: view, at: at, direction: direction),
|
||||
zoomed: nil)
|
||||
}
|
||||
/// Find a node containing a view with the specified ID.
|
||||
/// - Parameter id: The ID of the view to find
|
||||
/// - Returns: The node containing the view if found, nil otherwise
|
||||
func find(id: ViewType.ID) -> Node? {
|
||||
guard let root else { return nil }
|
||||
return root.find(id: id)
|
||||
}
|
||||
|
||||
/// Remove a node from the tree. If the node being removed is part of a split,
|
||||
/// the sibling node takes the place of the parent split.
|
||||
|
|
@ -396,6 +403,23 @@ extension SplitTree.Node {
|
|||
typealias SplitError = SplitTree.SplitError
|
||||
typealias Path = SplitTree.Path
|
||||
|
||||
/// Find a node containing a view with the specified ID.
|
||||
/// - Parameter id: The ID of the view to find
|
||||
/// - Returns: The node containing the view if found, nil otherwise
|
||||
func find(id: ViewType.ID) -> Node? {
|
||||
switch self {
|
||||
case .leaf(let view):
|
||||
return view.id == id ? self : nil
|
||||
|
||||
case .split(let split):
|
||||
if let found = split.left.find(id: id) {
|
||||
return found
|
||||
}
|
||||
|
||||
return split.right.find(id: id)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the node in the tree that contains the given view.
|
||||
func node(view: ViewType) -> Node? {
|
||||
switch (self) {
|
||||
|
|
|
|||
|
|
@ -860,7 +860,7 @@ class TerminalController: BaseTerminalController, TabGroupCloseCoordinator.Contr
|
|||
|
||||
// Restore focus to the previously focused surface
|
||||
if let focusedUUID = undoState.focusedSurface,
|
||||
let focusTarget = surfaceTree.first(where: { $0.uuid == focusedUUID }) {
|
||||
let focusTarget = surfaceTree.first(where: { $0.id == focusedUUID }) {
|
||||
DispatchQueue.main.async {
|
||||
Ghostty.moveFocus(to: focusTarget, from: nil)
|
||||
}
|
||||
|
|
@ -875,7 +875,7 @@ class TerminalController: BaseTerminalController, TabGroupCloseCoordinator.Contr
|
|||
return .init(
|
||||
frame: window.frame,
|
||||
surfaceTree: surfaceTree,
|
||||
focusedSurface: focusedSurface?.uuid,
|
||||
focusedSurface: focusedSurface?.id,
|
||||
tabIndex: window.tabGroup?.windows.firstIndex(of: window),
|
||||
tabGroup: window.tabGroup)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ class TerminalRestorableState: Codable {
|
|||
let surfaceTree: SplitTree<Ghostty.SurfaceView>
|
||||
|
||||
init(from controller: TerminalController) {
|
||||
self.focusedSurface = controller.focusedSurface?.uuid.uuidString
|
||||
self.focusedSurface = controller.focusedSurface?.id.uuidString
|
||||
self.surfaceTree = controller.surfaceTree
|
||||
}
|
||||
|
||||
|
|
@ -96,7 +96,7 @@ class TerminalWindowRestoration: NSObject, NSWindowRestoration {
|
|||
if let focusedStr = state.focusedSurface {
|
||||
var foundView: Ghostty.SurfaceView?
|
||||
for view in c.surfaceTree {
|
||||
if view.uuid.uuidString == focusedStr {
|
||||
if view.id.uuidString == focusedStr {
|
||||
foundView = view
|
||||
break
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,11 @@ import GhosttyKit
|
|||
|
||||
extension Ghostty {
|
||||
/// The NSView implementation for a terminal surface.
|
||||
class SurfaceView: OSView, ObservableObject, Codable {
|
||||
class SurfaceView: OSView, ObservableObject, Codable, Identifiable {
|
||||
typealias ID = UUID
|
||||
|
||||
/// Unique ID per surface
|
||||
let uuid: UUID
|
||||
let id: UUID
|
||||
|
||||
// The current title of the surface as defined by the pty. This can be
|
||||
// changed with escape codes. This is public because the callbacks go
|
||||
|
|
@ -180,7 +182,7 @@ extension Ghostty {
|
|||
|
||||
init(_ app: ghostty_app_t, baseConfig: SurfaceConfiguration? = nil, uuid: UUID? = nil) {
|
||||
self.markedText = NSMutableAttributedString()
|
||||
self.uuid = uuid ?? .init()
|
||||
self.id = uuid ?? .init()
|
||||
|
||||
// Our initial config always is our application wide config.
|
||||
if let appDelegate = NSApplication.shared.delegate as? AppDelegate {
|
||||
|
|
@ -1468,7 +1470,7 @@ extension Ghostty {
|
|||
content.body = body
|
||||
content.sound = UNNotificationSound.default
|
||||
content.categoryIdentifier = Ghostty.userNotificationCategory
|
||||
content.userInfo = ["surface": self.uuid.uuidString]
|
||||
content.userInfo = ["surface": self.id.uuidString]
|
||||
|
||||
let uuid = UUID().uuidString
|
||||
let request = UNNotificationRequest(
|
||||
|
|
@ -1576,7 +1578,7 @@ extension Ghostty {
|
|||
func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(pwd, forKey: .pwd)
|
||||
try container.encode(uuid.uuidString, forKey: .uuid)
|
||||
try container.encode(id.uuidString, forKey: .uuid)
|
||||
try container.encode(title, forKey: .title)
|
||||
try container.encode(titleFromTerminal != nil, forKey: .isUserSetTitle)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue