apprt: primary clipboard awareness (selection clipboard)

This commit is contained in:
Mitchell Hashimoto
2023-08-09 13:41:22 -07:00
parent 232bffe338
commit f3996ff0f8
4 changed files with 35 additions and 15 deletions

View File

@ -601,11 +601,11 @@ pub fn handleMessage(self: *Surface, msg: Message) !void {
.clipboard_read => |kind| try self.clipboardRead(kind),
.clipboard_write => |req| switch (req) {
.small => |v| try self.clipboardWrite(v.data[0..v.len]),
.stable => |v| try self.clipboardWrite(v),
.small => |v| try self.clipboardWrite(v.data[0..v.len], .standard),
.stable => |v| try self.clipboardWrite(v, .standard),
.alloc => |v| {
defer v.alloc.free(v.data);
try self.clipboardWrite(v.data);
try self.clipboardWrite(v.data, .standard);
},
},
@ -725,7 +725,7 @@ fn clipboardRead(self: *const Surface, kind: u8) !void {
return;
}
const data = self.rt_surface.getClipboardString() catch |err| {
const data = self.rt_surface.getClipboardString(.standard) catch |err| {
log.warn("error reading clipboard: {}", .{err});
return;
};
@ -755,7 +755,7 @@ fn clipboardRead(self: *const Surface, kind: u8) !void {
self.io_thread.wakeup.notify() catch {};
}
fn clipboardWrite(self: *const Surface, data: []const u8) !void {
fn clipboardWrite(self: *const Surface, data: []const u8, loc: apprt.Clipboard) !void {
if (!self.config.clipboard_write) {
log.info("application attempted to write clipboard, but 'clipboard-write' setting is off", .{});
return;
@ -773,7 +773,7 @@ fn clipboardWrite(self: *const Surface, data: []const u8) !void {
try dec.decode(buf, data);
assert(buf[buf.len] == 0);
self.rt_surface.setClipboardString(buf) catch |err| {
self.rt_surface.setClipboardString(buf, loc) catch |err| {
log.err("error setting clipboard string err={}", .{err});
return;
};
@ -1972,7 +1972,7 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !void
};
defer self.alloc.free(buf);
self.rt_surface.setClipboardString(buf) catch |err| {
self.rt_surface.setClipboardString(buf, .standard) catch |err| {
log.err("error setting clipboard string err={}", .{err});
return;
};
@ -1980,7 +1980,7 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !void
},
.paste_from_clipboard => {
const data = self.rt_surface.getClipboardString() catch |err| {
const data = self.rt_surface.getClipboardString(.standard) catch |err| {
log.warn("error reading clipboard: {}", .{err});
return;
};

View File

@ -913,9 +913,11 @@ pub const Surface = struct {
// ));
}
pub fn getClipboardString(self: *Surface) ![:0]const u8 {
const clipboard = c.gtk_widget_get_clipboard(@ptrCast(self.gl_area));
pub fn getClipboardString(
self: *Surface,
clipboard_type: apprt.Clipboard,
) ![:0]const u8 {
const clipboard = getClipboard(@ptrCast(self.gl_area), clipboard_type);
const content = c.gdk_clipboard_get_content(clipboard) orelse {
// On my machine, this NEVER works, so we fallback to glfw's
// implementation...
@ -933,12 +935,22 @@ pub const Surface = struct {
return std.mem.sliceTo(ptr, 0);
}
pub fn setClipboardString(self: *const Surface, val: [:0]const u8) !void {
const clipboard = c.gtk_widget_get_clipboard(@ptrCast(self.gl_area));
pub fn setClipboardString(
self: *const Surface,
val: [:0]const u8,
clipboard_type: apprt.Clipboard,
) !void {
const clipboard = getClipboard(@ptrCast(self.gl_area), clipboard_type);
c.gdk_clipboard_set_text(clipboard, val.ptr);
}
fn getClipboard(widget: *c.GtkWidget, clipboard: apprt.Clipboard) ?*c.GdkClipboard {
return switch (clipboard) {
.standard => c.gtk_widget_get_clipboard(widget),
.selection => c.gtk_widget_get_primary_clipboard(widget),
};
}
pub fn getCursorPos(self: *const Surface) !apprt.CursorPos {
return self.cursor_pos;
}

View File

@ -23,3 +23,11 @@ pub const IMEPos = struct {
x: f64,
y: f64,
};
/// The clipboard type.
///
/// If this is changed, you must also update ghostty.h
pub const Clipboard = enum(u1) {
standard = 0, // ctrl+c/v
selection = 1, // also known as the "primary" clipboard
};

View File

@ -1417,7 +1417,7 @@ const StreamHandler = struct {
}
pub fn clipboardContents(self: *StreamHandler, kind: u8, data: []const u8) !void {
// Note: we ignore the "kind" field and always use the primary clipboard.
// Note: we ignore the "kind" field and always use the standard clipboard.
// iTerm also appears to do this but other terminals seem to only allow
// certain. Let's investigate more.