diff --git a/key-bindings.c b/key-bindings.c index a5e1f9c8..22e5cf59 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -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 }", diff --git a/tmux.1 b/tmux.1 index dac3a648..dc1bfc00 100644 --- a/tmux.1 +++ b/tmux.1 @@ -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 diff --git a/window-copy.c b/window-copy.c index 2d528496..f8700555 100644 --- a/window-copy.c +++ b/window-copy.c @@ -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,