window caches all sizing so it doesn't depend on renderer state

This commit is contained in:
Mitchell Hashimoto
2022-11-15 19:30:15 -08:00
parent 6218792710
commit 6ec5684c27
2 changed files with 35 additions and 15 deletions

View File

@@ -79,8 +79,10 @@ io: termio.Impl,
io_thread: termio.Thread, io_thread: termio.Thread,
io_thr: std.Thread, io_thr: std.Thread,
/// The dimensions of the grid in rows and columns. /// All the cached sizes since we need them at various times.
screen_size: renderer.ScreenSize,
grid_size: renderer.GridSize, grid_size: renderer.GridSize,
cell_size: renderer.CellSize,
/// Explicit padding due to configuration /// Explicit padding due to configuration
padding: renderer.Padding, padding: renderer.Padding,
@@ -262,6 +264,9 @@ pub fn create(alloc: Allocator, app: *App, config: *const Config) !*Window {
}); });
errdefer font_group.deinit(alloc); errdefer font_group.deinit(alloc);
// Pre-calculate our initial cell size ourselves.
const cell_size = try renderer.CellSize.init(alloc, font_group);
// Convert our padding from points to pixels // Convert our padding from points to pixels
const padding_x = (@intToFloat(f32, config.@"window-padding-x") * x_dpi) / 72; const padding_x = (@intToFloat(f32, config.@"window-padding-x") * x_dpi) / 72;
const padding_y = (@intToFloat(f32, config.@"window-padding-y") * y_dpi) / 72; const padding_y = (@intToFloat(f32, config.@"window-padding-y") * y_dpi) / 72;
@@ -279,6 +284,7 @@ pub fn create(alloc: Allocator, app: *App, config: *const Config) !*Window {
.explicit = padding, .explicit = padding,
.balance = config.@"window-padding-balance", .balance = config.@"window-padding-balance",
}, },
.window_mailbox = .{ .window = self, .app = app.mailbox },
}); });
errdefer renderer_impl.deinit(); errdefer renderer_impl.deinit();
renderer_impl.background = .{ renderer_impl.background = .{
@@ -298,13 +304,16 @@ pub fn create(alloc: Allocator, app: *App, config: *const Config) !*Window {
.width = window_size.width, .width = window_size.width,
.height = window_size.height, .height = window_size.height,
}; };
const grid_size = renderer_impl.gridSize(screen_size); const grid_size = renderer.GridSize.init(
screen_size.subPadding(padding),
cell_size,
);
// Set a minimum size that is cols=10 h=4. This matches Mac's Terminal.app // Set a minimum size that is cols=10 h=4. This matches Mac's Terminal.app
// but is otherwise somewhat arbitrary. // but is otherwise somewhat arbitrary.
try window.setSizeLimits(.{ try window.setSizeLimits(.{
.width = @floatToInt(u32, renderer_impl.cell_size.width * 10), .width = @floatToInt(u32, cell_size.width * 10),
.height = @floatToInt(u32, renderer_impl.cell_size.height * 4), .height = @floatToInt(u32, cell_size.height * 4),
}, .{ .width = null, .height = null }); }, .{ .width = null, .height = null });
// Create the cursor // Create the cursor
@@ -371,7 +380,9 @@ pub fn create(alloc: Allocator, app: *App, config: *const Config) !*Window {
.io = io, .io = io,
.io_thread = io_thread, .io_thread = io_thread,
.io_thr = undefined, .io_thr = undefined,
.screen_size = screen_size,
.grid_size = grid_size, .grid_size = grid_size,
.cell_size = cell_size,
.padding = padding, .padding = padding,
.config = config, .config = config,
@@ -569,18 +580,22 @@ fn sizeCallback(window: glfw.Window, width: i32, height: i32) void {
}; };
}; };
const screen_size: renderer.ScreenSize = .{
.width = px_size.width,
.height = px_size.height,
};
const win = window.getUserPointer(Window) orelse return; const win = window.getUserPointer(Window) orelse return;
// TODO: if our screen size didn't change, then we should avoid the // TODO: if our screen size didn't change, then we should avoid the
// overhead of inter-thread communication // overhead of inter-thread communication
// Save our screen size
win.screen_size = .{
.width = px_size.width,
.height = px_size.height,
};
// Recalculate our grid size // Recalculate our grid size
win.grid_size = win.renderer.gridSize(screen_size); win.grid_size = renderer.GridSize.init(
win.screen_size.subPadding(win.padding),
win.cell_size,
);
if (win.grid_size.columns < 5 and (win.padding.left > 0 or win.padding.right > 0)) { if (win.grid_size.columns < 5 and (win.padding.left > 0 or win.padding.right > 0)) {
log.warn("WARNING: very small terminal grid detected with padding " ++ log.warn("WARNING: very small terminal grid detected with padding " ++
"set. Is your padding reasonable?", .{}); "set. Is your padding reasonable?", .{});
@@ -594,7 +609,7 @@ fn sizeCallback(window: glfw.Window, width: i32, height: i32) void {
_ = win.io_thread.mailbox.push(.{ _ = win.io_thread.mailbox.push(.{
.resize = .{ .resize = .{
.grid_size = win.grid_size, .grid_size = win.grid_size,
.screen_size = screen_size, .screen_size = win.screen_size,
.padding = win.padding, .padding = win.padding,
}, },
}, .{ .forever = {} }); }, .{ .forever = {} });
@@ -1386,10 +1401,10 @@ fn cursorPosCallback(
// //
// the boundary point at which we consider selection or non-selection // the boundary point at which we consider selection or non-selection
const cell_xboundary = win.renderer.cell_size.width * 0.6; const cell_xboundary = win.cell_size.width * 0.6;
// first xpos of the clicked cell // first xpos of the clicked cell
const cell_xstart = @intToFloat(f32, win.mouse.left_click_point.x) * win.renderer.cell_size.width; const cell_xstart = @intToFloat(f32, win.mouse.left_click_point.x) * win.cell_size.width;
const cell_start_xpos = win.mouse.left_click_xpos - cell_xstart; const cell_start_xpos = win.mouse.left_click_xpos - cell_xstart;
// If this is the same cell, then we only start the selection if weve // If this is the same cell, then we only start the selection if weve
@@ -1464,7 +1479,7 @@ fn posToViewport(self: Window, xpos: f64, ypos: f64) terminal.point.Viewport {
return .{ return .{
.x = if (xpos < 0) 0 else x: { .x = if (xpos < 0) 0 else x: {
// Our cell is the mouse divided by cell width // Our cell is the mouse divided by cell width
const cell_width = @floatCast(f64, self.renderer.cell_size.width); const cell_width = @floatCast(f64, self.cell_size.width);
const x = @floatToInt(usize, xpos / cell_width); const x = @floatToInt(usize, xpos / cell_width);
// Can be off the screen if the user drags it out, so max // Can be off the screen if the user drags it out, so max
@@ -1473,7 +1488,7 @@ fn posToViewport(self: Window, xpos: f64, ypos: f64) terminal.point.Viewport {
}, },
.y = if (ypos < 0) 0 else y: { .y = if (ypos < 0) 0 else y: {
const cell_height = @floatCast(f64, self.renderer.cell_size.height); const cell_height = @floatCast(f64, self.cell_size.height);
const y = @floatToInt(usize, ypos / cell_height); const y = @floatToInt(usize, ypos / cell_height);
break :y @min(y, self.io.terminal.rows - 1); break :y @min(y, self.io.terminal.rows - 1);
}, },

View File

@@ -2,6 +2,7 @@
const font = @import("../font/main.zig"); const font = @import("../font/main.zig");
const renderer = @import("../renderer.zig"); const renderer = @import("../renderer.zig");
const Window = @import("../Window.zig");
/// The font group that should be used. /// The font group that should be used.
font_group: *font.GroupCache, font_group: *font.GroupCache,
@@ -9,6 +10,10 @@ font_group: *font.GroupCache,
/// Padding options for the viewport. /// Padding options for the viewport.
padding: Padding, padding: Padding,
/// The mailbox for sending the window messages. This is only valid
/// once the thread has started and should not be used outside of the thread.
window_mailbox: Window.Mailbox,
pub const Padding = struct { pub const Padding = struct {
// Explicit padding options, in pixels. The windowing thread is // Explicit padding options, in pixels. The windowing thread is
// expected to convert points to pixels for a given DPI. // expected to convert points to pixels for a given DPI.