mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
apprt: primary clipboard awareness (selection clipboard)
This commit is contained in:
@ -601,11 +601,11 @@ pub fn handleMessage(self: *Surface, msg: Message) !void {
|
|||||||
.clipboard_read => |kind| try self.clipboardRead(kind),
|
.clipboard_read => |kind| try self.clipboardRead(kind),
|
||||||
|
|
||||||
.clipboard_write => |req| switch (req) {
|
.clipboard_write => |req| switch (req) {
|
||||||
.small => |v| try self.clipboardWrite(v.data[0..v.len]),
|
.small => |v| try self.clipboardWrite(v.data[0..v.len], .standard),
|
||||||
.stable => |v| try self.clipboardWrite(v),
|
.stable => |v| try self.clipboardWrite(v, .standard),
|
||||||
.alloc => |v| {
|
.alloc => |v| {
|
||||||
defer v.alloc.free(v.data);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = self.rt_surface.getClipboardString() catch |err| {
|
const data = self.rt_surface.getClipboardString(.standard) catch |err| {
|
||||||
log.warn("error reading clipboard: {}", .{err});
|
log.warn("error reading clipboard: {}", .{err});
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
@ -755,7 +755,7 @@ fn clipboardRead(self: *const Surface, kind: u8) !void {
|
|||||||
self.io_thread.wakeup.notify() catch {};
|
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) {
|
if (!self.config.clipboard_write) {
|
||||||
log.info("application attempted to write clipboard, but 'clipboard-write' setting is off", .{});
|
log.info("application attempted to write clipboard, but 'clipboard-write' setting is off", .{});
|
||||||
return;
|
return;
|
||||||
@ -773,7 +773,7 @@ fn clipboardWrite(self: *const Surface, data: []const u8) !void {
|
|||||||
try dec.decode(buf, data);
|
try dec.decode(buf, data);
|
||||||
assert(buf[buf.len] == 0);
|
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});
|
log.err("error setting clipboard string err={}", .{err});
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
@ -1972,7 +1972,7 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !void
|
|||||||
};
|
};
|
||||||
defer self.alloc.free(buf);
|
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});
|
log.err("error setting clipboard string err={}", .{err});
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
@ -1980,7 +1980,7 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !void
|
|||||||
},
|
},
|
||||||
|
|
||||||
.paste_from_clipboard => {
|
.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});
|
log.warn("error reading clipboard: {}", .{err});
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
@ -913,9 +913,11 @@ pub const Surface = struct {
|
|||||||
// ));
|
// ));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getClipboardString(self: *Surface) ![:0]const u8 {
|
pub fn getClipboardString(
|
||||||
const clipboard = c.gtk_widget_get_clipboard(@ptrCast(self.gl_area));
|
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 {
|
const content = c.gdk_clipboard_get_content(clipboard) orelse {
|
||||||
// On my machine, this NEVER works, so we fallback to glfw's
|
// On my machine, this NEVER works, so we fallback to glfw's
|
||||||
// implementation...
|
// implementation...
|
||||||
@ -933,12 +935,22 @@ pub const Surface = struct {
|
|||||||
return std.mem.sliceTo(ptr, 0);
|
return std.mem.sliceTo(ptr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setClipboardString(self: *const Surface, val: [:0]const u8) !void {
|
pub fn setClipboardString(
|
||||||
const clipboard = c.gtk_widget_get_clipboard(@ptrCast(self.gl_area));
|
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);
|
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 {
|
pub fn getCursorPos(self: *const Surface) !apprt.CursorPos {
|
||||||
return self.cursor_pos;
|
return self.cursor_pos;
|
||||||
}
|
}
|
||||||
|
@ -23,3 +23,11 @@ pub const IMEPos = struct {
|
|||||||
x: f64,
|
x: f64,
|
||||||
y: 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
|
||||||
|
};
|
||||||
|
@ -1417,7 +1417,7 @@ const StreamHandler = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn clipboardContents(self: *StreamHandler, kind: u8, data: []const u8) !void {
|
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
|
// iTerm also appears to do this but other terminals seem to only allow
|
||||||
// certain. Let's investigate more.
|
// certain. Let's investigate more.
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user