initial window size needs to take into account window chrome

This commit is contained in:
Mitchell Hashimoto
2023-09-30 21:35:50 -07:00
parent cc8e1cd936
commit a1a8aeb104
6 changed files with 97 additions and 87 deletions

View File

@@ -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 {

View File

@@ -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();

View File

@@ -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,