Rewrite of tmux mouse support which was a mess. Instead of having

options for "mouse-this" and "mouse-that", mouse events may be bound as
keys and there is one option "mouse" that turns on mouse support
entirely (set -g mouse on).

See the new MOUSE SUPPORT section of the man page for description of the
key names and new flags (-t= to specify the pane or window under mouse
as a target, and send-keys -M to pass through a mouse event).

The default builtin bindings for the mouse are:

    bind -n   MouseDown1Pane select-pane -t=; send-keys -M
    bind -n MouseDown1Status select-window -t=
    bind -n   MouseDrag1Pane copy-mode -M
    bind -n MouseDrag1Border resize-pane -M

To get the effect of turning mode-mouse off, do:

    unbind -n MouseDrag1Pane
    unbind -temacs-copy MouseDrag1Pane

The old mouse options are now gone, set-option -q may be used to
suppress warnings if mixing configuration files.
This commit is contained in:
nicm
2015-04-19 21:34:21 +00:00
parent ee123c2489
commit bf635e7741
27 changed files with 879 additions and 584 deletions

View File

@ -644,8 +644,8 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size)
{
struct mouse_event *m = &tty->mouse;
struct utf8_data utf8data;
u_int i, value, x, y, b, sgr, sgr_b, sgr_rel;
unsigned char c;
u_int i, value, x, y, b, sgr_b;
u_char sgr_type, c;
/*
* Standard mouse sequences are \033[M followed by three characters
@ -661,7 +661,8 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size)
*/
*size = 0;
x = y = b = sgr = sgr_b = sgr_rel = 0;
x = y = b = sgr_b = 0;
sgr_type = ' ';
/* First two bytes are always \033[. */
if (buf[0] != '\033')
@ -708,7 +709,7 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size)
else
y = value;
}
log_debug("mouse input: %.*s", (int) *size, buf);
log_debug("mouse input: %.*s", (int)*size, buf);
/* Check and return the mouse input. */
if (b < 32)
@ -748,22 +749,26 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size)
while (1) {
if (len <= *size)
return (1);
c = (u_char) buf[(*size)++];
c = (u_char)buf[(*size)++];
if (c == 'M' || c == 'm')
break;
if (c < '0' || c > '9')
return (-1);
y = 10 * y + (c - '0');
}
log_debug("mouse input (sgr): %.*s", (int) *size, buf);
log_debug("mouse input (SGR): %.*s", (int)*size, buf);
/* Check and return the mouse input. */
if (x < 1 || y < 1)
return (-1);
x--;
y--;
sgr = 1;
sgr_rel = (c == 'm');
b = sgr_b;
/* Type is M for press, m for release. */
sgr_type = c;
if (sgr_type == 'm')
b |= 3;
/*
* Some terminals (like PuTTY 0.63) mistakenly send
@ -771,64 +776,20 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size)
* Discard it before it reaches any program running inside
* tmux.
*/
if (sgr_rel && (sgr_b & 64))
if (sgr_type == 'm' && (sgr_b & 64))
return (-2);
/* Figure out what b would be in old format. */
b = sgr_b;
if (sgr_rel)
b |= 3;
} else
return (-1);
/* Fill in mouse structure. */
if (~m->event & MOUSE_EVENT_WHEEL) {
m->lx = m->x;
m->ly = m->y;
}
m->xb = b;
m->sgr = sgr;
m->sgr_xb = sgr_b;
m->sgr_rel = sgr_rel;
/* Fill mouse event. */
m->lx = m->x;
m->x = x;
m->ly = m->y;
m->y = y;
if (b & MOUSE_MASK_WHEEL) {
if (b & MOUSE_MASK_SHIFT)
m->scroll = 1;
else
m->scroll = MOUSE_WHEEL_SCALE;
if (b & MOUSE_MASK_META)
m->scroll *= MOUSE_WHEEL_SCALE;
if (b & MOUSE_MASK_CTRL)
m->scroll *= MOUSE_WHEEL_SCALE;
b &= MOUSE_MASK_BUTTONS;
if (b == 0)
m->wheel = MOUSE_WHEEL_UP;
else if (b == 1)
m->wheel = MOUSE_WHEEL_DOWN;
m->event = MOUSE_EVENT_WHEEL;
m->button = 3;
} else if ((b & MOUSE_MASK_BUTTONS) == 3) {
if (~m->event & MOUSE_EVENT_DRAG && x == m->sx && y == m->sy) {
m->event = MOUSE_EVENT_CLICK;
m->clicks = (m->clicks + 1) % 3;
} else
m->event = MOUSE_EVENT_DRAG;
m->event |= MOUSE_EVENT_UP;
} else {
if (b & MOUSE_MASK_DRAG)
m->event = MOUSE_EVENT_DRAG;
else {
m->event = MOUSE_EVENT_DOWN;
if (x != m->sx || y != m->sy)
m->clicks = 0;
}
m->button = (b & MOUSE_MASK_BUTTONS);
}
m->sx = x;
m->sy = y;
m->lb = m->b;
m->b = b;
m->sgr_type = sgr_type;
m->sgr_b = sgr_b;
return (0);
}