macos: handle setting initial window position when window is created

This commit is contained in:
Adam Wolf
2024-12-31 00:50:07 -06:00
committed by Mitchell Hashimoto
parent 970e45559b
commit 200d0d642b
4 changed files with 48 additions and 27 deletions

View File

@ -368,10 +368,10 @@ class TerminalController: BaseTerminalController {
}
}
// Center the window to start, we'll move the window frame automatically
// when cascading.
window.center()
// Set our window positioning to coordinates if config value exists, otherwise
// fallback to original centering behavior
setInitialWindowPosition(window, x: config.windowPositionX, y: config.windowPositionY, windowDecorations: config.windowDecorations)
// Make sure our theme is set on the window so styling is correct.
if let windowTheme = config.windowTheme {
window.windowTheme = .init(rawValue: windowTheme)
@ -468,6 +468,31 @@ class TerminalController: BaseTerminalController {
let data = TerminalRestorableState(from: self)
data.encode(with: state)
}
func setInitialWindowPosition(_ window: NSWindow, x: Int16?, y: Int16?, windowDecorations: Bool) {
if let primaryScreen = NSScreen.screens.first {
let frame = primaryScreen.visibleFrame
if let windowPositionX = x, let windowPositionY = y {
// Offset titlebar if needed, otherwise use default padding of 12
// NOTE: Not 100% certain where this extra padding comes from but I'd love
// to calculate it dynamically if possible
let titlebarHeight = windowDecorations ? window.frame.height - (window.contentView?.frame.height ?? 0) : 12
// Orient based on the top left of the primary monitor
let startPositionX = frame.origin.x + CGFloat(windowPositionX)
let startPositionY = (frame.origin.y + frame.height) - (CGFloat(windowPositionY) + window.frame.height) + titlebarHeight
window.setFrameOrigin(NSPoint(x: startPositionX, y: startPositionY))
} else {
// Fallback to original centering behavior
window.center()
}
} else {
// Fallback to original centering behavior
window.center()
}
}
// MARK: First Responder

View File

@ -517,9 +517,6 @@ extension Ghostty {
case GHOSTTY_ACTION_INITIAL_SIZE:
setInitialSize(app, target: target, v: action.action.initial_size)
case GHOSTTY_ACTION_INITIAL_POSITION:
setInitialPosition(app, target: target, v: action.action.initial_position)
case GHOSTTY_ACTION_CELL_SIZE:
setCellSize(app, target: target, v: action.action.cell_size)
@ -1072,26 +1069,6 @@ extension Ghostty {
}
}
private static func setInitialPosition(
_ app: ghostty_app_t,
target: ghostty_target_s,
v: ghostty_action_initial_position_s) {
switch (target.tag) {
case GHOSTTY_TARGET_APP:
Ghostty.logger.warning("mouse over link does nothing with an app target")
return
case GHOSTTY_TARGET_SURFACE:
guard let surface = target.target.surface else { return }
guard let surfaceView = self.surfaceView(from: surface) else { return }
surfaceView.initialPosition = NSMakePoint(Double(v.x), Double(v.y))
default:
assertionFailure()
}
}
private static func setCellSize(
_ app: ghostty_app_t,
target: ghostty_target_s,

View File

@ -149,6 +149,20 @@ extension Ghostty {
guard let ptr = v else { return "" }
return String(cString: ptr)
}
var windowPositionX: Int16? {
guard let config = self.config else { return nil }
var v: Int16 = 0
let key = "window-position-x"
return ghostty_config_get(config, &v, key, UInt(key.count)) ? v : nil
}
var windowPositionY: Int16? {
guard let config = self.config else { return nil }
var v: Int16 = 0
let key = "window-position-y"
return ghostty_config_get(config, &v, key, UInt(key.count)) ? v : nil
}
var windowNewTabPosition: String {
guard let config = self.config else { return "" }

View File

@ -42,6 +42,11 @@ fn getValue(ptr_raw: *anyopaque, value: anytype) bool {
ptr.* = @intCast(value);
},
i16 => {
const ptr: *c_short = @ptrCast(@alignCast(ptr_raw));
ptr.* = @intCast(value);
},
f32, f64 => |Float| {
const ptr: *Float = @ptrCast(@alignCast(ptr_raw));
ptr.* = @floatCast(value);