summaryrefslogtreecommitdiff
path: root/usr.bin/tmux
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2017-10-05 13:29:19 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2017-10-05 13:29:19 +0000
commitda840c6b3393179934a99b6616d48116aa4bdb40 (patch)
treede495e4ef9b71cc155a83d2e8ec9d9bde934c4cc /usr.bin/tmux
parentd28d0a68d32fa7886ca9b831dd7579be479817a4 (diff)
Add support for the xterm(1) title stack, from Brad Town, GitHub issue
1075.
Diffstat (limited to 'usr.bin/tmux')
-rw-r--r--usr.bin/tmux/input.c25
-rw-r--r--usr.bin/tmux/screen.c70
-rw-r--r--usr.bin/tmux/tmux.h6
3 files changed, 97 insertions, 4 deletions
diff --git a/usr.bin/tmux/input.c b/usr.bin/tmux/input.c
index 798a4dd0d2e..804cc73737f 100644
--- a/usr.bin/tmux/input.c
+++ b/usr.bin/tmux/input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: input.c,v 1.128 2017/09/10 08:01:23 nicm Exp $ */
+/* $OpenBSD: input.c,v 1.129 2017/10/05 13:29:18 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -1693,11 +1693,32 @@ input_csi_dispatch_winops(struct input_ctx *ictx)
/* FALLTHROUGH */
case 9:
case 10:
+ m++;
+ if (input_get(ictx, m, 0, -1) == -1)
+ return;
+ break;
case 22:
+ m++;
+ switch (input_get(ictx, m, 0, -1)) {
+ case -1:
+ return;
+ case 0:
+ case 2:
+ screen_push_title(ictx->ctx.s);
+ break;
+ }
+ break;
case 23:
m++;
- if (input_get(ictx, m, 0, -1) == -1)
+ switch (input_get(ictx, m, 0, -1)) {
+ case -1:
return;
+ case 0:
+ case 2:
+ screen_pop_title(ictx->ctx.s);
+ server_status_window(ictx->wp->window);
+ break;
+ }
break;
case 18:
input_reply(ictx, "\033[8;%u;%ut", wp->sy, wp->sx);
diff --git a/usr.bin/tmux/screen.c b/usr.bin/tmux/screen.c
index 262929a2105..32e16ba1935 100644
--- a/usr.bin/tmux/screen.c
+++ b/usr.bin/tmux/screen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: screen.c,v 1.47 2017/06/04 09:02:36 nicm Exp $ */
+/* $OpenBSD: screen.c,v 1.48 2017/10/05 13:29:18 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -25,17 +25,44 @@
#include "tmux.h"
+struct screen_title_entry {
+ char *text;
+
+ TAILQ_ENTRY(screen_title_entry) entry;
+};
+TAILQ_HEAD(screen_titles, screen_title_entry);
+
static void screen_resize_x(struct screen *, u_int);
static void screen_resize_y(struct screen *, u_int);
static void screen_reflow(struct screen *, u_int);
+/* Free titles stack. */
+static void
+screen_free_titles(struct screen *s)
+{
+ struct screen_title_entry *title_entry;
+
+ if (s->titles == NULL)
+ return;
+
+ while ((title_entry = TAILQ_FIRST(s->titles)) != NULL) {
+ TAILQ_REMOVE(s->titles, title_entry, entry);
+ free(title_entry->text);
+ free(title_entry);
+ }
+
+ free(s->titles);
+ s->titles = NULL;
+}
+
/* Create a new screen. */
void
screen_init(struct screen *s, u_int sx, u_int sy, u_int hlimit)
{
s->grid = grid_create(sx, sy, hlimit);
s->title = xstrdup("");
+ s->titles = NULL;
s->cstyle = 0;
s->ccolour = xstrdup("");
@@ -61,6 +88,7 @@ screen_reinit(struct screen *s)
grid_clear_lines(s->grid, s->grid->hsize, s->grid->sy, 8);
screen_clear_selection(s);
+ screen_free_titles(s);
}
/* Destroy a screen. */
@@ -70,7 +98,10 @@ screen_free(struct screen *s)
free(s->tabs);
free(s->title);
free(s->ccolour);
+
grid_destroy(s->grid);
+
+ screen_free_titles(s);
}
/* Reset tabs to default, eight spaces apart. */
@@ -111,6 +142,43 @@ screen_set_title(struct screen *s, const char *title)
utf8_stravis(&s->title, title, VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL);
}
+/* Push the current title onto the stack. */
+void
+screen_push_title(struct screen *s)
+{
+ struct screen_title_entry *title_entry;
+
+ if (s->titles == NULL) {
+ s->titles = xmalloc(sizeof *s->titles);
+ TAILQ_INIT(s->titles);
+ }
+ title_entry = xmalloc(sizeof *title_entry);
+ title_entry->text = xstrdup(s->title);
+ TAILQ_INSERT_HEAD(s->titles, title_entry, entry);
+}
+
+/*
+ * Pop a title from the stack and set it as the screen title. If the stack is
+ * empty, do nothing.
+ */
+void
+screen_pop_title(struct screen *s)
+{
+ struct screen_title_entry *title_entry;
+
+ if (s->titles == NULL)
+ return;
+
+ title_entry = TAILQ_FIRST(s->titles);
+ if (title_entry != NULL) {
+ screen_set_title(s, title_entry->text);
+
+ TAILQ_REMOVE(s->titles, title_entry, entry);
+ free(title_entry->text);
+ free(title_entry);
+ }
+}
+
/* Resize screen. */
void
screen_resize(struct screen *s, u_int sx, u_int sy, int reflow)
diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h
index f481184ec2c..d35363c171d 100644
--- a/usr.bin/tmux/tmux.h
+++ b/usr.bin/tmux/tmux.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.804 2017/08/30 18:13:47 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.805 2017/10/05 13:29:18 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -660,8 +660,10 @@ struct screen_sel {
};
/* Virtual screen. */
+struct screen_titles;
struct screen {
char *title;
+ struct screen_titles *titles;
struct grid *grid; /* grid data */
@@ -2082,6 +2084,8 @@ void screen_reset_tabs(struct screen *);
void screen_set_cursor_style(struct screen *, u_int);
void screen_set_cursor_colour(struct screen *, const char *);
void screen_set_title(struct screen *, const char *);
+void screen_push_title(struct screen *);
+void screen_pop_title(struct screen *);
void screen_resize(struct screen *, u_int, u_int, int);
void screen_set_selection(struct screen *,
u_int, u_int, u_int, u_int, u_int, struct grid_cell *);