Fix mouse interactions in terminal.
This commit is contained in:
+9
-53
@@ -1424,10 +1424,17 @@ fn onShortcut(
|
||||
// Only a terminal needs us to encode a paste for it. A web
|
||||
// pane has its own clipboard handling, so the key is left
|
||||
// alone rather than swallowed here.
|
||||
if (self.focusedTerminal() == null) return 0;
|
||||
self.paste();
|
||||
const terminal = self.focusedTerminal() orelse return 0;
|
||||
terminal.pasteFrom(.standard);
|
||||
return 1;
|
||||
},
|
||||
gdk.KEY_C, gdk.KEY_c => {
|
||||
// With nothing selected the key is declined rather than
|
||||
// swallowed, so a web pane's own copy still works and a
|
||||
// terminal still receives it.
|
||||
const terminal = self.focusedTerminal() orelse return 0;
|
||||
return if (terminal.copySelection(.standard)) 1 else 0;
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
@@ -1495,54 +1502,3 @@ fn onShortcut(
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Paste
|
||||
//
|
||||
// GTK4's clipboard API is asynchronous, so the read completes on a later
|
||||
// main loop turn. We resolve the destination tab at completion time rather
|
||||
// than capturing it, so closing a tab mid-paste can't leave a dangling
|
||||
// pointer.
|
||||
|
||||
fn paste(self: *Window) void {
|
||||
const clipboard = self.window.as(gtk.Widget).getClipboard();
|
||||
clipboard.readTextAsync(null, &onPasteReady, self);
|
||||
}
|
||||
|
||||
fn onPasteReady(
|
||||
source: ?*gobject.Object,
|
||||
result: *gio.AsyncResult,
|
||||
data: ?*anyopaque,
|
||||
) callconv(.c) void {
|
||||
const self: *Window = @ptrCast(@alignCast(data.?));
|
||||
const clipboard: *gdk.Clipboard = @ptrCast(@alignCast(source.?));
|
||||
|
||||
var err: ?*glib.Error = null;
|
||||
const text = clipboard.readTextFinish(result, &err) orelse {
|
||||
if (err) |e| {
|
||||
std.log.warn("paste failed: {s}", .{e.f_message orelse "unknown"});
|
||||
e.free();
|
||||
}
|
||||
return;
|
||||
};
|
||||
defer glib.free(text);
|
||||
|
||||
const terminal = self.focusedTerminal() orelse return;
|
||||
const session = terminal.session;
|
||||
// Coerce to a plain slice: encodePaste dispatches on the exact type.
|
||||
const span: []const u8 = std.mem.span(text);
|
||||
|
||||
// Refuse pastes containing control characters that would execute on
|
||||
// arrival (a newline in unbracketed mode runs the command immediately).
|
||||
const opts: vt.input.PasteOptions = .fromTerminal(&session.term);
|
||||
if (!vt.input.isSafePaste(span)) {
|
||||
std.log.warn("refusing unsafe paste", .{});
|
||||
return;
|
||||
}
|
||||
|
||||
const parts = vt.input.encodePaste(span, opts) catch |e| {
|
||||
std.log.warn("paste encode failed: {s}", .{@errorName(e)});
|
||||
return;
|
||||
};
|
||||
for (parts) |part| session.write(part);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user