mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-10-26 12:27:29 +00:00
macos: address quick terminal basic functionality with new API
This commit is contained in:
@@ -786,6 +786,7 @@ ghostty_app_t ghostty_surface_app(ghostty_surface_t);
|
|||||||
ghostty_surface_config_s ghostty_surface_inherited_config(ghostty_surface_t);
|
ghostty_surface_config_s ghostty_surface_inherited_config(ghostty_surface_t);
|
||||||
void ghostty_surface_update_config(ghostty_surface_t, ghostty_config_t);
|
void ghostty_surface_update_config(ghostty_surface_t, ghostty_config_t);
|
||||||
bool ghostty_surface_needs_confirm_quit(ghostty_surface_t);
|
bool ghostty_surface_needs_confirm_quit(ghostty_surface_t);
|
||||||
|
bool ghostty_surface_process_exited(ghostty_surface_t);
|
||||||
void ghostty_surface_refresh(ghostty_surface_t);
|
void ghostty_surface_refresh(ghostty_surface_t);
|
||||||
void ghostty_surface_draw(ghostty_surface_t);
|
void ghostty_surface_draw(ghostty_surface_t);
|
||||||
void ghostty_surface_set_content_scale(ghostty_surface_t, double, double);
|
void ghostty_surface_set_content_scale(ghostty_surface_t, double, double);
|
||||||
|
|||||||
@@ -612,6 +612,10 @@ class AppDelegate: NSObject,
|
|||||||
guard let surfaceView = notification.object as? Ghostty.SurfaceView else { return }
|
guard let surfaceView = notification.object as? Ghostty.SurfaceView else { return }
|
||||||
guard let window = surfaceView.window else { return }
|
guard let window = surfaceView.window else { return }
|
||||||
|
|
||||||
|
// We only want to listen to new tabs if the focused parent is
|
||||||
|
// a regular terminal controller.
|
||||||
|
guard window.windowController is TerminalController else { return }
|
||||||
|
|
||||||
let configAny = notification.userInfo?[Ghostty.Notification.NewSurfaceConfigKey]
|
let configAny = notification.userInfo?[Ghostty.Notification.NewSurfaceConfigKey]
|
||||||
let config = configAny as? Ghostty.SurfaceConfiguration
|
let config = configAny as? Ghostty.SurfaceConfiguration
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,12 @@ class QuickTerminalController: BaseTerminalController {
|
|||||||
selector: #selector(ghosttyConfigDidChange(_:)),
|
selector: #selector(ghosttyConfigDidChange(_:)),
|
||||||
name: .ghosttyConfigDidChange,
|
name: .ghosttyConfigDidChange,
|
||||||
object: nil)
|
object: nil)
|
||||||
|
center.addObserver(
|
||||||
|
self,
|
||||||
|
selector: #selector(closeWindow(_:)),
|
||||||
|
name: .ghosttyCloseWindow,
|
||||||
|
object: nil
|
||||||
|
)
|
||||||
center.addObserver(
|
center.addObserver(
|
||||||
self,
|
self,
|
||||||
selector: #selector(onNewTab),
|
selector: #selector(onNewTab),
|
||||||
@@ -198,16 +204,38 @@ class QuickTerminalController: BaseTerminalController {
|
|||||||
|
|
||||||
// If our surface tree is nil then we animate the window out.
|
// If our surface tree is nil then we animate the window out.
|
||||||
if (to.isEmpty) {
|
if (to.isEmpty) {
|
||||||
// Save the current window frame before animating out. This preserves
|
|
||||||
// the user's preferred window size and position for when the quick
|
|
||||||
// terminal is reactivated with a new surface. Without this, SwiftUI
|
|
||||||
// would reset the window to its minimum content size.
|
|
||||||
lastClosedFrame = window?.frame
|
|
||||||
|
|
||||||
animateOut()
|
animateOut()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func closeSurfaceNode(
|
||||||
|
_ node: SplitTree<Ghostty.SurfaceView>.Node,
|
||||||
|
withConfirmation: Bool = true
|
||||||
|
) {
|
||||||
|
// If this isn't the root then we're dealing with a split closure.
|
||||||
|
if surfaceTree.root != node {
|
||||||
|
super.closeSurfaceNode(node, withConfirmation: withConfirmation)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this isn't a final leaf then we're dealing with a split closure
|
||||||
|
guard case .leaf(let surface) = node else {
|
||||||
|
super.closeSurfaceNode(node, withConfirmation: withConfirmation)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// If its the root, we check if the process exited. If it did,
|
||||||
|
// then we do empty the tree.
|
||||||
|
if surface.processExited {
|
||||||
|
surfaceTree = .init()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// If its the root then we just animate out. We never actually allow
|
||||||
|
// the surface to fully close.
|
||||||
|
animateOut()
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: Methods
|
// MARK: Methods
|
||||||
|
|
||||||
func toggle() {
|
func toggle() {
|
||||||
@@ -252,12 +280,6 @@ class QuickTerminalController: BaseTerminalController {
|
|||||||
let view = Ghostty.SurfaceView(ghostty_app, baseConfig: nil)
|
let view = Ghostty.SurfaceView(ghostty_app, baseConfig: nil)
|
||||||
surfaceTree = SplitTree(view: view)
|
surfaceTree = SplitTree(view: view)
|
||||||
focusedSurface = view
|
focusedSurface = view
|
||||||
|
|
||||||
// Restore our previous frame if we have one
|
|
||||||
if let lastClosedFrame {
|
|
||||||
window.setFrame(lastClosedFrame, display: false)
|
|
||||||
self.lastClosedFrame = nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Animate the window in
|
// Animate the window in
|
||||||
@@ -283,6 +305,12 @@ class QuickTerminalController: BaseTerminalController {
|
|||||||
private func animateWindowIn(window: NSWindow, from position: QuickTerminalPosition) {
|
private func animateWindowIn(window: NSWindow, from position: QuickTerminalPosition) {
|
||||||
guard let screen = derivedConfig.quickTerminalScreen.screen else { return }
|
guard let screen = derivedConfig.quickTerminalScreen.screen else { return }
|
||||||
|
|
||||||
|
// Restore our previous frame if we have one
|
||||||
|
if let lastClosedFrame {
|
||||||
|
window.setFrame(lastClosedFrame, display: false)
|
||||||
|
self.lastClosedFrame = nil
|
||||||
|
}
|
||||||
|
|
||||||
// Move our window off screen to the top
|
// Move our window off screen to the top
|
||||||
position.setInitial(in: window, on: screen)
|
position.setInitial(in: window, on: screen)
|
||||||
|
|
||||||
@@ -393,6 +421,12 @@ class QuickTerminalController: BaseTerminalController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func animateWindowOut(window: NSWindow, to position: QuickTerminalPosition) {
|
private func animateWindowOut(window: NSWindow, to position: QuickTerminalPosition) {
|
||||||
|
// Save the current window frame before animating out. This preserves
|
||||||
|
// the user's preferred window size and position for when the quick
|
||||||
|
// terminal is reactivated with a new surface. Without this, SwiftUI
|
||||||
|
// would reset the window to its minimum content size.
|
||||||
|
lastClosedFrame = window.frame
|
||||||
|
|
||||||
// If we hid the dock then we unhide it.
|
// If we hid the dock then we unhide it.
|
||||||
hiddenDock = nil
|
hiddenDock = nil
|
||||||
|
|
||||||
|
|||||||
@@ -92,6 +92,12 @@ extension Ghostty {
|
|||||||
return ghostty_surface_needs_confirm_quit(surface)
|
return ghostty_surface_needs_confirm_quit(surface)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Retruns true if the process in this surface has exited.
|
||||||
|
var processExited: Bool {
|
||||||
|
guard let surface = self.surface else { return true }
|
||||||
|
return ghostty_surface_process_exited(surface)
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the inspector instance for this surface, or nil if the
|
// Returns the inspector instance for this surface, or nil if the
|
||||||
// surface has been closed.
|
// surface has been closed.
|
||||||
var inspector: ghostty_inspector_t? {
|
var inspector: ghostty_inspector_t? {
|
||||||
|
|||||||
@@ -1359,6 +1359,11 @@ pub const CAPI = struct {
|
|||||||
return surface.core_surface.needsConfirmQuit();
|
return surface.core_surface.needsConfirmQuit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if the surface process has exited.
|
||||||
|
export fn ghostty_surface_process_exited(surface: *Surface) bool {
|
||||||
|
return surface.core_surface.child_exited;
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns true if the surface has a selection.
|
/// Returns true if the surface has a selection.
|
||||||
export fn ghostty_surface_has_selection(surface: *Surface) bool {
|
export fn ghostty_surface_has_selection(surface: *Surface) bool {
|
||||||
return surface.core_surface.hasSelection();
|
return surface.core_surface.hasSelection();
|
||||||
|
|||||||
Reference in New Issue
Block a user