summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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