mirror of
https://github.com/tmux/tmux.git
synced 2025-11-03 08:16:08 +00:00
On some Windows terminals, if TIOCWINSZ does not return xpixel and
ypixel (they are zero), if this is the case then try the query escape sequences. From Dmitry Galchinsky in GitHub issue 4099.
This commit is contained in:
79
tty-keys.c
79
tty-keys.c
@@ -654,6 +654,74 @@ tty_keys_next1(struct tty *tty, const char *buf, size_t len, key_code *key,
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Process window size change escape sequences. */
|
||||
static int
|
||||
tty_keys_winsz(struct tty *tty, const char *buf, size_t len, size_t *size)
|
||||
{
|
||||
struct client *c = tty->client;
|
||||
size_t end;
|
||||
char tmp[64];
|
||||
u_int sx, sy, xpixel, ypixel, char_x, char_y;
|
||||
|
||||
*size = 0;
|
||||
|
||||
/* If we did not request this, ignore it. */
|
||||
if (!(tty->flags & TTY_WINSIZEQUERY))
|
||||
return (-1);
|
||||
|
||||
/* First two bytes are always \033[. */
|
||||
if (buf[0] != '\033')
|
||||
return (-1);
|
||||
if (len == 1)
|
||||
return (1);
|
||||
if (buf[1] != '[')
|
||||
return (-1);
|
||||
if (len == 2)
|
||||
return (1);
|
||||
|
||||
/*
|
||||
* Stop at either 't' or anything that isn't a
|
||||
* number or ';'.
|
||||
*/
|
||||
for (end = 2; end < len && end != sizeof tmp; end++) {
|
||||
if (buf[end] == 't')
|
||||
break;
|
||||
if (!isdigit((u_char)buf[end]) && buf[end] != ';')
|
||||
break;
|
||||
}
|
||||
if (end == len)
|
||||
return (1);
|
||||
if (end == sizeof tmp || buf[end] != 't')
|
||||
return (-1);
|
||||
|
||||
/* Copy to the buffer. */
|
||||
memcpy(tmp, buf + 2, end - 2);
|
||||
tmp[end - 2] = '\0';
|
||||
|
||||
/* Try to parse the window size sequence. */
|
||||
if (sscanf(tmp, "8;%u;%u", &sy, &sx) == 2) {
|
||||
/* Window size in characters. */
|
||||
tty_set_size(tty, sx, sy, tty->xpixel, tty->ypixel);
|
||||
|
||||
*size = end + 1;
|
||||
return (0);
|
||||
} else if (sscanf(tmp, "4;%u;%u", &ypixel, &xpixel) == 2) {
|
||||
/* Window size in pixels. */
|
||||
char_x = (xpixel && tty->sx) ? xpixel / tty->sx : 0;
|
||||
char_y = (ypixel && tty->sy) ? ypixel / tty->sy : 0;
|
||||
tty_set_size(tty, tty->sx, tty->sy, char_x, char_y);
|
||||
tty_invalidate(tty);
|
||||
|
||||
tty->flags &= ~TTY_WINSIZEQUERY;
|
||||
*size = end + 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
log_debug("%s: unrecognized window size sequence: %s", c->name, tmp);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
||||
/* Process at least one key in the buffer. Return 0 if no keys present. */
|
||||
int
|
||||
tty_keys_next(struct tty *tty)
|
||||
@@ -754,6 +822,17 @@ tty_keys_next(struct tty *tty)
|
||||
goto partial_key;
|
||||
}
|
||||
|
||||
/* Check for window size query */
|
||||
switch (tty_keys_winsz(tty, buf, len, &size)) {
|
||||
case 0: /* yes */
|
||||
key = KEYC_UNKNOWN;
|
||||
goto complete_key;
|
||||
case -1: /* no, or not valid */
|
||||
break;
|
||||
case 1: /* partial */
|
||||
goto partial_key;
|
||||
}
|
||||
|
||||
first_key:
|
||||
/* Try to lookup complete key. */
|
||||
n = tty_keys_next1(tty, buf, len, &key, &size, expired);
|
||||
|
||||
Reference in New Issue
Block a user