From bf635e7741f7b881f67ec7e4a5caa02f7ff3d786 Mon Sep 17 00:00:00 2001 From: nicm Date: Sun, 19 Apr 2015 21:34:21 +0000 Subject: 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. --- input-keys.c | 97 ++++++++++++++++++++++++++++++------------------------------ 1 file changed, 49 insertions(+), 48 deletions(-) (limited to 'input-keys.c') diff --git a/input-keys.c b/input-keys.c index f2d010d8..ae00e4a9 100644 --- a/input-keys.c +++ b/input-keys.c @@ -31,6 +31,8 @@ * direction with output). */ +void input_key_mouse(struct window_pane *, struct mouse_event *); + struct input_key_ent { int key; const char *data; @@ -135,7 +137,7 @@ const struct input_key_ent input_keys[] = { /* Translate a key code into an output key sequence. */ void -input_key(struct window_pane *wp, int key) +input_key(struct window_pane *wp, int key, struct mouse_event *m) { const struct input_key_ent *ike; u_int i; @@ -143,7 +145,14 @@ input_key(struct window_pane *wp, int key) char *out; u_char ch; - log_debug("writing key 0x%x", key); + log_debug("writing key 0x%x (%s)", key, key_string_lookup_key(key)); + + /* If this is a mouse key, pass off to mouse function. */ + if (KEYC_IS_MOUSE(key)) { + if (m != NULL && m->wp != -1 && (u_int)m->wp == wp->id) + input_key_mouse(wp, m); + return; + } /* * If this is a normal 7-bit key, just send it, with a leading escape @@ -200,55 +209,47 @@ input_key(struct window_pane *wp, int key) /* Translate mouse and output. */ void -input_mouse(struct window_pane *wp, struct session *s, struct mouse_event *m) +input_key_mouse(struct window_pane *wp, struct mouse_event *m) { - char buf[40]; - size_t len; - struct paste_buffer *pb; - int event; - - if (wp->screen->mode & ALL_MOUSE_MODES) { - /* - * Use the SGR (1006) extension only if the application - * requested it and the underlying terminal also sent the event - * in this format (this is because an old style mouse release - * event cannot be converted into the new SGR format, since the - * released button is unknown). Otherwise pretend that tmux - * doesn't speak this extension, and fall back to the UTF-8 - * (1005) extension if the application requested, or to the - * legacy format. - */ - if (m->sgr && (wp->screen->mode & MODE_MOUSE_SGR)) { - len = xsnprintf(buf, sizeof buf, "\033[<%u;%u;%u%c", - m->sgr_xb, m->x + 1, m->y + 1, - m->sgr_rel ? 'm' : 'M'); - } else if (wp->screen->mode & MODE_MOUSE_UTF8) { - len = xsnprintf(buf, sizeof buf, "\033[M"); - len += utf8_split2(m->xb + 32, &buf[len]); - len += utf8_split2(m->x + 33, &buf[len]); - len += utf8_split2(m->y + 33, &buf[len]); - } else { - if (m->xb > 223) - return; - len = xsnprintf(buf, sizeof buf, "\033[M"); - buf[len++] = m->xb + 32; - buf[len++] = m->x + 33; - buf[len++] = m->y + 33; - } - bufferevent_write(wp->event, buf, len); + char buf[40]; + size_t len; + u_int x, y; + + if ((wp->screen->mode & ALL_MOUSE_MODES) == 0) + return; + if (!window_pane_visible(wp)) + return; + if (cmd_mouse_at(wp, m, &x, &y, 0) != 0) return; - } - if (options_get_number(&wp->window->options, "mode-mouse") != 1) + /* If this pane is not in button mode, discard motion events. */ + if (!(wp->screen->mode & MODE_MOUSE_BUTTON) && (m->b & MOUSE_MASK_DRAG)) return; - event = m->event & (MOUSE_EVENT_CLICK|MOUSE_EVENT_WHEEL); - if (wp->mode == NULL && m->button == 1 && event == MOUSE_EVENT_CLICK) { - pb = paste_get_top(); - if (pb != NULL) - paste_send_pane(pb, wp, "\r", 1); - } else if (window_pane_set_mode(wp, &window_copy_mode) == 0) { - window_copy_init_from_pane(wp); - if (wp->mode->mouse != NULL) - wp->mode->mouse(wp, s, m); + + /* + * Use the SGR (1006) extension only if the application requested it + * and the underlying terminal also sent the event in this format (this + * is because an old style mouse release event cannot be converted into + * the new SGR format, since the released button is unknown). Otherwise + * pretend that tmux doesn't speak this extension, and fall back to the + * UTF-8 (1005) extension if the application requested, or to the + * legacy format. + */ + if (m->sgr_type != ' ' && (wp->screen->mode & MODE_MOUSE_SGR)) { + len = xsnprintf(buf, sizeof buf, "\033[<%u;%u;%u%c", + m->sgr_b, x + 1, y + 1, m->sgr_type); + } else if (wp->screen->mode & MODE_MOUSE_UTF8) { + len = xsnprintf(buf, sizeof buf, "\033[M"); + len += utf8_split2(m->b + 32, &buf[len]); + len += utf8_split2(x + 33, &buf[len]); + len += utf8_split2(y + 33, &buf[len]); + } else { + if (m->b > 223) + return; + len = xsnprintf(buf, sizeof buf, "\033[M"); + buf[len++] = m->b + 32; + buf[len++] = x + 33; + buf[len++] = y + 33; } + bufferevent_write(wp->event, buf, len); } -- cgit v1.2.3