mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-17 09:16:11 +03:00
terminal/kitty: placements support location enum (only pin for now)
This commit is contained in:
@ -196,7 +196,9 @@ fn display(
|
|||||||
|
|
||||||
// Add the placement
|
// Add the placement
|
||||||
const p: ImageStorage.Placement = .{
|
const p: ImageStorage.Placement = .{
|
||||||
.pin = placement_pin,
|
.location = .{
|
||||||
|
.pin = placement_pin,
|
||||||
|
},
|
||||||
.x_offset = d.x_offset,
|
.x_offset = d.x_offset,
|
||||||
.y_offset = d.y_offset,
|
.y_offset = d.y_offset,
|
||||||
.source_x = d.x,
|
.source_x = d.x,
|
||||||
@ -218,21 +220,23 @@ fn display(
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Cursor needs to move after placement
|
// Apply cursor movement setting. This only applies to pin placements.
|
||||||
switch (d.cursor_movement) {
|
switch (p.location) {
|
||||||
.none => {},
|
.pin => |pin| switch (d.cursor_movement) {
|
||||||
.after => {
|
.none => {},
|
||||||
// We use terminal.index to properly handle scroll regions.
|
.after => {
|
||||||
const size = p.gridSize(img, terminal);
|
// We use terminal.index to properly handle scroll regions.
|
||||||
for (0..size.rows) |_| terminal.index() catch |err| {
|
const size = p.gridSize(img, terminal);
|
||||||
log.warn("failed to move cursor: {}", .{err});
|
for (0..size.rows) |_| terminal.index() catch |err| {
|
||||||
break;
|
log.warn("failed to move cursor: {}", .{err});
|
||||||
};
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
terminal.setCursorPos(
|
terminal.setCursorPos(
|
||||||
terminal.screen.cursor.y,
|
terminal.screen.cursor.y,
|
||||||
p.pin.x + size.cols + 1,
|
pin.x + size.cols + 1,
|
||||||
);
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -576,8 +576,11 @@ pub const ImageStorage = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const Placement = struct {
|
pub const Placement = struct {
|
||||||
/// The tracked pin for this placement.
|
/// The location where this placement should be drawn.
|
||||||
pin: *PageList.Pin,
|
location: union(enum) {
|
||||||
|
/// Exactly placed on a screen pin.
|
||||||
|
pin: *PageList.Pin,
|
||||||
|
},
|
||||||
|
|
||||||
/// Offset of the x/y from the top-left of the cell.
|
/// Offset of the x/y from the top-left of the cell.
|
||||||
x_offset: u32 = 0,
|
x_offset: u32 = 0,
|
||||||
@ -600,7 +603,9 @@ pub const ImageStorage = struct {
|
|||||||
self: *const Placement,
|
self: *const Placement,
|
||||||
s: *terminal.Screen,
|
s: *terminal.Screen,
|
||||||
) void {
|
) void {
|
||||||
s.pages.untrackPin(self.pin);
|
switch (self.location) {
|
||||||
|
.pin => |p| s.pages.untrackPin(p),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the size in grid cells that this placement takes up.
|
/// Returns the size in grid cells that this placement takes up.
|
||||||
@ -648,9 +653,12 @@ pub const ImageStorage = struct {
|
|||||||
image: Image,
|
image: Image,
|
||||||
t: *const terminal.Terminal,
|
t: *const terminal.Terminal,
|
||||||
) Rect {
|
) Rect {
|
||||||
const grid_size = self.gridSize(image, t);
|
assert(self.location == .pin);
|
||||||
|
|
||||||
var br = switch (self.pin.downOverflow(grid_size.rows - 1)) {
|
const grid_size = self.gridSize(image, t);
|
||||||
|
const pin = self.location.pin;
|
||||||
|
|
||||||
|
var br = switch (pin.downOverflow(grid_size.rows - 1)) {
|
||||||
.offset => |v| v,
|
.offset => |v| v,
|
||||||
.overflow => |v| v.end,
|
.overflow => |v| v.end,
|
||||||
};
|
};
|
||||||
@ -658,12 +666,12 @@ pub const ImageStorage = struct {
|
|||||||
// We need to sub one here because the x value is
|
// We need to sub one here because the x value is
|
||||||
// one width already. So if the image is width "1"
|
// one width already. So if the image is width "1"
|
||||||
// then we add zero to X because X itelf is width 1.
|
// then we add zero to X because X itelf is width 1.
|
||||||
self.pin.x + (grid_size.cols - 1),
|
pin.x + (grid_size.cols - 1),
|
||||||
t.cols - 1,
|
t.cols - 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.top_left = self.pin.*,
|
.top_left = pin.*,
|
||||||
.bottom_right = br,
|
.bottom_right = br,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -692,8 +700,8 @@ test "storage: add placement with zero placement id" {
|
|||||||
defer s.deinit(alloc, &t.screen);
|
defer s.deinit(alloc, &t.screen);
|
||||||
try s.addImage(alloc, .{ .id = 1, .width = 50, .height = 50 });
|
try s.addImage(alloc, .{ .id = 1, .width = 50, .height = 50 });
|
||||||
try s.addImage(alloc, .{ .id = 2, .width = 25, .height = 25 });
|
try s.addImage(alloc, .{ .id = 2, .width = 25, .height = 25 });
|
||||||
try s.addPlacement(alloc, 1, 0, .{ .pin = try trackPin(&t, .{ .x = 25, .y = 25 }) });
|
try s.addPlacement(alloc, 1, 0, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 25, .y = 25 }) } });
|
||||||
try s.addPlacement(alloc, 1, 0, .{ .pin = try trackPin(&t, .{ .x = 25, .y = 25 }) });
|
try s.addPlacement(alloc, 1, 0, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 25, .y = 25 }) } });
|
||||||
|
|
||||||
try testing.expectEqual(@as(usize, 2), s.placements.count());
|
try testing.expectEqual(@as(usize, 2), s.placements.count());
|
||||||
try testing.expectEqual(@as(usize, 2), s.images.count());
|
try testing.expectEqual(@as(usize, 2), s.images.count());
|
||||||
@ -721,8 +729,8 @@ test "storage: delete all placements and images" {
|
|||||||
try s.addImage(alloc, .{ .id = 1 });
|
try s.addImage(alloc, .{ .id = 1 });
|
||||||
try s.addImage(alloc, .{ .id = 2 });
|
try s.addImage(alloc, .{ .id = 2 });
|
||||||
try s.addImage(alloc, .{ .id = 3 });
|
try s.addImage(alloc, .{ .id = 3 });
|
||||||
try s.addPlacement(alloc, 1, 1, .{ .pin = try trackPin(&t, .{ .x = 1, .y = 1 }) });
|
try s.addPlacement(alloc, 1, 1, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 1, .y = 1 }) } });
|
||||||
try s.addPlacement(alloc, 2, 1, .{ .pin = try trackPin(&t, .{ .x = 1, .y = 1 }) });
|
try s.addPlacement(alloc, 2, 1, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 1, .y = 1 }) } });
|
||||||
|
|
||||||
s.dirty = false;
|
s.dirty = false;
|
||||||
s.delete(alloc, &t, .{ .all = true });
|
s.delete(alloc, &t, .{ .all = true });
|
||||||
@ -745,8 +753,8 @@ test "storage: delete all placements and images preserves limit" {
|
|||||||
try s.addImage(alloc, .{ .id = 1 });
|
try s.addImage(alloc, .{ .id = 1 });
|
||||||
try s.addImage(alloc, .{ .id = 2 });
|
try s.addImage(alloc, .{ .id = 2 });
|
||||||
try s.addImage(alloc, .{ .id = 3 });
|
try s.addImage(alloc, .{ .id = 3 });
|
||||||
try s.addPlacement(alloc, 1, 1, .{ .pin = try trackPin(&t, .{ .x = 1, .y = 1 }) });
|
try s.addPlacement(alloc, 1, 1, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 1, .y = 1 }) } });
|
||||||
try s.addPlacement(alloc, 2, 1, .{ .pin = try trackPin(&t, .{ .x = 1, .y = 1 }) });
|
try s.addPlacement(alloc, 2, 1, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 1, .y = 1 }) } });
|
||||||
|
|
||||||
s.dirty = false;
|
s.dirty = false;
|
||||||
s.delete(alloc, &t, .{ .all = true });
|
s.delete(alloc, &t, .{ .all = true });
|
||||||
@ -769,8 +777,8 @@ test "storage: delete all placements" {
|
|||||||
try s.addImage(alloc, .{ .id = 1 });
|
try s.addImage(alloc, .{ .id = 1 });
|
||||||
try s.addImage(alloc, .{ .id = 2 });
|
try s.addImage(alloc, .{ .id = 2 });
|
||||||
try s.addImage(alloc, .{ .id = 3 });
|
try s.addImage(alloc, .{ .id = 3 });
|
||||||
try s.addPlacement(alloc, 1, 1, .{ .pin = try trackPin(&t, .{ .x = 1, .y = 1 }) });
|
try s.addPlacement(alloc, 1, 1, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 1, .y = 1 }) } });
|
||||||
try s.addPlacement(alloc, 2, 1, .{ .pin = try trackPin(&t, .{ .x = 1, .y = 1 }) });
|
try s.addPlacement(alloc, 2, 1, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 1, .y = 1 }) } });
|
||||||
|
|
||||||
s.dirty = false;
|
s.dirty = false;
|
||||||
s.delete(alloc, &t, .{ .all = false });
|
s.delete(alloc, &t, .{ .all = false });
|
||||||
@ -792,8 +800,8 @@ test "storage: delete all placements by image id" {
|
|||||||
try s.addImage(alloc, .{ .id = 1 });
|
try s.addImage(alloc, .{ .id = 1 });
|
||||||
try s.addImage(alloc, .{ .id = 2 });
|
try s.addImage(alloc, .{ .id = 2 });
|
||||||
try s.addImage(alloc, .{ .id = 3 });
|
try s.addImage(alloc, .{ .id = 3 });
|
||||||
try s.addPlacement(alloc, 1, 1, .{ .pin = try trackPin(&t, .{ .x = 1, .y = 1 }) });
|
try s.addPlacement(alloc, 1, 1, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 1, .y = 1 }) } });
|
||||||
try s.addPlacement(alloc, 2, 1, .{ .pin = try trackPin(&t, .{ .x = 1, .y = 1 }) });
|
try s.addPlacement(alloc, 2, 1, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 1, .y = 1 }) } });
|
||||||
|
|
||||||
s.dirty = false;
|
s.dirty = false;
|
||||||
s.delete(alloc, &t, .{ .id = .{ .image_id = 2 } });
|
s.delete(alloc, &t, .{ .id = .{ .image_id = 2 } });
|
||||||
@ -815,8 +823,8 @@ test "storage: delete all placements by image id and unused images" {
|
|||||||
try s.addImage(alloc, .{ .id = 1 });
|
try s.addImage(alloc, .{ .id = 1 });
|
||||||
try s.addImage(alloc, .{ .id = 2 });
|
try s.addImage(alloc, .{ .id = 2 });
|
||||||
try s.addImage(alloc, .{ .id = 3 });
|
try s.addImage(alloc, .{ .id = 3 });
|
||||||
try s.addPlacement(alloc, 1, 1, .{ .pin = try trackPin(&t, .{ .x = 1, .y = 1 }) });
|
try s.addPlacement(alloc, 1, 1, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 1, .y = 1 }) } });
|
||||||
try s.addPlacement(alloc, 2, 1, .{ .pin = try trackPin(&t, .{ .x = 1, .y = 1 }) });
|
try s.addPlacement(alloc, 2, 1, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 1, .y = 1 }) } });
|
||||||
|
|
||||||
s.dirty = false;
|
s.dirty = false;
|
||||||
s.delete(alloc, &t, .{ .id = .{ .delete = true, .image_id = 2 } });
|
s.delete(alloc, &t, .{ .id = .{ .delete = true, .image_id = 2 } });
|
||||||
@ -838,9 +846,9 @@ test "storage: delete placement by specific id" {
|
|||||||
try s.addImage(alloc, .{ .id = 1 });
|
try s.addImage(alloc, .{ .id = 1 });
|
||||||
try s.addImage(alloc, .{ .id = 2 });
|
try s.addImage(alloc, .{ .id = 2 });
|
||||||
try s.addImage(alloc, .{ .id = 3 });
|
try s.addImage(alloc, .{ .id = 3 });
|
||||||
try s.addPlacement(alloc, 1, 1, .{ .pin = try trackPin(&t, .{ .x = 1, .y = 1 }) });
|
try s.addPlacement(alloc, 1, 1, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 1, .y = 1 }) } });
|
||||||
try s.addPlacement(alloc, 1, 2, .{ .pin = try trackPin(&t, .{ .x = 1, .y = 1 }) });
|
try s.addPlacement(alloc, 1, 2, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 1, .y = 1 }) } });
|
||||||
try s.addPlacement(alloc, 2, 1, .{ .pin = try trackPin(&t, .{ .x = 1, .y = 1 }) });
|
try s.addPlacement(alloc, 2, 1, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 1, .y = 1 }) } });
|
||||||
|
|
||||||
s.dirty = false;
|
s.dirty = false;
|
||||||
s.delete(alloc, &t, .{ .id = .{
|
s.delete(alloc, &t, .{ .id = .{
|
||||||
@ -867,8 +875,8 @@ test "storage: delete intersecting cursor" {
|
|||||||
defer s.deinit(alloc, &t.screen);
|
defer s.deinit(alloc, &t.screen);
|
||||||
try s.addImage(alloc, .{ .id = 1, .width = 50, .height = 50 });
|
try s.addImage(alloc, .{ .id = 1, .width = 50, .height = 50 });
|
||||||
try s.addImage(alloc, .{ .id = 2, .width = 25, .height = 25 });
|
try s.addImage(alloc, .{ .id = 2, .width = 25, .height = 25 });
|
||||||
try s.addPlacement(alloc, 1, 1, .{ .pin = try trackPin(&t, .{ .x = 0, .y = 0 }) });
|
try s.addPlacement(alloc, 1, 1, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 0, .y = 0 }) } });
|
||||||
try s.addPlacement(alloc, 1, 2, .{ .pin = try trackPin(&t, .{ .x = 25, .y = 25 }) });
|
try s.addPlacement(alloc, 1, 2, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 25, .y = 25 }) } });
|
||||||
|
|
||||||
t.screen.cursorAbsolute(12, 12);
|
t.screen.cursorAbsolute(12, 12);
|
||||||
|
|
||||||
@ -899,8 +907,8 @@ test "storage: delete intersecting cursor plus unused" {
|
|||||||
defer s.deinit(alloc, &t.screen);
|
defer s.deinit(alloc, &t.screen);
|
||||||
try s.addImage(alloc, .{ .id = 1, .width = 50, .height = 50 });
|
try s.addImage(alloc, .{ .id = 1, .width = 50, .height = 50 });
|
||||||
try s.addImage(alloc, .{ .id = 2, .width = 25, .height = 25 });
|
try s.addImage(alloc, .{ .id = 2, .width = 25, .height = 25 });
|
||||||
try s.addPlacement(alloc, 1, 1, .{ .pin = try trackPin(&t, .{ .x = 0, .y = 0 }) });
|
try s.addPlacement(alloc, 1, 1, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 0, .y = 0 }) } });
|
||||||
try s.addPlacement(alloc, 1, 2, .{ .pin = try trackPin(&t, .{ .x = 25, .y = 25 }) });
|
try s.addPlacement(alloc, 1, 2, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 25, .y = 25 }) } });
|
||||||
|
|
||||||
t.screen.cursorAbsolute(12, 12);
|
t.screen.cursorAbsolute(12, 12);
|
||||||
|
|
||||||
@ -931,8 +939,8 @@ test "storage: delete intersecting cursor hits multiple" {
|
|||||||
defer s.deinit(alloc, &t.screen);
|
defer s.deinit(alloc, &t.screen);
|
||||||
try s.addImage(alloc, .{ .id = 1, .width = 50, .height = 50 });
|
try s.addImage(alloc, .{ .id = 1, .width = 50, .height = 50 });
|
||||||
try s.addImage(alloc, .{ .id = 2, .width = 25, .height = 25 });
|
try s.addImage(alloc, .{ .id = 2, .width = 25, .height = 25 });
|
||||||
try s.addPlacement(alloc, 1, 1, .{ .pin = try trackPin(&t, .{ .x = 0, .y = 0 }) });
|
try s.addPlacement(alloc, 1, 1, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 0, .y = 0 }) } });
|
||||||
try s.addPlacement(alloc, 1, 2, .{ .pin = try trackPin(&t, .{ .x = 25, .y = 25 }) });
|
try s.addPlacement(alloc, 1, 2, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 25, .y = 25 }) } });
|
||||||
|
|
||||||
t.screen.cursorAbsolute(26, 26);
|
t.screen.cursorAbsolute(26, 26);
|
||||||
|
|
||||||
@ -957,8 +965,8 @@ test "storage: delete by column" {
|
|||||||
defer s.deinit(alloc, &t.screen);
|
defer s.deinit(alloc, &t.screen);
|
||||||
try s.addImage(alloc, .{ .id = 1, .width = 50, .height = 50 });
|
try s.addImage(alloc, .{ .id = 1, .width = 50, .height = 50 });
|
||||||
try s.addImage(alloc, .{ .id = 2, .width = 25, .height = 25 });
|
try s.addImage(alloc, .{ .id = 2, .width = 25, .height = 25 });
|
||||||
try s.addPlacement(alloc, 1, 1, .{ .pin = try trackPin(&t, .{ .x = 0, .y = 0 }) });
|
try s.addPlacement(alloc, 1, 1, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 0, .y = 0 }) } });
|
||||||
try s.addPlacement(alloc, 1, 2, .{ .pin = try trackPin(&t, .{ .x = 25, .y = 25 }) });
|
try s.addPlacement(alloc, 1, 2, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 25, .y = 25 }) } });
|
||||||
|
|
||||||
s.dirty = false;
|
s.dirty = false;
|
||||||
s.delete(alloc, &t, .{ .column = .{
|
s.delete(alloc, &t, .{ .column = .{
|
||||||
@ -988,9 +996,9 @@ test "storage: delete by column 1x1" {
|
|||||||
var s: ImageStorage = .{};
|
var s: ImageStorage = .{};
|
||||||
defer s.deinit(alloc, &t.screen);
|
defer s.deinit(alloc, &t.screen);
|
||||||
try s.addImage(alloc, .{ .id = 1, .width = 1, .height = 1 });
|
try s.addImage(alloc, .{ .id = 1, .width = 1, .height = 1 });
|
||||||
try s.addPlacement(alloc, 1, 1, .{ .pin = try trackPin(&t, .{ .x = 0, .y = 0 }) });
|
try s.addPlacement(alloc, 1, 1, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 0, .y = 0 }) } });
|
||||||
try s.addPlacement(alloc, 1, 2, .{ .pin = try trackPin(&t, .{ .x = 1, .y = 0 }) });
|
try s.addPlacement(alloc, 1, 2, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 1, .y = 0 }) } });
|
||||||
try s.addPlacement(alloc, 1, 3, .{ .pin = try trackPin(&t, .{ .x = 2, .y = 0 }) });
|
try s.addPlacement(alloc, 1, 3, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 2, .y = 0 }) } });
|
||||||
|
|
||||||
s.delete(alloc, &t, .{ .column = .{
|
s.delete(alloc, &t, .{ .column = .{
|
||||||
.delete = false,
|
.delete = false,
|
||||||
@ -1023,8 +1031,8 @@ test "storage: delete by row" {
|
|||||||
defer s.deinit(alloc, &t.screen);
|
defer s.deinit(alloc, &t.screen);
|
||||||
try s.addImage(alloc, .{ .id = 1, .width = 50, .height = 50 });
|
try s.addImage(alloc, .{ .id = 1, .width = 50, .height = 50 });
|
||||||
try s.addImage(alloc, .{ .id = 2, .width = 25, .height = 25 });
|
try s.addImage(alloc, .{ .id = 2, .width = 25, .height = 25 });
|
||||||
try s.addPlacement(alloc, 1, 1, .{ .pin = try trackPin(&t, .{ .x = 0, .y = 0 }) });
|
try s.addPlacement(alloc, 1, 1, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 0, .y = 0 }) } });
|
||||||
try s.addPlacement(alloc, 1, 2, .{ .pin = try trackPin(&t, .{ .x = 25, .y = 25 }) });
|
try s.addPlacement(alloc, 1, 2, .{ .location = .{ .pin = try trackPin(&t, .{ .x = 25, .y = 25 }) } });
|
||||||
|
|
||||||
s.dirty = false;
|
s.dirty = false;
|
||||||
s.delete(alloc, &t, .{ .row = .{
|
s.delete(alloc, &t, .{ .row = .{
|
||||||
@ -1054,9 +1062,9 @@ test "storage: delete by row 1x1" {
|
|||||||
var s: ImageStorage = .{};
|
var s: ImageStorage = .{};
|
||||||
defer s.deinit(alloc, &t.screen);
|
defer s.deinit(alloc, &t.screen);
|
||||||
try s.addImage(alloc, .{ .id = 1, .width = 1, .height = 1 });
|
try s.addImage(alloc, .{ .id = 1, .width = 1, .height = 1 });
|
||||||
try s.addPlacement(alloc, 1, 1, .{ .pin = try trackPin(&t, .{ .y = 0 }) });
|
try s.addPlacement(alloc, 1, 1, .{ .location = .{ .pin = try trackPin(&t, .{ .y = 0 }) } });
|
||||||
try s.addPlacement(alloc, 1, 2, .{ .pin = try trackPin(&t, .{ .y = 1 }) });
|
try s.addPlacement(alloc, 1, 2, .{ .location = .{ .pin = try trackPin(&t, .{ .y = 1 }) } });
|
||||||
try s.addPlacement(alloc, 1, 3, .{ .pin = try trackPin(&t, .{ .y = 2 }) });
|
try s.addPlacement(alloc, 1, 3, .{ .location = .{ .pin = try trackPin(&t, .{ .y = 2 }) } });
|
||||||
|
|
||||||
s.delete(alloc, &t, .{ .row = .{
|
s.delete(alloc, &t, .{ .row = .{
|
||||||
.delete = false,
|
.delete = false,
|
||||||
|
Reference in New Issue
Block a user