diff options
author | nicm <nicm> | 2017-02-01 09:55:07 +0000 |
---|---|---|
committer | nicm <nicm> | 2017-02-01 09:55:07 +0000 |
commit | dd0c8147795c518de443c33895c614e52b42677f (patch) | |
tree | 2260ebc6d5ff2559ac2fd6156add15cc580407a3 /server-client.c | |
parent | 3408595f77920764bf6c4c313a0abc6a1cfb8048 (diff) | |
download | rtmux-dd0c8147795c518de443c33895c614e52b42677f.tar.gz rtmux-dd0c8147795c518de443c33895c614e52b42677f.tar.bz2 rtmux-dd0c8147795c518de443c33895c614e52b42677f.zip |
Implement "all event" (1003) mouse mode but in a way that works. The
main issue is that if we have two panes, A with 1002 and B with 1003, we
need to set 1003 outside tmux in order to get all the mouse events, but
then we need to suppress the ones that pane A doesn't want. This is easy
in SGR mouse mode, because buttons == 3 is only used for movement events
(for other events the trailing m/M marks a release instead), but in
normal mouse mode we can't tell so easily. So for that, look at the
previous event instead - if it is drag+release as well, then the current
event is a movement event.
Diffstat (limited to 'server-client.c')
-rw-r--r-- | server-client.c | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/server-client.c b/server-client.c index 88abe005..7f47602a 100644 --- a/server-client.c +++ b/server-client.c @@ -335,14 +335,27 @@ server_client_check_mouse(struct client *c) int flag; key_code key; struct timeval tv; - enum { NOTYPE, DOWN, UP, DRAG, WHEEL, DOUBLE, TRIPLE } type = NOTYPE; - enum { NOWHERE, PANE, STATUS, BORDER } where = NOWHERE; + enum { NOTYPE, MOVE, DOWN, UP, DRAG, WHEEL, DOUBLE, TRIPLE } type; + enum { NOWHERE, PANE, STATUS, BORDER } where; + + type = NOTYPE; + where = NOWHERE; log_debug("mouse %02x at %u,%u (last %u,%u) (%d)", m->b, m->x, m->y, m->lx, m->ly, c->tty.mouse_drag_flag); /* What type of event is this? */ - if (MOUSE_DRAG(m->b)) { + if ((m->sgr_type != ' ' && + MOUSE_DRAG(m->sgr_b) && + MOUSE_BUTTONS(m->sgr_b) == 3) || + (m->sgr_type == ' ' && + MOUSE_DRAG(m->b) && + MOUSE_BUTTONS(m->b) == 3 && + MOUSE_BUTTONS(m->lb) == 3)) { + type = MOVE; + x = m->x, y = m->y, b = 0; + log_debug("move at %u,%u", x, y); + } else if (MOUSE_DRAG(m->b)) { type = DRAG; if (c->tty.mouse_drag_flag) { x = m->x, y = m->y, b = m->b; @@ -500,6 +513,14 @@ have_event: switch (type) { case NOTYPE: break; + case MOVE: + if (where == PANE) + key = KEYC_MOUSEMOVE_PANE; + if (where == STATUS) + key = KEYC_MOUSEMOVE_STATUS; + if (where == BORDER) + key = KEYC_MOUSEMOVE_BORDER; + break; case DRAG: if (c->tty.mouse_drag_update != NULL) key = KEYC_DRAGGING; @@ -1055,7 +1076,7 @@ static void server_client_reset_state(struct client *c) { struct window *w = c->session->curw->window; - struct window_pane *wp = w->active; + struct window_pane *wp = w->active, *loop; struct screen *s = wp->screen; struct options *oo = c->session->options; int status, mode, o; @@ -1079,8 +1100,15 @@ server_client_reset_state(struct client *c) * mode. */ mode = s->mode; - if (options_get_number(oo, "mouse")) - mode = (mode & ~ALL_MOUSE_MODES) | MODE_MOUSE_BUTTON; + if (options_get_number(oo, "mouse")) { + mode &= ~ALL_MOUSE_MODES; + TAILQ_FOREACH(loop, &w->panes, entry) { + if (loop->screen->mode & MODE_MOUSE_ALL) + mode |= MODE_MOUSE_ALL; + } + if (~mode & MODE_MOUSE_ALL) + mode |= MODE_MOUSE_BUTTON; + } /* Set the terminal mode and reset attributes. */ tty_update_mode(&c->tty, mode, s); |