mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
macos: terminal surface view
This commit is contained in:
@ -7,6 +7,7 @@
|
|||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
A507573E299FF33C009D7DC7 /* TerminalSurfaceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A507573D299FF33C009D7DC7 /* TerminalSurfaceView.swift */; };
|
||||||
A535B9DA299C569B0017E2E4 /* ErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A535B9D9299C569B0017E2E4 /* ErrorView.swift */; };
|
A535B9DA299C569B0017E2E4 /* ErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A535B9D9299C569B0017E2E4 /* ErrorView.swift */; };
|
||||||
A5B30535299BEAAA0047F10C /* GhosttyApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5B30534299BEAAA0047F10C /* GhosttyApp.swift */; };
|
A5B30535299BEAAA0047F10C /* GhosttyApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5B30534299BEAAA0047F10C /* GhosttyApp.swift */; };
|
||||||
A5B30537299BEAAA0047F10C /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5B30536299BEAAA0047F10C /* ContentView.swift */; };
|
A5B30537299BEAAA0047F10C /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5B30536299BEAAA0047F10C /* ContentView.swift */; };
|
||||||
@ -15,6 +16,7 @@
|
|||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
A507573D299FF33C009D7DC7 /* TerminalSurfaceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TerminalSurfaceView.swift; sourceTree = "<group>"; };
|
||||||
A535B9D9299C569B0017E2E4 /* ErrorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorView.swift; sourceTree = "<group>"; };
|
A535B9D9299C569B0017E2E4 /* ErrorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorView.swift; sourceTree = "<group>"; };
|
||||||
A5B30531299BEAAA0047F10C /* Ghostty.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Ghostty.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
A5B30531299BEAAA0047F10C /* Ghostty.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Ghostty.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
A5B30534299BEAAA0047F10C /* GhosttyApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GhosttyApp.swift; sourceTree = "<group>"; };
|
A5B30534299BEAAA0047F10C /* GhosttyApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GhosttyApp.swift; sourceTree = "<group>"; };
|
||||||
@ -43,6 +45,7 @@
|
|||||||
A5B30534299BEAAA0047F10C /* GhosttyApp.swift */,
|
A5B30534299BEAAA0047F10C /* GhosttyApp.swift */,
|
||||||
A5B30536299BEAAA0047F10C /* ContentView.swift */,
|
A5B30536299BEAAA0047F10C /* ContentView.swift */,
|
||||||
A535B9D9299C569B0017E2E4 /* ErrorView.swift */,
|
A535B9D9299C569B0017E2E4 /* ErrorView.swift */,
|
||||||
|
A507573D299FF33C009D7DC7 /* TerminalSurfaceView.swift */,
|
||||||
);
|
);
|
||||||
path = Sources;
|
path = Sources;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -150,6 +153,7 @@
|
|||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
A507573E299FF33C009D7DC7 /* TerminalSurfaceView.swift in Sources */,
|
||||||
A5B30537299BEAAA0047F10C /* ContentView.swift in Sources */,
|
A5B30537299BEAAA0047F10C /* ContentView.swift in Sources */,
|
||||||
A535B9DA299C569B0017E2E4 /* ErrorView.swift in Sources */,
|
A535B9DA299C569B0017E2E4 /* ErrorView.swift in Sources */,
|
||||||
A5B30535299BEAAA0047F10C /* GhosttyApp.swift in Sources */,
|
A5B30535299BEAAA0047F10C /* GhosttyApp.swift in Sources */,
|
||||||
|
@ -20,7 +20,7 @@ struct GhosttyApp: App {
|
|||||||
case .error:
|
case .error:
|
||||||
ErrorView()
|
ErrorView()
|
||||||
case .ready:
|
case .ready:
|
||||||
ContentView()
|
TerminalSurfaceView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
59
macos/Sources/TerminalSurfaceView.swift
Normal file
59
macos/Sources/TerminalSurfaceView.swift
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
/// A surface is terminology in Ghostty for a terminal surface, or a place where a terminal is actually drawn
|
||||||
|
/// and interacted with. The word "surface" is used because a surface may represent a window, a tab,
|
||||||
|
/// a split, a small preview pane, etc. It is ANYTHING that has a terminal drawn to it.
|
||||||
|
///
|
||||||
|
/// We just wrap an AppKit NSView here at the moment so that we can behave as low level as possible
|
||||||
|
/// since that is what the Metal renderer in Ghostty expects. In the future, it may make more sense to
|
||||||
|
/// wrap an MTKView and use that, but for legacy reasons we didn't do that to begin with.
|
||||||
|
struct TerminalSurfaceView: NSViewRepresentable {
|
||||||
|
@StateObject private var state = TerminalSurfaceState()
|
||||||
|
|
||||||
|
func makeNSView(context: Context) -> TerminalSurfaceView_Real {
|
||||||
|
// We need the view as part of the state to be created previously because
|
||||||
|
// the view is sent to the Ghostty API so that it can manipulate it
|
||||||
|
// directly since we draw on a render thread.
|
||||||
|
return state.view;
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateNSView(_ view: TerminalSurfaceView_Real, context: Context) {
|
||||||
|
// Nothing we need to do here.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The state for the terminal surface view.
|
||||||
|
class TerminalSurfaceState: ObservableObject {
|
||||||
|
var view: TerminalSurfaceView_Real;
|
||||||
|
|
||||||
|
init() {
|
||||||
|
view = TerminalSurfaceView_Real()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The actual NSView implementation for the terminal surface.
|
||||||
|
class TerminalSurfaceView_Real: NSView {
|
||||||
|
// We need to support being a first responder so that we can get input events
|
||||||
|
override var acceptsFirstResponder: Bool { return true }
|
||||||
|
|
||||||
|
override func draw(_ dirtyRect: NSRect) {
|
||||||
|
print("DRAW: \(dirtyRect)")
|
||||||
|
NSColor.green.setFill()
|
||||||
|
dirtyRect.fill()
|
||||||
|
super.draw(dirtyRect)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func mouseDown(with event: NSEvent) {
|
||||||
|
print("Mouse down: \(event)")
|
||||||
|
}
|
||||||
|
|
||||||
|
override func keyDown(with event: NSEvent) {
|
||||||
|
print("Key down: \(event)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TerminalSurfaceView_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
TerminalSurfaceView()
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user