pull/12604/merge
Mohammad AlShami 2026-06-03 12:27:01 -07:00 committed by GitHub
commit 67bb0992fc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 88 additions and 52 deletions

View File

@ -2333,34 +2333,35 @@ fn setSelection(self: *Surface, sel_: ?terminal.Selection) !void {
try self.io.terminal.screens.active.select(sel_);
// If copy on select is false then exit early.
if (self.config.copy_on_select == .false) return;
if (self.config.copy_on_select == .none) return;
// Set our selection clipboard. If the selection is cleared we do not
// clear the clipboard.
const sel = sel_ orelse return;
switch (self.config.copy_on_select) {
.false => unreachable, // handled above with an early exit
.none => unreachable, // handled above with an early exit
// The selection clipboard is set if supported, otherwise nothing is copied.
.primary => try self.copySelectionToClipboards(
sel,
&.{.selection},
.mixed,
),
// Only the standard clipboard is set.
.clipboard => try self.copySelectionToClipboards(
sel,
&.{.standard},
.mixed,
),
// Both standard and selection clipboards are set.
.clipboard => try self.copySelectionToClipboards(
.both => try self.copySelectionToClipboards(
sel,
&.{ .standard, .selection },
.mixed,
),
// The selection clipboard is set if supported, otherwise the standard.
.true => {
const clipboard: apprt.Clipboard = if (self.rt_surface.supportsClipboard(.selection))
.selection
else
.standard;
try self.copySelectionToClipboards(
sel,
&.{clipboard},
.mixed,
);
},
}
}
@ -3995,22 +3996,16 @@ pub fn mouseButtonCallback(
}
}
// Middle-click paste source follows copy-on-select: when copy-on-select
// targets the selection clipboard, middle-click reads from it; when
// copy-on-select targets the system clipboard, middle-click reads from
// that instead. Falls back to the standard clipboard on platforms that
// do not support the selection clipboard.
// Middle-click action, either ignore, or paste from clipboard or paste from the selection clipboard if supported.
if (button == .middle and action == .press) switch (self.config.middle_click_action) {
.ignore => {},
.@"clipboard-paste" => {
_ = try self.startClipboardRequest(.standard, .{ .paste = {} });
},
.@"primary-paste" => {
const clipboard: apprt.Clipboard = switch (self.config.copy_on_select) {
.clipboard => .standard,
.true, .false => if (self.rt_surface.supportsClipboard(.selection))
.selection
else
.standard,
};
_ = try self.startClipboardRequest(clipboard, .{ .paste = {} });
if (self.rt_surface.supportsClipboard(.selection)) {
_ = try self.startClipboardRequest(.selection, .{ .paste = {} });
}
},
};

View File

@ -96,6 +96,12 @@ pub const compatibility = std.StaticStringMap(
// Ghostty 1.3 rename the "window" option to "new-window".
// See: https://github.com/ghostty-org/ghostty/pull/9764
.{ "macos-dock-drop-behavior", compatMacOSDockDropBehavior },
// Ghostty 1.4 updated "copy-on-select", allow copying to the selection
// clipboard (on supported operating systems), the system clipboard, or
// both. The semantics also changed but this is the correct mapping.
// See: https://github.com/ghostty-org/ghostty/pull/12604
.{ "copy-on-select", compatCopyOnSelect },
});
/// Set Ghostty's graphical user interface language to a language other than the
@ -2398,25 +2404,28 @@ keybind: Keybinds = .{},
/// limit per surface is double.
@"image-storage-limit": u32 = 320 * 1000 * 1000,
/// Whether to automatically copy selected text to the clipboard. `true`
/// will prefer to copy to the selection clipboard, otherwise it will copy to
/// the system clipboard.
/// Whether to automatically copy selected text to the clipboard.
///
/// The value `clipboard` will always copy text to the selection clipboard
/// as well as the system clipboard.
/// Valid values:
///
/// Middle-click primary paste (see `middle-click-action`) is enabled by
/// default even if this is `false`. The clipboard it pastes from follows
/// this setting: with `true` (or `false`) it reads from the selection
/// clipboard (falling back to the system clipboard on platforms without a
/// selection clipboard); with `clipboard` it reads from the system
/// clipboard.
/// * `none` - Do not copy selected text automatically.
///
/// The default value is true on Linux and macOS.
/// * `primary` - On Linux, copy to the selection clipboard only. This has no
/// effect on macOS. (Available since: 1.4.0)
///
/// * `clipboard` - Copy text to the system clipboard only.
///
/// * `both` - Copy to both clipboards on Linux, and only the system clipboard
/// on macOS. (Available since: 1.4.0)
///
/// For backward compatibility and convenience, a value of `true` is the same as
/// `primary` on Linux and `clipboard` on macOS, and `false` is an alias for
/// `none`.
///
/// The default value is `primary` on Linux and `none` otherwise.
@"copy-on-select": CopyOnSelect = switch (builtin.os.tag) {
.linux => .true,
.macos => .true,
else => .false,
.linux => .primary,
else => .none,
},
/// The action to take when the user right-clicks on the terminal surface.
@ -2435,8 +2444,9 @@ keybind: Keybinds = .{},
/// The action to take when the user middle-clicks on the terminal surface.
///
/// Valid values:
/// * `primary-paste` - Paste from the selection (or system) clipboard per
/// `copy-on-select`.
/// * `primary-paste` - Paste from the selection clipboard on Linux.
/// Does nothing on macOS.
/// * `clipboard-paste` - Paste from the system clipboard.
/// * `ignore` - Do nothing, ignore the middle click.
///
/// The default value is `primary-paste`.
@ -4886,6 +4896,31 @@ fn compatMacOSDockDropBehavior(
return false;
}
fn compatCopyOnSelect(
self: *Config,
alloc: Allocator,
key: []const u8,
value: ?[]const u8,
) bool {
_ = alloc;
assert(std.mem.eql(u8, key, "copy-on-select"));
if (std.mem.eql(u8, value orelse "", "true")) {
self.@"copy-on-select" = switch (builtin.os.tag) {
.linux, .freebsd => .primary,
else => .clipboard,
};
return true;
}
if (std.mem.eql(u8, value orelse "", "false")) {
self.@"copy-on-select" = .none;
return true;
}
return false;
}
/// Add a diagnostic message to the config with the given string.
/// This is always added with a location of "none".
pub fn addDiagnosticFmt(
@ -8617,16 +8652,20 @@ pub const RepeatableLink = struct {
/// Options for copy on select behavior.
pub const CopyOnSelect = enum {
/// Disables copy on select entirely.
false,
/// Disables copy on select entirely. This is the default on macOS.
none,
/// Copy on select is enabled, but goes to the selection clipboard.
/// This is not supported on platforms such as macOS. This is the default.
true,
/// This is not supported on platforms such as macOS. This is the default
/// on Linux.
primary,
/// Copy on select is enabled and goes to the system clipboard.
clipboard,
/// Copy on select is enabled and goes to both the system clipboard
/// and the selection clipboard (for Linux).
clipboard,
both,
};
/// Options for right-click actions.
@ -8650,8 +8689,10 @@ pub const RightClickAction = enum {
/// Options for middle-click actions.
pub const MiddleClickAction = enum {
/// Paste from the selection/standard clipboard per `copy-on-select`.
/// Paste from the selection clipboard.
@"primary-paste",
/// Paste from the standard clipboard.
@"clipboard-paste",
/// No action is taken on middle click.
ignore,