aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Marriott <nicholas.marriott@gmail.com>2022-04-27 11:34:08 +0100
committerNicholas Marriott <nicholas.marriott@gmail.com>2022-04-27 11:34:08 +0100
commitc6b51cea923e0c4e92636998a776ada42511b6e5 (patch)
treea4f40113cca66cd1bf0612c86f9949b638691ca3
parent58d1a206c6ae6b33059ea6b469c21dad92ea0841 (diff)
downloadrtmux-c6b51cea923e0c4e92636998a776ada42511b6e5.tar.gz
rtmux-c6b51cea923e0c4e92636998a776ada42511b6e5.tar.bz2
rtmux-c6b51cea923e0c4e92636998a776ada42511b6e5.zip
If a mouse position was above the maximum supported by the normal mouse
protocol (223), tmux was allowing it to wrap around. However, since tmux was not correctly handling this on input, other programs also do not handle it correctly, and the alternative SGR mouse mode is now widespread, this seems unnecessary, so remove this feature. Also define some constants to make it clearer what the numbers mean. Mostly from Leonid S Usov in GitHub issue 3165.
-rw-r--r--input-keys.c31
-rw-r--r--tmux.h6
-rw-r--r--tty-keys.c16
3 files changed, 35 insertions, 18 deletions
diff --git a/input-keys.c b/input-keys.c
index feb62f6d..ebf61333 100644
--- a/input-keys.c
+++ b/input-keys.c
@@ -606,19 +606,34 @@ input_key_get_mouse(struct screen *s, struct mouse_event *m, u_int x, u_int y,
len = xsnprintf(buf, sizeof buf, "\033[<%u;%u;%u%c",
m->sgr_b, x + 1, y + 1, m->sgr_type);
} else if (s->mode & MODE_MOUSE_UTF8) {
- if (m->b > 0x7ff - 32 || x > 0x7ff - 33 || y > 0x7ff - 33)
+ if (m->b > MOUSE_PARAM_UTF8_MAX - MOUSE_PARAM_BTN_OFF ||
+ x > MOUSE_PARAM_UTF8_MAX - MOUSE_PARAM_POS_OFF ||
+ y > MOUSE_PARAM_UTF8_MAX - MOUSE_PARAM_POS_OFF)
return (0);
len = xsnprintf(buf, sizeof buf, "\033[M");
- len += input_key_split2(m->b + 32, &buf[len]);
- len += input_key_split2(x + 33, &buf[len]);
- len += input_key_split2(y + 33, &buf[len]);
+ len += input_key_split2(m->b + MOUSE_PARAM_BTN_OFF, &buf[len]);
+ len += input_key_split2(x + MOUSE_PARAM_POS_OFF, &buf[len]);
+ len += input_key_split2(y + MOUSE_PARAM_POS_OFF, &buf[len]);
} else {
- if (m->b > 223)
+ if (m->b + MOUSE_PARAM_BTN_OFF > MOUSE_PARAM_MAX)
return (0);
+
len = xsnprintf(buf, sizeof buf, "\033[M");
- buf[len++] = m->b + 32;
- buf[len++] = x + 33;
- buf[len++] = y + 33;
+ buf[len++] = m->b + MOUSE_PARAM_BTN_OFF;
+
+ /*
+ * The incoming x and y may be out of the range which can be
+ * supported by the "normal" mouse protocol. Clamp the
+ * coordinates to the supported range.
+ */
+ if (x + MOUSE_PARAM_POS_OFF > MOUSE_PARAM_MAX)
+ buf[len++] = MOUSE_PARAM_MAX;
+ else
+ buf[len++] = x + MOUSE_PARAM_POS_OFF;
+ if (y + MOUSE_PARAM_POS_OFF > MOUSE_PARAM_MAX)
+ buf[len++] = MOUSE_PARAM_MAX;
+ else
+ buf[len++] = y + MOUSE_PARAM_POS_OFF;
}
*rbuf = buf;
diff --git a/tmux.h b/tmux.h
index a893bdb2..53084b8b 100644
--- a/tmux.h
+++ b/tmux.h
@@ -581,6 +581,12 @@ enum tty_code_code {
#define MOTION_MOUSE_MODES (MODE_MOUSE_BUTTON|MODE_MOUSE_ALL)
#define CURSOR_MODES (MODE_CURSOR|MODE_CURSOR_BLINKING|MODE_CURSOR_VERY_VISIBLE)
+/* Mouse protocol constants. */
+#define MOUSE_PARAM_MAX 0xff
+#define MOUSE_PARAM_UTF8_MAX 0x7ff
+#define MOUSE_PARAM_BTN_OFF 0x20
+#define MOUSE_PARAM_POS_OFF 0x21
+
/* A single UTF-8 character. */
typedef u_int utf8_char;
diff --git a/tty-keys.c b/tty-keys.c
index 8538e74b..64dd91bb 100644
--- a/tty-keys.c
+++ b/tty-keys.c
@@ -1061,17 +1061,13 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size,
log_debug("%s: mouse input: %.*s", c->name, (int)*size, buf);
/* Check and return the mouse input. */
- if (b < 32)
+ if (b < MOUSE_PARAM_BTN_OFF ||
+ x < MOUSE_PARAM_POS_OFF ||
+ y < MOUSE_PARAM_POS_OFF)
return (-1);
- b -= 32;
- if (x >= 33)
- x -= 33;
- else
- x = 256 - x;
- if (y >= 33)
- y -= 33;
- else
- y = 256 - y;
+ b -= MOUSE_PARAM_BTN_OFF;
+ x -= MOUSE_PARAM_POS_OFF;
+ y -= MOUSE_PARAM_POS_OFF;
} else if (buf[2] == '<') {
/* Read the three inputs. */
*size = 3;