mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +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,
|
mouse_interval: u64,
|
||||||
macos_non_native_fullscreen: configpkg.NonNativeFullscreen,
|
macos_non_native_fullscreen: configpkg.NonNativeFullscreen,
|
||||||
macos_option_as_alt: configpkg.OptionAsAlt,
|
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 {
|
pub fn init(alloc_gpa: Allocator, config: *const configpkg.Config) !DerivedConfig {
|
||||||
var arena = ArenaAllocator.init(alloc_gpa);
|
var arena = ArenaAllocator.init(alloc_gpa);
|
||||||
@ -156,6 +158,8 @@ const DerivedConfig = struct {
|
|||||||
.mouse_interval = config.@"click-repeat-interval" * 1_000_000, // 500ms
|
.mouse_interval = config.@"click-repeat-interval" * 1_000_000, // 500ms
|
||||||
.macos_non_native_fullscreen = config.@"macos-non-native-fullscreen",
|
.macos_non_native_fullscreen = config.@"macos-non-native-fullscreen",
|
||||||
.macos_option_as_alt = config.@"macos-option-as-alt",
|
.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
|
// Assignments happen sequentially so we have to do this last
|
||||||
// so that the memory is captured from allocs above.
|
// 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.
|
// changed, so we just return.
|
||||||
if (self.screen_size.equals(new_screen_size)) 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
|
// 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
|
// Mail the renderer so that it can update the GPU and re-render
|
||||||
_ = self.renderer_thread.mailbox.push(.{
|
_ = self.renderer_thread.mailbox.push(.{
|
||||||
.screen_size = self.screen_size,
|
.resize = .{
|
||||||
|
.screen_size = self.screen_size,
|
||||||
|
.padding = self.padding,
|
||||||
|
},
|
||||||
}, .{ .forever = {} });
|
}, .{ .forever = {} });
|
||||||
try self.queueRender();
|
try self.queueRender();
|
||||||
|
|
||||||
@ -1192,16 +1203,50 @@ pub fn scrollCallback(
|
|||||||
try self.queueRender();
|
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 x_dpi = content_scale.x * font.face.default_dpi;
|
||||||
const y_dpi = content_scale.y * 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: {
|
const size = size: {
|
||||||
var size = self.font_size;
|
var size = self.font_size;
|
||||||
size.xdpi = @intFromFloat(x_dpi);
|
size.xdpi = @intFromFloat(x_dpi);
|
||||||
size.ydpi = @intFromFloat(y_dpi);
|
size.ydpi = @intFromFloat(y_dpi);
|
||||||
break :size size;
|
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);
|
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.
|
/// The type of action to report for a mouse event.
|
||||||
|
@ -350,7 +350,10 @@ pub const Surface = struct {
|
|||||||
.y = @floatCast(y),
|
.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 {
|
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.
|
/// Resize the screen.
|
||||||
pub fn setScreenSize(self: *Metal, dim: renderer.ScreenSize) !void {
|
pub fn setScreenSize(
|
||||||
// Store our screen size
|
self: *Metal,
|
||||||
|
dim: renderer.ScreenSize,
|
||||||
|
pad: renderer.Padding,
|
||||||
|
) !void {
|
||||||
|
// Store our sizes
|
||||||
self.screen_size = dim;
|
self.screen_size = dim;
|
||||||
|
self.padding.explicit = pad;
|
||||||
|
|
||||||
// Recalculate the rows/columns. This can't fail since we just set
|
// Recalculate the rows/columns. This can't fail since we just set
|
||||||
// the screen size above.
|
// 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
|
/// Set the screen size for rendering. This will update the projection
|
||||||
/// used for the shader so that the scaling of the grid is correct.
|
/// 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();
|
if (single_threaded_draw) self.draw_mutex.lock();
|
||||||
defer if (single_threaded_draw) self.draw_mutex.unlock();
|
defer if (single_threaded_draw) self.draw_mutex.unlock();
|
||||||
|
|
||||||
// Store our screen size
|
// Store our screen size
|
||||||
self.screen_size = dim;
|
self.screen_size = dim;
|
||||||
|
self.padding.explicit = pad;
|
||||||
|
|
||||||
// Recalculate the rows/columns.
|
// Recalculate the rows/columns.
|
||||||
const grid_size = self.gridSize(dim);
|
const grid_size = self.gridSize(dim);
|
||||||
|
@ -252,8 +252,8 @@ fn drainMailbox(self: *Thread) !void {
|
|||||||
try self.renderer.setFontSize(size);
|
try self.renderer.setFontSize(size);
|
||||||
},
|
},
|
||||||
|
|
||||||
.screen_size => |size| {
|
.resize => |v| {
|
||||||
try self.renderer.setScreenSize(size);
|
try self.renderer.setScreenSize(v.screen_size, v.padding);
|
||||||
},
|
},
|
||||||
|
|
||||||
.change_config => |config| {
|
.change_config => |config| {
|
||||||
|
@ -20,8 +20,14 @@ pub const Message = union(enum) {
|
|||||||
/// the size changes.
|
/// the size changes.
|
||||||
font_size: font.face.DesiredSize,
|
font_size: font.face.DesiredSize,
|
||||||
|
|
||||||
/// Change the screen size.
|
/// Changes the screen size.
|
||||||
screen_size: renderer.ScreenSize,
|
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.
|
/// The derived configuration to update the renderer with.
|
||||||
change_config: struct {
|
change_config: struct {
|
||||||
|
@ -143,6 +143,14 @@ pub const Padding = struct {
|
|||||||
.left = self.left + other.left,
|
.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" {
|
test "Padding balanced on zero" {
|
||||||
|
Reference in New Issue
Block a user