diff options
Diffstat (limited to 'vendor/libghostty-vt')
| -rw-r--r-- | vendor/libghostty-vt/include/ghostty/vt/kitty_graphics.h | 9 | ||||
| -rw-r--r-- | vendor/libghostty-vt/src/terminal/c/kitty_graphics.zig | 55 |
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; |
