diff --git a/SYNCING b/SYNCING
index 07be40c4..51b78010 100644
--- a/SYNCING
+++ b/SYNCING
@@ -1,17 +1,17 @@
 Preamble
 ========
 
-Tmux portable relies on  repositories "tmux" and "tmux-openbsd".
+Tmux portable relies on  repositories "tmux" and "tmux-obsd".
 Here's a description of them:
 
 * "tmux" is the portable version, the one which contains code for other
   operating systems, and autotools, etc., which isn't found or needed in the
   OpenBSD base system.
 
-* "tmux-openbsd" is the version of tmux in OpenBSD base system which provides
+* "tmux-obsd" is the version of tmux in OpenBSD base system which provides
   the basis of the portable tmux version.
 
-Note:  The "tmux-openbsd" repository is actually handled by "git cvsimport"
+Note:  The "tmux-obsd" repository is actually handled by "git cvsimport"
 running at 15 minute intervals, so a commit made to OpenBSD's tmux CVS
 repository will take at least that long to appear in this git repository.
 (It might take longer, depending on the CVS mirror used to import the
@@ -34,11 +34,11 @@ this information has ever been set before.
 Cloning repositories
 ====================
 
-This involves having both tmux and tmux-openbsd cloned, as in:
+This involves having both tmux and tmux-obsd cloned, as in:
 
 % cd /some/where/useful
 % git clone https://github.com/tmux/tmux.git
-% git clone https://github.com/ThomasAdam/tmux-openbsd.git
+% git clone https://github.com/ThomasAdam/tmux-obsd.git
 
 Note that you do not need additional checkouts to manage the sync -- an
 existing clone of either repositories will suffice.  So if you already have
@@ -47,30 +47,30 @@ these checkouts existing, skip that.
 Adding in git-remotes
 =====================
 
-Because the portable "tmux" git repository and the "tmux-openbsd"
+Because the portable "tmux" git repository and the "tmux-obsd"
 repository do not inherently share any history between each other, the
 history has been faked between them.  This "faking of history" is something
 which has to be told to git for the purposes of comparing the "tmux" and
-"tmux-openbsd" repositories for syncing.  To do this, we must reference the
-clone of the "tmux-openbsd" repository from the "tmux" repository, as
+"tmux-obsd" repositories for syncing.  To do this, we must reference the
+clone of the "tmux-obsd" repository from the "tmux" repository, as
 shown by the following command:
 
 % cd /path/to/tmux
-% git remote add obsd-tmux file:///path/to/tmux-openbsd
+% git remote add obsd-tmux file:///path/to/tmux-obsd
 
 So that now, the remote "obsd-tmux" can be used to reference branches and
-commits from the "tmux-openbsd" repository, but from the context of the
+commits from the "tmux-obsd" repository, but from the context of the
 portable "tmux" repository, which makes sense because it's the "tmux"
 repository which will have the updates applied to them.
 
 Fetching updates
 ================
 
-To ensure the latest commits from "tmux-openbsd" can be found from within
-"tmux", we have to ensure the "master" branch from "tmux-openbsd" is
+To ensure the latest commits from "tmux-obsd" can be found from within
+"tmux", we have to ensure the "master" branch from "tmux-obsd" is
 up-to-date first, and then reference that update in "tmux", as in:
 
-% cd /path/to/tmux-openbsd
+% cd /path/to/tmux-obsd
 % git checkout master
 % git pull
 
@@ -82,9 +82,9 @@ Then back in "tmux":
 Creating the necessary branches
 ===============================
 
-Now that "tmux" can see commits and branches from "tmux-openbsd" by way
+Now that "tmux" can see commits and branches from "tmux-obsd" by way
 of the remote name "obsd-tmux", we can now create the master branch from
-"tmux-openbsd" in the "tmux" repository:
+"tmux-obsd" in the "tmux" repository:
 
 % git checkout -b obsd-master obsd-tmux/master
 
@@ -92,7 +92,7 @@ Adding in the fake history points
 =================================
 
 To tie both the "master" branch from "tmux" and the "obsd-master"
-branch from "tmux-openbsd" together, the fake history points added to the
+branch from "tmux-obsd" together, the fake history points added to the
 "tmux" repository need to be added.  To do this, we must add an
 additional refspec line, as in:
 
diff --git a/cmd.c b/cmd.c
index 8f69ed92..02d2ac41 100644
--- a/cmd.c
+++ b/cmd.c
@@ -636,7 +636,7 @@ cmd_list_free(struct cmd_list *cmdlist)
 
 /* Copy a command list, expanding %s in arguments. */
 struct cmd_list *
-cmd_list_copy(struct cmd_list *cmdlist, int argc, char **argv)
+cmd_list_copy(const struct cmd_list *cmdlist, int argc, char **argv)
 {
 	struct cmd	*cmd;
 	struct cmd_list	*new_cmdlist;
@@ -667,7 +667,7 @@ cmd_list_copy(struct cmd_list *cmdlist, int argc, char **argv)
 
 /* Get a command list as a string. */
 char *
-cmd_list_print(struct cmd_list *cmdlist, int escaped)
+cmd_list_print(const struct cmd_list *cmdlist, int escaped)
 {
 	struct cmd	*cmd, *next;
 	char		*buf, *this;
diff --git a/format.c b/format.c
index 9ce56104..42f80f6f 100644
--- a/format.c
+++ b/format.c
@@ -1119,6 +1119,20 @@ format_cb_cursor_character(struct format_tree *ft)
 	return (value);
 }
 
+/* Callback for cursor_colour. */
+static void *
+format_cb_cursor_colour(struct format_tree *ft)
+{
+	struct window_pane	*wp = ft->wp;
+
+	if (wp == NULL || wp->screen == NULL)
+		return (NULL);
+
+	if (wp->screen->ccolour != -1)
+		return (xstrdup(colour_tostring(wp->screen->ccolour)));
+	return (xstrdup(colour_tostring(wp->screen->default_ccolour)));
+}
+
 /* Callback for mouse_word. */
 static void *
 format_cb_mouse_word(struct format_tree *ft)
@@ -1159,6 +1173,12 @@ format_cb_mouse_hyperlink(struct format_tree *ft)
 		return (NULL);
 	if (cmd_mouse_at(wp, &ft->m, &x, &y, 0) != 0)
 		return (NULL);
+
+	if (!TAILQ_EMPTY(&wp->modes)) {
+		if (window_pane_mode(wp) != WINDOW_PANE_NO_MODE)
+			return (window_copy_get_hyperlink(wp, x, y));
+		return (NULL);
+	}
 	gd = wp->base.grid;
 	return (format_grid_hyperlink(gd, x, gd->hsize + y, wp->screen));
 }
@@ -1593,6 +1613,37 @@ format_cb_cursor_flag(struct format_tree *ft)
 	return (NULL);
 }
 
+/* Callback for cursor_shape. */
+static void *
+format_cb_cursor_shape(struct format_tree *ft)
+{
+	if (ft->wp != NULL && ft->wp->screen != NULL) {
+		switch (ft->wp->screen->cstyle) {
+		case SCREEN_CURSOR_BLOCK:
+			return (xstrdup("block"));
+    		case SCREEN_CURSOR_UNDERLINE:
+			return (xstrdup("underline"));
+    		case SCREEN_CURSOR_BAR:
+			return (xstrdup("bar"));
+    		default:
+			return (xstrdup("default"));
+		}
+	}
+	return (NULL);
+}
+
+/* Callback for cursor_very_visible. */
+static void *
+format_cb_cursor_very_visible(struct format_tree *ft)
+{
+	if (ft->wp != NULL && ft->wp->screen != NULL) {
+		if (ft->wp->screen->mode & MODE_CURSOR_VERY_VISIBLE)
+			return (xstrdup("1"));
+		return (xstrdup("0"));
+	}
+	return (NULL);
+}
+
 /* Callback for cursor_x. */
 static void *
 format_cb_cursor_x(struct format_tree *ft)
@@ -1611,6 +1662,18 @@ format_cb_cursor_y(struct format_tree *ft)
 	return (NULL);
 }
 
+/* Callback for cursor_blinking. */
+static void *
+format_cb_cursor_blinking(struct format_tree *ft)
+{
+	if (ft->wp != NULL && ft->wp->screen != NULL) {
+		if (ft->wp->screen->mode & MODE_CURSOR_BLINKING)
+			return (xstrdup("1"));
+		return (xstrdup("0"));
+	}
+	return (NULL);
+}
+
 /* Callback for history_limit. */
 static void *
 format_cb_history_limit(struct format_tree *ft)
@@ -2922,12 +2985,24 @@ static const struct format_table_entry format_table[] = {
 	{ "config_files", FORMAT_TABLE_STRING,
 	  format_cb_config_files
 	},
+	{ "cursor_blinking", FORMAT_TABLE_STRING,
+	  format_cb_cursor_blinking
+	},
 	{ "cursor_character", FORMAT_TABLE_STRING,
 	  format_cb_cursor_character
 	},
+	{ "cursor_colour", FORMAT_TABLE_STRING,
+	  format_cb_cursor_colour
+	},
 	{ "cursor_flag", FORMAT_TABLE_STRING,
 	  format_cb_cursor_flag
 	},
+	{ "cursor_shape", FORMAT_TABLE_STRING,
+	  format_cb_cursor_shape
+	},
+	{ "cursor_very_visible", FORMAT_TABLE_STRING,
+	  format_cb_cursor_very_visible
+	},
 	{ "cursor_x", FORMAT_TABLE_STRING,
 	  format_cb_cursor_x
 	},
@@ -5357,9 +5432,14 @@ format_grid_hyperlink(struct grid *gd, u_int x, u_int y, struct screen* s)
 	const char		*uri;
 	struct grid_cell	 gc;
 
-	grid_get_cell(gd, x, y, &gc);
-	if (gc.flags & GRID_FLAG_PADDING)
-		return (NULL);
+	for (;;) {
+		grid_get_cell(gd, x, y, &gc);
+		if (~gc.flags & GRID_FLAG_PADDING)
+			break;
+		if (x == 0)
+			return (NULL);
+		x--;
+	}
 	if (s->hyperlinks == NULL || gc.link == 0)
 		return (NULL);
 	if (!hyperlinks_get(s->hyperlinks, gc.link, &uri, NULL, NULL))
diff --git a/mode-tree.c b/mode-tree.c
index 24cbea04..508e870c 100644
--- a/mode-tree.c
+++ b/mode-tree.c
@@ -58,6 +58,7 @@ struct mode_tree_data {
 	mode_tree_menu_cb         menucb;
 	mode_tree_height_cb       heightcb;
 	mode_tree_key_cb	  keycb;
+	mode_tree_swap_cb	  swapcb;
 
 	struct mode_tree_list	  children;
 	struct mode_tree_list	  saved;
@@ -287,6 +288,35 @@ mode_tree_down(struct mode_tree_data *mtd, int wrap)
 	return (1);
 }
 
+static void
+mode_tree_swap(struct mode_tree_data *mtd, int direction)
+{
+	u_int	current_depth = mtd->line_list[mtd->current].depth;
+	u_int	swap_with, swap_with_depth;
+
+	if (mtd->swapcb == NULL)
+		return;
+
+	/* Find the next line at the same depth with the same parent . */
+	swap_with = mtd->current;
+	do {
+		if (direction < 0 && swap_with < (u_int)-direction)
+			return;
+		if (direction > 0 && swap_with + direction >= mtd->line_size)
+			return;
+		swap_with += direction;
+		swap_with_depth = mtd->line_list[swap_with].depth;
+	} while (swap_with_depth > current_depth);
+	if (swap_with_depth != current_depth)
+		return;
+
+	if (mtd->swapcb(mtd->line_list[mtd->current].item->itemdata,
+	    mtd->line_list[swap_with].item->itemdata)) {
+		mtd->current = swap_with;
+		mode_tree_build(mtd);
+	}
+}
+
 void *
 mode_tree_get_current(struct mode_tree_data *mtd)
 {
@@ -410,9 +440,9 @@ struct mode_tree_data *
 mode_tree_start(struct window_pane *wp, struct args *args,
     mode_tree_build_cb buildcb, mode_tree_draw_cb drawcb,
     mode_tree_search_cb searchcb, mode_tree_menu_cb menucb,
-    mode_tree_height_cb heightcb, mode_tree_key_cb keycb, void *modedata,
-    const struct menu_item *menu, const char **sort_list, u_int sort_size,
-    struct screen **s)
+    mode_tree_height_cb heightcb, mode_tree_key_cb keycb,
+    mode_tree_swap_cb swapcb, void *modedata, const struct menu_item *menu,
+    const char **sort_list, u_int sort_size, struct screen **s)
 {
 	struct mode_tree_data	*mtd;
 	const char		*sort;
@@ -455,6 +485,7 @@ mode_tree_start(struct window_pane *wp, struct args *args,
 	mtd->menucb = menucb;
 	mtd->heightcb = heightcb;
 	mtd->keycb = keycb;
+	mtd->swapcb = swapcb;
 
 	TAILQ_INIT(&mtd->children);
 
@@ -1147,6 +1178,14 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
 	case 'n'|KEYC_CTRL:
 		mode_tree_down(mtd, 1);
 		break;
+	case KEYC_UP|KEYC_SHIFT:
+	case 'K':
+		mode_tree_swap(mtd, -1);
+		break;
+	case KEYC_DOWN|KEYC_SHIFT:
+	case 'J':
+		mode_tree_swap(mtd, 1);
+		break;
 	case KEYC_PPAGE:
 	case 'b'|KEYC_CTRL:
 		for (i = 0; i < mtd->height; i++) {
diff --git a/options-table.c b/options-table.c
index a461b3ea..3d1b4f85 100644
--- a/options-table.c
+++ b/options-table.c
@@ -285,6 +285,13 @@ const struct options_table_entry options_table[] = {
 	  .text = "Style of the cursor."
 	},
 
+	{ .name = "default-client-command",
+	  .type = OPTIONS_TABLE_COMMAND,
+	  .scope = OPTIONS_TABLE_SERVER,
+	  .default_str = "new-session",
+	  .text = "Default command to run when tmux is run without a command."
+	},
+
 	{ .name = "default-terminal",
 	  .type = OPTIONS_TABLE_STRING,
 	  .scope = OPTIONS_TABLE_SERVER,
diff --git a/options.c b/options.c
index 5541a376..f39fbf2a 100644
--- a/options.c
+++ b/options.c
@@ -260,6 +260,7 @@ options_default(struct options *oo, const struct options_table_entry *oe)
 	struct options_entry	*o;
 	union options_value	*ov;
 	u_int			 i;
+	struct cmd_parse_result	*pr;
 
 	o = options_empty(oo, oe);
 	ov = &o->value;
@@ -278,6 +279,17 @@ options_default(struct options *oo, const struct options_table_entry *oe)
 	case OPTIONS_TABLE_STRING:
 		ov->string = xstrdup(oe->default_str);
 		break;
+	case OPTIONS_TABLE_COMMAND:
+		pr = cmd_parse_from_string(oe->default_str, NULL);
+		switch (pr->status) {
+		case CMD_PARSE_ERROR:
+			free(pr->error);
+			break;
+		case CMD_PARSE_SUCCESS:
+			ov->cmdlist = pr->cmdlist;
+			break;
+		}
+		break;
 	default:
 		ov->number = oe->default_num;
 		break;
@@ -737,6 +749,19 @@ options_get_number(struct options *oo, const char *name)
 	return (o->value.number);
 }
 
+const struct cmd_list *
+options_get_command(struct options *oo, const char *name)
+{
+	struct options_entry	*o;
+
+	o = options_get(oo, name);
+	if (o == NULL)
+		fatalx("missing option %s", name);
+	if (!OPTIONS_IS_COMMAND(o))
+		fatalx("option %s is not a command", name);
+	return (o->value.cmdlist);
+}
+
 struct options_entry *
 options_set_string(struct options *oo, const char *name, int append,
     const char *fmt, ...)
@@ -798,6 +823,30 @@ options_set_number(struct options *oo, const char *name, long long value)
 	return (o);
 }
 
+struct options_entry *
+options_set_command(struct options *oo, const char *name,
+    struct cmd_list *value)
+{
+	struct options_entry	*o;
+
+	if (*name == '@')
+		fatalx("user option %s must be a string", name);
+
+	o = options_get_only(oo, name);
+	if (o == NULL) {
+		o = options_default(oo, options_parent_table_entry(oo, name));
+		if (o == NULL)
+			return (NULL);
+	}
+
+	if (!OPTIONS_IS_COMMAND(o))
+		fatalx("option %s is not a command", name);
+	if (o->value.cmdlist != NULL)
+		cmd_list_free(o->value.cmdlist);
+	o->value.cmdlist = value;
+	return (o);
+}
+
 int
 options_scope_from_name(struct args *args, int window,
     const char *name, struct cmd_find_state *fs, struct options **oo,
@@ -1054,6 +1103,7 @@ options_from_string(struct options *oo, const struct options_table_entry *oe,
 	const char		*errstr, *new;
 	char			*old;
 	key_code		 key;
+	struct cmd_parse_result	*pr;
 
 	if (oe != NULL) {
 		if (value == NULL &&
@@ -1112,6 +1162,15 @@ options_from_string(struct options *oo, const struct options_table_entry *oe,
 	case OPTIONS_TABLE_CHOICE:
 		return (options_from_string_choice(oe, oo, name, value, cause));
 	case OPTIONS_TABLE_COMMAND:
+		pr = cmd_parse_from_string(value, NULL);
+		switch (pr->status) {
+		case CMD_PARSE_ERROR:
+			*cause = pr->error;
+			return (-1);
+		case CMD_PARSE_SUCCESS:
+			options_set_command(oo, name, pr->cmdlist);
+			return (0);
+		}
 		break;
 	}
 	return (-1);
diff --git a/server-client.c b/server-client.c
index 469bbc60..e9057339 100644
--- a/server-client.c
+++ b/server-client.c
@@ -3472,6 +3472,7 @@ server_client_dispatch_command(struct client *c, struct imsg *imsg)
 	struct cmd_parse_result	 *pr;
 	struct args_value	 *values;
 	struct cmdq_item	 *new_item;
+	struct cmd_list		 *cmdlist;
 
 	if (c->flags & CLIENT_EXIT)
 		return;
@@ -3492,33 +3493,33 @@ server_client_dispatch_command(struct client *c, struct imsg *imsg)
 	}
 
 	if (argc == 0) {
-		argc = 1;
-		argv = xcalloc(1, sizeof *argv);
-		*argv = xstrdup("new-session");
+		cmdlist = cmd_list_copy(options_get_command(global_options,
+		    "default-client-command"), 0, NULL);
+	} else {
+		values = args_from_vector(argc, argv);
+		pr = cmd_parse_from_arguments(values, argc, NULL);
+		switch (pr->status) {
+		case CMD_PARSE_ERROR:
+			cause = pr->error;
+			goto error;
+		case CMD_PARSE_SUCCESS:
+			break;
+		}
+		args_free_values(values, argc);
+		free(values);
+		cmd_free_argv(argc, argv);
+		cmdlist = pr->cmdlist;
 	}
 
-	values = args_from_vector(argc, argv);
-	pr = cmd_parse_from_arguments(values, argc, NULL);
-	switch (pr->status) {
-	case CMD_PARSE_ERROR:
-		cause = pr->error;
-		goto error;
-	case CMD_PARSE_SUCCESS:
-		break;
-	}
-	args_free_values(values, argc);
-	free(values);
-	cmd_free_argv(argc, argv);
-
 	if ((c->flags & CLIENT_READONLY) &&
-	    !cmd_list_all_have(pr->cmdlist, CMD_READONLY))
+	    !cmd_list_all_have(cmdlist, CMD_READONLY))
 		new_item = cmdq_get_callback(server_client_read_only, NULL);
 	else
-		new_item = cmdq_get_command(pr->cmdlist, NULL);
+		new_item = cmdq_get_command(cmdlist, NULL);
 	cmdq_append(c, new_item);
 	cmdq_append(c, cmdq_get_callback(server_client_command_done, NULL));
 
-	cmd_list_free(pr->cmdlist);
+	cmd_list_free(cmdlist);
 	return;
 
 error:
diff --git a/tmux.1 b/tmux.1
index 483e3987..ac9797b5 100644
--- a/tmux.1
+++ b/tmux.1
@@ -254,9 +254,10 @@ was given) and off.
 This specifies one of a set of commands used to control
 .Nm ,
 as described in the following sections.
-If no commands are specified, the
-.Ic new-session
-command is assumed.
+If no commands are specified, the command in
+.Ic default-client-command
+is assumed, which defaults to
+.Ic new-session .
 .El
 .Sh DEFAULT KEY BINDINGS
 .Nm
@@ -2715,6 +2716,8 @@ The following keys may be used in tree mode:
 .It Li "Enter" Ta "Choose selected item"
 .It Li "Up" Ta "Select previous item"
 .It Li "Down" Ta "Select next item"
+.It Li "S-Up" Ta "Swap the current window with the previous one"
+.It Li "S-Down" Ta "Swap the current window with the next one"
 .It Li "+" Ta "Expand selected item"
 .It Li "-" Ta "Collapse selected item"
 .It Li "M-+" Ta "Expand all items"
@@ -4083,6 +4086,10 @@ where the number is a hexadecimal number.
 Give the command to pipe to if the
 .Ic copy-pipe
 copy mode command is used without arguments.
+.It Ic default-client-command Ar command
+Set the default command to run when tmux is called without a command.
+The default is
+.Ic new-session .
 .It Ic default-terminal Ar terminal
 Set the default terminal for new windows created in this session - the
 default value of the
@@ -5944,6 +5951,7 @@ The following variables are available, where appropriate:
 .It Li "command_list_name" Ta "" Ta "Command name if listing commands"
 .It Li "command_list_usage" Ta "" Ta "Command usage if listing commands"
 .It Li "config_files" Ta "" Ta "List of configuration files loaded"
+.It Li "cursor_blinking" Ta "" Ta "1 if the cursor is blinking"
 .It Li "copy_cursor_hyperlink" Ta "" Ta "Hyperlink under cursor in copy mode"
 .It Li "copy_cursor_line" Ta "" Ta "Line the cursor is on in copy mode"
 .It Li "copy_cursor_word" Ta "" Ta "Word under cursor in copy mode"
@@ -5951,7 +5959,10 @@ The following variables are available, where appropriate:
 .It Li "copy_cursor_y" Ta "" Ta "Cursor Y position in copy mode"
 .It Li "current_file" Ta "" Ta "Current configuration file"
 .It Li "cursor_character" Ta "" Ta "Character at cursor in pane"
+.It Li "cursor_colour" Ta "" Ta "Cursor colour in pane"
 .It Li "cursor_flag" Ta "" Ta "Pane cursor flag"
+.It Li "cursor_shape" Ta "" Ta "Cursor shape in pane"
+.It Li "cursor_very_visible" Ta "" Ta "1 if the cursor is in very visible mode"
 .It Li "cursor_x" Ta "" Ta "Cursor X position in pane"
 .It Li "cursor_y" Ta "" Ta "Cursor Y position in pane"
 .It Li "history_bytes" Ta "" Ta "Number of bytes in window history"
diff --git a/tmux.h b/tmux.h
index c7602533..c9745253 100644
--- a/tmux.h
+++ b/tmux.h
@@ -2394,10 +2394,13 @@ struct options_entry *options_match_get(struct options *, const char *, int *,
 		     int, int *);
 const char	*options_get_string(struct options *, const char *);
 long long	 options_get_number(struct options *, const char *);
+const struct cmd_list *options_get_command(struct options *, const char *);
 struct options_entry * printflike(4, 5) options_set_string(struct options *,
 		     const char *, int, const char *, ...);
 struct options_entry *options_set_number(struct options *, const char *,
 		     long long);
+struct options_entry *options_set_command(struct options *, const char *,
+		     struct cmd_list *);
 int		 options_scope_from_name(struct args *, int,
 		     const char *, struct cmd_find_state *, struct options **,
 		     char **);
@@ -2681,12 +2684,12 @@ struct cmd	*cmd_copy(struct cmd *, int, char **);
 void		 cmd_free(struct cmd *);
 char		*cmd_print(struct cmd *);
 struct cmd_list	*cmd_list_new(void);
-struct cmd_list	*cmd_list_copy(struct cmd_list *, int, char **);
+struct cmd_list	*cmd_list_copy(const struct cmd_list *, int, char **);
 void		 cmd_list_append(struct cmd_list *, struct cmd *);
 void		 cmd_list_append_all(struct cmd_list *, struct cmd_list *);
 void		 cmd_list_move(struct cmd_list *, struct cmd_list *);
 void		 cmd_list_free(struct cmd_list *);
-char		*cmd_list_print(struct cmd_list *, int);
+char		*cmd_list_print(const struct cmd_list *, int);
 struct cmd	*cmd_list_first(struct cmd_list *);
 struct cmd	*cmd_list_next(struct cmd *);
 int		 cmd_list_all_have(struct cmd_list *, int);
@@ -2949,8 +2952,6 @@ void	 input_parse_screen(struct input_ctx *, struct screen *,
 void	 input_reply_clipboard(struct bufferevent *, const char *, size_t,
 	     const char *);
 void	 input_set_buffer_size(size_t);
-int 	 input_get_bg_client(struct window_pane *);
-int 	 input_get_bg_control_client(struct window_pane *);
 
 /* input-key.c */
 void	 input_key_build(void);
@@ -3327,6 +3328,7 @@ typedef int (*mode_tree_search_cb)(void *, void *, const char *);
 typedef void (*mode_tree_menu_cb)(void *, struct client *, key_code);
 typedef u_int (*mode_tree_height_cb)(void *, u_int);
 typedef key_code (*mode_tree_key_cb)(void *, void *, u_int);
+typedef int (*mode_tree_swap_cb)(void *, void *);
 typedef void (*mode_tree_each_cb)(void *, void *, struct client *, key_code);
 u_int	 mode_tree_count_tagged(struct mode_tree_data *);
 void	*mode_tree_get_current(struct mode_tree_data *);
@@ -3341,8 +3343,9 @@ void	 mode_tree_up(struct mode_tree_data *, int);
 int	 mode_tree_down(struct mode_tree_data *, int);
 struct mode_tree_data *mode_tree_start(struct window_pane *, struct args *,
 	     mode_tree_build_cb, mode_tree_draw_cb, mode_tree_search_cb,
-	     mode_tree_menu_cb, mode_tree_height_cb, mode_tree_key_cb, void *,
-	     const struct menu_item *, const char **, u_int, struct screen **);
+	     mode_tree_menu_cb, mode_tree_height_cb, mode_tree_key_cb,
+	     mode_tree_swap_cb, void *, const struct menu_item *, const char **,
+	     u_int, struct screen **);
 void	 mode_tree_zoom(struct mode_tree_data *, struct args *);
 void	 mode_tree_build(struct mode_tree_data *);
 void	 mode_tree_free(struct mode_tree_data *);
@@ -3387,6 +3390,7 @@ char		*window_copy_get_word(struct window_pane *, u_int, u_int);
 char		*window_copy_get_line(struct window_pane *, u_int);
 int		 window_copy_get_current_offset(struct window_pane *, u_int *,
 		     u_int *);
+char		*window_copy_get_hyperlink(struct window_pane *, u_int, u_int);
 
 /* window-option.c */
 extern const struct window_mode window_customize_mode;
@@ -3476,7 +3480,6 @@ void		 session_theme_changed(struct session *);
 /* utf8.c */
 enum utf8_state	 utf8_towc (const struct utf8_data *, wchar_t *);
 enum utf8_state	 utf8_fromwc(wchar_t wc, struct utf8_data *);
-int		 utf8_in_table(wchar_t, const wchar_t *, u_int);
 void		 utf8_update_width_cache(void);
 utf8_char	 utf8_build_one(u_char);
 enum utf8_state	 utf8_from_data(const struct utf8_data *, utf8_char *);
diff --git a/tty-keys.c b/tty-keys.c
index 45175171..7b0da5a2 100644
--- a/tty-keys.c
+++ b/tty-keys.c
@@ -937,6 +937,11 @@ partial_key:
 	delay = options_get_number(global_options, "escape-time");
 	if (delay == 0)
 		delay = 1;
+	if ((tty->flags & TTY_ALL_REQUEST_FLAGS) != TTY_ALL_REQUEST_FLAGS) {
+		log_debug("%s: increasing delay for active DA query", c->name);
+		if (delay < 500)
+			delay = 500;
+	}
 	tv.tv_sec = delay / 1000;
 	tv.tv_usec = (delay % 1000) * 1000L;
 
diff --git a/window-buffer.c b/window-buffer.c
index abdfa125..16cab7eb 100644
--- a/window-buffer.c
+++ b/window-buffer.c
@@ -350,7 +350,7 @@ window_buffer_init(struct window_mode_entry *wme, struct cmd_find_state *fs,
 
 	data->data = mode_tree_start(wp, args, window_buffer_build,
 	    window_buffer_draw, window_buffer_search, window_buffer_menu, NULL,
-	    window_buffer_get_key, data, window_buffer_menu_items,
+	    window_buffer_get_key, NULL, data, window_buffer_menu_items,
 	    window_buffer_sort_list, nitems(window_buffer_sort_list), &s);
 	mode_tree_zoom(data->data, args);
 
diff --git a/window-client.c b/window-client.c
index b704b530..c1b962f1 100644
--- a/window-client.c
+++ b/window-client.c
@@ -310,7 +310,7 @@ window_client_init(struct window_mode_entry *wme,
 
 	data->data = mode_tree_start(wp, args, window_client_build,
 	    window_client_draw, NULL, window_client_menu, NULL,
-	    window_client_get_key, data, window_client_menu_items,
+	    window_client_get_key, NULL, data, window_client_menu_items,
 	    window_client_sort_list, nitems(window_client_sort_list), &s);
 	mode_tree_zoom(data->data, args);
 
diff --git a/window-copy.c b/window-copy.c
index 7dcc8432..1dd12e45 100644
--- a/window-copy.c
+++ b/window-copy.c
@@ -884,6 +884,16 @@ window_copy_get_line(struct window_pane *wp, u_int y)
 	return (format_grid_line(gd, gd->hsize + y));
 }
 
+char *
+window_copy_get_hyperlink(struct window_pane *wp, u_int x, u_int y)
+{
+	struct window_mode_entry	*wme = TAILQ_FIRST(&wp->modes);
+	struct window_copy_mode_data	*data = wme->data;
+	struct grid			*gd = data->screen.grid;
+
+	return (format_grid_hyperlink(gd, x, gd->hsize + y, wp->screen));
+}
+
 static void *
 window_copy_cursor_hyperlink_cb(struct format_tree *ft)
 {
@@ -4263,6 +4273,8 @@ window_copy_match_at_cursor(struct window_copy_mode_data *data)
 			buf = xrealloc(buf, len + 2);
 			buf[len] = '\t';
 			len++;
+		} else if (gc.flags & GRID_FLAG_PADDING) {
+			/* nothing to do */
 		} else {
 			buf = xrealloc(buf, len + gc.data.size + 1);
 			memcpy(buf + len, gc.data.data, gc.data.size);
diff --git a/window-customize.c b/window-customize.c
index c49e57af..f30becfe 100644
--- a/window-customize.c
+++ b/window-customize.c
@@ -891,8 +891,8 @@ window_customize_init(struct window_mode_entry *wme, struct cmd_find_state *fs,
 
 	data->data = mode_tree_start(wp, args, window_customize_build,
 	    window_customize_draw, NULL, window_customize_menu,
-	    window_customize_height, NULL, data, window_customize_menu_items,
-	    NULL, 0, &s);
+	    window_customize_height, NULL, NULL, data,
+	    window_customize_menu_items, NULL, 0, &s);
 	mode_tree_zoom(data->data, args);
 
 	mode_tree_build(data->data);
diff --git a/window-tree.c b/window-tree.c
index 07d2bc2e..7e84189a 100644
--- a/window-tree.c
+++ b/window-tree.c
@@ -302,6 +302,7 @@ window_tree_build_pane(struct session *s, struct winlink *wl,
 	struct window_tree_itemdata	*item;
 	char				*name, *text;
 	u_int				 idx;
+	struct format_tree		*ft;
 
 	window_pane_index(wp, &idx);
 
@@ -311,8 +312,11 @@ window_tree_build_pane(struct session *s, struct winlink *wl,
 	item->winlink = wl->idx;
 	item->pane = wp->id;
 
-	text = format_single(NULL, data->format, NULL, s, wl, wp);
+	ft = format_create(NULL, NULL, FORMAT_PANE|wp->id, 0);
+	format_defaults(ft, NULL, s, wl, wp);
+	text = format_expand(ft, data->format);
 	xasprintf(&name, "%u", idx);
+	format_free(ft);
 
 	mode_tree_add(data->data, parent, item, (uint64_t)wp, name, text, -1);
 	free(text);
@@ -348,6 +352,7 @@ window_tree_build_window(struct session *s, struct winlink *wl,
 	struct window_pane		*wp, **l;
 	u_int				 n, i;
 	int				 expanded;
+	struct format_tree		*ft;
 
 	item = window_tree_add_item(data);
 	item->type = WINDOW_TREE_WINDOW;
@@ -355,8 +360,11 @@ window_tree_build_window(struct session *s, struct winlink *wl,
 	item->winlink = wl->idx;
 	item->pane = -1;
 
-	text = format_single(NULL, data->format, NULL, s, wl, NULL);
+	ft = format_create(NULL, NULL, FORMAT_PANE|wl->window->active->id, 0);
+	format_defaults(ft, NULL, s, wl, NULL);
+	text = format_expand(ft, data->format);
 	xasprintf(&name, "%u", wl->idx);
+	format_free(ft);
 
 	if (data->type == WINDOW_TREE_SESSION ||
 	    data->type == WINDOW_TREE_WINDOW)
@@ -373,7 +381,6 @@ window_tree_build_window(struct session *s, struct winlink *wl,
 	if (TAILQ_NEXT(wp, entry) == NULL) {
 		if (!window_tree_filter_pane(s, wl, wp, filter))
 			goto empty;
-		return (1);
 	}
 
 	l = NULL;
@@ -411,9 +418,10 @@ window_tree_build_session(struct session *s, void *modedata,
 	struct window_tree_itemdata	*item;
 	struct mode_tree_item		*mti;
 	char				*text;
-	struct winlink			*wl, **l;
+	struct winlink			*wl = s->curw, **l;
 	u_int				 n, i, empty;
 	int				 expanded;
+	struct format_tree		*ft;
 
 	item = window_tree_add_item(data);
 	item->type = WINDOW_TREE_SESSION;
@@ -421,7 +429,10 @@ window_tree_build_session(struct session *s, void *modedata,
 	item->winlink = -1;
 	item->pane = -1;
 
-	text = format_single(NULL, data->format, NULL, s, NULL, NULL);
+	ft = format_create(NULL, NULL, FORMAT_PANE|wl->window->active->id, 0);
+	format_defaults(ft, NULL, s, NULL, NULL);
+	text = format_expand(ft, data->format);
+	format_free(ft);
 
 	if (data->type == WINDOW_TREE_SESSION)
 		expanded = 0;
@@ -902,6 +913,58 @@ window_tree_get_key(void *modedata, void *itemdata, u_int line)
 	return (key);
 }
 
+static int
+window_tree_swap(void *cur_itemdata, void *other_itemdata)
+{
+	struct window_tree_itemdata	*cur = cur_itemdata;
+	struct window_tree_itemdata	*other = other_itemdata;
+	struct session			*cur_session, *other_session;
+	struct winlink			*cur_winlink, *other_winlink;
+	struct window			*cur_window, *other_window;
+	struct window_pane		*cur_pane, *other_pane;
+
+	if (cur->type != other->type)
+		return (0);
+	if (cur->type != WINDOW_TREE_WINDOW)
+		return (0);
+
+	window_tree_pull_item(cur, &cur_session, &cur_winlink, &cur_pane);
+	window_tree_pull_item(other, &other_session, &other_winlink,
+	    &other_pane);
+
+	if (cur_session != other_session)
+		return (0);
+
+	if (window_tree_sort->field != WINDOW_TREE_BY_INDEX &&
+	    window_tree_cmp_window(&cur_winlink, &other_winlink) != 0) {
+		/*
+		 * Swapping indexes would not swap positions in the tree, so
+		 * prevent swapping to avoid confusing the user.
+		 */
+		return (0);
+	}
+
+	other_window = other_winlink->window;
+	TAILQ_REMOVE(&other_window->winlinks, other_winlink, wentry);
+	cur_window = cur_winlink->window;
+	TAILQ_REMOVE(&cur_window->winlinks, cur_winlink, wentry);
+
+	other_winlink->window = cur_window;
+	TAILQ_INSERT_TAIL(&cur_window->winlinks, other_winlink, wentry);
+	cur_winlink->window = other_window;
+	TAILQ_INSERT_TAIL(&other_window->winlinks, cur_winlink, wentry);
+
+	if (cur_session->curw == cur_winlink)
+		session_set_current(cur_session, other_winlink);
+	else if (cur_session->curw == other_winlink)
+		session_set_current(cur_session, cur_winlink);
+	session_group_synchronize_from(cur_session);
+	server_redraw_session_group(cur_session);
+	recalculate_sizes();
+
+	return (1);
+}
+
 static struct screen *
 window_tree_init(struct window_mode_entry *wme, struct cmd_find_state *fs,
     struct args *args)
@@ -940,7 +1003,7 @@ window_tree_init(struct window_mode_entry *wme, struct cmd_find_state *fs,
 
 	data->data = mode_tree_start(wp, args, window_tree_build,
 	    window_tree_draw, window_tree_search, window_tree_menu, NULL,
-	    window_tree_get_key, data, window_tree_menu_items,
+	    window_tree_get_key, window_tree_swap, data, window_tree_menu_items,
 	    window_tree_sort_list, nitems(window_tree_sort_list), &s);
 	mode_tree_zoom(data->data, args);