mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
macos: confirm on quit
This commit is contained in:
@ -20,6 +20,7 @@
|
|||||||
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 */; };
|
||||||
A5CEAFFF29C2410700646FDA /* Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CEAFFE29C2410700646FDA /* Backport.swift */; };
|
A5CEAFFF29C2410700646FDA /* Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CEAFFE29C2410700646FDA /* Backport.swift */; };
|
||||||
A5D495A2299BEC7E00DD1313 /* GhosttyKit.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = A5D495A1299BEC7E00DD1313 /* GhosttyKit.xcframework */; };
|
A5D495A2299BEC7E00DD1313 /* GhosttyKit.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = A5D495A1299BEC7E00DD1313 /* GhosttyKit.xcframework */; };
|
||||||
|
A5FECBD729D1FC3900022361 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5FECBD629D1FC3900022361 /* ContentView.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
@ -38,6 +39,7 @@
|
|||||||
A5CEAFDD29B8058B00646FDA /* SplitView.Divider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplitView.Divider.swift; sourceTree = "<group>"; };
|
A5CEAFDD29B8058B00646FDA /* SplitView.Divider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplitView.Divider.swift; sourceTree = "<group>"; };
|
||||||
A5CEAFFE29C2410700646FDA /* Backport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Backport.swift; sourceTree = "<group>"; };
|
A5CEAFFE29C2410700646FDA /* Backport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Backport.swift; sourceTree = "<group>"; };
|
||||||
A5D495A1299BEC7E00DD1313 /* GhosttyKit.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = GhosttyKit.xcframework; sourceTree = "<group>"; };
|
A5D495A1299BEC7E00DD1313 /* GhosttyKit.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = GhosttyKit.xcframework; sourceTree = "<group>"; };
|
||||||
|
A5FECBD629D1FC3900022361 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@ -63,6 +65,7 @@
|
|||||||
A55685DF29A03A9F004303CE /* AppError.swift */,
|
A55685DF29A03A9F004303CE /* AppError.swift */,
|
||||||
A59444F629A2ED5200725BBA /* SettingsView.swift */,
|
A59444F629A2ED5200725BBA /* SettingsView.swift */,
|
||||||
A5CEAFFE29C2410700646FDA /* Backport.swift */,
|
A5CEAFFE29C2410700646FDA /* Backport.swift */,
|
||||||
|
A5FECBD629D1FC3900022361 /* ContentView.swift */,
|
||||||
);
|
);
|
||||||
path = Sources;
|
path = Sources;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -192,6 +195,7 @@
|
|||||||
files = (
|
files = (
|
||||||
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 */,
|
||||||
A55B7BB829B6F53A0055DE60 /* Package.swift in Sources */,
|
A55B7BB829B6F53A0055DE60 /* Package.swift in Sources */,
|
||||||
A55B7BBE29B701360055DE60 /* Ghostty.SplitView.swift in Sources */,
|
A55B7BBE29B701360055DE60 /* Ghostty.SplitView.swift in Sources */,
|
||||||
A55B7BB629B6F47F0055DE60 /* AppState.swift in Sources */,
|
A55B7BB629B6F47F0055DE60 /* AppState.swift in Sources */,
|
||||||
|
48
macos/Sources/ContentView.swift
Normal file
48
macos/Sources/ContentView.swift
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import SwiftUI
|
||||||
|
import GhosttyKit
|
||||||
|
|
||||||
|
struct ContentView: View {
|
||||||
|
let ghostty: Ghostty.AppState
|
||||||
|
|
||||||
|
@EnvironmentObject private var appDelegate: AppDelegate
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
switch ghostty.readiness {
|
||||||
|
case .loading:
|
||||||
|
Text("Loading")
|
||||||
|
.onChange(of: appDelegate.confirmQuit) { value in
|
||||||
|
guard value else { return }
|
||||||
|
NSApplication.shared.reply(toApplicationShouldTerminate: true)
|
||||||
|
}
|
||||||
|
case .error:
|
||||||
|
ErrorView()
|
||||||
|
.onChange(of: appDelegate.confirmQuit) { value in
|
||||||
|
guard value else { return }
|
||||||
|
NSApplication.shared.reply(toApplicationShouldTerminate: true)
|
||||||
|
}
|
||||||
|
case .ready:
|
||||||
|
Ghostty.TerminalSplit(onClose: Self.closeWindow)
|
||||||
|
.ghosttyApp(ghostty.app!)
|
||||||
|
.confirmationDialog(
|
||||||
|
"Quit Ghostty?",
|
||||||
|
isPresented: $appDelegate.confirmQuit) {
|
||||||
|
Button("Close Ghostty", role: .destructive) {
|
||||||
|
NSApplication.shared.reply(toApplicationShouldTerminate: true)
|
||||||
|
}
|
||||||
|
.keyboardShortcut(.defaultAction)
|
||||||
|
|
||||||
|
Button("Cancel", role: .cancel) {
|
||||||
|
NSApplication.shared.reply(toApplicationShouldTerminate: false)
|
||||||
|
}
|
||||||
|
.keyboardShortcut(.cancelAction)
|
||||||
|
} message: {
|
||||||
|
Text("All terminal sessions will be terminated.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static func closeWindow() {
|
||||||
|
guard let currentWindow = NSApp.keyWindow else { return }
|
||||||
|
currentWindow.close()
|
||||||
|
}
|
||||||
|
}
|
@ -18,15 +18,7 @@ struct GhosttyApp: App {
|
|||||||
|
|
||||||
var body: some Scene {
|
var body: some Scene {
|
||||||
WindowGroup {
|
WindowGroup {
|
||||||
switch ghostty.readiness {
|
ContentView(ghostty: ghostty)
|
||||||
case .loading:
|
|
||||||
Text("Loading")
|
|
||||||
case .error:
|
|
||||||
ErrorView()
|
|
||||||
case .ready:
|
|
||||||
Ghostty.TerminalSplit(onClose: Self.closeWindow)
|
|
||||||
.ghosttyApp(ghostty.app!)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.backport.defaultSize(width: 800, height: 600)
|
.backport.defaultSize(width: 800, height: 600)
|
||||||
.commands {
|
.commands {
|
||||||
@ -110,7 +102,9 @@ struct GhosttyApp: App {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AppDelegate: NSObject, NSApplicationDelegate {
|
class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
|
||||||
|
@Published var confirmQuit: Bool = false
|
||||||
|
|
||||||
// See CursedMenuManager for more information.
|
// See CursedMenuManager for more information.
|
||||||
private var menuManager: CursedMenuManager?
|
private var menuManager: CursedMenuManager?
|
||||||
|
|
||||||
@ -124,6 +118,11 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||||||
// we can't create from SwiftUI.
|
// we can't create from SwiftUI.
|
||||||
menuManager = CursedMenuManager()
|
menuManager = CursedMenuManager()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply {
|
||||||
|
confirmQuit = true
|
||||||
|
return .terminateLater
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// SwiftUI as of macOS 13.x provides no way to manage the default menu items that are created
|
/// SwiftUI as of macOS 13.x provides no way to manage the default menu items that are created
|
||||||
|
Reference in New Issue
Block a user