mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-10-17 15:21:50 +00:00
initial window size needs to take into account window chrome
This commit is contained in:
@@ -471,6 +471,36 @@ pub fn init(
|
||||
.{&self.io_thread},
|
||||
);
|
||||
self.io_thr.setName("io") catch {};
|
||||
|
||||
// Determine our initial window size if configured. We need to do this
|
||||
// quite late in the process because our height/width are in grid dimensions,
|
||||
// so we need to know our cell sizes first.
|
||||
//
|
||||
// Note: it is important to do this after the renderer is setup above.
|
||||
// This allows the apprt to fully initialize the surface before we
|
||||
// start messing with the window.
|
||||
if (config.@"window-height" > 0 and config.@"window-width" > 0) init: {
|
||||
const scale = rt_surface.getContentScale() catch break :init;
|
||||
const height = @max(config.@"window-height" * cell_size.height, 480);
|
||||
const width = @max(config.@"window-width" * cell_size.width, 640);
|
||||
const width_f32: f32 = @floatFromInt(width);
|
||||
const height_f32: f32 = @floatFromInt(height);
|
||||
|
||||
// The final values are affected by content scale and we need to
|
||||
// account for the padding so we get the exact correct grid size.
|
||||
const final_width: u32 =
|
||||
@as(u32, @intFromFloat(@ceil(width_f32 / scale.x))) +
|
||||
padding.left +
|
||||
padding.right;
|
||||
const final_height: u32 =
|
||||
@as(u32, @intFromFloat(@ceil(height_f32 / scale.y))) +
|
||||
padding.top +
|
||||
padding.bottom;
|
||||
|
||||
rt_surface.setInitialWindowSize(final_width, final_height) catch |err| {
|
||||
log.warn("unable to set initial window size: {s}", .{err});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Surface) void {
|
||||
|
@@ -87,6 +87,10 @@ pub const App = struct {
|
||||
|
||||
/// Toggle fullscreen for current window.
|
||||
toggle_fullscreen: ?*const fn (SurfaceUD, configpkg.NonNativeFullscreen) callconv(.C) void = null,
|
||||
|
||||
/// Set the initial window size. It is up to the user of libghostty to
|
||||
/// determine if it is the initial window and set this appropriately.
|
||||
set_initial_window_size: ?*const fn (SurfaceUD, u32, u32) callconv(.C) void = null,
|
||||
};
|
||||
|
||||
/// Special values for the goto_tab callback.
|
||||
@@ -734,6 +738,15 @@ pub const Surface = struct {
|
||||
func(self.opts.userdata, options);
|
||||
}
|
||||
|
||||
pub fn setInitialWindowSize(self: *const Surface, width: u32, height: u32) !void {
|
||||
const func = self.app.opts.set_initial_window_size orelse {
|
||||
log.info("runtime embedder does not set_initial_window_size", .{});
|
||||
return;
|
||||
};
|
||||
|
||||
func(self.opts.userdata, width, height);
|
||||
}
|
||||
|
||||
fn newSurfaceOptions(self: *const Surface) apprt.Surface.Options {
|
||||
const font_size: u16 = font_size: {
|
||||
if (!self.app.config.@"window-inherit-font-size") break :font_size 0;
|
||||
@@ -757,16 +770,6 @@ pub const Surface = struct {
|
||||
pub const CAPI = struct {
|
||||
const global = &@import("../main.zig").state;
|
||||
|
||||
/// ghostty_rect_s
|
||||
const Rect = extern struct {
|
||||
origin: bool = false,
|
||||
size: bool = false,
|
||||
x: u32 = 0,
|
||||
y: u32 = 0,
|
||||
w: u32 = 0,
|
||||
h: u32 = 0,
|
||||
};
|
||||
|
||||
/// Create a new app.
|
||||
export fn ghostty_app_new(
|
||||
opts: *const apprt.runtime.App.Options,
|
||||
@@ -874,21 +877,6 @@ pub const CAPI = struct {
|
||||
return surface.app.config.@"background-opacity" < 1.0;
|
||||
}
|
||||
|
||||
/// The desired window frame for a new window.
|
||||
export fn ghostty_surface_window_frame(surface: *Surface) Rect {
|
||||
const config = surface.app.config;
|
||||
|
||||
// If the desired height/width isn't configured, return 0.
|
||||
if (config.@"window-height" == 0 or config.@"window-width" == 0) return .{};
|
||||
|
||||
// Return the desired rect
|
||||
return .{
|
||||
.size = true,
|
||||
.h = @max(config.@"window-height" * surface.core_surface.cell_size.height, 480),
|
||||
.w = @max(config.@"window-width" * surface.core_surface.cell_size.width, 640),
|
||||
};
|
||||
}
|
||||
|
||||
/// Tell the surface that it needs to schedule a render
|
||||
export fn ghostty_surface_refresh(surface: *Surface) void {
|
||||
surface.refresh();
|
||||
|
@@ -376,15 +376,6 @@ pub const Surface = struct {
|
||||
self,
|
||||
);
|
||||
errdefer self.core_surface.deinit();
|
||||
|
||||
// If we have a desired window size, we can now calculate the size
|
||||
// because we have the cell size.
|
||||
if (config.@"window-height" > 0 or config.@"window-width" > 0) {
|
||||
self.window.setSize(.{
|
||||
.height = @max(config.@"window-height" * self.core_surface.cell_size.height, 480),
|
||||
.width = @max(config.@"window-width" * self.core_surface.cell_size.width, 640),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Surface) void {
|
||||
@@ -456,6 +447,13 @@ pub const Surface = struct {
|
||||
self.app.app.alloc.destroy(self);
|
||||
}
|
||||
|
||||
/// Set the initial window size. This is called exactly once at
|
||||
/// surface initialization time. This may be called before "self"
|
||||
/// is fully initialized.
|
||||
pub fn setInitialWindowSize(self: *const Surface, width: u32, height: u32) !void {
|
||||
self.window.setSize(.{ .width = width, .height = height });
|
||||
}
|
||||
|
||||
/// Set the size limits of the window.
|
||||
/// 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,
|
||||
|
Reference in New Issue
Block a user