aboutsummaryrefslogtreecommitdiff
path: root/vendor/libghostty-vt/src/inspector/widgets
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-09-10 21:51:57 +0300
committerGitHub <noreply@github.com>2026-09-10 21:51:57 +0300
commit425c86179791cd32e2d4ce0ae7f269940b4b0663 (patch)
treee52c4383a6d69216cbe2a32638bf90841d7e2189 /vendor/libghostty-vt/src/inspector/widgets
parent90e947a6e26e02f10ec7f1694c4eb5b78a86406b (diff)
chore: upgrade libghostty and preserve terminal behavior (#3906)
Diffstat (limited to 'vendor/libghostty-vt/src/inspector/widgets')
-rw-r--r--vendor/libghostty-vt/src/inspector/widgets/key.zig14
-rw-r--r--vendor/libghostty-vt/src/inspector/widgets/pagelist.zig2
-rw-r--r--vendor/libghostty-vt/src/inspector/widgets/screen.zig7
-rw-r--r--vendor/libghostty-vt/src/inspector/widgets/surface.zig13
-rw-r--r--vendor/libghostty-vt/src/inspector/widgets/termio.zig89
5 files changed, 104 insertions, 21 deletions
diff --git a/vendor/libghostty-vt/src/inspector/widgets/key.zig b/vendor/libghostty-vt/src/inspector/widgets/key.zig
index 7d7188a6..2a3f531e 100644
--- a/vendor/libghostty-vt/src/inspector/widgets/key.zig
+++ b/vendor/libghostty-vt/src/inspector/widgets/key.zig
@@ -232,8 +232,7 @@ fn modsTooltip(
mods: *const input.Mods,
buf: []u8,
) ![:0]const u8 {
- var stream = std.io.fixedBufferStream(buf);
- const writer = stream.writer();
+ var writer: std.Io.Writer = .fixed(buf);
var first = true;
if (mods.shift) {
try writer.writeAll("Shift");
@@ -254,7 +253,7 @@ fn modsTooltip(
try writer.writeAll("Super");
}
try writer.writeByte(0);
- const written = stream.getWritten();
+ const written = writer.buffered();
return written[0 .. written.len - 1 :0];
}
@@ -403,8 +402,7 @@ pub const Stream = struct {
cimgui.c.ImGui_TextDisabled("-");
} else {
var utf8_buf: [128]u8 = undefined;
- var utf8_stream = std.io.fixedBufferStream(&utf8_buf);
- const utf8_writer = utf8_stream.writer();
+ var utf8_writer: std.Io.Writer = .fixed(&utf8_buf);
if (std.unicode.Utf8View.init(ev.event.utf8)) |view| {
var utf8_it = view.iterator();
while (utf8_it.nextCodepoint()) |cp| {
@@ -423,8 +421,7 @@ pub const Stream = struct {
cimgui.c.ImGui_TextDisabled("-");
} else {
var pty_buf: [256]u8 = undefined;
- var pty_stream = std.io.fixedBufferStream(&pty_buf);
- const pty_writer = pty_stream.writer();
+ var pty_writer: std.Io.Writer = .fixed(&pty_buf);
for (ev.pty) |byte| {
if (byte == 0x1B) {
pty_writer.writeAll("ESC ") catch break;
@@ -444,8 +441,7 @@ pub const Stream = struct {
cimgui.c.ImGui_TextDisabled("-");
} else {
var binding_buf: [256]u8 = undefined;
- var binding_stream = std.io.fixedBufferStream(&binding_buf);
- const binding_writer = binding_stream.writer();
+ var binding_writer: std.Io.Writer = .fixed(&binding_buf);
for (ev.binding, 0..) |action, i| {
if (i > 0) binding_writer.writeAll(", ") catch break;
binding_writer.writeAll(@tagName(action)) catch break;
diff --git a/vendor/libghostty-vt/src/inspector/widgets/pagelist.zig b/vendor/libghostty-vt/src/inspector/widgets/pagelist.zig
index 7e001289..2aecafd3 100644
--- a/vendor/libghostty-vt/src/inspector/widgets/pagelist.zig
+++ b/vendor/libghostty-vt/src/inspector/widgets/pagelist.zig
@@ -162,7 +162,7 @@ fn summaryTable(pages: *const PageList) void {
);
_ = cimgui.c.ImGui_TableSetColumnIndex(2);
var limit_buf: [64]u8 = undefined;
- const limit = formatBytes(&limit_buf, pages.maxSize());
+ const limit = formatBytes(&limit_buf, pages.limits.max(.bytes));
cimgui.c.ImGui_TextUnformatted(limit.ptr);
cimgui.c.ImGui_TableNextRow();
diff --git a/vendor/libghostty-vt/src/inspector/widgets/screen.zig b/vendor/libghostty-vt/src/inspector/widgets/screen.zig
index 41c113e7..6e66a142 100644
--- a/vendor/libghostty-vt/src/inspector/widgets/screen.zig
+++ b/vendor/libghostty-vt/src/inspector/widgets/screen.zig
@@ -353,7 +353,12 @@ pub fn internalStateTable(
_ = cimgui.c.ImGui_TableSetColumnIndex(0);
cimgui.c.ImGui_Text("Memory Limit");
_ = cimgui.c.ImGui_TableSetColumnIndex(1);
- cimgui.c.ImGui_Text("%d bytes (%d KiB)", pages.maxSize(), units.toKibiBytes(pages.maxSize()));
+ const max_bytes = pages.limits.max(.bytes);
+ cimgui.c.ImGui_Text(
+ "%d bytes (%d KiB)",
+ max_bytes,
+ units.toKibiBytes(max_bytes),
+ );
cimgui.c.ImGui_TableNextRow();
_ = cimgui.c.ImGui_TableSetColumnIndex(0);
diff --git a/vendor/libghostty-vt/src/inspector/widgets/surface.zig b/vendor/libghostty-vt/src/inspector/widgets/surface.zig
index a630bad8..a23aebf0 100644
--- a/vendor/libghostty-vt/src/inspector/widgets/surface.zig
+++ b/vendor/libghostty-vt/src/inspector/widgets/surface.zig
@@ -9,6 +9,7 @@ const input = @import("../../input.zig");
const renderer = @import("../../renderer.zig");
const terminal = @import("../../terminal/main.zig");
const Surface = @import("../../Surface.zig");
+const global = @import("../../global.zig");
/// This is discovered via the hardcoded string in the ImGui demo window.
const window_imgui_demo = "Dear ImGui Demo";
@@ -46,7 +47,7 @@ pub const Inspector = struct {
pub fn draw(
self: *Inspector,
- surface: *const Surface,
+ surface: *Surface,
mouse: Mouse,
) void {
// Create our dockspace first. If we had to setup our dockspace,
@@ -56,8 +57,8 @@ pub const Inspector = struct {
// Draw everything that requires the terminal state mutex.
{
- surface.renderer_state.mutex.lock();
- defer surface.renderer_state.mutex.unlock();
+ surface.renderer_state.mutex.lockUncancelable(global.io());
+ defer surface.renderer_state.mutex.unlock(global.io());
const t = surface.renderer_state.terminal;
// Terminal info window
@@ -110,7 +111,7 @@ pub const Inspector = struct {
defer cimgui.c.ImGui_End();
if (open) {
self.vt_stream.draw(
- surface.alloc,
+ surface,
&t.colors.palette.current,
);
}
@@ -442,7 +443,7 @@ fn mouseTable(
if (state != .press) continue;
const button: input.MouseButton = @enumFromInt(i);
cimgui.c.ImGui_SameLine();
- cimgui.c.ImGui_Text("%s", (switch (button) {
+ cimgui.c.ImGui_Text("%s", @as([*]const u8, @ptrCast(switch (button) {
.unknown => "?",
.left => "L",
.middle => "M",
@@ -455,7 +456,7 @@ fn mouseTable(
.nine => "{9}",
.ten => "{10}",
.eleven => "{11}",
- }).ptr);
+ })));
}
}
}
diff --git a/vendor/libghostty-vt/src/inspector/widgets/termio.zig b/vendor/libghostty-vt/src/inspector/widgets/termio.zig
index b721d942..2c94b1bf 100644
--- a/vendor/libghostty-vt/src/inspector/widgets/termio.zig
+++ b/vendor/libghostty-vt/src/inspector/widgets/termio.zig
@@ -7,6 +7,8 @@ const CircBuf = @import("../../datastruct/main.zig").CircBuf;
const Surface = @import("../../Surface.zig");
const screen = @import("screen.zig");
+const log = std.log.scoped(.inspector_terminal_io);
+
/// VT event stream inspector widget.
pub const Stream = struct {
events: VTEvent.Ring,
@@ -30,7 +32,10 @@ pub const Stream = struct {
return .{
.events = events,
- .parser_stream = .initAlloc(alloc, handler),
+ .parser_stream = .init(.{
+ .allocator = alloc,
+ .handler = handler,
+ }),
};
}
@@ -59,9 +64,10 @@ pub const Stream = struct {
pub fn draw(
self: *Stream,
- alloc: Allocator,
+ surface: *Surface,
palette: *const terminal.color.Palette,
) void {
+ const alloc = surface.alloc;
const events = &self.events;
const handler = &self.parser_stream.handler;
const popup_filter = "Filter";
@@ -93,6 +99,16 @@ pub const Stream = struct {
handler.current_seq = 1;
}
+
+ cimgui.c.ImGui_SameLineEx(0, cimgui.c.ImGui_GetStyle().*.ItemInnerSpacing.x);
+ if (cimgui.c.ImGui_Button("Copy")) {
+ self.copyEvents(surface);
+ }
+
+ cimgui.c.ImGui_SameLineEx(0, cimgui.c.ImGui_GetStyle().*.ItemInnerSpacing.x);
+ if (cimgui.c.ImGui_Button("Export to file")) {
+ self.exportEvents(surface);
+ }
}
}
@@ -330,6 +346,73 @@ pub const Stream = struct {
}
} // filter popup
}
+
+ /// Copy all recorded events to the standard clipboard in chronological
+ /// order.
+ fn copyEvents(
+ self: *const Stream,
+ surface: *Surface,
+ ) void {
+ const alloc = surface.alloc;
+ const contents = self.formatEvents(alloc) catch |err| {
+ log.err("failed to format terminal IO events for copy err={}", .{err});
+ return;
+ };
+ defer alloc.free(contents);
+
+ surface.rt_surface.setClipboard(.standard, &.{.{
+ .mime = "text/plain",
+ .data = contents,
+ }}, false) catch |err| {
+ log.err("failed to copy terminal IO events err={}", .{err});
+ };
+ }
+
+ /// Ask the application runtime to save all recorded events to a file.
+ fn exportEvents(
+ self: *const Stream,
+ surface: *Surface,
+ ) void {
+ const alloc = surface.alloc;
+ const contents = self.formatEvents(alloc) catch |err| {
+ log.err("failed to format terminal IO events for export err={}", .{err});
+ return;
+ };
+ defer alloc.free(contents);
+
+ const handled = surface.rt_app.performAction(
+ .{ .surface = surface },
+ .export_terminal_io,
+ .{ .contents = contents },
+ ) catch |err| {
+ log.err("failed to export terminal IO events err={}", .{err});
+ return;
+ };
+ if (!handled) {
+ log.warn("application runtime does not support exporting terminal IO events", .{});
+ }
+ }
+
+ /// Format all recorded events as tab-separated text. Events are exported
+ /// oldest-first even though the inspector displays the newest event first.
+ fn formatEvents(
+ self: *const Stream,
+ alloc: Allocator,
+ ) ![:0]u8 {
+ var buf: std.Io.Writer.Allocating = .init(alloc);
+ errdefer buf.deinit();
+
+ try buf.writer.writeAll("Seq\tKind\tDescription\n");
+ var it = self.events.iterator(.forward);
+ while (it.next()) |ev| {
+ try buf.writer.print(
+ "{d}\t{s}\t{s}\n",
+ .{ ev.seq, @tagName(ev.kind), ev.raw_description },
+ );
+ }
+
+ return try buf.toOwnedSliceSentinel(0);
+ }
};
/// Helper function to check keyboard state and determine navigation action.
@@ -793,8 +876,6 @@ const VTHandler = struct {
vt_events.deleteOldest(1);
try vt_events.append(ev);
},
-
- else => return err,
};
// Do NOT skip it, because we want to record more information