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),
|
.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
|
/// Change the cell size for the terminal grid. This can happen as
|
||||||
/// a result of changing the font size at runtime.
|
/// a result of changing the font size at runtime.
|
||||||
fn setCellSize(self: *Window, size: renderer.CellSize) !void {
|
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});
|
} 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"))
|
else => if (@hasDecl(T, "oscUnimplemented"))
|
||||||
try self.handler.oscUnimplemented(cmd)
|
try self.handler.oscUnimplemented(cmd)
|
||||||
else
|
else
|
||||||
|
@ -815,4 +815,20 @@ const StreamHandler = struct {
|
|||||||
.set_title = buf,
|
.set_title = buf,
|
||||||
}, .{ .forever = {} });
|
}, .{ .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.
|
/// Change the cell size.
|
||||||
cell_size: renderer.CellSize,
|
cell_size: renderer.CellSize,
|
||||||
|
|
||||||
|
/// Read the clipboard and write to the pty.
|
||||||
|
clipboard_read: u8,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A window mailbox.
|
/// A window mailbox.
|
||||||
|
Reference in New Issue
Block a user