mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
feat(linux): allow setting an intial start position
This commit is contained in:

committed by
Mitchell Hashimoto

parent
600e417154
commit
5ced72498e
@ -577,6 +577,7 @@ typedef enum {
|
|||||||
GHOSTTY_ACTION_PRESENT_TERMINAL,
|
GHOSTTY_ACTION_PRESENT_TERMINAL,
|
||||||
GHOSTTY_ACTION_SIZE_LIMIT,
|
GHOSTTY_ACTION_SIZE_LIMIT,
|
||||||
GHOSTTY_ACTION_INITIAL_SIZE,
|
GHOSTTY_ACTION_INITIAL_SIZE,
|
||||||
|
GHOSTTY_ACTION_INITIAL_POSITION,
|
||||||
GHOSTTY_ACTION_CELL_SIZE,
|
GHOSTTY_ACTION_CELL_SIZE,
|
||||||
GHOSTTY_ACTION_INSPECTOR,
|
GHOSTTY_ACTION_INSPECTOR,
|
||||||
GHOSTTY_ACTION_RENDER_INSPECTOR,
|
GHOSTTY_ACTION_RENDER_INSPECTOR,
|
||||||
|
@ -621,6 +621,8 @@ pub fn init(
|
|||||||
const width = @max(config.@"window-width" * cell_size.width, 640);
|
const width = @max(config.@"window-width" * cell_size.width, 640);
|
||||||
const width_f32: f32 = @floatFromInt(width);
|
const width_f32: f32 = @floatFromInt(width);
|
||||||
const height_f32: f32 = @floatFromInt(height);
|
const height_f32: f32 = @floatFromInt(height);
|
||||||
|
const position_x = config.@"window-position-x";
|
||||||
|
const position_y = config.@"window-position-y";
|
||||||
|
|
||||||
// The final values are affected by content scale and we need to
|
// The final values are affected by content scale and we need to
|
||||||
// account for the padding so we get the exact correct grid size.
|
// account for the padding so we get the exact correct grid size.
|
||||||
@ -642,6 +644,14 @@ pub fn init(
|
|||||||
// an initial size shouldn't stop our terminal from working.
|
// an initial size shouldn't stop our terminal from working.
|
||||||
log.warn("unable to set initial window size: {s}", .{err});
|
log.warn("unable to set initial window size: {s}", .{err});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
rt_app.performAction(
|
||||||
|
.{ .surface = self },
|
||||||
|
.initial_position,
|
||||||
|
.{ .x = position_x, .y = position_y },
|
||||||
|
) catch |err| {
|
||||||
|
log.warn("unable to set initial window position: {s}", .{err});
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.title) |title| {
|
if (config.title) |title| {
|
||||||
|
@ -136,6 +136,11 @@ pub const Action = union(Key) {
|
|||||||
/// after the surface is initialized it should be ignored.
|
/// after the surface is initialized it should be ignored.
|
||||||
initial_size: InitialSize,
|
initial_size: InitialSize,
|
||||||
|
|
||||||
|
// Specifies the initial position of the target terminal. This will be
|
||||||
|
// sent only during the initialization of a surface. If it is received
|
||||||
|
// after the surface is initialized it should be ignored.
|
||||||
|
initial_position: InitialPosition,
|
||||||
|
|
||||||
/// The cell size has changed to the given dimensions in pixels.
|
/// The cell size has changed to the given dimensions in pixels.
|
||||||
cell_size: CellSize,
|
cell_size: CellSize,
|
||||||
|
|
||||||
@ -237,6 +242,7 @@ pub const Action = union(Key) {
|
|||||||
present_terminal,
|
present_terminal,
|
||||||
size_limit,
|
size_limit,
|
||||||
initial_size,
|
initial_size,
|
||||||
|
initial_position,
|
||||||
cell_size,
|
cell_size,
|
||||||
inspector,
|
inspector,
|
||||||
render_inspector,
|
render_inspector,
|
||||||
@ -427,6 +433,11 @@ pub const InitialSize = extern struct {
|
|||||||
height: u32,
|
height: u32,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const InitialPosition = extern struct {
|
||||||
|
x: i32,
|
||||||
|
y: i32,
|
||||||
|
};
|
||||||
|
|
||||||
pub const CellSize = extern struct {
|
pub const CellSize = extern struct {
|
||||||
width: u32,
|
width: u32,
|
||||||
height: u32,
|
height: u32,
|
||||||
|
@ -178,6 +178,14 @@ pub const App = struct {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
.initial_position => switch (target) {
|
||||||
|
.app => {},
|
||||||
|
.surface => |surface| surface.rt_surface.setInitialWindowPosition(
|
||||||
|
value.x,
|
||||||
|
value.y,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
|
||||||
.toggle_fullscreen => self.toggleFullscreen(target),
|
.toggle_fullscreen => self.toggleFullscreen(target),
|
||||||
|
|
||||||
.open_config => try configpkg.edit.open(self.app.alloc),
|
.open_config => try configpkg.edit.open(self.app.alloc),
|
||||||
@ -663,6 +671,15 @@ pub const Surface = struct {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the initial window position. This is called exactly once at
|
||||||
|
/// surface initialization time. This may be called before "self"
|
||||||
|
/// is fully initialized.
|
||||||
|
fn setInitialWindowPosition(self: *const Surface, x: i32, y: i32) void {
|
||||||
|
log.debug("setting initial window position ({},{})", .{ x, y });
|
||||||
|
|
||||||
|
self.window.setPos(.{ .x = x, .y = y });
|
||||||
|
}
|
||||||
|
|
||||||
/// Set the size limits of the window.
|
/// Set the size limits of the window.
|
||||||
/// Note: this interface is not good, we should redo it if we plan
|
/// Note: this interface is not good, we should redo it if we plan
|
||||||
/// to use this more. i.e. you can't set max width but no max height,
|
/// to use this more. i.e. you can't set max width but no max height,
|
||||||
|
@ -786,6 +786,21 @@ fn setInitialSize(
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn setInitialPosition(
|
||||||
|
_: *App,
|
||||||
|
target: apprt.Target,
|
||||||
|
value: apprt.action.InitialPosition,
|
||||||
|
) void {
|
||||||
|
switch (target) {
|
||||||
|
.app => {},
|
||||||
|
.surface => |v| v.rt_surface.setInitialWindowPosition(
|
||||||
|
value.x,
|
||||||
|
value.y,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn showDesktopNotification(
|
fn showDesktopNotification(
|
||||||
self: *App,
|
self: *App,
|
||||||
target: apprt.Target,
|
target: apprt.Target,
|
||||||
|
@ -840,6 +840,12 @@ pub fn setInitialWindowSize(self: *const Surface, width: u32, height: u32) !void
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn setInitialWindowPosition(self: *const Surface, x: i32, y: i32) !void {
|
||||||
|
// We need the surface's window to set the position.
|
||||||
|
const window = self.container.window() orelse return;
|
||||||
|
c.gtk_window_move(@ptrCast(window.window), x, y);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn grabFocus(self: *Surface) void {
|
pub fn grabFocus(self: *Surface) void {
|
||||||
if (self.container.tab()) |tab| {
|
if (self.container.tab()) |tab| {
|
||||||
// If any other surface was focused and zoomed in, set it to non zoomed in
|
// If any other surface was focused and zoomed in, set it to non zoomed in
|
||||||
|
@ -1108,6 +1108,19 @@ keybind: Keybinds = .{},
|
|||||||
@"window-height": u32 = 0,
|
@"window-height": u32 = 0,
|
||||||
@"window-width": u32 = 0,
|
@"window-width": u32 = 0,
|
||||||
|
|
||||||
|
/// The initial window position. This position is in pixels and is relative
|
||||||
|
/// to the top-left corner of the screen. Both values must be set to take
|
||||||
|
/// effect. If only one value is set, it is ignored.
|
||||||
|
///
|
||||||
|
/// Note that the window manager may put limits on the position or override
|
||||||
|
/// the position. For example, a tiling window manager may force the window
|
||||||
|
/// to be a certain position to fit within the grid. There is nothing Ghostty
|
||||||
|
/// will do about this, but it will make an effort.
|
||||||
|
///
|
||||||
|
/// This will default to the top-left corner of the screen if not set (0, 0).
|
||||||
|
@"window-position-x": i32 = 0,
|
||||||
|
@"window-position-y": i32 = 0,
|
||||||
|
|
||||||
/// Whether to enable saving and restoring window state. Window state includes
|
/// Whether to enable saving and restoring window state. Window state includes
|
||||||
/// their position, size, tabs, splits, etc. Some window state requires shell
|
/// their position, size, tabs, splits, etc. Some window state requires shell
|
||||||
/// integration, such as preserving working directories. See `shell-integration`
|
/// integration, such as preserving working directories. See `shell-integration`
|
||||||
|
Reference in New Issue
Block a user