mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
macos: quick terminal restores focus to previous application
This commit is contained in:
@ -13,6 +13,11 @@ class QuickTerminalController: BaseTerminalController {
|
|||||||
/// The current state of the quick terminal
|
/// The current state of the quick terminal
|
||||||
private(set) var visible: Bool = false
|
private(set) var visible: Bool = false
|
||||||
|
|
||||||
|
/// The previously running application when the terminal is shown. This is NEVER Ghostty.
|
||||||
|
/// If this is set then when the quick terminal is animated out then we will restore this
|
||||||
|
/// application to the front.
|
||||||
|
private var previousApp: NSRunningApplication? = nil
|
||||||
|
|
||||||
init(_ ghostty: Ghostty.App,
|
init(_ ghostty: Ghostty.App,
|
||||||
position: QuickTerminalPosition = .top,
|
position: QuickTerminalPosition = .top,
|
||||||
baseConfig base: Ghostty.SurfaceConfiguration? = nil,
|
baseConfig base: Ghostty.SurfaceConfiguration? = nil,
|
||||||
@ -58,10 +63,23 @@ class QuickTerminalController: BaseTerminalController {
|
|||||||
override func windowDidResignKey(_ notification: Notification) {
|
override func windowDidResignKey(_ notification: Notification) {
|
||||||
super.windowDidResignKey(notification)
|
super.windowDidResignKey(notification)
|
||||||
|
|
||||||
|
// If we're not visible then we don't want to run any of the logic below
|
||||||
|
// because things like resetting our previous app assume we're visible.
|
||||||
|
// windowDidResignKey will also get called after animateOut so this
|
||||||
|
// ensures we don't run logic twice.
|
||||||
|
guard visible else { return }
|
||||||
|
|
||||||
// We don't animate out if there is a modal sheet being shown currently.
|
// We don't animate out if there is a modal sheet being shown currently.
|
||||||
// This lets us show alerts without causing the window to disappear.
|
// This lets us show alerts without causing the window to disappear.
|
||||||
guard window?.attachedSheet == nil else { return }
|
guard window?.attachedSheet == nil else { return }
|
||||||
|
|
||||||
|
// If our app is still active, then it means that we're switching
|
||||||
|
// to another window within our app, so we remove the previous app
|
||||||
|
// so we don't restore it.
|
||||||
|
if NSApp.isActive {
|
||||||
|
self.previousApp = nil
|
||||||
|
}
|
||||||
|
|
||||||
animateOut()
|
animateOut()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,6 +121,14 @@ class QuickTerminalController: BaseTerminalController {
|
|||||||
// If our application is not active, then we grab focus. The quick terminal
|
// If our application is not active, then we grab focus. The quick terminal
|
||||||
// always grabs focus on animation in.
|
// always grabs focus on animation in.
|
||||||
if !NSApp.isActive {
|
if !NSApp.isActive {
|
||||||
|
// If we have a previously focused application and it isn't us, then
|
||||||
|
// we want to store it so we can restore state later.
|
||||||
|
if let previousApp = NSWorkspace.shared.frontmostApplication,
|
||||||
|
previousApp.bundleIdentifier != Bundle.main.bundleIdentifier
|
||||||
|
{
|
||||||
|
self.previousApp = previousApp
|
||||||
|
}
|
||||||
|
|
||||||
NSApp.activate(ignoringOtherApps: true)
|
NSApp.activate(ignoringOtherApps: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,6 +204,18 @@ class QuickTerminalController: BaseTerminalController {
|
|||||||
// This causes the window to be removed from the screen list and macOS
|
// This causes the window to be removed from the screen list and macOS
|
||||||
// handles what should be focused next.
|
// handles what should be focused next.
|
||||||
window.orderOut(self)
|
window.orderOut(self)
|
||||||
|
|
||||||
|
// If we have a previously active application, restore focus to it.
|
||||||
|
if let previousApp = self.previousApp {
|
||||||
|
// Make sure we unset the state no matter what
|
||||||
|
self.previousApp = nil
|
||||||
|
|
||||||
|
// If the app is terminated to nothing
|
||||||
|
guard !previousApp.isTerminated else { return }
|
||||||
|
|
||||||
|
// Ignore the result, it doesn't change our behavior.
|
||||||
|
_ = previousApp.activate(options: [])
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user