aboutsummaryrefslogtreecommitdiff
path: root/vendor/libghostty-vt
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/libghostty-vt')
-rw-r--r--vendor/libghostty-vt/include/ghostty/vt/kitty_graphics.h9
-rw-r--r--vendor/libghostty-vt/src/terminal/c/kitty_graphics.zig55
2 files changed, 64 insertions, 0 deletions
diff --git a/vendor/libghostty-vt/include/ghostty/vt/kitty_graphics.h b/vendor/libghostty-vt/include/ghostty/vt/kitty_graphics.h
index 9bace3a3..d5b50067 100644
--- a/vendor/libghostty-vt/include/ghostty/vt/kitty_graphics.h
+++ b/vendor/libghostty-vt/include/ghostty/vt/kitty_graphics.h
@@ -343,6 +343,15 @@ typedef enum GHOSTTY_ENUM_TYPED {
*/
GHOSTTY_KITTY_IMAGE_DATA_DATA_LEN = 8,
+ /**
+ * Timestamp of the image's most recent transmission, in nanoseconds.
+ * The epoch is unspecified; only equality and ordering between values
+ * read from the same terminal are meaningful.
+ *
+ * Output type: uint64_t *
+ */
+ GHOSTTY_KITTY_IMAGE_DATA_TRANSMIT_TIME_NS = 9,
+
GHOSTTY_KITTY_IMAGE_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
} GhosttyKittyGraphicsImageData;
diff --git a/vendor/libghostty-vt/src/terminal/c/kitty_graphics.zig b/vendor/libghostty-vt/src/terminal/c/kitty_graphics.zig
index d50b8c4c..a00632ed 100644
--- a/vendor/libghostty-vt/src/terminal/c/kitty_graphics.zig
+++ b/vendor/libghostty-vt/src/terminal/c/kitty_graphics.zig
@@ -178,6 +178,7 @@ pub const ImageData = enum(c_int) {
compression = 6,
data_ptr = 7,
data_len = 8,
+ transmit_time_ns = 9,
pub fn OutType(comptime self: ImageData) type {
return switch (self) {
@@ -187,6 +188,7 @@ pub const ImageData = enum(c_int) {
.compression => ImageCompression,
.data_ptr => [*]const u8,
.data_len => usize,
+ .transmit_time_ns => u64,
};
}
};
@@ -258,11 +260,22 @@ fn imageGetTyped(
.compression => out.* = image.compression,
.data_ptr => out.* = image.data.ptr,
.data_len => out.* = image.data.len,
+ .transmit_time_ns => out.* = instantNanos(image.transmit_time),
}
return .success;
}
+/// Flattens an Instant's platform timestamp to nanoseconds for the C API.
+/// The epoch is unspecified; only equality and ordering are meaningful.
+fn instantNanos(instant: std.time.Instant) u64 {
+ if (@TypeOf(instant.timestamp) == u64) return instant.timestamp;
+ const ts = instant.timestamp;
+ const sec: u64 = @intCast(@max(ts.sec, 0));
+ const nsec: u64 = @intCast(@max(ts.nsec, 0));
+ return sec *| std.time.ns_per_s +| nsec;
+}
+
pub fn placement_iterator_new(
alloc_: ?*const CAllocator,
out: *PlacementIterator,
@@ -977,6 +990,48 @@ test "image_get_handle and image_get with transmitted image" {
try testing.expect(data_len > 0);
}
+test "image_get transmit_time_ns changes on retransmission" {
+ if (comptime !build_options.kitty_graphics) return error.SkipZigTest;
+
+ var t: terminal_c.Terminal = null;
+ try testing.expectEqual(Result.success, terminal_c.new(
+ &lib.alloc.test_allocator,
+ &t,
+ .{ .cols = 80, .rows = 24, .max_scrollback = 0 },
+ ));
+ defer terminal_c.free(t);
+
+ const cmd = "\x1b_Ga=T,t=d,f=24,i=1,p=1,s=1,v=2;////////\x1b\\";
+ terminal_c.vt_write(t, cmd.ptr, cmd.len);
+
+ var graphics: KittyGraphics = undefined;
+ try testing.expectEqual(Result.success, terminal_c.get(
+ t,
+ .kitty_graphics,
+ @ptrCast(&graphics),
+ ));
+
+ var first: u64 = undefined;
+ try testing.expectEqual(Result.success, image_get(
+ image_get_handle(graphics, 1),
+ .transmit_time_ns,
+ @ptrCast(&first),
+ ));
+ try testing.expect(first > 0);
+
+ std.Thread.sleep(1 * std.time.ns_per_ms);
+ const retransmit = "\x1b_Ga=t,t=d,f=24,i=1,s=1,v=2;AAAAAAAA\x1b\\";
+ terminal_c.vt_write(t, retransmit.ptr, retransmit.len);
+
+ var second: u64 = undefined;
+ try testing.expectEqual(Result.success, image_get(
+ image_get_handle(graphics, 1),
+ .transmit_time_ns,
+ @ptrCast(&second),
+ ));
+ try testing.expect(second > first);
+}
+
test "placement_rect with transmit and display" {
if (comptime !build_options.kitty_graphics) return error.SkipZigTest;