=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/window-copy.c,v retrieving revision 1.216 retrieving revision 1.217 diff -u -r1.216 -r1.217 --- src/usr.bin/tmux/window-copy.c 2019/04/23 09:39:07 1.216 +++ src/usr.bin/tmux/window-copy.c 2019/04/25 06:34:57 1.217 @@ -1,4 +1,4 @@ -/* $OpenBSD: window-copy.c,v 1.216 2019/04/23 09:39:07 nicm Exp $ */ +/* $OpenBSD: window-copy.c,v 1.217 2019/04/25 06:34:57 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -116,6 +116,7 @@ static void window_copy_rectangle_toggle(struct window_mode_entry *); static void window_copy_move_mouse(struct mouse_event *); static void window_copy_drag_update(struct client *, struct mouse_event *); +static void window_copy_drag_release(struct client *, struct mouse_event *); const struct window_mode window_copy_mode = { .name = "copy-mode", @@ -231,8 +232,35 @@ int jumptype; char jumpchar; + + struct event dragtimer; +#define WINDOW_COPY_DRAG_REPEAT_TIME 50000 }; +static void +window_copy_scroll_timer(__unused int fd, __unused short events, void *arg) +{ + struct window_mode_entry *wme = arg; + struct window_pane *wp = wme->wp; + struct window_copy_mode_data *data = wme->data; + struct timeval tv = { + .tv_usec = WINDOW_COPY_DRAG_REPEAT_TIME + }; + + evtimer_del(&data->dragtimer); + + if (TAILQ_FIRST(&wp->modes) != wme) + return; + + if (data->cy == 0) { + evtimer_add(&data->dragtimer, &tv); + window_copy_cursor_up(wme, 1); + } else if (data->cy == screen_size_y(&data->screen) - 1) { + evtimer_add(&data->dragtimer, &tv); + window_copy_cursor_down(wme, 1); + } +} + static struct window_copy_mode_data * window_copy_common_init(struct window_mode_entry *wme) { @@ -261,6 +289,8 @@ screen_init(&data->screen, screen_size_x(base), screen_size_y(base), 0); data->modekeys = options_get_number(wp->window->options, "mode-keys"); + evtimer_set(&data->dragtimer, window_copy_scroll_timer, wme); + return (data); } @@ -319,6 +349,8 @@ struct window_pane *wp = wme->wp; struct window_copy_mode_data *data = wme->data; + evtimer_del(&data->dragtimer); + if (wp->fd != -1 && --wp->disabled == 0) bufferevent_enable(wp->event, EV_READ|EV_WRITE); @@ -3248,7 +3280,7 @@ return; c->tty.mouse_drag_update = window_copy_drag_update; - c->tty.mouse_drag_release = NULL; /* will fire MouseDragEnd key */ + c->tty.mouse_drag_release = window_copy_drag_release; window_copy_update_cursor(wme, x, y); window_copy_start_selection(wme); @@ -3261,7 +3293,10 @@ struct window_pane *wp; struct window_mode_entry *wme; struct window_copy_mode_data *data; - u_int x, y, old_cy; + u_int x, y, old_cx, old_cy; + struct timeval tv = { + .tv_usec = WINDOW_COPY_DRAG_REPEAT_TIME + }; if (c == NULL) return; @@ -3272,13 +3307,46 @@ wme = TAILQ_FIRST(&wp->modes); if (wme == NULL || wme->mode != &window_copy_mode) return; + data = wme->data; + evtimer_del(&data->dragtimer); if (cmd_mouse_at(wp, m, &x, &y, 0) != 0) return; + old_cx = data->cx; old_cy = data->cy; window_copy_update_cursor(wme, x, y); if (window_copy_update_selection(wme, 1)) window_copy_redraw_selection(wme, old_cy); + if (old_cy != data->cy || old_cx == data->cx) { + if (y == 0) { + evtimer_add(&data->dragtimer, &tv); + window_copy_cursor_up(wme, 1); + } else if (y == screen_size_y(&data->screen) - 1) { + evtimer_add(&data->dragtimer, &tv); + window_copy_cursor_down(wme, 1); + } + } +} + +static void +window_copy_drag_release(struct client *c, struct mouse_event *m) +{ + struct window_pane *wp; + struct window_mode_entry *wme; + struct window_copy_mode_data *data; + + if (c == NULL) + return; + + wp = cmd_mouse_pane(m, NULL, NULL); + if (wp == NULL) + return; + wme = TAILQ_FIRST(&wp->modes); + if (wme == NULL || wme->mode != &window_copy_mode) + return; + + data = wme->data; + evtimer_del(&data->dragtimer); }