aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@openbsd.org>2010-05-31 19:51:29 +0000
committerNicholas Marriott <nicm@openbsd.org>2010-05-31 19:51:29 +0000
commit43fa9a9ba60f0fba1f5c7985ed9c65cea304d2c4 (patch)
tree89dc06ea00452e3f6e440d6875016ee9d0910c66
parente1e120de1c4fc5f37940ba3a6567acc914f1692c (diff)
downloadrtmux-43fa9a9ba60f0fba1f5c7985ed9c65cea304d2c4.tar.gz
rtmux-43fa9a9ba60f0fba1f5c7985ed9c65cea304d2c4.tar.bz2
rtmux-43fa9a9ba60f0fba1f5c7985ed9c65cea304d2c4.zip
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).
-rw-r--r--tmux.16
-rw-r--r--tmux.h5
-rw-r--r--tty-keys.c3
-rw-r--r--tty.c17
-rw-r--r--window-copy.c52
5 files changed, 67 insertions, 16 deletions
diff --git a/tmux.1 b/tmux.1
index 9b565dd1..94e60758 100644
--- a/tmux.1
+++ b/tmux.1
@@ -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 961019d8..3069f89b 100644
--- a/tmux.h
+++ b/tmux.h
@@ -541,7 +541,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.
@@ -1086,7 +1087,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 27107bb8..59002fb2 100644
--- a/tty-keys.c
+++ b/tty-keys.c
@@ -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 72be2c84..92ddf41f 100644
--- a/tty.c
+++ b/tty.c
@@ -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 3b42c456..66402eca 100644
--- a/window-copy.c
+++ b/window-copy.c
@@ -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