mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
macos: wip
This commit is contained in:
@ -27,6 +27,9 @@
|
|||||||
A571AB1D2A206FCF00248498 /* GhosttyKit.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = A5D495A1299BEC7E00DD1313 /* GhosttyKit.xcframework */; };
|
A571AB1D2A206FCF00248498 /* GhosttyKit.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = A5D495A1299BEC7E00DD1313 /* GhosttyKit.xcframework */; };
|
||||||
A59444F729A2ED5200725BBA /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59444F629A2ED5200725BBA /* SettingsView.swift */; };
|
A59444F729A2ED5200725BBA /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59444F629A2ED5200725BBA /* SettingsView.swift */; };
|
||||||
A59630972AEE163600D64628 /* HostingWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59630962AEE163600D64628 /* HostingWindow.swift */; };
|
A59630972AEE163600D64628 /* HostingWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59630962AEE163600D64628 /* HostingWindow.swift */; };
|
||||||
|
A596309A2AEE1C6400D64628 /* Terminal.xib in Resources */ = {isa = PBXBuildFile; fileRef = A59630992AEE1C6400D64628 /* Terminal.xib */; };
|
||||||
|
A596309C2AEE1C9E00D64628 /* TerminalController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A596309B2AEE1C9E00D64628 /* TerminalController.swift */; };
|
||||||
|
A596309E2AEE1D6C00D64628 /* TerminalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A596309D2AEE1D6C00D64628 /* TerminalView.swift */; };
|
||||||
A59FB5CF2AE0DB50009128F3 /* InspectorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59FB5CE2AE0DB50009128F3 /* InspectorView.swift */; };
|
A59FB5CF2AE0DB50009128F3 /* InspectorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59FB5CE2AE0DB50009128F3 /* InspectorView.swift */; };
|
||||||
A59FB5D12AE0DEA7009128F3 /* MetalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59FB5D02AE0DEA7009128F3 /* MetalView.swift */; };
|
A59FB5D12AE0DEA7009128F3 /* MetalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59FB5D02AE0DEA7009128F3 /* MetalView.swift */; };
|
||||||
A5A1F8852A489D6800D1E8BC /* terminfo in Resources */ = {isa = PBXBuildFile; fileRef = A5A1F8842A489D6800D1E8BC /* terminfo */; };
|
A5A1F8852A489D6800D1E8BC /* terminfo in Resources */ = {isa = PBXBuildFile; fileRef = A5A1F8842A489D6800D1E8BC /* terminfo */; };
|
||||||
@ -62,6 +65,9 @@
|
|||||||
A571AB1C2A206FC600248498 /* Ghostty-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = "Ghostty-Info.plist"; sourceTree = "<group>"; };
|
A571AB1C2A206FC600248498 /* Ghostty-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = "Ghostty-Info.plist"; sourceTree = "<group>"; };
|
||||||
A59444F629A2ED5200725BBA /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
|
A59444F629A2ED5200725BBA /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
|
||||||
A59630962AEE163600D64628 /* HostingWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HostingWindow.swift; sourceTree = "<group>"; };
|
A59630962AEE163600D64628 /* HostingWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HostingWindow.swift; sourceTree = "<group>"; };
|
||||||
|
A59630992AEE1C6400D64628 /* Terminal.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = Terminal.xib; sourceTree = "<group>"; };
|
||||||
|
A596309B2AEE1C9E00D64628 /* TerminalController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TerminalController.swift; sourceTree = "<group>"; };
|
||||||
|
A596309D2AEE1D6C00D64628 /* TerminalView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TerminalView.swift; sourceTree = "<group>"; };
|
||||||
A59FB5CE2AE0DB50009128F3 /* InspectorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InspectorView.swift; sourceTree = "<group>"; };
|
A59FB5CE2AE0DB50009128F3 /* InspectorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InspectorView.swift; sourceTree = "<group>"; };
|
||||||
A59FB5D02AE0DEA7009128F3 /* MetalView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MetalView.swift; sourceTree = "<group>"; };
|
A59FB5D02AE0DEA7009128F3 /* MetalView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MetalView.swift; sourceTree = "<group>"; };
|
||||||
A5A1F8842A489D6800D1E8BC /* terminfo */ = {isa = PBXFileReference; lastKnownFileType = folder; name = terminfo; path = "../zig-out/share/terminfo"; sourceTree = "<group>"; };
|
A5A1F8842A489D6800D1E8BC /* terminfo */ = {isa = PBXFileReference; lastKnownFileType = folder; name = terminfo; path = "../zig-out/share/terminfo"; sourceTree = "<group>"; };
|
||||||
@ -97,6 +103,7 @@
|
|||||||
children = (
|
children = (
|
||||||
A56D58872ACDE6BE00508D2C /* Services */,
|
A56D58872ACDE6BE00508D2C /* Services */,
|
||||||
A53426372A7DC53A00EBB7A2 /* Primary Window */,
|
A53426372A7DC53A00EBB7A2 /* Primary Window */,
|
||||||
|
A59630982AEE1C4400D64628 /* Terminal */,
|
||||||
A534263E2A7DCC5800EBB7A2 /* Settings */,
|
A534263E2A7DCC5800EBB7A2 /* Settings */,
|
||||||
);
|
);
|
||||||
path = Features;
|
path = Features;
|
||||||
@ -173,6 +180,16 @@
|
|||||||
path = Services;
|
path = Services;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
A59630982AEE1C4400D64628 /* Terminal */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
A59630992AEE1C6400D64628 /* Terminal.xib */,
|
||||||
|
A596309B2AEE1C9E00D64628 /* TerminalController.swift */,
|
||||||
|
A596309D2AEE1D6C00D64628 /* TerminalView.swift */,
|
||||||
|
);
|
||||||
|
path = Terminal;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
A5A1F8862A489D7400D1E8BC /* Resources */ = {
|
A5A1F8862A489D7400D1E8BC /* Resources */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -280,6 +297,7 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
A545D1A22A5772CE006E0AE4 /* shell-integration in Resources */,
|
A545D1A22A5772CE006E0AE4 /* shell-integration in Resources */,
|
||||||
|
A596309A2AEE1C6400D64628 /* Terminal.xib in Resources */,
|
||||||
A5A1F8852A489D6800D1E8BC /* terminfo in Resources */,
|
A5A1F8852A489D6800D1E8BC /* terminfo in Resources */,
|
||||||
A5CDF1912AAF9A5800513312 /* ConfigurationErrors.xib in Resources */,
|
A5CDF1912AAF9A5800513312 /* ConfigurationErrors.xib in Resources */,
|
||||||
A5B30539299BEAAB0047F10C /* Assets.xcassets in Resources */,
|
A5B30539299BEAAB0047F10C /* Assets.xcassets in Resources */,
|
||||||
@ -295,6 +313,7 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
A59FB5CF2AE0DB50009128F3 /* InspectorView.swift in Sources */,
|
A59FB5CF2AE0DB50009128F3 /* InspectorView.swift in Sources */,
|
||||||
|
A596309C2AEE1C9E00D64628 /* TerminalController.swift in Sources */,
|
||||||
A53426392A7DC55C00EBB7A2 /* PrimaryWindowManager.swift in Sources */,
|
A53426392A7DC55C00EBB7A2 /* PrimaryWindowManager.swift in Sources */,
|
||||||
85DE1C922A6A3DCA00493853 /* PrimaryWindow.swift in Sources */,
|
85DE1C922A6A3DCA00493853 /* PrimaryWindow.swift in Sources */,
|
||||||
A56D58892ACDE6CA00508D2C /* ServiceProvider.swift in Sources */,
|
A56D58892ACDE6CA00508D2C /* ServiceProvider.swift in Sources */,
|
||||||
@ -318,6 +337,7 @@
|
|||||||
85102A1C2A6E32890084AB3E /* PrimaryWindowController.swift in Sources */,
|
85102A1C2A6E32890084AB3E /* PrimaryWindowController.swift in Sources */,
|
||||||
A5CEAFFF29C2410700646FDA /* Backport.swift in Sources */,
|
A5CEAFFF29C2410700646FDA /* Backport.swift in Sources */,
|
||||||
8503D7C72A549C66006CFF3D /* FullScreenHandler.swift in Sources */,
|
8503D7C72A549C66006CFF3D /* FullScreenHandler.swift in Sources */,
|
||||||
|
A596309E2AEE1D6C00D64628 /* TerminalView.swift in Sources */,
|
||||||
A5CEAFDE29B8058B00646FDA /* SplitView.Divider.swift in Sources */,
|
A5CEAFDE29B8058B00646FDA /* SplitView.Divider.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
@ -73,11 +73,15 @@ class AppDelegate: NSObject, ObservableObject, NSApplicationDelegate, GhosttyApp
|
|||||||
|
|
||||||
// Let's launch our first window.
|
// Let's launch our first window.
|
||||||
// TODO: we should detect if we restored windows and if so not launch a new window.
|
// TODO: we should detect if we restored windows and if so not launch a new window.
|
||||||
windowManager.addInitialWindow()
|
// TODO: remove when TerminalController is done
|
||||||
|
// windowManager.addInitialWindow()
|
||||||
|
|
||||||
// Initial config loading
|
// Initial config loading
|
||||||
configDidReload(ghostty)
|
configDidReload(ghostty)
|
||||||
|
|
||||||
|
let c = TerminalController(ghostty)
|
||||||
|
c.showWindow(self)
|
||||||
|
|
||||||
// Register our service provider. This must happen after everything
|
// Register our service provider. This must happen after everything
|
||||||
// else is initialized.
|
// else is initialized.
|
||||||
NSApp.servicesProvider = ServiceProvider()
|
NSApp.servicesProvider = ServiceProvider()
|
||||||
|
31
macos/Sources/Features/Terminal/Terminal.xib
Normal file
31
macos/Sources/Features/Terminal/Terminal.xib
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
|
<dependencies>
|
||||||
|
<deployment identifier="macosx"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
|
</dependencies>
|
||||||
|
<objects>
|
||||||
|
<customObject id="-2" userLabel="File's Owner" customClass="TerminalController" customModule="Ghostty" customModuleProvider="target">
|
||||||
|
<connections>
|
||||||
|
<outlet property="window" destination="QvC-M9-y7g" id="cg9-Ep-qHg"/>
|
||||||
|
</connections>
|
||||||
|
</customObject>
|
||||||
|
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||||
|
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||||
|
<window title="👻 Ghostty" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g">
|
||||||
|
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||||
|
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||||
|
<rect key="contentRect" x="0.0" y="0.0" width="800" height="600"/>
|
||||||
|
<rect key="screenRect" x="0.0" y="0.0" width="3008" height="1667"/>
|
||||||
|
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="800" height="600"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
</view>
|
||||||
|
<connections>
|
||||||
|
<outlet property="delegate" destination="-2" id="tG2-b7-nb8"/>
|
||||||
|
</connections>
|
||||||
|
<point key="canvasLocation" x="132" y="-82"/>
|
||||||
|
</window>
|
||||||
|
</objects>
|
||||||
|
</document>
|
50
macos/Sources/Features/Terminal/TerminalController.swift
Normal file
50
macos/Sources/Features/Terminal/TerminalController.swift
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import Foundation
|
||||||
|
import Cocoa
|
||||||
|
import SwiftUI
|
||||||
|
import Combine
|
||||||
|
|
||||||
|
class TerminalController: NSWindowController, NSWindowDelegate {
|
||||||
|
override var windowNibName: NSNib.Name? { "Terminal" }
|
||||||
|
|
||||||
|
/// The app instance that this terminal view will represent.
|
||||||
|
let ghostty: Ghostty.AppState
|
||||||
|
|
||||||
|
init(_ ghostty: Ghostty.AppState) {
|
||||||
|
self.ghostty = ghostty
|
||||||
|
super.init(window: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) is not supported for this view")
|
||||||
|
}
|
||||||
|
|
||||||
|
//MARK: - NSWindowController
|
||||||
|
|
||||||
|
override func windowWillLoad() {
|
||||||
|
// We want every new terminal window to cascade so they don't directly overlap.
|
||||||
|
shouldCascadeWindows = true
|
||||||
|
}
|
||||||
|
|
||||||
|
override func windowDidLoad() {
|
||||||
|
guard let window = window else { return }
|
||||||
|
|
||||||
|
// Terminals typically operate in sRGB color space and macOS defaults
|
||||||
|
// to "native" which is typically P3. There is a lot more resources
|
||||||
|
// covered in thie GitHub issue: https://github.com/mitchellh/ghostty/pull/376
|
||||||
|
window.colorSpace = NSColorSpace.sRGB
|
||||||
|
|
||||||
|
// Center the window to start, we'll move the window frame automatically
|
||||||
|
// when cascading.
|
||||||
|
window.center()
|
||||||
|
|
||||||
|
// Initialize our content view to the SwiftUI root
|
||||||
|
window.contentView = NSHostingView(rootView: TerminalView(
|
||||||
|
ghostty: self.ghostty
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
//MARK: - NSWindowDelegate
|
||||||
|
|
||||||
|
func windowWillClose(_ notification: Notification) {
|
||||||
|
}
|
||||||
|
}
|
65
macos/Sources/Features/Terminal/TerminalView.swift
Normal file
65
macos/Sources/Features/Terminal/TerminalView.swift
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import SwiftUI
|
||||||
|
import GhosttyKit
|
||||||
|
|
||||||
|
struct TerminalView: View {
|
||||||
|
@ObservedObject var ghostty: Ghostty.AppState
|
||||||
|
|
||||||
|
// This seems like a crutch after switching from SwiftUI to AppKit lifecycle.
|
||||||
|
@FocusState private var focused: Bool
|
||||||
|
|
||||||
|
@FocusedValue(\.ghosttySurfaceView) private var focusedSurface
|
||||||
|
@FocusedValue(\.ghosttySurfaceTitle) private var surfaceTitle
|
||||||
|
@FocusedValue(\.ghosttySurfaceZoomed) private var zoomedSplit
|
||||||
|
@FocusedValue(\.ghosttySurfaceCellSize) private var cellSize
|
||||||
|
|
||||||
|
// The title for our window
|
||||||
|
private var title: String {
|
||||||
|
var title = "👻"
|
||||||
|
|
||||||
|
if let surfaceTitle = surfaceTitle {
|
||||||
|
if (surfaceTitle.count > 0) {
|
||||||
|
title = surfaceTitle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let zoomedSplit = zoomedSplit {
|
||||||
|
if zoomedSplit {
|
||||||
|
title = "🔍 " + title
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return title
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
switch ghostty.readiness {
|
||||||
|
case .loading:
|
||||||
|
Text("Loading")
|
||||||
|
case .error:
|
||||||
|
ErrorView()
|
||||||
|
case .ready:
|
||||||
|
let center = NotificationCenter.default
|
||||||
|
let gotoTab = center.publisher(for: Ghostty.Notification.ghosttyGotoTab)
|
||||||
|
let toggleFullscreen = center.publisher(for: Ghostty.Notification.ghosttyToggleFullscreen)
|
||||||
|
|
||||||
|
VStack(spacing: 0) {
|
||||||
|
// If we're running in debug mode we show a warning so that users
|
||||||
|
// know that performance will be degraded.
|
||||||
|
if (ghostty.info.mode == GHOSTTY_BUILD_MODE_DEBUG) {
|
||||||
|
DebugBuildWarningView()
|
||||||
|
}
|
||||||
|
|
||||||
|
Ghostty.TerminalSplit(onClose: Self.closeWindow, baseConfig: nil)
|
||||||
|
.ghosttyApp(ghostty.app!)
|
||||||
|
.ghosttyConfig(ghostty.config!)
|
||||||
|
.focused($focused)
|
||||||
|
.onAppear { self.focused = true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static func closeWindow() {
|
||||||
|
guard let currentWindow = NSApp.keyWindow else { return }
|
||||||
|
currentWindow.close()
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user