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_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,
cell_size: renderer.CellSize,
/// Explicit padding due to configuration
padding: renderer.Padding,
@@ -262,6 +264,9 @@ pub fn create(alloc: Allocator, app: *App, config: *const Config) !*Window {
});
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
const padding_x = (@intToFloat(f32, config.@"window-padding-x") * x_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,
.balance = config.@"window-padding-balance",
},
.window_mailbox = .{ .window = self, .app = app.mailbox },
});
errdefer renderer_impl.deinit();
renderer_impl.background = .{
@@ -298,13 +304,16 @@ pub fn create(alloc: Allocator, app: *App, config: *const Config) !*Window {
.width = window_size.width,
.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
// but is otherwise somewhat arbitrary.
try window.setSizeLimits(.{
.width = @floatToInt(u32, renderer_impl.cell_size.width * 10),
.height = @floatToInt(u32, renderer_impl.cell_size.height * 4),
.width = @floatToInt(u32, cell_size.width * 10),
.height = @floatToInt(u32, cell_size.height * 4),
}, .{ .width = null, .height = null });
// Create the cursor
@@ -371,7 +380,9 @@ pub fn create(alloc: Allocator, app: *App, config: *const Config) !*Window {
.io = io,
.io_thread = io_thread,
.io_thr = undefined,
.screen_size = screen_size,
.grid_size = grid_size,
.cell_size = cell_size,
.padding = padding,
.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;
// TODO: if our screen size didn't change, then we should avoid the
// overhead of inter-thread communication
// Save our screen size
win.screen_size = .{
.width = px_size.width,
.height = px_size.height,
};
// 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)) {
log.warn("WARNING: very small terminal grid detected with padding " ++
"set. Is your padding reasonable?", .{});
@@ -594,7 +609,7 @@ fn sizeCallback(window: glfw.Window, width: i32, height: i32) void {
_ = win.io_thread.mailbox.push(.{
.resize = .{
.grid_size = win.grid_size,
.screen_size = screen_size,
.screen_size = win.screen_size,
.padding = win.padding,
},
}, .{ .forever = {} });
@@ -1386,10 +1401,10 @@ fn cursorPosCallback(
//
// 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
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;
// 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 .{
.x = if (xpos < 0) 0 else x: {
// 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);
// 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: {
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);
break :y @min(y, self.io.terminal.rows - 1);
},

View File

@@ -2,6 +2,7 @@
const font = @import("../font/main.zig");
const renderer = @import("../renderer.zig");
const Window = @import("../Window.zig");
/// The font group that should be used.
font_group: *font.GroupCache,
@@ -9,6 +10,10 @@ font_group: *font.GroupCache,
/// Padding options for the viewport.
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 {
// Explicit padding options, in pixels. The windowing thread is
// expected to convert points to pixels for a given DPI.