mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
OSC 52 read
This commit is contained in:
@ -592,9 +592,41 @@ pub fn handleMessage(self: *Window, msg: Message) !void {
|
||||
},
|
||||
|
||||
.cell_size => |size| try self.setCellSize(size),
|
||||
|
||||
.clipboard_read => |kind| try self.clipboardRead(kind),
|
||||
}
|
||||
}
|
||||
|
||||
fn clipboardRead(self: *const Window, kind: u8) !void {
|
||||
const data = glfw.getClipboardString() catch |err| {
|
||||
log.warn("error reading clipboard: {}", .{err});
|
||||
return;
|
||||
};
|
||||
|
||||
// Even if the clipboard data is empty we reply, since presumably
|
||||
// the client app is expecting a reply. We first allocate our buffer.
|
||||
// This must hold the base64 encoded data PLUS the OSC code surrounding it.
|
||||
const enc = std.base64.standard.Encoder;
|
||||
const size = enc.calcSize(data.len);
|
||||
var buf = try self.alloc.alloc(u8, size + 8); // 8 for OSC
|
||||
defer self.alloc.free(buf);
|
||||
|
||||
// Wrap our data with the OSC code
|
||||
const prefix = try std.fmt.bufPrint(buf, "\x1b]52;{c};", .{kind});
|
||||
assert(prefix.len == 7);
|
||||
buf[buf.len - 1] = '\x1b';
|
||||
|
||||
// Do the base64 encoding
|
||||
const encoded = enc.encode(buf[prefix.len..], data);
|
||||
assert(encoded.len == size);
|
||||
|
||||
_ = self.io_thread.mailbox.push(try termio.Message.writeReq(
|
||||
self.alloc,
|
||||
buf,
|
||||
), .{ .forever = {} });
|
||||
self.io_thread.wakeup.send() catch {};
|
||||
}
|
||||
|
||||
/// Change the cell size for the terminal grid. This can happen as
|
||||
/// a result of changing the font size at runtime.
|
||||
fn setCellSize(self: *Window, size: renderer.CellSize) !void {
|
||||
|
@ -464,6 +464,12 @@ pub fn Stream(comptime Handler: type) type {
|
||||
} else log.warn("unimplemented OSC callback: {}", .{cmd});
|
||||
},
|
||||
|
||||
.clipboard_contents => |clip| {
|
||||
if (@hasDecl(T, "clipboardContents")) {
|
||||
try self.handler.clipboardContents(clip.kind, clip.data);
|
||||
} else log.warn("unimplemented OSC callback: {}", .{cmd});
|
||||
},
|
||||
|
||||
else => if (@hasDecl(T, "oscUnimplemented"))
|
||||
try self.handler.oscUnimplemented(cmd)
|
||||
else
|
||||
|
@ -815,4 +815,20 @@ const StreamHandler = struct {
|
||||
.set_title = buf,
|
||||
}, .{ .forever = {} });
|
||||
}
|
||||
|
||||
pub fn clipboardContents(self: *StreamHandler, kind: u8, data: []const u8) !void {
|
||||
// Note: we ignore the "kind" field and always use the primary clipboard.
|
||||
// iTerm also appears to do this but other terminals seem to only allow
|
||||
// certain. Let's investigate more.
|
||||
|
||||
// Get clipboard contents
|
||||
if (data.len == 1 and data[0] == '?') {
|
||||
_ = self.window_mailbox.push(.{
|
||||
.clipboard_read = kind,
|
||||
}, .{ .forever = {} });
|
||||
return;
|
||||
}
|
||||
|
||||
unreachable;
|
||||
}
|
||||
};
|
||||
|
@ -12,6 +12,9 @@ pub const Message = union(enum) {
|
||||
|
||||
/// Change the cell size.
|
||||
cell_size: renderer.CellSize,
|
||||
|
||||
/// Read the clipboard and write to the pty.
|
||||
clipboard_read: u8,
|
||||
};
|
||||
|
||||
/// A window mailbox.
|
||||
|
Reference in New Issue
Block a user