mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
content scale change events should also impact viewport padding
This calculates the new padding pixel values and propogates those changes to the renderer.
This commit is contained in:
@ -139,6 +139,8 @@ const DerivedConfig = struct {
|
||||
mouse_interval: u64,
|
||||
macos_non_native_fullscreen: configpkg.NonNativeFullscreen,
|
||||
macos_option_as_alt: configpkg.OptionAsAlt,
|
||||
window_padding_x: u32,
|
||||
window_padding_y: u32,
|
||||
|
||||
pub fn init(alloc_gpa: Allocator, config: *const configpkg.Config) !DerivedConfig {
|
||||
var arena = ArenaAllocator.init(alloc_gpa);
|
||||
@ -156,6 +158,8 @@ const DerivedConfig = struct {
|
||||
.mouse_interval = config.@"click-repeat-interval" * 1_000_000, // 500ms
|
||||
.macos_non_native_fullscreen = config.@"macos-non-native-fullscreen",
|
||||
.macos_option_as_alt = config.@"macos-option-as-alt",
|
||||
.window_padding_x = config.@"window-padding-x",
|
||||
.window_padding_y = config.@"window-padding-y",
|
||||
|
||||
// Assignments happen sequentially so we have to do this last
|
||||
// so that the memory is captured from allocs above.
|
||||
@ -871,12 +875,19 @@ pub fn sizeCallback(self: *Surface, size: apprt.SurfaceSize) !void {
|
||||
// changed, so we just return.
|
||||
if (self.screen_size.equals(new_screen_size)) return;
|
||||
|
||||
try self.resize(new_screen_size);
|
||||
}
|
||||
|
||||
fn resize(self: *Surface, size: renderer.ScreenSize) !void {
|
||||
// Save our screen size
|
||||
self.screen_size = new_screen_size;
|
||||
self.screen_size = size;
|
||||
|
||||
// Mail the renderer so that it can update the GPU and re-render
|
||||
_ = self.renderer_thread.mailbox.push(.{
|
||||
.screen_size = self.screen_size,
|
||||
.resize = .{
|
||||
.screen_size = self.screen_size,
|
||||
.padding = self.padding,
|
||||
},
|
||||
}, .{ .forever = {} });
|
||||
try self.queueRender();
|
||||
|
||||
@ -1192,16 +1203,50 @@ pub fn scrollCallback(
|
||||
try self.queueRender();
|
||||
}
|
||||
|
||||
pub fn contentScaleCallback(self: *Surface, content_scale: apprt.ContentScale) void {
|
||||
/// This is called when the content scale of the surface changes. The surface
|
||||
/// can then update any DPI-sensitive state.
|
||||
pub fn contentScaleCallback(self: *Surface, content_scale: apprt.ContentScale) !void {
|
||||
// Calculate the new DPI
|
||||
const x_dpi = content_scale.x * font.face.default_dpi;
|
||||
const y_dpi = content_scale.y * font.face.default_dpi;
|
||||
|
||||
// Update our font size which is dependent on the DPI
|
||||
const size = size: {
|
||||
var size = self.font_size;
|
||||
size.xdpi = @intFromFloat(x_dpi);
|
||||
size.ydpi = @intFromFloat(y_dpi);
|
||||
break :size size;
|
||||
};
|
||||
|
||||
// If our DPI didn't actually change, save a lot of work by doing nothing.
|
||||
if (size.xdpi == self.font_size.xdpi and size.ydpi == self.font_size.ydpi) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.setFontSize(size);
|
||||
|
||||
// Update our padding which is dependent on DPI.
|
||||
self.padding = padding: {
|
||||
const padding_x: u32 = padding_x: {
|
||||
const padding_x: f32 = @floatFromInt(self.config.window_padding_x);
|
||||
break :padding_x @intFromFloat(@floor(padding_x * x_dpi / 72));
|
||||
};
|
||||
const padding_y: u32 = padding_y: {
|
||||
const padding_y: f32 = @floatFromInt(self.config.window_padding_y);
|
||||
break :padding_y @intFromFloat(@floor(padding_y * y_dpi / 72));
|
||||
};
|
||||
|
||||
break :padding .{
|
||||
.top = padding_y,
|
||||
.bottom = padding_y,
|
||||
.right = padding_x,
|
||||
.left = padding_x,
|
||||
};
|
||||
};
|
||||
|
||||
// Force a resize event because the change in padding will affect
|
||||
// pixel-level changes to the renderer and viewport.
|
||||
try self.resize(self.screen_size);
|
||||
}
|
||||
|
||||
/// The type of action to report for a mouse event.
|
||||
|
@ -350,7 +350,10 @@ pub const Surface = struct {
|
||||
.y = @floatCast(y),
|
||||
};
|
||||
|
||||
self.core_surface.contentScaleCallback(self.content_scale);
|
||||
self.core_surface.contentScaleCallback(self.content_scale) catch |err| {
|
||||
log.err("error in content scale callback err={}", .{err});
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
pub fn updateSize(self: *Surface, width: u32, height: u32) void {
|
||||
|
@ -1048,9 +1048,14 @@ pub fn changeConfig(self: *Metal, config: *DerivedConfig) !void {
|
||||
}
|
||||
|
||||
/// Resize the screen.
|
||||
pub fn setScreenSize(self: *Metal, dim: renderer.ScreenSize) !void {
|
||||
// Store our screen size
|
||||
pub fn setScreenSize(
|
||||
self: *Metal,
|
||||
dim: renderer.ScreenSize,
|
||||
pad: renderer.Padding,
|
||||
) !void {
|
||||
// Store our sizes
|
||||
self.screen_size = dim;
|
||||
self.padding.explicit = pad;
|
||||
|
||||
// Recalculate the rows/columns. This can't fail since we just set
|
||||
// the screen size above.
|
||||
|
@ -1427,12 +1427,17 @@ pub fn changeConfig(self: *OpenGL, config: *DerivedConfig) !void {
|
||||
|
||||
/// Set the screen size for rendering. This will update the projection
|
||||
/// used for the shader so that the scaling of the grid is correct.
|
||||
pub fn setScreenSize(self: *OpenGL, dim: renderer.ScreenSize) !void {
|
||||
pub fn setScreenSize(
|
||||
self: *OpenGL,
|
||||
dim: renderer.ScreenSize,
|
||||
pad: renderer.Padding,
|
||||
) !void {
|
||||
if (single_threaded_draw) self.draw_mutex.lock();
|
||||
defer if (single_threaded_draw) self.draw_mutex.unlock();
|
||||
|
||||
// Store our screen size
|
||||
self.screen_size = dim;
|
||||
self.padding.explicit = pad;
|
||||
|
||||
// Recalculate the rows/columns.
|
||||
const grid_size = self.gridSize(dim);
|
||||
|
@ -252,8 +252,8 @@ fn drainMailbox(self: *Thread) !void {
|
||||
try self.renderer.setFontSize(size);
|
||||
},
|
||||
|
||||
.screen_size => |size| {
|
||||
try self.renderer.setScreenSize(size);
|
||||
.resize => |v| {
|
||||
try self.renderer.setScreenSize(v.screen_size, v.padding);
|
||||
},
|
||||
|
||||
.change_config => |config| {
|
||||
|
@ -20,8 +20,14 @@ pub const Message = union(enum) {
|
||||
/// the size changes.
|
||||
font_size: font.face.DesiredSize,
|
||||
|
||||
/// Change the screen size.
|
||||
screen_size: renderer.ScreenSize,
|
||||
/// Changes the screen size.
|
||||
resize: struct {
|
||||
/// The full screen (drawable) size. This does NOT include padding.
|
||||
screen_size: renderer.ScreenSize,
|
||||
|
||||
/// The explicit padding values.
|
||||
padding: renderer.Padding,
|
||||
},
|
||||
|
||||
/// The derived configuration to update the renderer with.
|
||||
change_config: struct {
|
||||
|
@ -143,6 +143,14 @@ pub const Padding = struct {
|
||||
.left = self.left + other.left,
|
||||
};
|
||||
}
|
||||
|
||||
/// Equality test between two paddings.
|
||||
pub fn eql(self: Padding, other: Padding) bool {
|
||||
return self.top == other.top and
|
||||
self.bottom == other.bottom and
|
||||
self.right == other.right and
|
||||
self.left == other.left;
|
||||
}
|
||||
};
|
||||
|
||||
test "Padding balanced on zero" {
|
||||
|
Reference in New Issue
Block a user