summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Adam <thomas@xteddy.org>2024-09-30 12:01:11 +0100
committerThomas Adam <thomas@xteddy.org>2024-09-30 12:01:11 +0100
commit25b1cc1e8e5b78fab718fa797f2cf2ccc310079e (patch)
treea43831465b1c7f73f6599e850bf6ceb2006d697c
parent7b148f7b5b6a40e6a7e02188235776ae03a95c88 (diff)
parent89adec0ca5f3cf7510b3854967b33b399871da7e (diff)
Merge branch 'obsd-master'
-rw-r--r--job.c23
-rw-r--r--popup.c2
-rw-r--r--tmux.h3
-rw-r--r--tty-keys.c79
-rw-r--r--tty.c11
5 files changed, 107 insertions, 11 deletions
diff --git a/job.c b/job.c
index cab91d2c..eeb90f42 100644
--- a/job.c
+++ b/job.c
@@ -69,9 +69,10 @@ static LIST_HEAD(joblist, job) all_jobs = LIST_HEAD_INITIALIZER(all_jobs);
/* Start a job running. */
struct job *
-job_run(const char *cmd, int argc, char **argv, struct environ *e, struct session *s,
- const char *cwd, job_update_cb updatecb, job_complete_cb completecb,
- job_free_cb freecb, void *data, int flags, int sx, int sy)
+job_run(const char *cmd, int argc, char **argv, struct environ *e,
+ struct session *s, const char *cwd, job_update_cb updatecb,
+ job_complete_cb completecb, job_free_cb freecb, void *data, int flags,
+ int sx, int sy)
{
struct job *job;
struct environ *env;
@@ -81,6 +82,7 @@ job_run(const char *cmd, int argc, char **argv, struct environ *e, struct sessio
sigset_t set, oldset;
struct winsize ws;
char **argvp, tty[TTY_NAME_MAX], *argv0;
+ struct options *oo;
/*
* Do not set TERM during .tmux.conf (second argument here), it is nice
@@ -91,12 +93,17 @@ job_run(const char *cmd, int argc, char **argv, struct environ *e, struct sessio
if (e != NULL)
environ_copy(e, env);
- if (s != NULL)
- shell = options_get_string(s->options, "default-shell");
- else
- shell = options_get_string(global_s_options, "default-shell");
- if (!checkshell(shell))
+ if (~flags & JOB_DEFAULTSHELL)
shell = _PATH_BSHELL;
+ else {
+ if (s != NULL)
+ oo = s->options;
+ else
+ oo = global_s_options;
+ shell = options_get_string(oo, "default-shell");
+ if (!checkshell(shell))
+ shell = _PATH_BSHELL;
+ }
argv0 = shell_argv0(shell, 0);
sigfillset(&set);
diff --git a/popup.c b/popup.c
index 706295fe..97f532c0 100644
--- a/popup.c
+++ b/popup.c
@@ -717,7 +717,7 @@ popup_display(int flags, enum box_lines lines, struct cmdq_item *item, u_int px,
pd->job = job_run(shellcmd, argc, argv, env, s, cwd,
popup_job_update_cb, popup_job_complete_cb, NULL, pd,
- JOB_NOWAIT|JOB_PTY|JOB_KEEPWRITE, jx, jy);
+ JOB_NOWAIT|JOB_PTY|JOB_KEEPWRITE|JOB_DEFAULTSHELL, jx, jy);
pd->ictx = input_init(NULL, job_get_event(pd->job), &pd->palette);
server_client_set_overlay(c, 0, popup_check_cb, popup_mode_cb,
diff --git a/tmux.h b/tmux.h
index 0b14ccd0..2dc231cb 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1508,6 +1508,7 @@ struct tty {
#define TTY_HAVEXDA 0x200
#define TTY_SYNCING 0x400
#define TTY_HAVEDA2 0x800 /* Secondary DA. */
+#define TTY_WINSIZEQUERY 0x1000
#define TTY_ALL_REQUEST_FLAGS \
(TTY_HAVEDA|TTY_HAVEDA2|TTY_HAVEXDA)
int flags;
@@ -2341,6 +2342,7 @@ typedef void (*job_free_cb) (void *);
#define JOB_NOWAIT 0x1
#define JOB_KEEPWRITE 0x2
#define JOB_PTY 0x4
+#define JOB_DEFAULTSHELL 0x8
struct job *job_run(const char *, int, char **, struct environ *,
struct session *, const char *, job_update_cb,
job_complete_cb, job_free_cb, void *, int, int, int);
@@ -2403,6 +2405,7 @@ void tty_cell(struct tty *, const struct grid_cell *,
int tty_init(struct tty *, struct client *);
void tty_resize(struct tty *);
void tty_set_size(struct tty *, u_int, u_int, u_int, u_int);
+void tty_invalidate(struct tty *);
void tty_start_tty(struct tty *);
void tty_send_requests(struct tty *);
void tty_repeat_requests(struct tty *);
diff --git a/tty-keys.c b/tty-keys.c
index 3debeea1..3c08db11 100644
--- a/tty-keys.c
+++ b/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);
diff --git a/tty.c b/tty.c
index 28dca400..2c9b7299 100644
--- a/tty.c
+++ b/tty.c
@@ -42,7 +42,6 @@ static void tty_cursor_pane(struct tty *, const struct tty_ctx *, u_int,
u_int);
static void tty_cursor_pane_unless_wrap(struct tty *,
const struct tty_ctx *, u_int, u_int);
-static void tty_invalidate(struct tty *);
static void tty_colours(struct tty *, const struct grid_cell *);
static void tty_check_fg(struct tty *, struct colour_palette *,
struct grid_cell *);
@@ -140,6 +139,14 @@ tty_resize(struct tty *tty)
ypixel = 0;
} else
ypixel = ws.ws_ypixel / sy;
+
+ if ((xpixel == 0 || ypixel == 0) &&
+ tty->out != NULL &&
+ !(tty->flags & TTY_WINSIZEQUERY) &&
+ (tty->term->flags & TERM_VT100LIKE)) {
+ tty_puts(tty, "\033[18t\033[14t");
+ tty->flags |= TTY_WINSIZEQUERY;
+ }
} else {
sx = 80;
sy = 24;
@@ -2369,7 +2376,7 @@ tty_reset(struct tty *tty)
memcpy(&tty->last_cell, &grid_default_cell, sizeof tty->last_cell);
}
-static void
+void
tty_invalidate(struct tty *tty)
{
memcpy(&tty->cell, &grid_default_cell, sizeof tty->cell);