Implement needed modifications for issue #12600

For middle-click-action
* Kept the option "primary-paste" instead of "paste-primary" to keep
backwards compatibility
* Added the option "clipboard-paste"

For copy-on-select
* Added the both, none and primary options

Updated config documentation

Run zig fmt

Move true/false options for copy-on-select to the compatibility handler

Update src/config/Config.zig

Co-authored-by: kat <65649991+00-kat@users.noreply.github.com>

Update src/config/Config.zig

Co-authored-by: kat <65649991+00-kat@users.noreply.github.com>

Update src/config/Config.zig

Co-authored-by: kat <65649991+00-kat@users.noreply.github.com>

Update src/config/Config.zig

Co-authored-by: kat <65649991+00-kat@users.noreply.github.com>

Update src/config/Config.zig

Co-authored-by: kat <65649991+00-kat@users.noreply.github.com>

Update src/config/Config.zig

Co-authored-by: kat <65649991+00-kat@users.noreply.github.com>

Update src/Surface.zig

Co-authored-by: kat <65649991+00-kat@users.noreply.github.com>

Update src/Surface.zig

Co-authored-by: kat <65649991+00-kat@users.noreply.github.com>

Update src/config/Config.zig

Co-authored-by: kat <65649991+00-kat@users.noreply.github.com>

Update src/config/Config.zig

Co-authored-by: kat <65649991+00-kat@users.noreply.github.com>

Update src/config/Config.zig

Co-authored-by: kat <65649991+00-kat@users.noreply.github.com>

Update src/config/Config.zig

Co-authored-by: kat <65649991+00-kat@users.noreply.github.com>

Update src/config/Config.zig

Co-authored-by: kat <65649991+00-kat@users.noreply.github.com>

Update src/Surface.zig

Co-authored-by: kat <65649991+00-kat@users.noreply.github.com>

Update src/Surface.zig

Co-authored-by: kat <65649991+00-kat@users.noreply.github.com>

Reorder switch items

Apply comment from kat

Remove redundent code
This commit is contained in:
Mohammad H. AlShami
2026-05-07 01:25:51 +03:00
parent 0254a7f06f
commit dfccdb2d4d
2 changed files with 88 additions and 55 deletions

View File

@@ -2378,31 +2378,29 @@ fn setSelection(self: *Surface, sel_: ?terminal.Selection) !void {
fn setSelectionAndCopy(self: *Surface, sel: terminal.Selection) !void {
try self.setSelection(sel);
// If copy on select is false then exit early.
if (self.config.copy_on_select == .false) return;
switch (self.config.copy_on_select) {
.false => unreachable, // handled above with an early exit
.none => {},
// 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,
);
},
}
}
@@ -3891,7 +3889,7 @@ pub fn mouseButtonCallback(
// The selection clipboard is only updated for left-click drag when
// the left button is released. This is to avoid the clipboard
// being updated on every mouse move which would be noisy.
if (self.config.copy_on_select != .false) {
if (self.config.copy_on_select != .none) {
const prev_ = self.io.terminal.screens.active.selection;
if (prev_) |prev| {
try self.setSelectionAndCopy(terminal.Selection.init(
@@ -4049,22 +4047,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 = clipboard });
if (self.rt_surface.supportsClipboard(.selection)) {
_ = try self.startClipboardRequest(.selection, .{ .paste = {} });
}
},
};

View File

@@ -100,6 +100,12 @@ pub const compatibility = std.StaticStringMap(
// Ghostty 1.4 renamed `scrollback-limit` to `scrollback-limit-bytes`
// when `scrollback-limit-lines` was added so the units are explicit.
.{ "scrollback-limit", cli.compatibilityRenamed(Config, "scrollback-limit-bytes") },
// 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
@@ -2517,25 +2523,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.
@@ -2554,8 +2563,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`.
@@ -5047,6 +5057,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(
@@ -8728,16 +8763,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.
@@ -8761,8 +8800,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,