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