=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/window-copy.c,v retrieving revision 1.216 retrieving revision 1.217 diff -c -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 **** ! /* $OpenBSD: window-copy.c,v 1.216 2019/04/23 09:39:07 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott --- 1,4 ---- ! /* $OpenBSD: window-copy.c,v 1.217 2019/04/25 06:34:57 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott *************** *** 116,121 **** --- 116,122 ---- 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,238 **** --- 232,266 ---- 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,266 **** --- 289,296 ---- 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,324 **** --- 349,356 ---- 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,3254 **** return; c->tty.mouse_drag_update = window_copy_drag_update; ! c->tty.mouse_drag_release = NULL; /* will fire MouseDragEnd key */ window_copy_update_cursor(wme, x, y); window_copy_start_selection(wme); --- 3280,3286 ---- return; c->tty.mouse_drag_update = window_copy_drag_update; ! c->tty.mouse_drag_release = window_copy_drag_release; window_copy_update_cursor(wme, x, y); window_copy_start_selection(wme); *************** *** 3261,3267 **** struct window_pane *wp; struct window_mode_entry *wme; struct window_copy_mode_data *data; ! u_int x, y, old_cy; if (c == NULL) return; --- 3293,3302 ---- struct window_pane *wp; struct window_mode_entry *wme; struct window_copy_mode_data *data; ! u_int x, y, old_cx, old_cy; ! struct timeval tv = { ! .tv_usec = WINDOW_COPY_DRAG_REPEAT_TIME ! }; if (c == NULL) return; *************** *** 3272,3284 **** --- 3307,3352 ---- 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); }