mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 16:26:08 +03:00
terminal/kitty-gfx: move cursor after image placement
This commit is contained in:
@ -63,6 +63,10 @@ tabstops: Tabstops,
|
||||
rows: usize,
|
||||
cols: usize,
|
||||
|
||||
/// The size of the screen in pixels. This is used for pty events and images
|
||||
width_px: u32 = 0,
|
||||
height_px: u32 = 0,
|
||||
|
||||
/// The current scrolling region.
|
||||
scrolling_region: ScrollingRegion,
|
||||
|
||||
@ -305,6 +309,9 @@ pub fn resize(self: *Terminal, alloc: Allocator, cols_req: usize, rows: usize) !
|
||||
else
|
||||
cols_req;
|
||||
|
||||
// If our cols/rows didn't change then we're done
|
||||
if (self.cols == cols and self.rows == rows) return;
|
||||
|
||||
// Resize our tabstops
|
||||
// TODO: use resize, but it doesn't set new tabstops
|
||||
if (self.cols != cols) {
|
||||
|
@ -19,7 +19,6 @@ const log = std.log.scoped(.kitty_gfx);
|
||||
// - terminal state around deleting images (i.e. CSI J)
|
||||
// - terminal state around deleting placements (i.e. scrolling)
|
||||
// (not exhaustive, almost every op is ignoring additional config)
|
||||
|
||||
/// Execute a Kitty graphics command against the given terminal. This
|
||||
/// will never fail, but the response may indicate an error and the
|
||||
/// terminal state may not be updated to reflect the command. This will
|
||||
@ -175,6 +174,58 @@ fn display(
|
||||
return result;
|
||||
};
|
||||
|
||||
// Cursor needs to move after placement
|
||||
switch (d.cursor_movement) {
|
||||
.none => {},
|
||||
.after => {
|
||||
// Determine the rectangle of the image in grid cells
|
||||
const image_grid_size: struct {
|
||||
columns: u32,
|
||||
rows: u32,
|
||||
} = grid_size: {
|
||||
// Calculate our cell size.
|
||||
const terminal_width_f64: f64 = @floatFromInt(terminal.width_px);
|
||||
const terminal_height_f64: f64 = @floatFromInt(terminal.height_px);
|
||||
const grid_columns_f64: f64 = @floatFromInt(terminal.cols);
|
||||
const grid_rows_f64: f64 = @floatFromInt(terminal.rows);
|
||||
const cell_width_f64 = terminal_width_f64 / grid_columns_f64;
|
||||
const cell_height_f64 = terminal_height_f64 / grid_rows_f64;
|
||||
|
||||
// Calculate our image size in grid cells
|
||||
const width_f64: f64 = @floatFromInt(img.width);
|
||||
const height_f64: f64 = @floatFromInt(img.height);
|
||||
const width_cells: u32 = @intFromFloat(@ceil(width_f64 / cell_width_f64));
|
||||
const height_cells: u32 = @intFromFloat(@ceil(height_f64 / cell_height_f64));
|
||||
|
||||
break :grid_size .{ .columns = width_cells, .rows = height_cells };
|
||||
};
|
||||
log.warn("terminal width={} height={} image_grid={}", .{
|
||||
terminal.width_px,
|
||||
terminal.height_px,
|
||||
image_grid_size,
|
||||
});
|
||||
|
||||
// If we are moving beneath the screen we need to scroll.
|
||||
// TODO: handle scroll regions
|
||||
var new_y = terminal.screen.cursor.y + image_grid_size.rows;
|
||||
if (new_y >= terminal.rows) {
|
||||
const scroll_amount = (new_y + 1) - terminal.rows;
|
||||
terminal.screen.scroll(.{ .screen = @intCast(scroll_amount) }) catch |err| {
|
||||
// If this failed we just warn, the screen will just be in a
|
||||
// weird state but nothing fatal.
|
||||
log.warn("scroll for image failed: {}", .{err});
|
||||
};
|
||||
new_y = terminal.rows - 1;
|
||||
}
|
||||
|
||||
// Move the cursor
|
||||
terminal.setCursorPos(
|
||||
terminal.screen.cursor.x + image_grid_size.columns,
|
||||
new_y,
|
||||
);
|
||||
},
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -103,6 +103,8 @@ pub fn init(alloc: Allocator, opts: termio.Options) !Exec {
|
||||
);
|
||||
errdefer term.deinit(alloc);
|
||||
term.color_palette = opts.config.palette;
|
||||
term.width_px = opts.screen_size.width;
|
||||
term.height_px = opts.screen_size.height;
|
||||
|
||||
var subprocess = try Subprocess.init(alloc, opts);
|
||||
errdefer subprocess.deinit();
|
||||
@ -255,10 +257,6 @@ pub fn resize(
|
||||
const padded_size = screen_size.subPadding(padding);
|
||||
try self.subprocess.resize(grid_size, padded_size);
|
||||
|
||||
// If our grid size didn't change, then we don't need to change
|
||||
// the underlying terminal.
|
||||
if (grid_size.equals(self.grid_size)) return;
|
||||
|
||||
// Update our cached grid size
|
||||
self.grid_size = grid_size;
|
||||
|
||||
@ -268,7 +266,15 @@ pub fn resize(
|
||||
defer self.renderer_state.mutex.unlock();
|
||||
|
||||
// Update the size of our terminal state
|
||||
try self.terminal.resize(self.alloc, grid_size.columns, grid_size.rows);
|
||||
try self.terminal.resize(
|
||||
self.alloc,
|
||||
grid_size.columns,
|
||||
grid_size.rows,
|
||||
);
|
||||
|
||||
// Update our pixel sizes
|
||||
self.terminal.width_px = screen_size.width;
|
||||
self.terminal.height_px = screen_size.height;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user