mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
Remember last focused window position for next startup
This commit is contained in:

committed by
Mitchell Hashimoto

parent
d1614f6bc4
commit
31273aaabc
@ -72,6 +72,7 @@
|
|||||||
A5A2A3CA2D4445E30033CF96 /* Dock.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A2A3C92D4445E20033CF96 /* Dock.swift */; };
|
A5A2A3CA2D4445E30033CF96 /* Dock.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A2A3C92D4445E20033CF96 /* Dock.swift */; };
|
||||||
A5A2A3CC2D444ABB0033CF96 /* NSApplication+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A2A3CB2D444AB80033CF96 /* NSApplication+Extension.swift */; };
|
A5A2A3CC2D444ABB0033CF96 /* NSApplication+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A2A3CB2D444AB80033CF96 /* NSApplication+Extension.swift */; };
|
||||||
A5A6F72A2CC41B8900B232A5 /* Xcode.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A6F7292CC41B8700B232A5 /* Xcode.swift */; };
|
A5A6F72A2CC41B8900B232A5 /* Xcode.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A6F7292CC41B8700B232A5 /* Xcode.swift */; };
|
||||||
|
A5AEB1652D5BE7D000513529 /* LastWindowPosition.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5AEB1642D5BE7BF00513529 /* LastWindowPosition.swift */; };
|
||||||
A5B30539299BEAAB0047F10C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A5B30538299BEAAB0047F10C /* Assets.xcassets */; };
|
A5B30539299BEAAB0047F10C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A5B30538299BEAAB0047F10C /* Assets.xcassets */; };
|
||||||
A5CA378C2D2A4DEB00931030 /* KeyboardLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CA378B2D2A4DE800931030 /* KeyboardLayout.swift */; };
|
A5CA378C2D2A4DEB00931030 /* KeyboardLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CA378B2D2A4DE800931030 /* KeyboardLayout.swift */; };
|
||||||
A5CA378E2D31D6C300931030 /* Weak.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CA378D2D31D6C100931030 /* Weak.swift */; };
|
A5CA378E2D31D6C300931030 /* Weak.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CA378D2D31D6C100931030 /* Weak.swift */; };
|
||||||
@ -168,6 +169,7 @@
|
|||||||
A5A2A3C92D4445E20033CF96 /* Dock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dock.swift; sourceTree = "<group>"; };
|
A5A2A3C92D4445E20033CF96 /* Dock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dock.swift; sourceTree = "<group>"; };
|
||||||
A5A2A3CB2D444AB80033CF96 /* NSApplication+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSApplication+Extension.swift"; sourceTree = "<group>"; };
|
A5A2A3CB2D444AB80033CF96 /* NSApplication+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSApplication+Extension.swift"; sourceTree = "<group>"; };
|
||||||
A5A6F7292CC41B8700B232A5 /* Xcode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Xcode.swift; sourceTree = "<group>"; };
|
A5A6F7292CC41B8700B232A5 /* Xcode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Xcode.swift; sourceTree = "<group>"; };
|
||||||
|
A5AEB1642D5BE7BF00513529 /* LastWindowPosition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LastWindowPosition.swift; 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; };
|
||||||
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>"; };
|
||||||
@ -270,6 +272,7 @@
|
|||||||
A534263D2A7DCBB000EBB7A2 /* Helpers */ = {
|
A534263D2A7DCBB000EBB7A2 /* Helpers */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
A5AEB1642D5BE7BF00513529 /* LastWindowPosition.swift */,
|
||||||
A5A6F7292CC41B8700B232A5 /* Xcode.swift */,
|
A5A6F7292CC41B8700B232A5 /* Xcode.swift */,
|
||||||
A5CEAFFE29C2410700646FDA /* Backport.swift */,
|
A5CEAFFE29C2410700646FDA /* Backport.swift */,
|
||||||
A5333E1B2B5A1CE3008AEFF7 /* CrossKit.swift */,
|
A5333E1B2B5A1CE3008AEFF7 /* CrossKit.swift */,
|
||||||
@ -623,6 +626,7 @@
|
|||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
A5AEB1652D5BE7D000513529 /* LastWindowPosition.swift in Sources */,
|
||||||
A59630A42AF059BB00D64628 /* Ghostty.SplitNode.swift in Sources */,
|
A59630A42AF059BB00D64628 /* Ghostty.SplitNode.swift in Sources */,
|
||||||
A514C8D62B54A16400493A16 /* Ghostty.Config.swift in Sources */,
|
A514C8D62B54A16400493A16 /* Ghostty.Config.swift in Sources */,
|
||||||
A54B0CEB2D0CFB4C00CBEFF8 /* NSImage+Extension.swift in Sources */,
|
A54B0CEB2D0CFB4C00CBEFF8 /* NSImage+Extension.swift in Sources */,
|
||||||
|
@ -283,9 +283,12 @@ class TerminalController: BaseTerminalController {
|
|||||||
private func setInitialWindowPosition(x: Int16?, y: Int16?, windowDecorations: Bool) {
|
private func setInitialWindowPosition(x: Int16?, y: Int16?, windowDecorations: Bool) {
|
||||||
guard let window else { return }
|
guard let window else { return }
|
||||||
|
|
||||||
// If we don't have both an X and Y we center.
|
// If we don't have an X/Y then we try to use the previously saved window pos.
|
||||||
guard let x, let y else {
|
guard let x, let y else {
|
||||||
|
if (!LastWindowPosition.shared.restore(window)) {
|
||||||
window.center()
|
window.center()
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -490,6 +493,20 @@ class TerminalController: BaseTerminalController {
|
|||||||
override func windowDidMove(_ notification: Notification) {
|
override func windowDidMove(_ notification: Notification) {
|
||||||
super.windowDidMove(notification)
|
super.windowDidMove(notification)
|
||||||
self.fixTabBar()
|
self.fixTabBar()
|
||||||
|
|
||||||
|
// Whenever we move save our last position for the next start.
|
||||||
|
if let window {
|
||||||
|
LastWindowPosition.shared.save(window)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func windowDidBecomeMain(_ notification: Notification) {
|
||||||
|
// Whenever we get focused, use that as our last window position for
|
||||||
|
// restart. This differs from Terminal.app but matches iTerm2 behavior
|
||||||
|
// and I think its sensible.
|
||||||
|
if let window {
|
||||||
|
LastWindowPosition.shared.save(window)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when the window will be encoded. We handle the data encoding here in the
|
// Called when the window will be encoded. We handle the data encoding here in the
|
||||||
|
34
macos/Sources/Helpers/LastWindowPosition.swift
Normal file
34
macos/Sources/Helpers/LastWindowPosition.swift
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import Cocoa
|
||||||
|
|
||||||
|
/// Manages the persistence and restoration of window positions across app launches.
|
||||||
|
class LastWindowPosition {
|
||||||
|
static let shared = LastWindowPosition()
|
||||||
|
|
||||||
|
private let positionKey = "NSWindowLastPosition"
|
||||||
|
|
||||||
|
func save(_ window: NSWindow) {
|
||||||
|
let origin = window.frame.origin
|
||||||
|
let point = [origin.x, origin.y]
|
||||||
|
UserDefaults.standard.set(point, forKey: positionKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
func restore(_ window: NSWindow) -> Bool {
|
||||||
|
guard let points = UserDefaults.standard.array(forKey: positionKey) as? [Double],
|
||||||
|
points.count == 2 else { return false }
|
||||||
|
|
||||||
|
let lastPosition = CGPoint(x: points[0], y: points[1])
|
||||||
|
|
||||||
|
guard let screen = window.screen ?? NSScreen.main else { return false }
|
||||||
|
let visibleFrame = screen.visibleFrame
|
||||||
|
|
||||||
|
var newFrame = window.frame
|
||||||
|
newFrame.origin = lastPosition
|
||||||
|
if !visibleFrame.contains(newFrame.origin) {
|
||||||
|
newFrame.origin.x = max(visibleFrame.minX, min(visibleFrame.maxX - newFrame.width, newFrame.origin.x))
|
||||||
|
newFrame.origin.y = max(visibleFrame.minY, min(visibleFrame.maxY - newFrame.height, newFrame.origin.y))
|
||||||
|
}
|
||||||
|
|
||||||
|
window.setFrame(newFrame, display: true)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user