diff --git a/src/terminal/kitty/graphics_storage.zig b/src/terminal/kitty/graphics_storage.zig index ce91573f9..7bbb14958 100644 --- a/src/terminal/kitty/graphics_storage.zig +++ b/src/terminal/kitty/graphics_storage.zig @@ -298,12 +298,18 @@ pub const ImageStorage = struct { ); }, - .column => |v| { + .column => |v| column: { + if (v.x <= 0) { + log.warn("delete column must be greater than zero", .{}); + break :column; + } + + const x = v.x - 1; var it = self.placements.iterator(); while (it.next()) |entry| { const img = self.imageById(entry.key_ptr.image_id) orelse continue; const rect = entry.value_ptr.rect(img, t); - if (rect.top_left.x <= v.x and rect.bottom_right.x >= v.x) { + if (rect.top_left.x <= x and rect.bottom_right.x >= x) { entry.value_ptr.deinit(&t.screen); self.placements.removeByPtr(entry.key_ptr); if (v.delete) self.deleteIfUnused(alloc, img.id); @@ -315,10 +321,15 @@ pub const ImageStorage = struct { }, .row => |v| row: { + if (v.y <= 0) { + log.warn("delete row must be greater than zero", .{}); + break :row; + } + // v.y is in active coords so we want to convert it to a pin // so we can compare by page offsets. const target_pin = t.screen.pages.pin(.{ .active = .{ - .y = std.math.cast(size.CellCountInt, v.y) orelse break :row, + .y = std.math.cast(size.CellCountInt, v.y - 1) orelse break :row, } }) orelse break :row; var it = self.placements.iterator(); @@ -956,6 +967,39 @@ test "storage: delete by column" { }) != null); } +test "storage: delete by column 1x1" { + const testing = std.testing; + const alloc = testing.allocator; + var t = try terminal.Terminal.init(alloc, .{ .rows = 100, .cols = 100 }); + defer t.deinit(alloc); + t.width_px = 100; + t.height_px = 100; + + var s: ImageStorage = .{}; + defer s.deinit(alloc, &t.screen); + 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, 2, .{ .pin = try trackPin(&t, .{ .x = 1, .y = 0 }) }); + try s.addPlacement(alloc, 1, 3, .{ .pin = try trackPin(&t, .{ .x = 2, .y = 0 }) }); + + s.delete(alloc, &t, .{ .column = .{ + .delete = false, + .x = 2, + } }); + try testing.expectEqual(@as(usize, 2), s.placements.count()); + try testing.expectEqual(@as(usize, 1), s.images.count()); + + // verify the placement is what we expect + try testing.expect(s.placements.get(.{ + .image_id = 1, + .placement_id = .{ .tag = .external, .id = 1 }, + }) != null); + try testing.expect(s.placements.get(.{ + .image_id = 1, + .placement_id = .{ .tag = .external, .id = 3 }, + }) != null); +} + test "storage: delete by row" { const testing = std.testing; const alloc = testing.allocator; @@ -988,3 +1032,36 @@ test "storage: delete by row" { .placement_id = .{ .tag = .external, .id = 1 }, }) != null); } + +test "storage: delete by row 1x1" { + const testing = std.testing; + const alloc = testing.allocator; + var t = try terminal.Terminal.init(alloc, .{ .rows = 100, .cols = 100 }); + defer t.deinit(alloc); + t.width_px = 100; + t.height_px = 100; + + var s: ImageStorage = .{}; + defer s.deinit(alloc, &t.screen); + 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, 2, .{ .pin = try trackPin(&t, .{ .y = 1 }) }); + try s.addPlacement(alloc, 1, 3, .{ .pin = try trackPin(&t, .{ .y = 2 }) }); + + s.delete(alloc, &t, .{ .row = .{ + .delete = false, + .y = 2, + } }); + try testing.expectEqual(@as(usize, 2), s.placements.count()); + try testing.expectEqual(@as(usize, 1), s.images.count()); + + // verify the placement is what we expect + try testing.expect(s.placements.get(.{ + .image_id = 1, + .placement_id = .{ .tag = .external, .id = 1 }, + }) != null); + try testing.expect(s.placements.get(.{ + .image_id = 1, + .placement_id = .{ .tag = .external, .id = 3 }, + }) != null); +}