Add a scroll-to-mouse command for copy mode to scroll to the mouse

position and bind to the scrollbar, brings the scrollbar keys into line
with the other mouse keys. From Michael Grant, GitHub issue 4731.
This commit is contained in:
nicm
2025-12-10 21:24:43 +00:00
parent 52e2a7d990
commit 672e89a640
3 changed files with 32 additions and 8 deletions

View File

@@ -480,9 +480,9 @@ key_bindings_init(void)
"bind -n M-MouseDown3Pane { display-menu -t= -xM -yM -T '#[align=centre]#{pane_index} (#{pane_id})' " DEFAULT_PANE_MENU " }",
/* Mouse on scrollbar. */
"bind -n MouseDown1ScrollbarUp { copy-mode -u }",
"bind -n MouseDown1ScrollbarDown { copy-mode -d }",
"bind -n MouseDrag1ScrollbarSlider { copy-mode -S }",
"bind -n MouseDown1ScrollbarUp { if -Ft= '#{pane_in_mode}' { send -X page-up } {copy-mode -u } }",
"bind -n MouseDown1ScrollbarDown { if -Ft= '#{pane_in_mode}' { send -X page-down } {copy-mode -d } }",
"bind -n MouseDrag1ScrollbarSlider { if -Ft= '#{pane_in_mode}' { send -X scroll-to-mouse } { copy-mode -S } }",
/* Copy mode (emacs) keys. */
"bind -Tcopy-mode C-Space { send -X begin-selection }",

15
tmux.1
View File

@@ -2211,6 +2211,13 @@ but also exit copy mode if the cursor reaches the bottom.
Scroll so that the current line becomes the middle one while keeping the
cursor on that line.
.It Xo
.Ic scroll-to-mouse
.Xc
Scroll pane in copy-mode when bound to a mouse drag event.
.Fl e
causes copy mode to exit when at the bottom.
.Pp
.It Xo
.Ic scroll-top
.Xc
Scroll down until the current line is at the top while keeping the cursor on
@@ -2447,12 +2454,10 @@ cancels copy mode and any other modes.
.Fl M
begins a mouse drag (only valid if bound to a mouse key binding, see
.Sx MOUSE SUPPORT ) .
.Pp
.Fl S
scrolls when bound to a mouse drag event; for example,
.Ic copy-mode -Se
is bound to
.Ar MouseDrag1ScrollbarSlider
by default.
enters copy-mode and scrolls when bound to a mouse drag event; See
.Ic scroll-to-mouse .
.Pp
.Fl s
copies from

View File

@@ -1479,6 +1479,20 @@ window_copy_cmd_scroll_middle(struct window_copy_cmd_state *cs)
return (window_copy_cmd_scroll_to(cs, mid_value));
}
/* Scroll the pane to the mouse in the scrollbar. */
static enum window_copy_cmd_action
window_copy_cmd_scroll_to_mouse(struct window_copy_cmd_state *cs)
{
struct window_mode_entry *wme = cs->wme;
struct window_pane *wp = wme->wp;
struct client *c = cs->c;
struct mouse_event *m = cs->m;
int scroll_exit = args_has(cs->wargs, 'e');
window_copy_scroll(wp, c->tty.mouse_slider_mpos, m->y, scroll_exit);
return (WINDOW_COPY_CMD_NOTHING);
}
/* Scroll line containing the cursor to the top. */
static enum window_copy_cmd_action
window_copy_cmd_scroll_top(struct window_copy_cmd_state *cs)
@@ -3044,6 +3058,11 @@ static const struct {
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
.f = window_copy_cmd_scroll_middle
},
{ .command = "scroll-to-mouse",
.args = { "e", 0, 0, NULL },
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
.f = window_copy_cmd_scroll_to_mouse
},
{ .command = "scroll-top",
.args = { "", 0, 0, NULL },
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,