Module Name:    src
Committed By:   christos
Date:           Sun Jan 23 16:47:46 UTC 2022

Modified Files:
        src/external/bsd/tmux/dist: cmd-display-menu.c cmd-new-session.c
            format.c input-keys.c input.c key-bindings.c resize.c screen.c
            server-client.c status.c tmux.1 tmux.c tmux.h tty-keys.c tty-term.c
            tty.c window-buffer.c window-copy.c window.c
        src/external/bsd/tmux/usr.bin/tmux: Makefile

Log Message:
merge changes between tmux-3.2 and tmux-3.2a


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/external/bsd/tmux/dist/cmd-display-menu.c \
    src/external/bsd/tmux/dist/resize.c
cvs rdiff -u -r1.9 -r1.10 src/external/bsd/tmux/dist/cmd-new-session.c \
    src/external/bsd/tmux/dist/server-client.c
cvs rdiff -u -r1.12 -r1.13 src/external/bsd/tmux/dist/format.c \
    src/external/bsd/tmux/dist/screen.c src/external/bsd/tmux/dist/tmux.c
cvs rdiff -u -r1.11 -r1.12 src/external/bsd/tmux/dist/input-keys.c
cvs rdiff -u -r1.15 -r1.16 src/external/bsd/tmux/dist/input.c \
    src/external/bsd/tmux/dist/tty-keys.c
cvs rdiff -u -r1.10 -r1.11 src/external/bsd/tmux/dist/key-bindings.c
cvs rdiff -u -r1.13 -r1.14 src/external/bsd/tmux/dist/status.c \
    src/external/bsd/tmux/dist/window-copy.c
cvs rdiff -u -r1.14 -r1.15 src/external/bsd/tmux/dist/tmux.1 \
    src/external/bsd/tmux/dist/tty-term.c src/external/bsd/tmux/dist/window.c
cvs rdiff -u -r1.19 -r1.20 src/external/bsd/tmux/dist/tmux.h
cvs rdiff -u -r1.8 -r1.9 src/external/bsd/tmux/dist/tty.c
cvs rdiff -u -r1.7 -r1.8 src/external/bsd/tmux/dist/window-buffer.c
cvs rdiff -u -r1.27 -r1.28 src/external/bsd/tmux/usr.bin/tmux/Makefile

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/external/bsd/tmux/dist/cmd-display-menu.c
diff -u src/external/bsd/tmux/dist/cmd-display-menu.c:1.3 src/external/bsd/tmux/dist/cmd-display-menu.c:1.4
--- src/external/bsd/tmux/dist/cmd-display-menu.c:1.3	Sun Apr 18 10:01:29 2021
+++ src/external/bsd/tmux/dist/cmd-display-menu.c	Sun Jan 23 11:47:46 2022
@@ -205,7 +205,7 @@ cmd_display_menu_get_position(struct cli
 	if (xp == NULL || strcmp(xp, "C") == 0)
 		xp = "#{popup_centre_x}";
 	else if (strcmp(xp, "R") == 0)
-		xp = "#{popup_right}";
+		xp = "#{popup_pane_right}";
 	else if (strcmp(xp, "P") == 0)
 		xp = "#{popup_pane_left}";
 	else if (strcmp(xp, "M") == 0)
Index: src/external/bsd/tmux/dist/resize.c
diff -u src/external/bsd/tmux/dist/resize.c:1.3 src/external/bsd/tmux/dist/resize.c:1.4
--- src/external/bsd/tmux/dist/resize.c:1.3	Sat Apr 17 16:42:09 2021
+++ src/external/bsd/tmux/dist/resize.c	Sun Jan 23 11:47:46 2022
@@ -108,17 +108,19 @@ clients_with_window(struct window *w)
 }
 
 static int
-clients_calculate_size(int type, int current, struct session *s,
-    struct window *w, int (*skip_client)(struct client *, int, int,
-    struct session *, struct window *), u_int *sx, u_int *sy, u_int *xpixel,
-    u_int *ypixel)
+clients_calculate_size(int type, int current, struct client *c,
+    struct session *s, struct window *w, int (*skip_client)(struct client *,
+    int, int, struct session *, struct window *), u_int *sx, u_int *sy,
+    u_int *xpixel, u_int *ypixel)
 {
 	struct client	*loop;
 	u_int		 cx, cy, n = 0;
 
 	/* Manual windows do not have their size changed based on a client. */
-	if (type == WINDOW_SIZE_MANUAL)
+	if (type == WINDOW_SIZE_MANUAL) {
+		log_debug("%s: type is manual", __func__);
 		return (0);
+	}
 
 	/*
 	 * Start comparing with 0 for largest and UINT_MAX for smallest or
@@ -134,23 +136,29 @@ clients_calculate_size(int type, int cur
 	 * For latest, count the number of clients with this window. We only
 	 * care if there is more than one.
 	 */
-	if (type == WINDOW_SIZE_LATEST)
+	if (type == WINDOW_SIZE_LATEST && w != NULL)
 		n = clients_with_window(w);
 
 	/* Loop over the clients and work out the size. */
 	TAILQ_FOREACH(loop, &clients, entry) {
-		if (ignore_client_size(loop))
+		if (loop != c && ignore_client_size(loop)) {
+			log_debug("%s: ignoring %s", __func__, loop->name);
 			continue;
-		if (skip_client(loop, type, current, s, w))
+		}
+		if (loop != c && skip_client(loop, type, current, s, w)) {
+			log_debug("%s: skipping %s", __func__, loop->name);
 			continue;
+		}
 
 		/*
 		 * If there are multiple clients attached, only accept the
 		 * latest client; otherwise let the only client be chosen as
 		 * for smallest.
 		 */
-		if (type == WINDOW_SIZE_LATEST && n > 1 && loop != w->latest)
+		if (type == WINDOW_SIZE_LATEST && n > 1 && loop != w->latest) {
+			log_debug("%s: %s is not latest", __func__, loop->name);
 			continue;
+		}
 
 		/* Work out this client's size. */
 		cx = loop->tty.sx;
@@ -175,16 +183,24 @@ clients_calculate_size(int type, int cur
 			*xpixel = loop->tty.xpixel;
 			*ypixel = loop->tty.ypixel;
 		}
+		log_debug("%s: after %s (%ux%u), size is %ux%u", __func__,
+		    loop->name, cx, cy, *sx, *sy);
 	}
 
 	/* Return whether a suitable size was found. */
-	if (type == WINDOW_SIZE_LARGEST)
+	if (type == WINDOW_SIZE_LARGEST) {
+		log_debug("%s: type is largest", __func__);
 		return (*sx != 0 && *sy != 0);
+	}
+	if (type == WINDOW_SIZE_LATEST)
+		log_debug("%s: type is latest", __func__);
+	else
+		log_debug("%s: type is smallest", __func__);
 	return (*sx != UINT_MAX && *sy != UINT_MAX);
 }
 
 static int
-default_window_size_skip_client (struct client *loop, int type,
+default_window_size_skip_client(struct client *loop, int type,
     __unused int current, struct session *s, struct window *w)
 {
 	/*
@@ -221,23 +237,25 @@ default_window_size(struct client *c, st
 			*sy = c->tty.sy - status_line_size(c);
 			*xpixel = c->tty.xpixel;
 			*ypixel = c->tty.ypixel;
+			log_debug("%s: using %ux%u from %s", __func__, *sx, *sy,
+			    c->name);
 			goto done;
 		}
-		if (w == NULL)
-			type = WINDOW_SIZE_MANUAL;
 	}
 
 	/*
 	 * Look for a client to base the size on. If none exists (or the type
 	 * is manual), use the default-size option.
 	 */
-	if (!clients_calculate_size(type, 0, s, w,
+	if (!clients_calculate_size(type, 0, c, s, w,
 	    default_window_size_skip_client, sx, sy, xpixel, ypixel)) {
 		value = options_get_string(s->options, "default-size");
 		if (sscanf(value, "%ux%u", sx, sy) != 2) {
 			*sx = 80;
 			*sy = 24;
 		}
+		log_debug("%s: using %ux%u from default-size", __func__, *sx,
+		    *sy);
 	}
 
 done:
@@ -250,6 +268,7 @@ done:
 		*sy = WINDOW_MINIMUM;
 	if (*sy > WINDOW_MAXIMUM)
 		*sy = WINDOW_MAXIMUM;
+	log_debug("%s: resulting size is %ux%u", __func__, *sx, *sy);
 }
 
 static int
@@ -289,7 +308,7 @@ recalculate_size(struct window *w, int n
 	current = options_get_number(w->options, "aggressive-resize");
 
 	/* Look for a suitable client and get the new size. */
-	changed = clients_calculate_size(type, current, NULL, w,
+	changed = clients_calculate_size(type, current, NULL, NULL, w,
 	    recalculate_size_skip_client, &sx, &sy, &xpixel, &ypixel);
 
 	/*

Index: src/external/bsd/tmux/dist/cmd-new-session.c
diff -u src/external/bsd/tmux/dist/cmd-new-session.c:1.9 src/external/bsd/tmux/dist/cmd-new-session.c:1.10
--- src/external/bsd/tmux/dist/cmd-new-session.c:1.9	Sat Apr 17 16:42:09 2021
+++ src/external/bsd/tmux/dist/cmd-new-session.c	Sun Jan 23 11:47:46 2022
@@ -269,6 +269,7 @@ cmd_new_session_exec(struct cmd *self, s
 	memset(&sc, 0, sizeof sc);
 	sc.item = item;
 	sc.s = s;
+	sc.tc = c;
 
 	sc.name = args_get(args, 'n');
 	sc.argc = args->argc;
Index: src/external/bsd/tmux/dist/server-client.c
diff -u src/external/bsd/tmux/dist/server-client.c:1.9 src/external/bsd/tmux/dist/server-client.c:1.10
--- src/external/bsd/tmux/dist/server-client.c:1.9	Sat Apr 17 16:42:09 2021
+++ src/external/bsd/tmux/dist/server-client.c	Sun Jan 23 11:47:46 2022
@@ -43,6 +43,7 @@ static void	server_client_check_modes(st
 static void	server_client_set_title(struct client *);
 static void	server_client_reset_state(struct client *);
 static int	server_client_assume_paste(struct session *);
+static void	server_client_update_latest(struct client *);
 
 static void	server_client_dispatch(struct imsg *, void *);
 static void	server_client_dispatch_command(struct client *, struct imsg *);
@@ -271,6 +272,40 @@ server_client_open(struct client *c, cha
 	return (0);
 }
 
+/* Lost an attached client. */
+static void
+server_client_attached_lost(struct client *c)
+{
+	struct session	*s = c->session;
+	struct window	*w;
+	struct client	*loop;
+	struct client	*found;
+
+	log_debug("lost attached client %p", c);
+
+	/*
+	 * By this point the session in the client has been cleared so walk all
+	 * windows to find any with this client as the latest.
+	 */
+	RB_FOREACH(w, windows, &windows) {
+		if (w->latest != c)
+			continue;
+
+		found = NULL;
+		TAILQ_FOREACH(loop, &clients, entry) {
+			s = loop->session;
+			if (loop == c || s == NULL || s->curw->window != w)
+				continue;
+			if (found == NULL ||
+			    timercmp(&loop->activity_time, &found->activity_time,
+			    >))
+				found = loop;
+		}
+		if (found != NULL)
+			server_client_update_latest(found);
+	}
+}
+
 /* Lost a client. */
 void
 server_client_lost(struct client *c)
@@ -296,8 +331,10 @@ server_client_lost(struct client *c)
 	TAILQ_REMOVE(&clients, c, entry);
 	log_debug("lost client %p", c);
 
-	if (c->flags & CLIENT_ATTACHED)
+	if (c->flags & CLIENT_ATTACHED) {
+		server_client_attached_lost(c);
 		notify_client("client-detached", c);
+	}
 
 	if (c->flags & CLIENT_CONTROL)
 		control_stop(c);
@@ -1410,84 +1447,79 @@ server_client_resize_timer(__unused int 
 	evtimer_del(&wp->resize_timer);
 }
 
-/* Start the resize timer. */
-static void
-server_client_start_resize_timer(struct window_pane *wp)
-{
-	struct timeval	tv = { .tv_usec = 250000 };
-
-	log_debug("%s: %%%u resize timer started", __func__, wp->id);
-	evtimer_add(&wp->resize_timer, &tv);
-}
-
-/* Force timer event. */
-static void
-server_client_force_timer(__unused int fd, __unused short events, void *data)
-{
-	struct window_pane	*wp = data;
-
-	log_debug("%s: %%%u force timer expired", __func__, wp->id);
-	evtimer_del(&wp->force_timer);
-	wp->flags |= PANE_RESIZENOW;
-}
-
-/* Start the force timer. */
-static void
-server_client_start_force_timer(struct window_pane *wp)
-{
-	struct timeval	tv = { .tv_usec = 10000 };
-
-	log_debug("%s: %%%u force timer started", __func__, wp->id);
-	evtimer_add(&wp->force_timer, &tv);
-}
-
 /* Check if pane should be resized. */
 static void
 server_client_check_pane_resize(struct window_pane *wp)
 {
-	if (!event_initialized(&wp->resize_timer))
-		evtimer_set(&wp->resize_timer, server_client_resize_timer, wp);
-	if (!event_initialized(&wp->force_timer))
-		evtimer_set(&wp->force_timer, server_client_force_timer, wp);
+	struct window_pane_resize	*r;
+	struct window_pane_resize	*r1;
+	struct window_pane_resize	*first;
+	struct window_pane_resize	*last;
+	struct timeval			 tv = { .tv_usec = 250000 };
 
-	if (~wp->flags & PANE_RESIZE)
+	if (TAILQ_EMPTY(&wp->resize_queue))
 		return;
-	log_debug("%s: %%%u needs to be resized", __func__, wp->id);
 
-	if (evtimer_pending(&wp->resize_timer, NULL)) {
-		log_debug("%s: %%%u resize timer is running", __func__, wp->id);
+	if (!event_initialized(&wp->resize_timer))
+		evtimer_set(&wp->resize_timer, server_client_resize_timer, wp);
+	if (evtimer_pending(&wp->resize_timer, NULL))
 		return;
+
+	log_debug("%s: %%%u needs to be resized", __func__, wp->id);
+	TAILQ_FOREACH(r, &wp->resize_queue, entry) {
+		log_debug("queued resize: %ux%u -> %ux%u", r->osx, r->osy,
+		    r->sx, r->sy);
 	}
-	server_client_start_resize_timer(wp);
 
-	if (~wp->flags & PANE_RESIZEFORCE) {
-		/*
-		 * The timer is not running and we don't need to force a
-		 * resize, so just resize immediately.
-		 */
-		log_debug("%s: resizing %%%u now", __func__, wp->id);
-		window_pane_send_resize(wp, 0);
-		wp->flags &= ~PANE_RESIZE;
+	/*
+	 * There are three cases that matter:
+	 *
+	 * - Only one resize. It can just be applied.
+	 *
+	 * - Multiple resizes and the ending size is different from the
+	 *   starting size. We can discard all resizes except the most recent.
+	 *
+	 * - Multiple resizes and the ending size is the same as the starting
+	 *   size. We must resize at least twice to force the application to
+	 *   redraw. So apply the first and leave the last on the queue for
+	 *   next time.
+	 */
+	first = TAILQ_FIRST(&wp->resize_queue);
+	last = TAILQ_LAST(&wp->resize_queue, window_pane_resizes);
+	if (first == last) {
+		/* Only one resize. */
+		window_pane_send_resize(wp, first->sx, first->sy);
+		TAILQ_REMOVE(&wp->resize_queue, first, entry);
+		free(first);
+	} else if (last->sx != first->osx || last->sy != first->osy) {
+		/* Multiple resizes ending up with a different size. */
+		window_pane_send_resize(wp, last->sx, last->sy);
+		TAILQ_FOREACH_SAFE(r, &wp->resize_queue, entry, r1) {
+			TAILQ_REMOVE(&wp->resize_queue, r, entry);
+			free(r);
+		}
 	} else {
 		/*
-		 * The timer is not running, but we need to force a resize. If
-		 * the force timer has expired, resize to the real size now.
-		 * Otherwise resize to the force size and start the timer.
+		 * Multiple resizes ending up with the same size. There will
+		 * not be more than one to the same size in succession so we
+		 * can just use the last-but-one on the list and leave the last
+		 * for later. We reduce the time until the next check to avoid
+		 * a long delay between the resizes.
 		 */
-		if (wp->flags & PANE_RESIZENOW) {
-			log_debug("%s: resizing %%%u after forced resize",
-			    __func__, wp->id);
-			window_pane_send_resize(wp, 0);
-			wp->flags &= ~(PANE_RESIZE|PANE_RESIZEFORCE|PANE_RESIZENOW);
-		} else if (!evtimer_pending(&wp->force_timer, NULL)) {
-			log_debug("%s: forcing resize of %%%u", __func__,
-			    wp->id);
-			window_pane_send_resize(wp, 1);
-			server_client_start_force_timer(wp);
+		r = TAILQ_PREV(last, window_pane_resizes, entry);
+		window_pane_send_resize(wp, r->sx, r->sy);
+		TAILQ_FOREACH_SAFE(r, &wp->resize_queue, entry, r1) {
+			if (r == last)
+				break;
+			TAILQ_REMOVE(&wp->resize_queue, r, entry);
+			free(r);
 		}
+		tv.tv_usec = 10000;
 	}
+	evtimer_add(&wp->resize_timer, &tv);
 }
 
+
 /* Check pane buffer size. */
 static void
 server_client_check_pane_buffer(struct window_pane *wp)

Index: src/external/bsd/tmux/dist/format.c
diff -u src/external/bsd/tmux/dist/format.c:1.12 src/external/bsd/tmux/dist/format.c:1.13
--- src/external/bsd/tmux/dist/format.c:1.12	Sat Apr 17 16:42:09 2021
+++ src/external/bsd/tmux/dist/format.c	Sun Jan 23 11:47:46 2022
@@ -103,7 +103,7 @@ format_job_cmp(struct format_job *fj1, s
 #define FORMAT_CHARACTER 0x10000
 
 /* Limit on recursion. */
-#define FORMAT_LOOP_LIMIT 10
+#define FORMAT_LOOP_LIMIT 100
 
 /* Format expand flags. */
 #define FORMAT_EXPAND_TIME 0x1
@@ -3991,7 +3991,7 @@ format_replace_expression(struct format_
 		result = (mleft < mright);
 		break;
 	case LESS_THAN_EQUAL:
-		result = (mleft > mright);
+		result = (mleft <= mright);
 		break;
 	}
 	if (use_fp)
@@ -4199,7 +4199,7 @@ format_replace(struct format_expand_stat
 			value = xstrdup("0");
 		} else {
 			format_log(es, "search '%s' pane %%%u", new, wp->id);
-			value = format_search(fm, wp, new);
+			value = format_search(search, wp, new);
 		}
 		free(new);
 	} else if (cmp != NULL) {
@@ -4441,8 +4441,10 @@ format_expand1(struct format_expand_stat
 	if (fmt == NULL || *fmt == '\0')
 		return (xstrdup(""));
 
-	if (es->loop == FORMAT_LOOP_LIMIT)
+	if (es->loop == FORMAT_LOOP_LIMIT) {
+		format_log(es, "reached loop limit (%u)", FORMAT_LOOP_LIMIT);
 		return (xstrdup(""));
+	}
 	es->loop++;
 
 	format_log(es, "expanding format: %s", fmt);
Index: src/external/bsd/tmux/dist/screen.c
diff -u src/external/bsd/tmux/dist/screen.c:1.12 src/external/bsd/tmux/dist/screen.c:1.13
--- src/external/bsd/tmux/dist/screen.c:1.12	Sat Apr 17 16:42:09 2021
+++ src/external/bsd/tmux/dist/screen.c	Sun Jan 23 11:47:46 2022
@@ -100,7 +100,9 @@ screen_reinit(struct screen *s)
 	s->rupper = 0;
 	s->rlower = screen_size_y(s) - 1;
 
-	s->mode = MODE_CURSOR | MODE_WRAP;
+	s->mode = MODE_CURSOR|MODE_WRAP;
+	if (options_get_number(global_options, "extended-keys") == 2)
+		s->mode |= MODE_KEXTENDED;
 
 	if (s->saved_grid != NULL)
 		screen_alternate_off(s, NULL, 0);
Index: src/external/bsd/tmux/dist/tmux.c
diff -u src/external/bsd/tmux/dist/tmux.c:1.12 src/external/bsd/tmux/dist/tmux.c:1.13
--- src/external/bsd/tmux/dist/tmux.c:1.12	Sat Apr 17 16:42:09 2021
+++ src/external/bsd/tmux/dist/tmux.c	Sun Jan 23 11:47:46 2022
@@ -328,7 +328,7 @@ main(int argc, char **argv)
 	char					*path = NULL, *label = NULL;
 	char					*cause, **var;
 	const char				*s, *cwd;
-	int					 opt, keys, feat = 0;
+	int					 opt, keys, feat = 0, fflag = 0;
 	uint64_t				 flags = 0;
 	const struct options_table_entry	*oe;
 	u_int					 i;
@@ -373,10 +373,15 @@ main(int argc, char **argv)
 				flags |= CLIENT_CONTROL;
 			break;
 		case 'f':
-			for (i = 0; i < cfg_nfiles; i++)
-				free(cfg_files[i]);
-			free(cfg_files);
-			expand_paths(optarg, &cfg_files, &cfg_nfiles, 0);
+			if (!fflag) {
+				fflag = 1;
+				for (i = 0; i < cfg_nfiles; i++)
+					free(cfg_files[i]);
+				cfg_nfiles = 0;
+			}
+			cfg_files = xreallocarray(cfg_files, cfg_nfiles + 1,
+			    sizeof *cfg_files);
+			cfg_files[cfg_nfiles++] = xstrdup(optarg);
 			cfg_quiet = 0;
 			break;
  		case 'V':

Index: src/external/bsd/tmux/dist/input-keys.c
diff -u src/external/bsd/tmux/dist/input-keys.c:1.11 src/external/bsd/tmux/dist/input-keys.c:1.12
--- src/external/bsd/tmux/dist/input-keys.c:1.11	Sat Apr 17 16:42:09 2021
+++ src/external/bsd/tmux/dist/input-keys.c	Sun Jan 23 11:47:46 2022
@@ -94,30 +94,6 @@ static struct input_key_entry input_key_
 	{ .key = KEYC_F12,
 	  .data = "\033[24~"
 	},
-	{ .key = KEYC_F1|KEYC_SHIFT,
-	  .data = "\033[25~"
-	},
-	{ .key = KEYC_F2|KEYC_SHIFT,
-	  .data = "\033[26~"
-	},
-	{ .key = KEYC_F3|KEYC_SHIFT,
-	  .data = "\033[28~"
-	},
-	{ .key = KEYC_F4|KEYC_SHIFT,
-	  .data = "\033[29~"
-	},
-	{ .key = KEYC_F5|KEYC_SHIFT,
-	  .data = "\033[31~"
-	},
-	{ .key = KEYC_F6|KEYC_SHIFT,
-	  .data = "\033[32~"
-	},
-	{ .key = KEYC_F7|KEYC_SHIFT,
-	  .data = "\033[33~"
-	},
-	{ .key = KEYC_F8|KEYC_SHIFT,
-	  .data = "\033[34~"
-	},
 	{ .key = KEYC_IC,
 	  .data = "\033[2~"
 	},
@@ -476,7 +452,7 @@ input_key(struct screen *s, struct buffe
 		input_key_write(__func__, bev, (const char *)ud.data, 1);
 		return (0);
 	}
-	if (justkey > 0x7f && justkey < KEYC_BASE) {
+	if (KEYC_IS_UNICODE(justkey)) {
 		if (key & KEYC_META)
 			input_key_write(__func__, bev, "\033", 1);
 		utf8_to_data(justkey, &ud);

Index: src/external/bsd/tmux/dist/input.c
diff -u src/external/bsd/tmux/dist/input.c:1.15 src/external/bsd/tmux/dist/input.c:1.16
--- src/external/bsd/tmux/dist/input.c:1.15	Sat Apr 17 16:42:09 2021
+++ src/external/bsd/tmux/dist/input.c	Sun Jan 23 11:47:46 2022
@@ -1390,6 +1390,8 @@ input_csi_dispatch(struct input_ctx *ict
 	case INPUT_CSI_MODSET:
 		n = input_get(ictx, 0, 0, 0);
 		m = input_get(ictx, 1, 0, 0);
+		if (options_get_number(global_options, "extended-keys") == 2)
+			break;
 		if (n == 0 || (n == 4 && m == 0))
 			screen_write_mode_clear(sctx, MODE_KEXTENDED);
 		else if (n == 4 && (m == 1 || m == 2))
Index: src/external/bsd/tmux/dist/tty-keys.c
diff -u src/external/bsd/tmux/dist/tty-keys.c:1.15 src/external/bsd/tmux/dist/tty-keys.c:1.16
--- src/external/bsd/tmux/dist/tty-keys.c:1.15	Sat Apr 17 16:42:09 2021
+++ src/external/bsd/tmux/dist/tty-keys.c	Sun Jan 23 11:47:46 2022
@@ -252,7 +252,8 @@ static const key_code tty_default_xterm_
 	KEYC_CTRL,
 	KEYC_SHIFT|KEYC_CTRL,
 	KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL,
-	KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL
+	KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL,
+	KEYC_META|KEYC_IMPLIED_META
 };
 
 /*
@@ -944,6 +945,9 @@ tty_keys_extended_key(struct tty *tty, c
 	case 8:
 		nkey |= (KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL);
 		break;
+	case 9:
+		nkey |= (KEYC_META|KEYC_IMPLIED_META);
+		break;
 	default:
 		*key = KEYC_NONE;
 		break;
@@ -955,23 +959,22 @@ tty_keys_extended_key(struct tty *tty, c
 	 */
 	if (nkey & KEYC_CTRL) {
 		onlykey = (nkey & KEYC_MASK_KEY);
-		if (onlykey < 32) {
-			if (onlykey != 9)
-				onlykey = (nkey & ~KEYC_CTRL);
-			else
-				onlykey = (9|KEYC_CTRL);
-		} else {
-			if (onlykey >= 97 && onlykey <= 122)
-				onlykey -= 96;
-			else if (onlykey >= 64 && onlykey <= 95)
-				onlykey -= 64;
-			else if (onlykey == 32)
-				onlykey = 0;
-			else if (onlykey == 63)
-				onlykey = 127;
-			onlykey |= ((nkey & KEYC_MASK_MODIFIERS) & ~KEYC_CTRL);
-		}
-		nkey = onlykey;
+		if (onlykey < 32 &&
+		    onlykey != 9 &&
+		    onlykey != 13 &&
+		    onlykey != 27)
+			/* nothing */;
+		else if (onlykey >= 97 && onlykey <= 122)
+			onlykey -= 96;
+		else if (onlykey >= 64 && onlykey <= 95)
+			onlykey -= 64;
+		else if (onlykey == 32)
+			onlykey = 0;
+		else if (onlykey == 63)
+			onlykey = 127;
+		else
+			onlykey |= KEYC_CTRL;
+		nkey = onlykey|((nkey & KEYC_MASK_MODIFIERS) & ~KEYC_CTRL);
 	}
 
 	if (log_get_level() != 0) {

Index: src/external/bsd/tmux/dist/key-bindings.c
diff -u src/external/bsd/tmux/dist/key-bindings.c:1.10 src/external/bsd/tmux/dist/key-bindings.c:1.11
--- src/external/bsd/tmux/dist/key-bindings.c:1.10	Sat Apr 17 16:42:09 2021
+++ src/external/bsd/tmux/dist/key-bindings.c	Sun Jan 23 11:47:46 2022
@@ -215,6 +215,9 @@ key_bindings_add(const char *name, key_c
 	if (repeat)
 		bd->flags |= KEY_BINDING_REPEAT;
 	bd->cmdlist = cmdlist;
+
+	log_debug("%s: %#llx %s = %s", __func__, bd->key,
+	    key_string_lookup_key(bd->key, 1), cmd_list_print(bd->cmdlist, 0));
 }
 
 void
@@ -231,6 +234,9 @@ key_bindings_remove(const char *name, ke
 	if (bd == NULL)
 		return;
 
+	log_debug("%s: %#llx %s", __func__, bd->key,
+	    key_string_lookup_key(bd->key, 1));
+
 	RB_REMOVE(key_bindings, &table->key_bindings, bd);
 	key_bindings_free(bd);
 

Index: src/external/bsd/tmux/dist/status.c
diff -u src/external/bsd/tmux/dist/status.c:1.13 src/external/bsd/tmux/dist/status.c:1.14
--- src/external/bsd/tmux/dist/status.c:1.13	Tue Apr 20 13:42:31 2021
+++ src/external/bsd/tmux/dist/status.c	Sun Jan 23 11:47:46 2022
@@ -226,6 +226,8 @@ status_line_size(struct client *c)
 
 	if (c->flags & (CLIENT_STATUSOFF|CLIENT_CONTROL))
 		return (0);
+	if (s == NULL)
+		return (options_get_number(global_s_options, "status"));
 	return (s->statuslines);
 }
 
@@ -1298,7 +1300,7 @@ process_key:
 	return (0);
 
 append_key:
-	if (key <= 0x1f || key >= KEYC_BASE)
+	if (key <= 0x1f || (key >= KEYC_BASE && key < KEYC_BASE_END))
 		return (0);
 	if (key <= 0x7f)
 		utf8_set(&tmp, key);
Index: src/external/bsd/tmux/dist/window-copy.c
diff -u src/external/bsd/tmux/dist/window-copy.c:1.13 src/external/bsd/tmux/dist/window-copy.c:1.14
--- src/external/bsd/tmux/dist/window-copy.c:1.13	Sat Apr 17 16:42:10 2021
+++ src/external/bsd/tmux/dist/window-copy.c	Sun Jan 23 11:47:46 2022
@@ -1102,10 +1102,13 @@ static enum window_copy_cmd_action
 window_copy_cmd_cursor_right(struct window_copy_cmd_state *cs)
 {
 	struct window_mode_entry	*wme = cs->wme;
+	struct window_copy_mode_data	*data = wme->data;
 	u_int				 np = wme->prefix;
 
-	for (; np != 0; np--)
-		window_copy_cursor_right(wme, 0);
+	for (; np != 0; np--) {
+		window_copy_cursor_right(wme, data->screen.sel != NULL &&
+		    data->rectflag);
+	}
 	return (WINDOW_COPY_CMD_NOTHING);
 }
 
@@ -4425,10 +4428,12 @@ window_copy_cursor_up(struct window_mode
 	struct window_copy_mode_data	*data = wme->data;
 	struct screen			*s = &data->screen;
 	u_int				 ox, oy, px, py;
+	int				 norectsel;
 
+	norectsel = data->screen.sel == NULL || !data->rectflag;
 	oy = screen_hsize(data->backing) + data->cy - data->oy;
 	ox = window_copy_find_length(wme, oy);
-	if (data->cx != ox) {
+	if (norectsel && data->cx != ox) {
 		data->lastcx = data->cx;
 		data->lastsx = ox;
 	}
@@ -4437,7 +4442,8 @@ window_copy_cursor_up(struct window_mode
 		window_copy_other_end(wme);
 
 	if (scroll_only || data->cy == 0) {
-		data->cx = data->lastcx;
+		if (norectsel)
+			data->cx = data->lastcx;
 		window_copy_scroll_down(wme, 1);
 		if (scroll_only) {
 			if (data->cy == screen_size_y(s) - 1)
@@ -4446,7 +4452,11 @@ window_copy_cursor_up(struct window_mode
 				window_copy_redraw_lines(wme, data->cy, 2);
 		}
 	} else {
-		window_copy_update_cursor(wme, data->lastcx, data->cy - 1);
+		if (norectsel) {
+			window_copy_update_cursor(wme, data->lastcx,
+			    data->cy - 1);
+		} else
+			window_copy_update_cursor(wme, data->cx, data->cy - 1);
 		if (window_copy_update_selection(wme, 1, 0)) {
 			if (data->cy == screen_size_y(s) - 1)
 				window_copy_redraw_lines(wme, data->cy, 1);
@@ -4455,7 +4465,7 @@ window_copy_cursor_up(struct window_mode
 		}
 	}
 
-	if (data->screen.sel == NULL || !data->rectflag) {
+	if (norectsel) {
 		py = screen_hsize(data->backing) + data->cy - data->oy;
 		px = window_copy_find_length(wme, py);
 		if ((data->cx >= data->lastsx && data->cx != px) ||
@@ -4492,10 +4502,12 @@ window_copy_cursor_down(struct window_mo
 	struct window_copy_mode_data	*data = wme->data;
 	struct screen			*s = &data->screen;
 	u_int				 ox, oy, px, py;
+	int				 norectsel;
 
+	norectsel = data->screen.sel == NULL || !data->rectflag;
 	oy = screen_hsize(data->backing) + data->cy - data->oy;
 	ox = window_copy_find_length(wme, oy);
-	if (data->cx != ox) {
+	if (norectsel && data->cx != ox) {
 		data->lastcx = data->cx;
 		data->lastsx = ox;
 	}
@@ -4504,17 +4516,22 @@ window_copy_cursor_down(struct window_mo
 		window_copy_other_end(wme);
 
 	if (scroll_only || data->cy == screen_size_y(s) - 1) {
-		data->cx = data->lastcx;
+		if (norectsel)
+			data->cx = data->lastcx;
 		window_copy_scroll_up(wme, 1);
 		if (scroll_only && data->cy > 0)
 			window_copy_redraw_lines(wme, data->cy - 1, 2);
 	} else {
-		window_copy_update_cursor(wme, data->lastcx, data->cy + 1);
+		if (norectsel) {
+			window_copy_update_cursor(wme, data->lastcx,
+			    data->cy + 1);
+		} else
+			window_copy_update_cursor(wme, data->cx, data->cy + 1);
 		if (window_copy_update_selection(wme, 1, 0))
 			window_copy_redraw_lines(wme, data->cy - 1, 2);
 	}
 
-	if (data->screen.sel == NULL || !data->rectflag) {
+	if (norectsel) {
 		py = screen_hsize(data->backing) + data->cy - data->oy;
 		px = window_copy_find_length(wme, py);
 		if ((data->cx >= data->lastsx && data->cx != px) ||

Index: src/external/bsd/tmux/dist/tmux.1
diff -u src/external/bsd/tmux/dist/tmux.1:1.14 src/external/bsd/tmux/dist/tmux.1:1.15
--- src/external/bsd/tmux/dist/tmux.1:1.14	Sat Apr 17 16:42:09 2021
+++ src/external/bsd/tmux/dist/tmux.1	Sun Jan 23 11:47:46 2022
@@ -2953,6 +2953,8 @@ Ctrl keys may be prefixed with
 .Ql C-
 or
 .Ql ^ ,
+Shift keys with
+.Ql S-
 and Alt (meta) with
 .Ql M- .
 In addition, the following special key names are accepted:
@@ -3418,11 +3420,24 @@ sessions.
 .Xc
 If enabled, the server will exit when there are no attached clients.
 .It Xo Ic extended-keys
-.Op Ic on | off
+.Op Ic on | off | always
 .Xc
-When enabled, extended keys are requested from the terminal and if supported
-are recognised by
-.Nm .
+When
+.Ic on
+or
+.Ic always ,
+the escape sequence to enable extended keys is sent to the terminal, if
+.Nm
+knows that it is supported.
+.Nm
+always recognises extended keys itself.
+If this option is
+.Ic on ,
+.Nm
+will only forward extended keys to applications when they request them; if
+.Ic always ,
+.Nm
+will always forward the keys.
 .It Xo Ic focus-events
 .Op Ic on | off
 .Xc
@@ -3501,8 +3516,8 @@ capabilities to be set instead,
 is intended for classes of functionality supported in a standard way but not
 reported by
 .Xr terminfo 5 .
-Care must be taken only to configure this with features the terminal actually
-support.
+Care must be taken to configure this only with features the terminal actually
+supports.
 .Pp
 This is an array option where each entry is a colon-separated string made up
 of a terminal type pattern (matched using
@@ -3524,6 +3539,10 @@ Supports extended keys.
 Supports focus reporting.
 .It margins
 Supports DECSLRM margins.
+.It mouse
+Supports
+.Xr xterm 1
+mouse sequences.
 .It overline
 Supports the overline SGR attribute.
 .It rectfill
@@ -6036,6 +6055,10 @@ Disable and enable focus reporting.
 These are set automatically if the
 .Em XT
 capability is present.
+.It Em \&Rect
+Tell
+.Nm
+that the terminal supports rectangle operations.
 .It Em \&Smol
 Enable the overline attribute.
 .It Em \&Smulx
@@ -6116,12 +6139,13 @@ and matching
 .Em %end
 or
 .Em %error
-have two arguments: an integer time (as seconds from epoch) and command number.
+have three arguments: an integer time (as seconds from epoch), command number and
+flags (currently not used).
 For example:
 .Bd -literal -offset indent
-%begin 1363006971 2
+%begin 1363006971 2 1
 0: ksh* (1 panes) [80x24] [layout b25f,80x24,0,0,2] @2 (active)
-%end 1363006971 2
+%end 1363006971 2 1
 .Ed
 .Pp
 The
Index: src/external/bsd/tmux/dist/tty-term.c
diff -u src/external/bsd/tmux/dist/tty-term.c:1.14 src/external/bsd/tmux/dist/tty-term.c:1.15
--- src/external/bsd/tmux/dist/tty-term.c:1.14	Sat Apr 17 16:42:09 2021
+++ src/external/bsd/tmux/dist/tty-term.c	Sun Jan 23 11:47:46 2022
@@ -251,6 +251,7 @@ static const struct tty_term_code_entry 
 	[TTYC_MS] = { TTYCODE_STRING, "Ms" },
 	[TTYC_OL] = { TTYCODE_STRING, "ol" },
 	[TTYC_OP] = { TTYCODE_STRING, "op" },
+	[TTYC_RECT] = { TTYCODE_STRING, "Rect" },
 	[TTYC_REV] = { TTYCODE_STRING, "rev" },
 	[TTYC_RGB] = { TTYCODE_FLAG, "RGB" },
 	[TTYC_RIN] = { TTYCODE_STRING, "rin" },
@@ -434,10 +435,11 @@ tty_term_apply_overrides(struct tty_term
 	struct options_entry		*o;
 	struct options_array_item	*a;
 	union options_value		*ov;
-	const char			*s;
+	const char			*s, *acs;
 	size_t				 offset;
 	char				*first;
 
+	/* Update capabilities from the option. */
 	o = options_get_only(global_options, "terminal-overrides");
 	a = options_array_first(o);
 	while (a != NULL) {
@@ -450,6 +452,64 @@ tty_term_apply_overrides(struct tty_term
 			tty_term_apply(term, s + offset, 0);
 		a = options_array_next(a);
 	}
+
+	/* Update the RGB flag if the terminal has RGB colours. */
+	if (tty_term_has(term, TTYC_SETRGBF) &&
+	    tty_term_has(term, TTYC_SETRGBB))
+		term->flags |= TERM_RGBCOLOURS;
+	else
+		term->flags &= ~TERM_RGBCOLOURS;
+	log_debug("RGBCOLOURS flag is %d", !!(term->flags & TERM_RGBCOLOURS));
+
+	/*
+	 * Set or clear the DECSLRM flag if the terminal has the margin
+	 * capabilities.
+	 */
+	if (tty_term_has(term, TTYC_CMG) && tty_term_has(term, TTYC_CLMG))
+		term->flags |= TERM_DECSLRM;
+	else
+		term->flags &= ~TERM_DECSLRM;
+	log_debug("DECSLRM flag is %d", !!(term->flags & TERM_DECSLRM));
+
+	/*
+	 * Set or clear the DECFRA flag if the terminal has the rectangle
+	 * capability.
+	 */
+	if (tty_term_has(term, TTYC_RECT))
+		term->flags |= TERM_DECFRA;
+	else
+		term->flags &= ~TERM_DECFRA;
+	log_debug("DECFRA flag is %d", !!(term->flags & TERM_DECFRA));
+
+	/*
+	 * Terminals without am (auto right margin) wrap at at $COLUMNS - 1
+	 * rather than $COLUMNS (the cursor can never be beyond $COLUMNS - 1).
+	 *
+	 * Terminals without xenl (eat newline glitch) ignore a newline beyond
+	 * the right edge of the terminal, but tmux doesn't care about this -
+	 * it always uses absolute only moves the cursor with a newline when
+	 * also sending a linefeed.
+	 *
+	 * This is irritating, most notably because it is painful to write to
+	 * the very bottom-right of the screen without scrolling.
+	 *
+	 * Flag the terminal here and apply some workarounds in other places to
+	 * do the best possible.
+	 */
+	if (!tty_term_flag(term, TTYC_AM))
+		term->flags |= TERM_NOAM;
+	else
+		term->flags &= ~TERM_NOAM;
+	log_debug("NOAM flag is %d", !!(term->flags & TERM_NOAM));
+
+	/* Generate ACS table. If none is present, use nearest ASCII. */
+	memset(term->acs, 0, sizeof term->acs);
+	if (tty_term_has(term, TTYC_ACSC))
+		acs = tty_term_string(term, TTYC_ACSC);
+	else
+		acs = "a#j+k+l+m+n+o-p-q-r-s-t+u+v+w+x|y<z>~.";
+	for (; acs[0] != '\0' && acs[1] != '\0'; acs += 2)
+		term->acs[(u_char) acs[0]][0] = acs[1];
 }
 
 struct tty_term *
@@ -463,7 +523,7 @@ tty_term_create(struct tty *tty, char *n
 	struct options_array_item		*a;
 	union options_value			*ov;
 	u_int					 i, j;
-	const char				*s, *acs, *value;
+	const char				*s, *value;
 	size_t					 offset, namelen;
 	char					*first;
 
@@ -566,40 +626,10 @@ tty_term_create(struct tty *tty, char *n
 	    (!tty_term_has(term, TTYC_SETRGBF) ||
 	    !tty_term_has(term, TTYC_SETRGBB)))
 		tty_add_features(feat, "RGB", ",");
-	if (tty_term_has(term, TTYC_SETRGBF) &&
-	    tty_term_has(term, TTYC_SETRGBB))
-		term->flags |= TERM_RGBCOLOURS;
 
 	/* Apply the features and overrides again. */
-	tty_apply_features(term, *feat);
-	tty_term_apply_overrides(term);
-
-	/*
-	 * Terminals without am (auto right margin) wrap at at $COLUMNS - 1
-	 * rather than $COLUMNS (the cursor can never be beyond $COLUMNS - 1).
-	 *
-	 * Terminals without xenl (eat newline glitch) ignore a newline beyond
-	 * the right edge of the terminal, but tmux doesn't care about this -
-	 * it always uses absolute only moves the cursor with a newline when
-	 * also sending a linefeed.
-	 *
-	 * This is irritating, most notably because it is painful to write to
-	 * the very bottom-right of the screen without scrolling.
-	 *
-	 * Flag the terminal here and apply some workarounds in other places to
-	 * do the best possible.
-	 */
-	if (!tty_term_flag(term, TTYC_AM))
-		term->flags |= TERM_NOAM;
-
-	/* Generate ACS table. If none is present, use nearest ASCII. */
-	memset(term->acs, 0, sizeof term->acs);
-	if (tty_term_has(term, TTYC_ACSC))
-		acs = tty_term_string(term, TTYC_ACSC);
-	else
-		acs = "a#j+k+l+m+n+o-p-q-r-s-t+u+v+w+x|y<z>~.";
-	for (; acs[0] != '\0' && acs[1] != '\0'; acs += 2)
-		term->acs[(u_char) acs[0]][0] = acs[1];
+	if (tty_apply_features(term, *feat))
+		tty_term_apply_overrides(term);
 
 	/* Log the capabilities. */
 	for (i = 0; i < tty_term_ncodes(); i++)
Index: src/external/bsd/tmux/dist/window.c
diff -u src/external/bsd/tmux/dist/window.c:1.14 src/external/bsd/tmux/dist/window.c:1.15
--- src/external/bsd/tmux/dist/window.c:1.14	Sat Apr 17 16:42:10 2021
+++ src/external/bsd/tmux/dist/window.c	Sun Jan 23 11:47:46 2022
@@ -329,6 +329,8 @@ window_create(u_int sx, u_int sy, u_int 
 
 	window_update_activity(w);
 
+	log_debug("%s: @%u create %ux%u (%ux%u)", __func__, w->id, sx, sy,
+	    w->xpixel, w->ypixel);
 	return (w);
 }
 
@@ -423,25 +425,18 @@ window_resize(struct window *w, u_int sx
 }
 
 void
-window_pane_send_resize(struct window_pane *wp, int force)
+window_pane_send_resize(struct window_pane *wp, u_int sx, u_int sy)
 {
 	struct window	*w = wp->window;
 	struct winsize	 ws;
-	u_int  		 sy;
 
 	if (wp->fd == -1)
 		return;
 
-	if (!force)
-		sy = wp->sy;
-	else if (wp->sy <= 1)
-		sy = wp->sy + 1;
-	else
-		sy = wp->sy - 1;
-	log_debug("%s: %%%u resize to %u,%u", __func__, wp->id, wp->sx, sy);
+	log_debug("%s: %%%u resize to %u,%u", __func__, wp->id, sx, sy);
 
 	memset(&ws, 0, sizeof ws);
-	ws.ws_col = wp->sx;
+	ws.ws_col = sx;
 	ws.ws_row = sy;
 	ws.ws_xpixel = w->xpixel * ws.ws_col;
 	ws.ws_ypixel = w->ypixel * ws.ws_row;
@@ -865,29 +860,19 @@ window_pane_create(struct window *w, u_i
 	wp->id = next_window_pane_id++;
 	RB_INSERT(window_pane_tree, &all_window_panes, wp);
 
-	wp->argc = 0;
-	wp->argv = NULL;
-	wp->shell = NULL;
-	wp->cwd = NULL;
-
 	wp->fd = -1;
-	wp->event = NULL;
 
 	wp->fg = 8;
 	wp->bg = 8;
 
 	TAILQ_INIT(&wp->modes);
 
-	wp->layout_cell = NULL;
-
-	wp->xoff = 0;
-	wp->yoff = 0;
+	TAILQ_INIT (&wp->resize_queue);
 
 	wp->sx = sx;
 	wp->sy = sy;
 
 	wp->pipe_fd = -1;
-	wp->pipe_event = NULL;
 
 	screen_init(&wp->base, sx, sy, hlimit);
 	wp->screen = &wp->base;
@@ -903,6 +888,9 @@ window_pane_create(struct window *w, u_i
 static void
 window_pane_destroy(struct window_pane *wp)
 {
+	struct window_pane_resize	*r;
+	struct window_pane_resize	*r1;
+
 	window_pane_reset_mode_all(wp);
 	free(wp->searchstr);
 
@@ -927,8 +915,10 @@ window_pane_destroy(struct window_pane *
 
 	if (event_initialized(&wp->resize_timer))
 		event_del(&wp->resize_timer);
-	if (event_initialized(&wp->force_timer))
-		event_del(&wp->force_timer);
+	TAILQ_FOREACH_SAFE(r, &wp->resize_queue, entry, r1) {
+		TAILQ_REMOVE(&wp->resize_queue, r, entry);
+		free(r);
+	}
 
 	RB_REMOVE(window_pane_tree, &all_window_panes, wp);
 
@@ -997,9 +987,18 @@ void
 window_pane_resize(struct window_pane *wp, u_int sx, u_int sy)
 {
 	struct window_mode_entry	*wme;
+	struct window_pane_resize	*r;
 
 	if (sx == wp->sx && sy == wp->sy)
 		return;
+
+	r = xmalloc (sizeof *r);
+	r->sx = sx;
+	r->sy = sy;
+	r->osx = wp->sx;
+	r->osy = wp->sy;
+	TAILQ_INSERT_TAIL (&wp->resize_queue, r, entry);
+
 	wp->sx = sx;
 	wp->sy = sy;
 
@@ -1009,14 +1008,6 @@ window_pane_resize(struct window_pane *w
 	wme = TAILQ_FIRST(&wp->modes);
 	if (wme != NULL && wme->mode->resize != NULL)
 		wme->mode->resize(wme, sx, sy);
-
-	/*
-	 * If the pane has already been resized, set the force flag and make
-	 * the application resize twice to force it to redraw.
-	 */
-	if (wp->flags & PANE_RESIZE)
-		wp->flags |= PANE_RESIZEFORCE;
-	wp->flags |= PANE_RESIZE;
 }
 
 void

Index: src/external/bsd/tmux/dist/tmux.h
diff -u src/external/bsd/tmux/dist/tmux.h:1.19 src/external/bsd/tmux/dist/tmux.h:1.20
--- src/external/bsd/tmux/dist/tmux.h:1.19	Tue Apr 20 13:42:31 2021
+++ src/external/bsd/tmux/dist/tmux.h	Sun Jan 23 11:47:46 2022
@@ -109,11 +109,16 @@ struct winlink;
 #define VISUAL_ON 1
 #define VISUAL_BOTH 2
 
-/* Special key codes. */
-#define KEYC_NONE            0x00ff000000000ULL
-#define KEYC_UNKNOWN         0x00fe000000000ULL
-#define KEYC_BASE            0x0001000000000ULL
-#define KEYC_USER            0x0002000000000ULL
+/* No key or unknown key. */
+#define KEYC_NONE            0x000ff000000000ULL
+#define KEYC_UNKNOWN         0x000fe000000000ULL
+
+/*
+ * Base for special (that is, not Unicode) keys. An enum must be at most a
+ * signed int, so these are based in the highest Unicode PUA.
+ */
+#define KEYC_BASE            0x0000000010e000ULL
+#define KEYC_USER            0x0000000010f000ULL
 
 /* Key modifier bits. */
 #define KEYC_META            0x00100000000000ULL
@@ -136,8 +141,15 @@ struct winlink;
 #define KEYC_NUSER 1000
 
 /* Is this a mouse key? */
-#define KEYC_IS_MOUSE(key) (((key) & KEYC_MASK_KEY) >= KEYC_MOUSE &&	\
-    ((key) & KEYC_MASK_KEY) < KEYC_BSPACE)
+#define KEYC_IS_MOUSE(key) \
+	(((key) & KEYC_MASK_KEY) >= KEYC_MOUSE && \
+	 ((key) & KEYC_MASK_KEY) < KEYC_BSPACE)
+
+/* Is this a Unicode key? */
+#define KEYC_IS_UNICODE(key) \
+	(((key) & KEYC_MASK_KEY) > 0x7f && \
+	 (((key) & KEYC_MASK_KEY) < KEYC_BASE || \
+	  ((key) & KEYC_MASK_KEY) >= KEYC_BASE_END))
 
 /* Multiple click timeout. */
 #define KEYC_CLICK_TIMEOUT 300
@@ -159,8 +171,8 @@ struct winlink;
 	{ #s "Border", KEYC_ ## name ## _BORDER }
 
 /*
- * A single key. This can be ASCII or Unicode or one of the keys starting at
- * KEYC_BASE.
+ * A single key. This can be ASCII or Unicode or one of the keys between
+ * KEYC_BASE and KEYC_BASE_END.
  */
 typedef unsigned long long key_code;
 
@@ -253,6 +265,9 @@ enum {
 	KEYC_KP_ENTER,
 	KEYC_KP_ZERO,
 	KEYC_KP_PERIOD,
+
+	/* End of special keys. */
+	KEYC_BASE_END
 };
 
 /* Termcap codes. */
@@ -452,6 +467,7 @@ enum tty_code_code {
 	TTYC_MS,
 	TTYC_OL,
 	TTYC_OP,
+	TTYC_RECT,
 	TTYC_REV,
 	TTYC_RGB,
 	TTYC_RI,
@@ -918,7 +934,7 @@ struct window_mode_entry {
 	struct screen			*screen;
 	u_int				 prefix;
 
-	TAILQ_ENTRY (window_mode_entry)	 entry;
+	TAILQ_ENTRY(window_mode_entry)	 entry;
 };
 
 /* Offsets into pane buffer. */
@@ -926,6 +942,18 @@ struct window_pane_offset {
 	size_t	used;
 };
 
+/* Queued pane resize. */
+struct window_pane_resize {
+	u_int				sx;
+	u_int				sy;
+
+	u_int				osx;
+	u_int				osy;
+
+	TAILQ_ENTRY(window_pane_resize)	entry;
+};
+TAILQ_HEAD(window_pane_resizes, window_pane_resize);
+
 /* Child window structure. */
 struct window_pane {
 	u_int		 id;
@@ -950,8 +978,8 @@ struct window_pane {
 #define PANE_REDRAW 0x1
 #define PANE_DROP 0x2
 #define PANE_FOCUSED 0x4
-#define PANE_RESIZE 0x8
-#define PANE_RESIZEFORCE 0x10
+/* 0x8 unused */
+/* 0x10 unused */
 #define PANE_FOCUSPUSH 0x20
 #define PANE_INPUTOFF 0x40
 #define PANE_CHANGED 0x80
@@ -960,7 +988,6 @@ struct window_pane {
 #define PANE_STATUSDRAWN 0x400
 #define PANE_EMPTY 0x800
 #define PANE_STYLECHANGED 0x1000
-#define PANE_RESIZENOW 0x2000
 
 	int		 argc;
 	char	       **argv;
@@ -977,8 +1004,8 @@ struct window_pane {
 	struct window_pane_offset offset;
 	size_t		 base_offset;
 
+	struct window_pane_resizes resize_queue;
 	struct event	 resize_timer;
-	struct event	 force_timer;
 
 	struct input_ctx *ictx;
 
@@ -996,7 +1023,7 @@ struct window_pane {
 	struct screen	 status_screen;
 	size_t		 status_size;
 
-	TAILQ_HEAD (, window_mode_entry) modes;
+	TAILQ_HEAD(, window_mode_entry) modes;
 
 	char		*searchstr;
 	int		 searchregex;
@@ -2756,7 +2783,7 @@ void		 window_redraw_active_switch(struc
 struct window_pane *window_add_pane(struct window *, struct window_pane *,
 		     u_int, int);
 void		 window_resize(struct window *, u_int, u_int, int, int);
-void		 window_pane_send_resize(struct window_pane *, int);
+void		 window_pane_send_resize(struct window_pane *, u_int, u_int);
 int		 window_zoom(struct window_pane *);
 int		 window_unzoom(struct window *);
 int		 window_push_zoom(struct window *, int, int);

Index: src/external/bsd/tmux/dist/tty.c
diff -u src/external/bsd/tmux/dist/tty.c:1.8 src/external/bsd/tmux/dist/tty.c:1.9
--- src/external/bsd/tmux/dist/tty.c:1.8	Sat Apr 17 16:42:09 2021
+++ src/external/bsd/tmux/dist/tty.c	Sun Jan 23 11:47:46 2022
@@ -958,13 +958,8 @@ tty_redraw_region(struct tty *tty, const
 		return;
 	}
 
-	if (ctx->ocy < ctx->orupper || ctx->ocy > ctx->orlower) {
-		for (i = ctx->ocy; i < ctx->sy; i++)
-			tty_draw_pane(tty, ctx, i);
-	} else {
-		for (i = ctx->orupper; i <= ctx->orlower; i++)
-			tty_draw_pane(tty, ctx, i);
-	}
+	for (i = ctx->orupper; i <= ctx->orlower; i++)
+		tty_draw_pane(tty, ctx, i);
 }
 
 /* Is this position visible in the pane? */

Index: src/external/bsd/tmux/dist/window-buffer.c
diff -u src/external/bsd/tmux/dist/window-buffer.c:1.7 src/external/bsd/tmux/dist/window-buffer.c:1.8
--- src/external/bsd/tmux/dist/window-buffer.c:1.7	Sat Apr 17 16:42:09 2021
+++ src/external/bsd/tmux/dist/window-buffer.c	Sun Jan 23 11:47:46 2022
@@ -294,8 +294,8 @@ window_buffer_get_key(void *modedata, vo
 	struct window_buffer_modedata	*data = modedata;
 	struct window_buffer_itemdata	*item = itemdata;
 	struct format_tree		*ft;
-	struct session			*s;
-	struct winlink			*wl;
+	struct session			*s = NULL;
+	struct winlink			*wl = NULL;
 	struct window_pane		*wp = NULL;
 	struct paste_buffer		*pb;
 	char				*expanded;

Index: src/external/bsd/tmux/usr.bin/tmux/Makefile
diff -u src/external/bsd/tmux/usr.bin/tmux/Makefile:1.27 src/external/bsd/tmux/usr.bin/tmux/Makefile:1.28
--- src/external/bsd/tmux/usr.bin/tmux/Makefile:1.27	Sat Apr 17 16:42:10 2021
+++ src/external/bsd/tmux/usr.bin/tmux/Makefile	Sun Jan 23 11:47:46 2022
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.27 2021/04/17 20:42:10 christos Exp $
+# $NetBSD: Makefile,v 1.28 2022/01/23 16:47:46 christos Exp $
 
 .include <bsd.own.mk>
 
@@ -166,6 +166,7 @@ CPPFLAGS+=	\
 -DHAVE_BITSTRING_H=1 \
 -DHAVE_BSD_GETOPT=1 \
 -DHAVE_CFMAKERAW=1 \
+-DHAVE_CFMAKERAWEP=1 \
 -DHAVE_CLOCK_GETTIME=1 \
 -DHAVE_CLOSEFROM=1 \
 -DHAVE_CURSES_H=1 \
@@ -218,14 +219,14 @@ CPPFLAGS+=	\
 -DPACKAGE=\"tmux\" \
 -DPACKAGE_BUGREPORT=\"\" \
 -DPACKAGE_NAME=\"tmux\" \
--DPACKAGE_STRING=\"tmux\ 3.2\" \
+-DPACKAGE_STRING=\"tmux\ 3.2a\" \
 -DPACKAGE_TARNAME=\"tmux\" \
 -DPACKAGE_URL=\"\" \
--DPACKAGE_VERSION=\"3.2\" \
+-DPACKAGE_VERSION=\"3.2a\" \
 -DSTDC_HEADERS=1 \
 -DTMUX_CONF="\"/etc/tmux.conf:~/.tmux.conf:~/.config/tmux/tmux.conf\"" \
--DTMUX_VERSION='"3.2"' \
--DVERSION=\"3.2\" \
+-DTMUX_VERSION='"3.2a"' \
+-DVERSION=\"3.2a\" \
 -D_ALL_SOURCE=1 \
 -D_GNU_SOURCE=1 \
 -D_NETBSD_SOURCE \

Reply via email to