mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +03:00
Make selection part of the cache key for GPU cells
If the selection state changes for a given row, the row must be invalidated.
This commit is contained in:
19
src/Grid.zig
19
src/Grid.zig
@ -20,6 +20,7 @@ const log = std.log.scoped(.grid);
|
|||||||
// separately for alt screens. By storing that in the key, we very likely
|
// separately for alt screens. By storing that in the key, we very likely
|
||||||
// have the cache already for when the primary screen is reactivated.
|
// have the cache already for when the primary screen is reactivated.
|
||||||
const CellsLRU = lru.AutoHashMap(struct {
|
const CellsLRU = lru.AutoHashMap(struct {
|
||||||
|
selection: ?terminal.Selection,
|
||||||
screen: terminal.Terminal.ScreenType,
|
screen: terminal.Terminal.ScreenType,
|
||||||
row_id: terminal.Screen.RowHeader.Id,
|
row_id: terminal.Screen.RowHeader.Id,
|
||||||
}, std.ArrayListUnmanaged(GPUCell));
|
}, std.ArrayListUnmanaged(GPUCell));
|
||||||
@ -384,8 +385,26 @@ pub fn rebuildCells(self: *Grid, term: *Terminal) !void {
|
|||||||
while (rowIter.next()) |row| {
|
while (rowIter.next()) |row| {
|
||||||
defer y += 1;
|
defer y += 1;
|
||||||
|
|
||||||
|
// Our selection value is only non-null if this selection happens
|
||||||
|
// to contain this row. If the selection changes for any reason,
|
||||||
|
// then we invalidate the cache.
|
||||||
|
const selection = sel: {
|
||||||
|
if (term.selection) |sel| {
|
||||||
|
const screen_point = (terminal.point.Viewport{
|
||||||
|
.x = 0,
|
||||||
|
.y = y,
|
||||||
|
}).toScreen(&term.screen);
|
||||||
|
|
||||||
|
// If we are selected, we our colors are just inverted fg/bg
|
||||||
|
if (sel.containsRow(screen_point)) break :sel sel;
|
||||||
|
}
|
||||||
|
|
||||||
|
break :sel null;
|
||||||
|
};
|
||||||
|
|
||||||
// Get our value from the cache.
|
// Get our value from the cache.
|
||||||
const gop = try self.cells_lru.getOrPut(self.alloc, .{
|
const gop = try self.cells_lru.getOrPut(self.alloc, .{
|
||||||
|
.selection = selection,
|
||||||
.screen = term.active_screen,
|
.screen = term.active_screen,
|
||||||
.row_id = row.getId(),
|
.row_id = row.getId(),
|
||||||
});
|
});
|
||||||
|
@ -40,6 +40,14 @@ pub fn contains(self: Selection, p: ScreenPoint) bool {
|
|||||||
return p.y > tl.y and p.y < br.y;
|
return p.y > tl.y and p.y < br.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if the selection contains the row of the given point,
|
||||||
|
/// regardless of the x value.
|
||||||
|
pub fn containsRow(self: Selection, p: ScreenPoint) bool {
|
||||||
|
const tl = self.topLeft();
|
||||||
|
const br = self.bottomRight();
|
||||||
|
return p.y >= tl.y and p.y <= br.y;
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the top left point of the selection.
|
/// Returns the top left point of the selection.
|
||||||
pub fn topLeft(self: Selection) ScreenPoint {
|
pub fn topLeft(self: Selection) ScreenPoint {
|
||||||
return switch (self.order()) {
|
return switch (self.order()) {
|
||||||
@ -78,6 +86,9 @@ test "Selection: contains" {
|
|||||||
try testing.expect(sel.contains(.{ .x = 1, .y = 2 }));
|
try testing.expect(sel.contains(.{ .x = 1, .y = 2 }));
|
||||||
try testing.expect(!sel.contains(.{ .x = 1, .y = 1 }));
|
try testing.expect(!sel.contains(.{ .x = 1, .y = 1 }));
|
||||||
try testing.expect(!sel.contains(.{ .x = 5, .y = 2 }));
|
try testing.expect(!sel.contains(.{ .x = 5, .y = 2 }));
|
||||||
|
try testing.expect(!sel.containsRow(.{ .x = 1, .y = 3 }));
|
||||||
|
try testing.expect(sel.containsRow(.{ .x = 1, .y = 1 }));
|
||||||
|
try testing.expect(sel.containsRow(.{ .x = 5, .y = 2 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reverse
|
// Reverse
|
||||||
|
@ -76,6 +76,12 @@ pub const ScreenPoint = struct {
|
|||||||
(self.y == other.y and self.x < other.x);
|
(self.y == other.y and self.x < other.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if this screen point is currently in the active viewport.
|
||||||
|
pub fn inViewport(self: ScreenPoint, screen: *const Screen) bool {
|
||||||
|
return self.y >= screen.viewport and
|
||||||
|
self.y < screen.viewport + screen.rows;
|
||||||
|
}
|
||||||
|
|
||||||
/// Converts this to a viewport point. If the point is above the
|
/// Converts this to a viewport point. If the point is above the
|
||||||
/// viewport this will move the point to (0, 0) and if it is below
|
/// viewport this will move the point to (0, 0) and if it is below
|
||||||
/// the viewport it'll move it to (cols - 1, rows - 1).
|
/// the viewport it'll move it to (cols - 1, rows - 1).
|
||||||
|
Reference in New Issue
Block a user