diff --git a/format.c b/format.c
index 9ce56104..3757180b 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
 	},
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/tmux.1 b/tmux.1
index 483e3987..7a2aad7a 100644
--- a/tmux.1
+++ b/tmux.1
@@ -2715,6 +2715,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"
@@ -5944,6 +5946,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 +5954,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 f7c59308..bde95365 100644
--- a/tmux.h
+++ b/tmux.h
@@ -3324,6 +3324,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 *);
@@ -3338,8 +3339,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 *);
@@ -3384,6 +3386,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;
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 3a4f59bb..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)
 {
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..6b14bb63 100644
--- a/window-tree.c
+++ b/window-tree.c
@@ -902,6 +902,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 +992,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);