mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
macos: merge AppController and AppDelegate, organize groups
This commit is contained in:
@ -8,11 +8,11 @@
|
|||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
8503D7C72A549C66006CFF3D /* FullScreenHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8503D7C62A549C66006CFF3D /* FullScreenHandler.swift */; };
|
8503D7C72A549C66006CFF3D /* FullScreenHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8503D7C62A549C66006CFF3D /* FullScreenHandler.swift */; };
|
||||||
85102A1A2A6E32720084AB3E /* WindowService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85102A192A6E32720084AB3E /* WindowService.swift */; };
|
85102A1C2A6E32890084AB3E /* PrimaryWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85102A1B2A6E32890084AB3E /* PrimaryWindowController.swift */; };
|
||||||
85102A1C2A6E32890084AB3E /* WindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85102A1B2A6E32890084AB3E /* WindowController.swift */; };
|
|
||||||
852655222A597CA900E4F7AD /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 852655212A597CA900E4F7AD /* main.swift */; };
|
|
||||||
857F63812A5E64F200CA4815 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 857F63802A5E64F200CA4815 /* MainMenu.xib */; };
|
857F63812A5E64F200CA4815 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 857F63802A5E64F200CA4815 /* MainMenu.xib */; };
|
||||||
85DE1C922A6A3DCA00493853 /* CustomWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85DE1C912A6A3DCA00493853 /* CustomWindow.swift */; };
|
85DE1C922A6A3DCA00493853 /* PrimaryWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85DE1C912A6A3DCA00493853 /* PrimaryWindow.swift */; };
|
||||||
|
A53426352A7DA53D00EBB7A2 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A53426342A7DA53D00EBB7A2 /* AppDelegate.swift */; };
|
||||||
|
A53426392A7DC55C00EBB7A2 /* PrimaryWindowManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A53426382A7DC55C00EBB7A2 /* PrimaryWindowManager.swift */; };
|
||||||
A535B9DA299C569B0017E2E4 /* ErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A535B9D9299C569B0017E2E4 /* ErrorView.swift */; };
|
A535B9DA299C569B0017E2E4 /* ErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A535B9D9299C569B0017E2E4 /* ErrorView.swift */; };
|
||||||
A545D1A22A5772CE006E0AE4 /* shell-integration in Resources */ = {isa = PBXBuildFile; fileRef = A545D1A12A5772CE006E0AE4 /* shell-integration */; };
|
A545D1A22A5772CE006E0AE4 /* shell-integration in Resources */ = {isa = PBXBuildFile; fileRef = A545D1A12A5772CE006E0AE4 /* shell-integration */; };
|
||||||
A55685E029A03A9F004303CE /* AppError.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55685DF29A03A9F004303CE /* AppError.swift */; };
|
A55685E029A03A9F004303CE /* AppError.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55685DF29A03A9F004303CE /* AppError.swift */; };
|
||||||
@ -23,7 +23,6 @@
|
|||||||
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 */; };
|
||||||
A5A1F8852A489D6800D1E8BC /* terminfo in Resources */ = {isa = PBXBuildFile; fileRef = A5A1F8842A489D6800D1E8BC /* terminfo */; };
|
A5A1F8852A489D6800D1E8BC /* terminfo in Resources */ = {isa = PBXBuildFile; fileRef = A5A1F8842A489D6800D1E8BC /* terminfo */; };
|
||||||
A5B30535299BEAAA0047F10C /* GhosttyAppController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5B30534299BEAAA0047F10C /* GhosttyAppController.swift */; };
|
|
||||||
A5B30539299BEAAB0047F10C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A5B30538299BEAAB0047F10C /* Assets.xcassets */; };
|
A5B30539299BEAAB0047F10C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A5B30538299BEAAB0047F10C /* Assets.xcassets */; };
|
||||||
A5CEAFDC29B8009000646FDA /* SplitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CEAFDB29B8009000646FDA /* SplitView.swift */; };
|
A5CEAFDC29B8009000646FDA /* SplitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CEAFDB29B8009000646FDA /* SplitView.swift */; };
|
||||||
A5CEAFDE29B8058B00646FDA /* SplitView.Divider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CEAFDD29B8058B00646FDA /* SplitView.Divider.swift */; };
|
A5CEAFDE29B8058B00646FDA /* SplitView.Divider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CEAFDD29B8058B00646FDA /* SplitView.Divider.swift */; };
|
||||||
@ -34,11 +33,11 @@
|
|||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
8503D7C62A549C66006CFF3D /* FullScreenHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FullScreenHandler.swift; sourceTree = "<group>"; };
|
8503D7C62A549C66006CFF3D /* FullScreenHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FullScreenHandler.swift; sourceTree = "<group>"; };
|
||||||
85102A192A6E32720084AB3E /* WindowService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowService.swift; sourceTree = "<group>"; };
|
85102A1B2A6E32890084AB3E /* PrimaryWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrimaryWindowController.swift; sourceTree = "<group>"; };
|
||||||
85102A1B2A6E32890084AB3E /* WindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowController.swift; sourceTree = "<group>"; };
|
|
||||||
852655212A597CA900E4F7AD /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
|
|
||||||
857F63802A5E64F200CA4815 /* MainMenu.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainMenu.xib; sourceTree = "<group>"; };
|
857F63802A5E64F200CA4815 /* MainMenu.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainMenu.xib; sourceTree = "<group>"; };
|
||||||
85DE1C912A6A3DCA00493853 /* CustomWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomWindow.swift; sourceTree = "<group>"; };
|
85DE1C912A6A3DCA00493853 /* PrimaryWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrimaryWindow.swift; sourceTree = "<group>"; };
|
||||||
|
A53426342A7DA53D00EBB7A2 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||||
|
A53426382A7DC55C00EBB7A2 /* PrimaryWindowManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrimaryWindowManager.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>"; };
|
||||||
A545D1A12A5772CE006E0AE4 /* shell-integration */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "shell-integration"; path = "../zig-out/share/shell-integration"; sourceTree = "<group>"; };
|
A545D1A12A5772CE006E0AE4 /* shell-integration */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "shell-integration"; path = "../zig-out/share/shell-integration"; sourceTree = "<group>"; };
|
||||||
A55685DF29A03A9F004303CE /* AppError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppError.swift; sourceTree = "<group>"; };
|
A55685DF29A03A9F004303CE /* AppError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppError.swift; sourceTree = "<group>"; };
|
||||||
@ -50,7 +49,6 @@
|
|||||||
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>"; };
|
||||||
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>"; };
|
||||||
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 /* GhosttyAppController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GhosttyAppController.swift; sourceTree = "<group>"; };
|
|
||||||
A5B30538299BEAAB0047F10C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
A5B30538299BEAAB0047F10C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||||
A5B3053D299BEAAB0047F10C /* Ghostty.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Ghostty.entitlements; sourceTree = "<group>"; };
|
A5B3053D299BEAAB0047F10C /* Ghostty.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Ghostty.entitlements; sourceTree = "<group>"; };
|
||||||
A5CEAFDB29B8009000646FDA /* SplitView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplitView.swift; sourceTree = "<group>"; };
|
A5CEAFDB29B8009000646FDA /* SplitView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplitView.swift; sourceTree = "<group>"; };
|
||||||
@ -73,14 +71,39 @@
|
|||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
|
A53426362A7DC53000EBB7A2 /* Features */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
A53426372A7DC53A00EBB7A2 /* Primary Window */,
|
||||||
|
);
|
||||||
|
path = Features;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
A53426372A7DC53A00EBB7A2 /* Primary Window */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
A53426382A7DC55C00EBB7A2 /* PrimaryWindowManager.swift */,
|
||||||
|
85102A1B2A6E32890084AB3E /* PrimaryWindowController.swift */,
|
||||||
|
85DE1C912A6A3DCA00493853 /* PrimaryWindow.swift */,
|
||||||
|
);
|
||||||
|
path = "Primary Window";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
A534263A2A7DC61B00EBB7A2 /* Core */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
A53426342A7DA53D00EBB7A2 /* AppDelegate.swift */,
|
||||||
|
);
|
||||||
|
path = Core;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
A54CD6ED299BEB14008C95BB /* Sources */ = {
|
A54CD6ED299BEB14008C95BB /* Sources */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
A5D495A0299BEC2200DD1313 /* Preview Content */,
|
A534263A2A7DC61B00EBB7A2 /* Core */,
|
||||||
|
A53426362A7DC53000EBB7A2 /* Features */,
|
||||||
A5CEAFDA29B8005900646FDA /* SplitView */,
|
A5CEAFDA29B8005900646FDA /* SplitView */,
|
||||||
A55B7BB429B6F4410055DE60 /* Ghostty */,
|
A55B7BB429B6F4410055DE60 /* Ghostty */,
|
||||||
A5B30534299BEAAA0047F10C /* GhosttyAppController.swift */,
|
|
||||||
85DE1C912A6A3DCA00493853 /* CustomWindow.swift */,
|
|
||||||
857F63802A5E64F200CA4815 /* MainMenu.xib */,
|
857F63802A5E64F200CA4815 /* MainMenu.xib */,
|
||||||
A535B9D9299C569B0017E2E4 /* ErrorView.swift */,
|
A535B9D9299C569B0017E2E4 /* ErrorView.swift */,
|
||||||
A55685DF29A03A9F004303CE /* AppError.swift */,
|
A55685DF29A03A9F004303CE /* AppError.swift */,
|
||||||
@ -89,9 +112,6 @@
|
|||||||
A5FECBD629D1FC3900022361 /* ContentView.swift */,
|
A5FECBD629D1FC3900022361 /* ContentView.swift */,
|
||||||
A5FECBD829D2010400022361 /* WindowAccessor.swift */,
|
A5FECBD829D2010400022361 /* WindowAccessor.swift */,
|
||||||
8503D7C62A549C66006CFF3D /* FullScreenHandler.swift */,
|
8503D7C62A549C66006CFF3D /* FullScreenHandler.swift */,
|
||||||
852655212A597CA900E4F7AD /* main.swift */,
|
|
||||||
85102A192A6E32720084AB3E /* WindowService.swift */,
|
|
||||||
85102A1B2A6E32890084AB3E /* WindowController.swift */,
|
|
||||||
);
|
);
|
||||||
path = Sources;
|
path = Sources;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -146,13 +166,6 @@
|
|||||||
path = SplitView;
|
path = SplitView;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
A5D495A0299BEC2200DD1313 /* Preview Content */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
);
|
|
||||||
path = "Preview Content";
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
A5D495A3299BECBA00DD1313 /* Frameworks */ = {
|
A5D495A3299BECBA00DD1313 /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -233,8 +246,9 @@
|
|||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
85102A1A2A6E32720084AB3E /* WindowService.swift in Sources */,
|
A53426392A7DC55C00EBB7A2 /* PrimaryWindowManager.swift in Sources */,
|
||||||
85DE1C922A6A3DCA00493853 /* CustomWindow.swift in Sources */,
|
85DE1C922A6A3DCA00493853 /* PrimaryWindow.swift in Sources */,
|
||||||
|
A53426352A7DA53D00EBB7A2 /* AppDelegate.swift in Sources */,
|
||||||
A55B7BBC29B6FC330055DE60 /* SurfaceView.swift in Sources */,
|
A55B7BBC29B6FC330055DE60 /* SurfaceView.swift in Sources */,
|
||||||
A59444F729A2ED5200725BBA /* SettingsView.swift in Sources */,
|
A59444F729A2ED5200725BBA /* SettingsView.swift in Sources */,
|
||||||
A5FECBD729D1FC3900022361 /* ContentView.swift in Sources */,
|
A5FECBD729D1FC3900022361 /* ContentView.swift in Sources */,
|
||||||
@ -245,9 +259,7 @@
|
|||||||
A55685E029A03A9F004303CE /* AppError.swift in Sources */,
|
A55685E029A03A9F004303CE /* AppError.swift in Sources */,
|
||||||
A5FECBD929D2010400022361 /* WindowAccessor.swift in Sources */,
|
A5FECBD929D2010400022361 /* WindowAccessor.swift in Sources */,
|
||||||
A535B9DA299C569B0017E2E4 /* ErrorView.swift in Sources */,
|
A535B9DA299C569B0017E2E4 /* ErrorView.swift in Sources */,
|
||||||
A5B30535299BEAAA0047F10C /* GhosttyAppController.swift in Sources */,
|
85102A1C2A6E32890084AB3E /* PrimaryWindowController.swift in Sources */,
|
||||||
85102A1C2A6E32890084AB3E /* WindowController.swift in Sources */,
|
|
||||||
852655222A597CA900E4F7AD /* main.swift in Sources */,
|
|
||||||
A5CEAFFF29C2410700646FDA /* Backport.swift in Sources */,
|
A5CEAFFF29C2410700646FDA /* Backport.swift in Sources */,
|
||||||
8503D7C72A549C66006CFF3D /* FullScreenHandler.swift in Sources */,
|
8503D7C72A549C66006CFF3D /* FullScreenHandler.swift in Sources */,
|
||||||
A5CEAFDE29B8058B00646FDA /* SplitView.Divider.swift in Sources */,
|
A5CEAFDE29B8058B00646FDA /* SplitView.Divider.swift in Sources */,
|
||||||
@ -381,7 +393,6 @@
|
|||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
DEVELOPMENT_ASSET_PATHS = "\"Sources/Preview Content\"";
|
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
@ -415,7 +426,6 @@
|
|||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
DEVELOPMENT_ASSET_PATHS = "\"Sources/Preview Content\"";
|
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
|
@ -1,36 +1,82 @@
|
|||||||
import OSLog
|
|
||||||
import SwiftUI
|
|
||||||
import AppKit
|
import AppKit
|
||||||
|
import OSLog
|
||||||
import GhosttyKit
|
import GhosttyKit
|
||||||
|
|
||||||
class GhosttyAppController: NSObject {
|
@NSApplicationMain
|
||||||
@IBOutlet weak fileprivate var mainMenu: NSMenu!
|
class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
|
||||||
|
// The application logger. We should probably move this at some point to a dedicated
|
||||||
|
// class/struct but for now it lives here! 🤷♂️
|
||||||
static let logger = Logger(
|
static let logger = Logger(
|
||||||
subsystem: Bundle.main.bundleIdentifier!,
|
subsystem: Bundle.main.bundleIdentifier!,
|
||||||
category: String(describing: AppDelegate.self)
|
category: String(describing: AppDelegate.self)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// confirmQuit published so other views can check whether quit needs to be confirmed.
|
||||||
|
@Published var confirmQuit: Bool = false
|
||||||
|
|
||||||
/// The ghostty global state. Only one per process.
|
/// The ghostty global state. Only one per process.
|
||||||
var ghostty: Ghostty.AppState = Ghostty.AppState()
|
private var ghostty: Ghostty.AppState = Ghostty.AppState()
|
||||||
|
|
||||||
/// Manages windows and tabs, ensuring they're allocated/deallocated correctly
|
/// Manages windows and tabs, ensuring they're allocated/deallocated correctly
|
||||||
var windowService: WindowService!
|
private var windowManager: PrimaryWindowManager!
|
||||||
|
|
||||||
override init() {
|
override init() {
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
// We're initialized through the MainMenu, because we're a referenced objected.
|
windowManager = PrimaryWindowManager(ghostty: self.ghostty)
|
||||||
// So when we're here, we initialize the WindowService, which will open first window.
|
}
|
||||||
windowService = WindowService(ghostty: self.ghostty)
|
|
||||||
|
func applicationDidFinishLaunching(_ notification: Notification) {
|
||||||
|
// System settings overrides
|
||||||
|
UserDefaults.standard.register(defaults: [
|
||||||
|
// Disable this so that repeated key events make it through to our terminal views.
|
||||||
|
"ApplePressAndHoldEnabled": false,
|
||||||
|
])
|
||||||
|
|
||||||
|
// Let's launch our first window.
|
||||||
|
// TODO: we should detect if we restored windows and if so not launch a new window.
|
||||||
|
windowManager.addInitialWindow()
|
||||||
|
}
|
||||||
|
|
||||||
|
func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply {
|
||||||
|
let windows = NSApplication.shared.windows
|
||||||
|
if (windows.isEmpty) { return .terminateNow }
|
||||||
|
|
||||||
|
// This probably isn't fully safe. The isEmpty check above is aspirational, it doesn't
|
||||||
|
// quite work with SwiftUI because windows are retained on close. So instead we check
|
||||||
|
// if there are any that are visible. I'm guessing this breaks under certain scenarios.
|
||||||
|
if (windows.allSatisfy { !$0.isVisible }) { return .terminateNow }
|
||||||
|
|
||||||
|
// If the user is shutting down, restarting, or logging out, we don't confirm quit.
|
||||||
|
if let event = NSAppleEventManager.shared().currentAppleEvent {
|
||||||
|
if let why = event.attributeDescriptor(forKeyword: AEKeyword("why?")!) {
|
||||||
|
switch (why.typeCodeValue) {
|
||||||
|
case kAEShutDown:
|
||||||
|
fallthrough
|
||||||
|
|
||||||
|
case kAERestart:
|
||||||
|
fallthrough
|
||||||
|
|
||||||
|
case kAEReallyLogOut:
|
||||||
|
return .terminateNow
|
||||||
|
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have some visible window, and all our windows will watch the confirmQuit.
|
||||||
|
confirmQuit = true
|
||||||
|
return .terminateLater
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func newWindow(_ sender: Any?) {
|
@IBAction func newWindow(_ sender: Any?) {
|
||||||
windowService.addNewWindow()
|
windowManager.addNewWindow()
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func newTab(_ sender: Any?) {
|
@IBAction func newTab(_ sender: Any?) {
|
||||||
windowService.addNewTab()
|
windowManager.addNewTab()
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func closeWindow(_ sender: Any) {
|
@IBAction func closeWindow(_ sender: Any) {
|
||||||
@ -48,7 +94,7 @@ class GhosttyAppController: NSObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func focusedSurface() -> ghostty_surface_t? {
|
private func focusedSurface() -> ghostty_surface_t? {
|
||||||
guard let window = NSApp.keyWindow as? CustomWindow else { return nil }
|
guard let window = NSApp.keyWindow as? PrimaryWindow else { return nil }
|
||||||
return window.focusedSurfaceWrapper.surface
|
return window.focusedSurfaceWrapper.surface
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,48 +137,3 @@ class GhosttyAppController: NSObject {
|
|||||||
ghostty.splitMoveFocus(surface: surface, direction: direction)
|
ghostty.splitMoveFocus(surface: surface, direction: direction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
|
|
||||||
// confirmQuit published so other views can check whether quit needs to be confirmed.
|
|
||||||
@Published var confirmQuit: Bool = false
|
|
||||||
|
|
||||||
func applicationDidFinishLaunching(_ notification: Notification) {
|
|
||||||
UserDefaults.standard.register(defaults: [
|
|
||||||
// Disable this so that repeated key events make it through to our terminal views.
|
|
||||||
"ApplePressAndHoldEnabled": false,
|
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
||||||
func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply {
|
|
||||||
let windows = NSApplication.shared.windows
|
|
||||||
if (windows.isEmpty) { return .terminateNow }
|
|
||||||
|
|
||||||
// This probably isn't fully safe. The isEmpty check above is aspirational, it doesn't
|
|
||||||
// quite work with SwiftUI because windows are retained on close. So instead we check
|
|
||||||
// if there are any that are visible. I'm guessing this breaks under certain scenarios.
|
|
||||||
if (windows.allSatisfy { !$0.isVisible }) { return .terminateNow }
|
|
||||||
|
|
||||||
// If the user is shutting down, restarting, or logging out, we don't confirm quit.
|
|
||||||
if let event = NSAppleEventManager.shared().currentAppleEvent {
|
|
||||||
if let why = event.attributeDescriptor(forKeyword: AEKeyword("why?")!) {
|
|
||||||
switch (why.typeCodeValue) {
|
|
||||||
case kAEShutDown:
|
|
||||||
fallthrough
|
|
||||||
|
|
||||||
case kAERestart:
|
|
||||||
fallthrough
|
|
||||||
|
|
||||||
case kAEReallyLogOut:
|
|
||||||
return .terminateNow
|
|
||||||
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We have some visible window, and all our windows will watch the confirmQuit.
|
|
||||||
confirmQuit = true
|
|
||||||
return .terminateLater
|
|
||||||
}
|
|
||||||
}
|
|
@ -8,18 +8,20 @@ class FocusedSurfaceWrapper {
|
|||||||
var surface: ghostty_surface_t?
|
var surface: ghostty_surface_t?
|
||||||
}
|
}
|
||||||
|
|
||||||
// CustomWindow exists purely so we can override canBecomeKey and canBecomeMain.
|
// PrimaryWindow is the primary window you'd associate with a terminal: the window
|
||||||
// We need that for the non-native fullscreen.
|
// that contains one or more terminals (splits, and such).
|
||||||
// If we don't use `CustomWindow` we'll get warning messages in the output to say that
|
//
|
||||||
// `makeKeyWindow` was called and returned NO.
|
// We need to subclass NSWindow so that we can override some methods for features
|
||||||
class CustomWindow: NSWindow {
|
// such as non-native fullscreen.
|
||||||
|
class PrimaryWindow: NSWindow {
|
||||||
var focusedSurfaceWrapper: FocusedSurfaceWrapper = FocusedSurfaceWrapper()
|
var focusedSurfaceWrapper: FocusedSurfaceWrapper = FocusedSurfaceWrapper()
|
||||||
|
|
||||||
static func create(ghostty: Ghostty.AppState, appDelegate: AppDelegate) -> CustomWindow {
|
static func create(ghostty: Ghostty.AppState, appDelegate: AppDelegate) -> PrimaryWindow {
|
||||||
let window = CustomWindow(
|
let window = PrimaryWindow(
|
||||||
contentRect: NSRect(x: 0, y: 0, width: 800, height: 600),
|
contentRect: NSRect(x: 0, y: 0, width: 800, height: 600),
|
||||||
styleMask: [.titled, .closable, .miniaturizable, .resizable],
|
styleMask: [.titled, .closable, .miniaturizable, .resizable],
|
||||||
backing: .buffered, defer: false)
|
backing: .buffered,
|
||||||
|
defer: false)
|
||||||
window.center()
|
window.center()
|
||||||
window.contentView = NSHostingView(rootView: ContentView(
|
window.contentView = NSHostingView(rootView: ContentView(
|
||||||
ghostty: ghostty,
|
ghostty: ghostty,
|
@ -0,0 +1,14 @@
|
|||||||
|
import Cocoa
|
||||||
|
|
||||||
|
class PrimaryWindowController: NSWindowController {
|
||||||
|
// Keep track of the last point that our window was launched at so that new
|
||||||
|
// windows "cascade" over each other and don't just launch directly on top
|
||||||
|
// of each other.
|
||||||
|
static var lastCascadePoint = NSPoint(x: 0, y: 0)
|
||||||
|
|
||||||
|
static func create(ghosttyApp: Ghostty.AppState, appDelegate: AppDelegate) -> PrimaryWindowController {
|
||||||
|
let window = PrimaryWindow.create(ghostty: ghosttyApp, appDelegate: appDelegate)
|
||||||
|
lastCascadePoint = window.cascadeTopLeft(from: lastCascadePoint)
|
||||||
|
return PrimaryWindowController(window: window)
|
||||||
|
}
|
||||||
|
}
|
@ -1,17 +1,20 @@
|
|||||||
import Cocoa
|
import Cocoa
|
||||||
import Combine
|
import Combine
|
||||||
|
|
||||||
// WindowService manages the windows and tabs in the application.
|
// PrimaryWindowManager manages the windows and tabs in the primary window
|
||||||
// It keeps references to windows and cleans them up when they're cloned.
|
// of the application. It keeps references to windows and cleans them up when
|
||||||
|
// they're cloned.
|
||||||
|
//
|
||||||
|
// If we ever have multiple tabbed window types we can make this generic but
|
||||||
|
// right now only our primary window is ever duplicated or tabbed so we're not
|
||||||
|
// doing that.
|
||||||
//
|
//
|
||||||
// It is based on the patterns presented in this blog post:
|
// It is based on the patterns presented in this blog post:
|
||||||
// https://christiantietze.de/posts/2019/07/nswindow-tabbing-multiple-nswindowcontroller/
|
// https://christiantietze.de/posts/2019/07/nswindow-tabbing-multiple-nswindowcontroller/
|
||||||
class WindowService {
|
class PrimaryWindowManager {
|
||||||
struct ManagedWindow {
|
struct ManagedWindow {
|
||||||
let windowController: NSWindowController
|
let windowController: NSWindowController
|
||||||
|
|
||||||
let window: NSWindow
|
let window: NSWindow
|
||||||
|
|
||||||
let closePublisher: AnyCancellable
|
let closePublisher: AnyCancellable
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,11 +23,10 @@ class WindowService {
|
|||||||
|
|
||||||
init(ghostty: Ghostty.AppState) {
|
init(ghostty: Ghostty.AppState) {
|
||||||
self.ghostty = ghostty
|
self.ghostty = ghostty
|
||||||
|
|
||||||
addInitialWindow()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func addInitialWindow() {
|
/// Add the initial window for the application. This should only be called once from the AppDelegate.
|
||||||
|
func addInitialWindow() {
|
||||||
guard let controller = createWindowController() else { return }
|
guard let controller = createWindowController() else { return }
|
||||||
controller.showWindow(self)
|
controller.showWindow(self)
|
||||||
let result = addManagedWindow(windowController: controller)
|
let result = addManagedWindow(windowController: controller)
|
||||||
@ -54,12 +56,12 @@ class WindowService {
|
|||||||
return (mainManagedWindow ?? managedWindows.first).map { $0.window }
|
return (mainManagedWindow ?? managedWindows.first).map { $0.window }
|
||||||
}
|
}
|
||||||
|
|
||||||
private func createWindowController() -> WindowController? {
|
private func createWindowController() -> PrimaryWindowController? {
|
||||||
guard let appDelegate = NSApplication.shared.delegate as? AppDelegate else { return nil }
|
guard let appDelegate = NSApplication.shared.delegate as? AppDelegate else { return nil }
|
||||||
return WindowController.create(ghosttyApp: self.ghostty, appDelegate: appDelegate)
|
return PrimaryWindowController.create(ghosttyApp: self.ghostty, appDelegate: appDelegate)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func addManagedWindow(windowController: WindowController) -> ManagedWindow? {
|
private func addManagedWindow(windowController: PrimaryWindowController) -> ManagedWindow? {
|
||||||
guard let window = windowController.window else { return nil }
|
guard let window = windowController.window else { return nil }
|
||||||
|
|
||||||
let pubClose = NotificationCenter.default.publisher(for: NSWindow.willCloseNotification, object: window)
|
let pubClose = NotificationCenter.default.publisher(for: NSWindow.willCloseNotification, object: window)
|
@ -38,7 +38,7 @@ extension Ghostty {
|
|||||||
init() {
|
init() {
|
||||||
// Initialize ghostty global state. This happens once per process.
|
// Initialize ghostty global state. This happens once per process.
|
||||||
guard ghostty_init() == GHOSTTY_SUCCESS else {
|
guard ghostty_init() == GHOSTTY_SUCCESS else {
|
||||||
GhosttyAppController.logger.critical("ghostty_init failed")
|
AppDelegate.logger.critical("ghostty_init failed")
|
||||||
readiness = .error
|
readiness = .error
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -68,7 +68,7 @@ extension Ghostty {
|
|||||||
|
|
||||||
// Create the ghostty app.
|
// Create the ghostty app.
|
||||||
guard let app = ghostty_app_new(&runtime_cfg, cfg) else {
|
guard let app = ghostty_app_new(&runtime_cfg, cfg) else {
|
||||||
GhosttyAppController.logger.critical("ghostty_app_new failed")
|
AppDelegate.logger.critical("ghostty_app_new failed")
|
||||||
readiness = .error
|
readiness = .error
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -87,7 +87,7 @@ extension Ghostty {
|
|||||||
static func reloadConfig() -> ghostty_config_t? {
|
static func reloadConfig() -> ghostty_config_t? {
|
||||||
// Initialize the global configuration.
|
// Initialize the global configuration.
|
||||||
guard let cfg = ghostty_config_new() else {
|
guard let cfg = ghostty_config_new() else {
|
||||||
GhosttyAppController.logger.critical("ghostty_config_new failed")
|
AppDelegate.logger.critical("ghostty_config_new failed")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,7 +189,7 @@ extension Ghostty {
|
|||||||
|
|
||||||
static func reloadConfig(_ userdata: UnsafeMutableRawPointer?) -> ghostty_config_t? {
|
static func reloadConfig(_ userdata: UnsafeMutableRawPointer?) -> ghostty_config_t? {
|
||||||
guard let newConfig = AppState.reloadConfig() else {
|
guard let newConfig = AppState.reloadConfig() else {
|
||||||
GhosttyAppController.logger.warning("failed to reload configuration")
|
AppDelegate.logger.warning("failed to reload configuration")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,15 +5,20 @@
|
|||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21701"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21701"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication"/>
|
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||||
|
<connections>
|
||||||
|
<outlet property="delegate" destination="bbz-4X-AYv" id="4pZ-gB-Uf0"/>
|
||||||
|
</connections>
|
||||||
|
</customObject>
|
||||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||||
|
<customObject id="bbz-4X-AYv" userLabel="AppDelegate" customClass="AppDelegate" customModule="Ghostty" customModuleProvider="target"/>
|
||||||
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
|
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
|
||||||
<menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
|
<menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
|
||||||
<items>
|
<items>
|
||||||
<menuItem title="NewApplication" id="1Xt-HY-uBw">
|
<menuItem title="Ghostty" id="1Xt-HY-uBw">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<menu key="submenu" title="NewApplication" systemMenu="apple" id="uQy-DD-JDr">
|
<menu key="submenu" title="Ghostty" systemMenu="apple" id="uQy-DD-JDr">
|
||||||
<items>
|
<items>
|
||||||
<menuItem title="About Ghostty" id="5kV-Vb-QxS">
|
<menuItem title="About Ghostty" id="5kV-Vb-QxS">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
@ -56,34 +61,34 @@
|
|||||||
<items>
|
<items>
|
||||||
<menuItem title="New Window" keyEquivalent="n" id="Was-JA-tGl">
|
<menuItem title="New Window" keyEquivalent="n" id="Was-JA-tGl">
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="newWindow:" target="IUl-M9-b48" id="hDE-pE-3Ml"/>
|
<action selector="newWindow:" target="bbz-4X-AYv" id="NnC-l5-DUY"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="New Tab" keyEquivalent="t" id="uTG-Vz-hJU">
|
<menuItem title="New Tab" keyEquivalent="t" id="uTG-Vz-hJU">
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="newTab:" target="IUl-M9-b48" id="MHd-lY-6H5"/>
|
<action selector="newTab:" target="bbz-4X-AYv" id="cxO-CS-TJq"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
|
<menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
|
||||||
<menuItem title="Split Horizontally" keyEquivalent="d" id="VUR-Ld-nLx">
|
<menuItem title="Split Horizontally" keyEquivalent="d" id="VUR-Ld-nLx">
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="splitHorizontally:" target="IUl-M9-b48" id="0y5-Ge-OF5"/>
|
<action selector="splitHorizontally:" target="bbz-4X-AYv" id="QT1-Yt-gYJ"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Split Vertically" keyEquivalent="D" id="UDZ-4y-6xL">
|
<menuItem title="Split Vertically" keyEquivalent="D" id="UDZ-4y-6xL">
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="splitVertically:" target="IUl-M9-b48" id="QZ1-5M-OQG"/>
|
<action selector="splitVertically:" target="bbz-4X-AYv" id="ZZF-3f-OwW"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem isSeparatorItem="YES" id="sjq-M1-UGS"/>
|
<menuItem isSeparatorItem="YES" id="sjq-M1-UGS"/>
|
||||||
<menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG">
|
<menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG">
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="close:" target="IUl-M9-b48" id="Cc3-qR-k0Z"/>
|
<action selector="close:" target="bbz-4X-AYv" id="Szc-Fu-9yk"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Close Window" keyEquivalent="W" id="W5w-UZ-crk">
|
<menuItem title="Close Window" keyEquivalent="W" id="W5w-UZ-crk">
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="closeWindow:" target="IUl-M9-b48" id="Yaz-fy-DFE"/>
|
<action selector="closeWindow:" target="bbz-4X-AYv" id="j4w-Nd-9bO"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
</items>
|
</items>
|
||||||
@ -114,12 +119,12 @@
|
|||||||
<menuItem isSeparatorItem="YES" id="rlu-tP-x0P"/>
|
<menuItem isSeparatorItem="YES" id="rlu-tP-x0P"/>
|
||||||
<menuItem title="Select Previous Split" keyEquivalent="[" id="Lic-px-1wg">
|
<menuItem title="Select Previous Split" keyEquivalent="[" id="Lic-px-1wg">
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="splitMoveFocusPrevious:" target="IUl-M9-b48" id="d37-lc-L2w"/>
|
<action selector="splitMoveFocusPrevious:" target="bbz-4X-AYv" id="mOs-gG-dAC"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Select Next Split" keyEquivalent="]" id="bD7-ei-wKU">
|
<menuItem title="Select Next Split" keyEquivalent="]" id="bD7-ei-wKU">
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="splitMoveFocusNext:" target="IUl-M9-b48" id="eJ4-vo-aSM"/>
|
<action selector="splitMoveFocusNext:" target="bbz-4X-AYv" id="rU6-Vw-DoW"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Select Split" id="dos-9S-LXC">
|
<menuItem title="Select Split" id="dos-9S-LXC">
|
||||||
@ -129,25 +134,25 @@
|
|||||||
<menuItem title="Select Split Above" keyEquivalent="" id="0yU-hC-8xF">
|
<menuItem title="Select Split Above" keyEquivalent="" id="0yU-hC-8xF">
|
||||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="splitMoveFocusAbove:" target="IUl-M9-b48" id="Ngp-ty-rtO"/>
|
<action selector="splitMoveFocusAbove:" target="bbz-4X-AYv" id="HDw-f2-RJY"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Select Split Below" keyEquivalent="" id="QDz-d9-CBr">
|
<menuItem title="Select Split Below" keyEquivalent="" id="QDz-d9-CBr">
|
||||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="splitMoveFocusBelow:" target="IUl-M9-b48" id="NZF-SR-DRF"/>
|
<action selector="splitMoveFocusBelow:" target="bbz-4X-AYv" id="fmW-hZ-uOA"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Select Split Left" keyEquivalent="" id="cTK-oy-KuV">
|
<menuItem title="Select Split Left" keyEquivalent="" id="cTK-oy-KuV">
|
||||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="splitMoveFocusLeft:" target="IUl-M9-b48" id="lqR-BO-6Xc"/>
|
<action selector="splitMoveFocusLeft:" target="bbz-4X-AYv" id="N1i-a2-7N5"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Select Split Right" keyEquivalent="" id="upj-mc-L7X">
|
<menuItem title="Select Split Right" keyEquivalent="" id="upj-mc-L7X">
|
||||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="splitMoveFocusRight:" target="IUl-M9-b48" id="gjS-dq-5ll"/>
|
<action selector="splitMoveFocusRight:" target="bbz-4X-AYv" id="Pgi-df-84r"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
</items>
|
</items>
|
||||||
@ -171,10 +176,5 @@
|
|||||||
</items>
|
</items>
|
||||||
<point key="canvasLocation" x="139" y="154"/>
|
<point key="canvasLocation" x="139" y="154"/>
|
||||||
</menu>
|
</menu>
|
||||||
<customObject id="IUl-M9-b48" customClass="GhosttyAppController" customModule="Ghostty" customModuleProvider="target">
|
|
||||||
<connections>
|
|
||||||
<outlet property="mainMenu" destination="AYu-sK-qS6" id="VpF-hi-cLE"/>
|
|
||||||
</connections>
|
|
||||||
</customObject>
|
|
||||||
</objects>
|
</objects>
|
||||||
</document>
|
</document>
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
import Cocoa
|
|
||||||
|
|
||||||
class WindowController: NSWindowController {
|
|
||||||
static var lastCascadePoint = NSPoint(x: 0, y: 0)
|
|
||||||
|
|
||||||
static func create(ghosttyApp: Ghostty.AppState, appDelegate: AppDelegate) -> WindowController {
|
|
||||||
let window = CustomWindow.create(ghostty: ghosttyApp, appDelegate: appDelegate)
|
|
||||||
lastCascadePoint = window.cascadeTopLeft(from: lastCascadePoint)
|
|
||||||
return WindowController(window: window)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
import AppKit
|
|
||||||
|
|
||||||
let app = NSApplication.shared
|
|
||||||
let delegate = AppDelegate()
|
|
||||||
app.delegate = delegate
|
|
||||||
|
|
||||||
_ = NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)
|
|
Reference in New Issue
Block a user