From 12ac19939c365b3f29660b252ed36028f9a4a7a9 Mon Sep 17 00:00:00 2001 From: Andrei Lebedev <14347159+lebdron@users.noreply.github.com> Date: Mon, 27 Apr 2026 01:27:22 +1000 Subject: [PATCH] feat: add middle-click action configuration --- src/Surface.zig | 25 +++++++++++++++---------- src/config.zig | 1 + src/config/Config.zig | 30 +++++++++++++++++++++++++----- 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/Surface.zig b/src/Surface.zig index 9dd0088c9..086c0fc8e 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -311,6 +311,7 @@ const DerivedConfig = struct { clipboard_codepoint_map: configpkg.Config.RepeatableClipboardCodepointMap, copy_on_select: configpkg.CopyOnSelect, right_click_action: configpkg.RightClickAction, + middle_click_action: configpkg.MiddleClickAction, confirm_close_surface: configpkg.ConfirmCloseSurface, cursor_click_to_move: bool, desktop_notifications: bool, @@ -389,6 +390,7 @@ const DerivedConfig = struct { .clipboard_codepoint_map = try config.@"clipboard-codepoint-map".clone(alloc), .copy_on_select = config.@"copy-on-select", .right_click_action = config.@"right-click-action", + .middle_click_action = config.@"middle-click-action", .confirm_close_surface = config.@"confirm-close-surface", .cursor_click_to_move = config.@"cursor-click-to-move", .desktop_notifications = config.@"desktop-notifications", @@ -4014,16 +4016,19 @@ pub fn mouseButtonCallback( // 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. - if (button == .middle and action == .press) { - 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 (button == .middle and action == .press) switch (self.config.middle_click_action) { + .ignore => {}, + .@"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 = {} }); + }, + }; // Right-click down selects word for context menus. If the apprt // doesn't implement context menus this can be a bit weird but they diff --git a/src/config.zig b/src/config.zig index 289b6a811..05a2761a3 100644 --- a/src/config.zig +++ b/src/config.zig @@ -23,6 +23,7 @@ pub const Command = Config.Command; pub const ConfirmCloseSurface = Config.ConfirmCloseSurface; pub const CopyOnSelect = Config.CopyOnSelect; pub const RightClickAction = Config.RightClickAction; +pub const MiddleClickAction = Config.MiddleClickAction; pub const CustomShaderAnimation = Config.CustomShaderAnimation; pub const FontSyntheticStyle = Config.FontSyntheticStyle; pub const FontShapingBreak = Config.FontShapingBreak; diff --git a/src/config/Config.zig b/src/config/Config.zig index f9a7c95c4..5b1d73deb 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -2404,11 +2404,12 @@ keybind: Keybinds = .{}, /// The value `clipboard` will always copy text to the selection clipboard /// as well as the system clipboard. /// -/// Middle-click paste is always enabled 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. +/// 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. /// /// The default value is true on Linux and macOS. @"copy-on-select": CopyOnSelect = switch (builtin.os.tag) { @@ -2430,6 +2431,16 @@ keybind: Keybinds = .{}, /// The default value is `context-menu`. @"right-click-action": RightClickAction = .@"context-menu", +/// 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`. +/// * `ignore` - Do nothing, ignore the middle click. +/// +/// The default value is `primary-paste`. +@"middle-click-action": MiddleClickAction = .@"primary-paste", + /// 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 /// use a platform-specific default. The default on macOS is determined by the @@ -8653,6 +8664,15 @@ pub const RightClickAction = enum { @"context-menu", }; +/// Options for middle-click actions. +pub const MiddleClickAction = enum { + /// Paste from the selection/standard clipboard per `copy-on-select`. + @"primary-paste", + + /// No action is taken on middle click. + ignore, +}; + /// Shell integration values pub const ShellIntegration = enum { none,