From 00f4e6bae07e3c9429654900ba297150850b3d36 Mon Sep 17 00:00:00 2001 From: LimaTheLime Date: Sat, 22 Feb 2025 20:26:41 +0000 Subject: [PATCH 1/5] Moved clipboard logic to copyOnMouseAction, created copy-on-right-click config --- src/Surface.zig | 41 +++++++++++++++++++++++---------------- src/apprt/gtk/Surface.zig | 2 +- src/config.zig | 2 +- src/config/Config.zig | 10 ++++++++-- 4 files changed, 34 insertions(+), 21 deletions(-) diff --git a/src/Surface.zig b/src/Surface.zig index 98c344927e..ca2a7da319 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -235,7 +235,8 @@ const DerivedConfig = struct { clipboard_trim_trailing_spaces: bool, clipboard_paste_protection: bool, clipboard_paste_bracketed_safe: bool, - copy_on_select: configpkg.CopyOnSelect, + copy_on_select: configpkg.CopyOnMouseAction, + copy_on_right_click: configpkg.CopyOnMouseAction, confirm_close_surface: configpkg.ConfirmCloseSurface, cursor_click_to_move: bool, desktop_notifications: bool, @@ -297,6 +298,7 @@ const DerivedConfig = struct { .clipboard_paste_protection = config.@"clipboard-paste-protection", .clipboard_paste_bracketed_safe = config.@"clipboard-paste-bracketed-safe", .copy_on_select = config.@"copy-on-select", + .copy_on_right_click = config.@"copy-on-right-click", .confirm_close_surface = config.@"confirm-close-surface", .cursor_click_to_move = config.@"cursor-click-to-move", .desktop_notifications = config.@"desktop-notifications", @@ -1405,20 +1407,7 @@ fn clipboardWrite(self: *const Surface, data: []const u8, loc: apprt.Clipboard) /// Set the selection contents. /// /// This must be called with the renderer mutex held. -fn setSelection(self: *Surface, sel_: ?terminal.Selection) !void { - const prev_ = self.io.terminal.screen.selection; - try self.io.terminal.screen.select(sel_); - - // If copy on select is false then exit early. - if (self.config.copy_on_select == .false) return; - - // Set our selection clipboard. If the selection is cleared we do not - // clear the clipboard. If the selection is set, we only set the clipboard - // again if it changed, since setting the clipboard can be an expensive - // operation. - const sel = sel_ orelse return; - if (prev_) |prev| if (sel.eql(prev)) return; - +fn copyOnMouseAction(self: *Surface, sel: terminal.Selection, action: configpkg.CopyOnMouseAction) !void { const buf = self.io.terminal.screen.selectionString(self.alloc, .{ .sel = sel, .trim = self.config.clipboard_trim_trailing_spaces, @@ -1430,7 +1419,7 @@ fn setSelection(self: *Surface, sel_: ?terminal.Selection) !void { // Set the clipboard. This is not super DRY but it is clear what // we're doing for each setting without being clever. - switch (self.config.copy_on_select) { + switch (action) { .false => unreachable, // handled above with an early exit // Both standard and selection clipboards are set. @@ -1469,6 +1458,22 @@ fn setSelection(self: *Surface, sel_: ?terminal.Selection) !void { } } +fn setSelection(self: *Surface, sel_: ?terminal.Selection) !void { + const prev_ = self.io.terminal.screen.selection; + try self.io.terminal.screen.select(sel_); + + // If copy on select is false then exit early. + if (self.config.copy_on_select == .false) return; + + // clear the clipboard. If the selection is set, we only set the clipboard + // again if it changed, since setting the clipboard can be an expensive + // operation. + const sel = sel_ orelse return; + if (prev_) |prev| if (sel.eql(prev)) return; + + try self.copyOnMouseAction(sel, self.config.copy_on_select); +} + /// Change the cell size for the terminal grid. This can happen as /// a result of changing the font size at runtime. fn setCellSize(self: *Surface, size: renderer.CellSize) !void { @@ -3074,6 +3079,7 @@ pub fn mouseButtonCallback( // are supported by our two main apprts so we always do this. If we // want to be careful in the future we can add a function to apprts // that let's us know. + if (button == .right and action == .press) sel: { self.renderer_state.mutex.lock(); defer self.renderer_state.mutex.unlock(); @@ -3103,14 +3109,15 @@ pub fn mouseButtonCallback( // If we already have a selection and the selection contains // where we clicked then we don't want to modify the selection. if (self.io.terminal.screen.selection) |prev_sel| { + try self.copyOnMouseAction(prev_sel, self.config.copy_on_right_click); if (prev_sel.contains(screen, pin)) break :sel; - // The selection doesn't contain our pin, so we create a new // word selection where we clicked. } const sel = screen.selectWord(pin) orelse break :sel; try self.setSelection(sel); + try self.copyOnMouseAction(sel, self.config.copy_on_right_click); try self.queueRender(); } diff --git a/src/apprt/gtk/Surface.zig b/src/apprt/gtk/Surface.zig index 9a8c4513db..c1fa1ed759 100644 --- a/src/apprt/gtk/Surface.zig +++ b/src/apprt/gtk/Surface.zig @@ -1464,7 +1464,7 @@ fn gtkMouseDown( // If a right click isn't consumed, mouseButtonCallback selects the hovered // word and returns false. We can use this to handle the context menu // opening under normal scenarios. - if (!consumed and button == .right) { + if (!consumed and button == .right and self.app.config.@"copy-on-right-click" == .false) { self.showContextMenu(@floatCast(x), @floatCast(y)); } } diff --git a/src/config.zig b/src/config.zig index a8ffe2ec7b..aa88c616dc 100644 --- a/src/config.zig +++ b/src/config.zig @@ -15,7 +15,7 @@ pub const formatEntry = formatter.formatEntry; // Field types pub const ClipboardAccess = Config.ClipboardAccess; pub const ConfirmCloseSurface = Config.ConfirmCloseSurface; -pub const CopyOnSelect = Config.CopyOnSelect; +pub const CopyOnMouseAction = Config.CopyOnMouseAction; pub const CustomShaderAnimation = Config.CustomShaderAnimation; pub const FontSyntheticStyle = Config.FontSyntheticStyle; pub const FontStyle = Config.FontStyle; diff --git a/src/config/Config.zig b/src/config/Config.zig index 768629fd46..e285b5ecb4 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -1506,7 +1506,13 @@ keybind: Keybinds = .{}, /// paste is always enabled even if this is `false`. /// /// The default value is true on Linux and macOS. -@"copy-on-select": CopyOnSelect = switch (builtin.os.tag) { +@"copy-on-select": CopyOnMouseAction = switch (builtin.os.tag) { + .linux => .true, + .macos => .true, + else => .false, +}, + +@"copy-on-right-click": CopyOnMouseAction = switch (builtin.os.tag) { .linux => .true, .macos => .true, else => .false, @@ -5754,7 +5760,7 @@ pub const RepeatableLink = struct { }; /// Options for copy on select behavior. -pub const CopyOnSelect = enum { +pub const CopyOnMouseAction = enum { /// Disables copy on select entirely. false, From cc55ffa26ddd5e4d64067ed1d3e3b8c30bb6bb15 Mon Sep 17 00:00:00 2001 From: LimaTheLime Date: Sat, 22 Feb 2025 20:36:42 +0000 Subject: [PATCH 2/5] Sets sane default for copy-to-right-click --- src/config/Config.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/config/Config.zig b/src/config/Config.zig index e285b5ecb4..ff8a734df7 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -1513,8 +1513,8 @@ keybind: Keybinds = .{}, }, @"copy-on-right-click": CopyOnMouseAction = switch (builtin.os.tag) { - .linux => .true, - .macos => .true, + .linux => .false, + .macos => .false, else => .false, }, From e6f530354cc0b669ac87e851fe2fc94942ca0a8e Mon Sep 17 00:00:00 2001 From: LimaTheLime Date: Sun, 23 Feb 2025 11:22:00 +0000 Subject: [PATCH 3/5] Moved copy to break condition, fixed syntax and config --- src/Surface.zig | 8 +++++--- src/config/Config.zig | 6 +----- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/Surface.zig b/src/Surface.zig index ca2a7da319..cee125a33e 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -1465,7 +1465,7 @@ fn setSelection(self: *Surface, sel_: ?terminal.Selection) !void { // If copy on select is false then exit early. if (self.config.copy_on_select == .false) return; - // clear the clipboard. If the selection is set, we only set the clipboard + // Clear the clipboard. If the selection is set, we only set the clipboard // again if it changed, since setting the clipboard can be an expensive // operation. const sel = sel_ orelse return; @@ -3109,8 +3109,10 @@ pub fn mouseButtonCallback( // If we already have a selection and the selection contains // where we clicked then we don't want to modify the selection. if (self.io.terminal.screen.selection) |prev_sel| { - try self.copyOnMouseAction(prev_sel, self.config.copy_on_right_click); - if (prev_sel.contains(screen, pin)) break :sel; + if (prev_sel.contains(screen, pin)) { + try self.copyOnMouseAction(prev_sel, self.config.copy_on_right_click); + break :sel; + } // The selection doesn't contain our pin, so we create a new // word selection where we clicked. } diff --git a/src/config/Config.zig b/src/config/Config.zig index ff8a734df7..2861c12b93 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -1512,11 +1512,7 @@ keybind: Keybinds = .{}, else => .false, }, -@"copy-on-right-click": CopyOnMouseAction = switch (builtin.os.tag) { - .linux => .false, - .macos => .false, - else => .false, -}, +@"copy-on-right-click": CopyOnMouseAction = .false, /// The time in milliseconds between clicks to consider a click a repeat /// (double, triple, etc.) or an entirely new single click. A value of zero will From 54e3dc635c834f8f68b049ae2fbe60bc2e95d25b Mon Sep 17 00:00:00 2001 From: LimaTheLime Date: Sun, 23 Feb 2025 11:34:22 +0000 Subject: [PATCH 4/5] Added config explanation --- src/config/Config.zig | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/config/Config.zig b/src/config/Config.zig index 2861c12b93..e0b73643bf 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -1512,6 +1512,20 @@ keybind: Keybinds = .{}, else => .false, }, +/// Whether to copy selected text to the clipboard on right mouse click. `true` +/// will prefer to copy to the selection clipboard, otherwise it will copy to +/// the system clipboard. +/// +/// The value `clipboard` will always copy text to the selection clipboard +/// as well as the system clipboard. +/// +/// Middle-click paste will always use the selection clipboard. Middle-click +/// paste is always enabled even if this is `false`. +/// +/// The default value is false for all systems. +/// +/// At present this will only disable the context menu on Linux in the future +/// this shoul also disable the context menu on macOS @"copy-on-right-click": CopyOnMouseAction = .false, /// The time in milliseconds between clicks to consider a click a repeat From f1f42311de31598b41aa1c13290bf82eeb9fd936 Mon Sep 17 00:00:00 2001 From: LimaTheLime Date: Sun, 23 Feb 2025 12:22:27 +0000 Subject: [PATCH 5/5] typo-fix --- src/config/Config.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/Config.zig b/src/config/Config.zig index 20577a1917..d5e5204833 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -1525,7 +1525,7 @@ keybind: Keybinds = .{}, /// The default value is false for all systems. /// /// At present this will only disable the context menu on Linux in the future -/// this shoul also disable the context menu on macOS +/// this should also disable the context menu on macOS @"copy-on-right-click": CopyOnMouseAction = .false, /// The time in milliseconds between clicks to consider a click a repeat