From f62d3d22bb542e262ee961e5f3e2db33b963b4db Mon Sep 17 00:00:00 2001 From: Tiago Cunha Date: Sun, 6 Jun 2010 00:23:44 +0000 Subject: [PATCH] Sync OpenBSD patchset 710: When the mode-mouse option is on, support dragging to make a selection in copy mode. Also support the scroll wheel, although xterm strangely does not ignore it in application mouse mode, causing redraw artifacts when scrolling up (other terminals appear to be better behaved). --- tmux.1 | 10 ++++------ tmux.h | 7 ++++--- tty-keys.c | 5 +++-- tty.c | 19 ++++++++++++------ window-copy.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++----- 5 files changed, 73 insertions(+), 22 deletions(-) diff --git a/tmux.1 b/tmux.1 index 79d21c9c..49101053 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1,4 +1,4 @@ -.\" $Id: tmux.1,v 1.254 2010-06-06 00:21:36 tcunha Exp $ +.\" $Id: tmux.1,v 1.255 2010-06-06 00:23:44 tcunha Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott .\" @@ -14,7 +14,7 @@ .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: May 30 2010 $ +.Dd $Mdocdate: May 31 2010 $ .Dt TMUX 1 .Os .Sh NAME @@ -2078,10 +2078,8 @@ Key bindings default to emacs. .Op Ic on | off .Xc Mouse state in modes. -If on, -.Nm -will respond to mouse clicks by moving the cursor in copy mode or selecting an -option in choice mode. +If on, the mouse may be used to copy a selection by dragging in copy mode, or +to select an option in choice mode. .Pp .It Xo Ic monitor-activity .Op Ic on | off diff --git a/tmux.h b/tmux.h index effb690a..c0d3298c 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.559 2010-06-05 20:29:11 micahcowan Exp $ */ +/* $Id: tmux.h,v 1.560 2010-06-06 00:23:44 tcunha Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -544,7 +544,8 @@ struct mode_key_table { #define MODE_KCURSOR 0x4 #define MODE_KKEYPAD 0x8 /* set = application, clear = number */ #define MODE_MOUSE 0x10 -#define MODE_WRAP 0x20 /* whether lines wrap */ +#define MODE_MOUSEMOTION 0x20 +#define MODE_WRAP 0x40 /* whether lines wrap */ /* * A single UTF-8 character. @@ -1089,7 +1090,7 @@ struct client { #define CLIENT_TERMINAL 0x1 #define CLIENT_PREFIX 0x2 -#define CLIENT_MOUSE 0x4 +/* 0x4 unused */ #define CLIENT_REDRAW 0x8 #define CLIENT_STATUS 0x10 #define CLIENT_REPEAT 0x20 /* allow command to repeat within repeat time */ diff --git a/tty-keys.c b/tty-keys.c index f2460dd6..e4085483 100644 --- a/tty-keys.c +++ b/tty-keys.c @@ -1,4 +1,4 @@ -/* $Id: tty-keys.c,v 1.56 2010-03-15 20:44:51 nicm Exp $ */ +/* $Id: tty-keys.c,v 1.57 2010-06-06 00:23:44 tcunha Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -612,7 +612,8 @@ tty_keys_mouse(const char *buf, size_t len, size_t *size, struct mouse_event *m) return (1); *size = 6; - log_debug("mouse input is: %.6s", buf); + log_debug( + "mouse input: %.6s (%hhu,%hhu/%hhu)", buf, buf[4], buf[5], buf[3]); m->b = buf[3]; m->x = buf[4]; diff --git a/tty.c b/tty.c index 729f000d..4ec22383 100644 --- a/tty.c +++ b/tty.c @@ -1,4 +1,4 @@ -/* $Id: tty.c,v 1.189 2010-03-08 14:53:49 tcunha Exp $ */ +/* $Id: tty.c,v 1.190 2010-06-06 00:23:44 tcunha Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -402,11 +402,18 @@ tty_update_mode(struct tty *tty, int mode) else tty_putcode(tty, TTYC_CIVIS); } - if (changed & MODE_MOUSE) { - if (mode & MODE_MOUSE) - tty_puts(tty, "\033[?1000h"); - else - tty_puts(tty, "\033[?1000l"); + if (changed & (MODE_MOUSE|MODE_MOUSEMOTION)) { + if (mode & MODE_MOUSE) { + if (mode & MODE_MOUSEMOTION) + tty_puts(tty, "\033[?1003h"); + else + tty_puts(tty, "\033[?1000h"); + } else { + if (mode & MODE_MOUSEMOTION) + tty_puts(tty, "\033[?1003l"); + else + tty_puts(tty, "\033[?1000l"); + } } if (changed & MODE_KKEYPAD) { if (mode & MODE_KKEYPAD) diff --git a/window-copy.c b/window-copy.c index fdc97949..6369220b 100644 --- a/window-copy.c +++ b/window-copy.c @@ -1,4 +1,4 @@ -/* $Id: window-copy.c,v 1.119 2010-06-05 20:29:11 micahcowan Exp $ */ +/* $Id: window-copy.c,v 1.120 2010-06-06 00:23:44 tcunha Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -760,17 +760,61 @@ window_copy_mouse( { struct window_copy_mode_data *data = wp->modedata; struct screen *s = &data->screen; + u_int i; + + /* + * xterm mouse mode is fairly silly. Buttons are in the bottom two + * bits: 0 button 1; 1 button 2; 2 button 3; 3 buttons released. + * + * Bit 3 is shift; bit 4 is meta; bit 5 control. + * + * Bit 6 is added for mouse buttons 4 and 5. + */ - if ((m->b & 3) == 3) - return; if (m->x >= screen_size_x(s)) return; if (m->y >= screen_size_y(s)) return; - window_copy_update_cursor(wp, m->x, m->y); - if (window_copy_update_selection(wp)) + /* If mouse wheel (buttons 4 and 5), scroll. */ + if ((m->b & 64) == 64) { + if ((m->b & 3) == 0) { + for (i = 0; i < 5; i++) + window_copy_cursor_up(wp, 0); + } else if ((m->b & 3) == 1) { + for (i = 0; i < 5; i++) + window_copy_cursor_down(wp, 0); + } + return; + } + + /* + * If already reading motion, move the cursor while buttons are still + * pressed, or stop the selection on their release. + */ + if (s->mode & MODE_MOUSEMOTION) { + if ((m->b & 3) != 3) { + window_copy_update_cursor(wp, m->x, m->y); + if (window_copy_update_selection(wp)) + window_copy_redraw_screen(wp); + } else { + s->mode &= ~MODE_MOUSEMOTION; + if (sess != NULL) { + window_copy_copy_selection(wp, sess); + window_pane_reset_mode(wp); + } + } + return; + } + + /* Otherwise i other buttons pressed, start selection and motion. */ + if ((m->b & 3) != 3) { + s->mode |= MODE_MOUSEMOTION; + + window_copy_update_cursor(wp, m->x, m->y); + window_copy_start_selection(wp); window_copy_redraw_screen(wp); + } } void