summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Adam <thomas@xteddy.org>2019-03-12 12:02:42 +0000
committerThomas Adam <thomas@xteddy.org>2019-03-12 12:02:42 +0000
commit3ec05e940505f1d0b4e55413f949fdfaceddedde (patch)
tree843d754e76bb7386f39cb5743ab8de859e880ddd
parentf8a30e158821876e8c30d46ab2728bce739e35de (diff)
parent3f6bfbaf2babcc7f08f628a82ff31b0b52014e58 (diff)
Merge branch 'obsd-master'
-rw-r--r--cfg.c10
-rw-r--r--cmd-capture-pane.c3
-rw-r--r--cmd-copy-mode.c13
-rw-r--r--cmd-queue.c14
-rw-r--r--cmd-respawn-pane.c2
-rw-r--r--cmd-respawn-window.c2
-rw-r--r--cmd-run-shell.c6
-rw-r--r--cmd-send-keys.c12
-rw-r--r--format.c38
-rw-r--r--input.c4
-rw-r--r--server-client.c32
-rw-r--r--tmux.h7
-rw-r--r--window-clock.c5
-rw-r--r--window-copy.c61
-rw-r--r--window.c87
15 files changed, 181 insertions, 115 deletions
diff --git a/cfg.c b/cfg.c
index 8b6ecd97..84db9fb3 100644
--- a/cfg.c
+++ b/cfg.c
@@ -340,17 +340,17 @@ cfg_print_causes(struct cmdq_item *item)
void
cfg_show_causes(struct session *s)
{
- struct window_pane *wp;
- u_int i;
+ struct window_pane *wp;
+ struct window_mode_entry *wme;
+ u_int i;
if (s == NULL || cfg_ncauses == 0)
return;
wp = s->curw->window->active;
- if (wp->mode == NULL || wp->mode->mode != &window_view_mode) {
- window_pane_reset_mode(wp);
+ wme = TAILQ_FIRST(&wp->modes);
+ if (wme == NULL || wme->mode != &window_view_mode)
window_pane_set_mode(wp, &window_view_mode, NULL, NULL);
- }
for (i = 0; i < cfg_ncauses; i++) {
window_copy_add(wp, "%s", cfg_causes[i]);
free(cfg_causes[i]);
diff --git a/cmd-capture-pane.c b/cmd-capture-pane.c
index cb01f502..dd1576c4 100644
--- a/cmd-capture-pane.c
+++ b/cmd-capture-pane.c
@@ -199,8 +199,7 @@ cmd_capture_pane_exec(struct cmd *self, struct cmdq_item *item)
size_t len;
if (self->entry == &cmd_clear_history_entry) {
- if (wp->mode != NULL && wp->mode->mode == &window_copy_mode)
- window_pane_reset_mode(wp);
+ window_pane_reset_mode_all(wp);
grid_clear_history(wp->base.grid);
return (CMD_RETURN_NORMAL);
}
diff --git a/cmd-copy-mode.c b/cmd-copy-mode.c
index d9471aab..bd05f8a2 100644
--- a/cmd-copy-mode.c
+++ b/cmd-copy-mode.c
@@ -60,7 +60,6 @@ cmd_copy_mode_exec(struct cmd *self, struct cmdq_item *item)
struct client *c = item->client;
struct session *s;
struct window_pane *wp = item->target.wp;
- int flag;
if (args_has(args, 'M')) {
if ((wp = cmd_mouse_pane(&shared->mouse, &s, NULL)) == NULL)
@@ -74,16 +73,10 @@ cmd_copy_mode_exec(struct cmd *self, struct cmdq_item *item)
return (CMD_RETURN_NORMAL);
}
- if (wp->mode == NULL || wp->mode->mode != &window_copy_mode) {
- flag = window_pane_set_mode(wp, &window_copy_mode, NULL, args);
- if (flag != 0)
- return (CMD_RETURN_NORMAL);
- }
- if (args_has(args, 'M')) {
- if (wp->mode != NULL && wp->mode->mode != &window_copy_mode)
- return (CMD_RETURN_NORMAL);
+ if (window_pane_set_mode(wp, &window_copy_mode, NULL, args) != 0)
+ return (CMD_RETURN_NORMAL);
+ if (args_has(args, 'M'))
window_copy_start_drag(c, &shared->mouse);
- }
if (args_has(self->args, 'u'))
window_copy_pageup(wp, 0);
diff --git a/cmd-queue.c b/cmd-queue.c
index 2a95a3e5..97b3c1c9 100644
--- a/cmd-queue.c
+++ b/cmd-queue.c
@@ -404,10 +404,11 @@ cmdq_guard(struct cmdq_item *item, const char *guard, int flags)
void
cmdq_print(struct cmdq_item *item, const char *fmt, ...)
{
- struct client *c = item->client;
- struct window_pane *wp;
- va_list ap;
- char *tmp, *msg;
+ struct client *c = item->client;
+ struct window_pane *wp;
+ struct window_mode_entry *wme;
+ va_list ap;
+ char *tmp, *msg;
va_start(ap, fmt);
@@ -426,10 +427,9 @@ cmdq_print(struct cmdq_item *item, const char *fmt, ...)
server_client_push_stdout(c);
} else {
wp = c->session->curw->window->active;
- if (wp->mode == NULL || wp->mode->mode != &window_view_mode) {
- window_pane_reset_mode(wp);
+ wme = TAILQ_FIRST(&wp->modes);
+ if (wme == NULL || wme->mode != &window_view_mode)
window_pane_set_mode(wp, &window_view_mode, NULL, NULL);
- }
window_copy_vadd(wp, fmt, ap);
}
diff --git a/cmd-respawn-pane.c b/cmd-respawn-pane.c
index 3d78c495..eb4a7e09 100644
--- a/cmd-respawn-pane.c
+++ b/cmd-respawn-pane.c
@@ -67,7 +67,7 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmdq_item *item)
return (CMD_RETURN_ERROR);
}
- window_pane_reset_mode(wp);
+ window_pane_reset_mode_all(wp);
screen_reinit(&wp->base);
input_init(wp);
diff --git a/cmd-respawn-window.c b/cmd-respawn-window.c
index a1e26117..68791990 100644
--- a/cmd-respawn-window.c
+++ b/cmd-respawn-window.c
@@ -99,7 +99,7 @@ cmd_respawn_window_exec(struct cmd *self, struct cmdq_item *item)
free(cwd);
layout_init(w, wp);
- window_pane_reset_mode(wp);
+ window_pane_reset_mode_all(wp);
screen_reinit(&wp->base);
input_init(wp);
window_set_active_pane(w, wp);
diff --git a/cmd-run-shell.c b/cmd-run-shell.c
index 8e99f90b..c9a478c7 100644
--- a/cmd-run-shell.c
+++ b/cmd-run-shell.c
@@ -60,6 +60,7 @@ cmd_run_shell_print(struct job *job, const char *msg)
struct cmd_run_shell_data *cdata = job_get_data(job);
struct window_pane *wp = NULL;
struct cmd_find_state fs;
+ struct window_mode_entry *wme;
if (cdata->wp_id != -1)
wp = window_pane_find_by_id(cdata->wp_id);
@@ -75,10 +76,9 @@ cmd_run_shell_print(struct job *job, const char *msg)
return;
}
- if (wp->mode == NULL || wp->mode->mode != &window_view_mode) {
- window_pane_reset_mode(wp);
+ wme = TAILQ_FIRST(&wp->modes);
+ if (wme == NULL || wme->mode != &window_view_mode)
window_pane_set_mode(wp, &window_view_mode, NULL, NULL);
- }
window_copy_add(wp, "%s", msg);
}
diff --git a/cmd-send-keys.c b/cmd-send-keys.c
index 80799c54..d9c39f63 100644
--- a/cmd-send-keys.c
+++ b/cmd-send-keys.c
@@ -61,10 +61,11 @@ cmd_send_keys_inject(struct client *c, struct cmdq_item *item, key_code key)
struct window_pane *wp = item->target.wp;
struct session *s = item->target.s;
struct winlink *wl = item->target.wl;
- struct window_mode_entry *wme = wp->mode;
+ struct window_mode_entry *wme;
struct key_table *table;
struct key_binding *bd;
+ wme = TAILQ_FIRST(&wp->modes);
if (wme == NULL || wme->mode->key_table == NULL) {
if (options_get_number(wp->window->options, "xterm-keys"))
key |= KEYC_XTERM;
@@ -90,7 +91,7 @@ cmd_send_keys_exec(struct cmd *self, struct cmdq_item *item)
struct session *s = item->target.s;
struct winlink *wl = item->target.wl;
struct mouse_event *m = &item->shared->mouse;
- struct window_mode_entry *wme = wp->mode;
+ struct window_mode_entry *wme = TAILQ_FIRST(&wp->modes);
struct utf8_data *ud, *uc;
wchar_t wc;
int i, literal;
@@ -105,8 +106,13 @@ cmd_send_keys_exec(struct cmd *self, struct cmdq_item *item)
free(cause);
return (CMD_RETURN_ERROR);
}
- if (wme != NULL && (args_has(args, 'X') || args->argc == 0))
+ if (wme != NULL && (args_has(args, 'X') || args->argc == 0)) {
+ if (wme == NULL || wme->mode->command == NULL) {
+ cmdq_error(item, "not in a mode");
+ return (CMD_RETURN_ERROR);
+ }
wme->prefix = np;
+ }
}
if (args_has(args, 'X')) {
diff --git a/format.c b/format.c
index 29f8d47e..6b493841 100644
--- a/format.c
+++ b/format.c
@@ -632,6 +632,22 @@ format_cb_session_group_list(struct format_tree *ft, struct format_entry *fe)
evbuffer_free(buffer);
}
+/* Callback for pane_in_mode. */
+static void
+format_cb_pane_in_mode(struct format_tree *ft, struct format_entry *fe)
+{
+ struct window_pane *wp = ft->wp;
+ u_int n = 0;
+ struct window_mode_entry *wme;
+
+ if (wp == NULL)
+ return;
+
+ TAILQ_FOREACH(wme, &wp->modes, entry)
+ n++;
+ xasprintf(&fe->value, "%u", n);
+}
+
/* Merge a format tree. */
static void
format_merge(struct format_tree *ft, struct format_tree *from)
@@ -1511,10 +1527,11 @@ format_defaults_winlink(struct format_tree *ft, struct winlink *wl)
void
format_defaults_pane(struct format_tree *ft, struct window_pane *wp)
{
- struct window *w = wp->window;
- struct grid *gd = wp->base.grid;
- int status = wp->status;
- u_int idx;
+ struct window *w = wp->window;
+ struct grid *gd = wp->base.grid;
+ int status = wp->status;
+ u_int idx;
+ struct window_mode_entry *wme;
if (ft->w == NULL)
ft->w = w;
@@ -1549,9 +1566,13 @@ format_defaults_pane(struct format_tree *ft, struct window_pane *wp)
format_add(ft, "pane_at_right", "%d", wp->xoff + wp->sx == w->sx);
format_add(ft, "pane_at_bottom", "%d", wp->yoff + wp->sy == w->sy);
- format_add(ft, "pane_in_mode", "%d", wp->screen != &wp->base);
- if (wp->mode != NULL)
- format_add(ft, "pane_mode", "%s", wp->mode->mode->name);
+ wme = TAILQ_FIRST(&wp->modes);
+ if (wme != NULL) {
+ format_add(ft, "pane_mode", "%s", wme->mode->name);
+ if (wme->mode->formats != NULL)
+ wme->mode->formats(wme, ft);
+ }
+ format_add_cb(ft, "pane_in_mode", format_cb_pane_in_mode);
format_add(ft, "pane_synchronized", "%d",
!!options_get_number(w->options, "synchronize-panes"));
@@ -1569,9 +1590,6 @@ format_defaults_pane(struct format_tree *ft, struct window_pane *wp)
format_add(ft, "scroll_region_upper", "%u", wp->base.rupper);
format_add(ft, "scroll_region_lower", "%u", wp->base.rlower);
- if (wp->mode != NULL && wp->mode->mode->formats != NULL)
- wp->mode->mode->formats(wp->mode, ft);
-
format_add(ft, "alternate_on", "%d", wp->saved_grid ? 1 : 0);
format_add(ft, "alternate_saved_x", "%u", wp->saved_cx);
format_add(ft, "alternate_saved_y", "%u", wp->saved_cy);
diff --git a/input.c b/input.c
index c498bc50..049b82e1 100644
--- a/input.c
+++ b/input.c
@@ -805,7 +805,7 @@ input_reset(struct window_pane *wp, int clear)
input_reset_cell(ictx);
if (clear) {
- if (wp->mode == NULL)
+ if (TAILQ_EMPTY(&wp->modes))
screen_write_start(&ictx->ctx, wp, &wp->base);
else
screen_write_start(&ictx->ctx, NULL, &wp->base);
@@ -861,7 +861,7 @@ input_parse(struct window_pane *wp)
* Open the screen. Use NULL wp if there is a mode set as don't want to
* update the tty.
*/
- if (wp->mode == NULL)
+ if (TAILQ_EMPTY(&wp->modes))
screen_write_start(&ictx->ctx, wp, &wp->base);
else
screen_write_start(&ictx->ctx, NULL, &wp->base);
diff --git a/server-client.c b/server-client.c
index df44a4a3..098ff45e 100644
--- a/server-client.c
+++ b/server-client.c
@@ -919,18 +919,18 @@ server_client_assume_paste(struct session *s)
void
server_client_handle_key(struct client *c, key_code key)
{
- struct mouse_event *m = &c->tty.mouse;
- struct session *s = c->session;
- struct winlink *wl;
- struct window *w;
- struct window_pane *wp;
- struct timeval tv;
- struct key_table *table, *first;
- const char *tablename;
- struct key_binding *bd;
- int xtimeout, flags;
- struct cmd_find_state fs;
- key_code key0;
+ struct mouse_event *m = &c->tty.mouse;
+ struct session *s = c->session;
+ struct winlink *wl;
+ struct window *w;
+ struct window_pane *wp;
+ struct window_mode_entry *wme;
+ struct timeval tv;
+ struct key_table *table, *first;
+ struct key_binding *bd;
+ int xtimeout, flags;
+ struct cmd_find_state fs;
+ key_code key0;
/* Check the client is good to accept input. */
if (s == NULL || (c->flags & (CLIENT_DEAD|CLIENT_SUSPENDED)) != 0)
@@ -1007,11 +1007,9 @@ server_client_handle_key(struct client *c, key_code key)
*/
if (server_client_is_default_key_table(c, c->keytable) &&
wp != NULL &&
- wp->mode != NULL &&
- wp->mode->mode->key_table != NULL) {
- tablename = wp->mode->mode->key_table(wp->mode);
- table = key_bindings_get_table(tablename, 1);
- }
+ (wme = TAILQ_FIRST(&wp->modes)) != NULL &&
+ wme->mode->key_table != NULL)
+ table = key_bindings_get_table(wme->mode->key_table(wme), 1);
else
table = c->keytable;
first = table;
diff --git a/tmux.h b/tmux.h
index 66ea3b7d..7090402d 100644
--- a/tmux.h
+++ b/tmux.h
@@ -724,7 +724,10 @@ struct window_mode_entry {
const struct window_mode *mode;
void *data;
+ struct screen *screen;
u_int prefix;
+
+ TAILQ_ENTRY (window_mode_entry) entry;
};
/* Child window structure. */
@@ -770,6 +773,7 @@ struct window_pane {
int fd;
struct bufferevent *event;
+ u_int disabled;
struct event resize_timer;
@@ -795,7 +799,7 @@ struct window_pane {
struct grid *saved_grid;
struct grid_cell saved_cell;
- struct window_mode_entry *mode;
+ TAILQ_HEAD (, window_mode_entry) modes;
struct event modetimer;
time_t modelast;
char *searchstr;
@@ -2210,6 +2214,7 @@ int window_pane_set_mode(struct window_pane *,
const struct window_mode *, struct cmd_find_state *,
struct args *);
void window_pane_reset_mode(struct window_pane *);
+void window_pane_reset_mode_all(struct window_pane *);
void window_pane_key(struct window_pane *, struct client *,
struct session *, struct winlink *, key_code,
struct mouse_event *);
diff --git a/window-clock.c b/window-clock.c
index c7074c0d..f98d7923 100644
--- a/window-clock.c
+++ b/window-clock.c
@@ -136,6 +136,9 @@ window_clock_timer_callback(__unused int fd, __unused short events, void *arg)
evtimer_del(&data->timer);
evtimer_add(&data->timer, &tv);
+ if (TAILQ_FIRST(&wp->modes) != wme)
+ return;
+
t = time(NULL);
gmtime_r(&t, &now);
gmtime_r(&data->tim, &then);
@@ -144,7 +147,7 @@ window_clock_timer_callback(__unused int fd, __unused short events, void *arg)
data->tim = t;
window_clock_draw_screen(wme);
- server_redraw_window(wp->window);
+ wp->flags |= PANE_REDRAW;
}
static struct screen *
diff --git a/window-copy.c b/window-copy.c
index d7ce3e8a..223741d1 100644
--- a/window-copy.c
+++ b/window-copy.c
@@ -258,7 +258,7 @@ window_copy_init(struct window_mode_entry *wme,
data = window_copy_common_init(wme);
- if (wp->fd != -1)
+ if (wp->fd != -1 && wp->disabled++ == 0)
bufferevent_disable(wp->event, EV_READ|EV_WRITE);
data->backing = &wp->base;
@@ -302,7 +302,7 @@ window_copy_free(struct window_mode_entry *wme)
struct window_pane *wp = wme->wp;
struct window_copy_mode_data *data = wme->data;
- if (wp->fd != -1)
+ if (wp->fd != -1 && --wp->disabled == 0)
bufferevent_enable(wp->event, EV_READ|EV_WRITE);
free(data->searchmark);
@@ -330,7 +330,7 @@ window_copy_add(struct window_pane *wp, const char *fmt, ...)
void
window_copy_vadd(struct window_pane *wp, const char *fmt, va_list ap)
{
- struct window_mode_entry *wme = wp->mode;
+ struct window_mode_entry *wme = TAILQ_FIRST(&wp->modes);
struct window_copy_mode_data *data = wme->data;
struct screen *backing = data->backing;
struct screen_write_ctx back_ctx, ctx;
@@ -377,7 +377,7 @@ window_copy_vadd(struct window_pane *wp, const char *fmt, va_list ap)
void
window_copy_pageup(struct window_pane *wp, int half_page)
{
- window_copy_pageup1(wp->mode, half_page);
+ window_copy_pageup1(TAILQ_FIRST(&wp->modes), half_page);
}
static void
@@ -2540,34 +2540,38 @@ window_copy_rectangle_toggle(struct window_mode_entry *wme)
static void
window_copy_move_mouse(struct mouse_event *m)
{
- struct window_pane *wp;
- u_int x, y;
+ struct window_pane *wp;
+ struct window_mode_entry *wme;
+ u_int x, y;
wp = cmd_mouse_pane(m, NULL, NULL);
- if (wp == NULL ||
- wp->mode == NULL ||
- wp->mode->mode != &window_copy_mode)
+ if (wp == NULL)
+ return;
+ wme = TAILQ_FIRST(&wp->modes);
+ if (wme == NULL || wme->mode != &window_copy_mode)
return;
if (cmd_mouse_at(wp, m, &x, &y, 0) != 0)
return;
- window_copy_update_cursor(wp->mode, x, y);
+ window_copy_update_cursor(wme, x, y);
}
void
window_copy_start_drag(struct client *c, struct mouse_event *m)
{
- struct window_pane *wp;
- u_int x, y;
+ struct window_pane *wp;
+ struct window_mode_entry *wme;
+ u_int x, y;
if (c == NULL)
return;
wp = cmd_mouse_pane(m, NULL, NULL);
- if (wp == NULL ||
- wp->mode == NULL ||
- wp->mode->mode != &window_copy_mode)
+ if (wp == NULL)
+ return;
+ wme = TAILQ_FIRST(&wp->modes);
+ if (wme == NULL || wme->mode != &window_copy_mode)
return;
if (cmd_mouse_at(wp, m, &x, &y, 1) != 0)
@@ -2576,30 +2580,35 @@ window_copy_start_drag(struct client *c, struct mouse_event *m)
c->tty.mouse_drag_update = window_copy_drag_update;
c->tty.mouse_drag_release = NULL; /* will fire MouseDragEnd key */
- window_copy_update_cursor(wp->mode, x, y);
- window_copy_start_selection(wp->mode);
- window_copy_redraw_screen(wp->mode);
+ window_copy_update_cursor(wme, x, y);
+ window_copy_start_selection(wme);
+ window_copy_redraw_screen(wme);
}
static void
-window_copy_drag_update(__unused struct client *c, struct mouse_event *m)
+window_copy_drag_update(struct client *c, struct mouse_event *m)
{
struct window_pane *wp;
+ struct window_mode_entry *wme;
struct window_copy_mode_data *data;
u_int x, y, old_cy;
+ if (c == NULL)
+ return;
+
wp = cmd_mouse_pane(m, NULL, NULL);
- if (wp == NULL ||
- wp->mode == NULL ||
- wp->mode->mode != &window_copy_mode)
+ if (wp == NULL)
return;
- data = wp->mode->data;
+ wme = TAILQ_FIRST(&wp->modes);
+ if (wme == NULL || wme->mode != &window_copy_mode)
+ return;
+ data = wme->data;
if (cmd_mouse_at(wp, m, &x, &y, 0) != 0)
return;
old_cy = data->cy;
- window_copy_update_cursor(wp->mode, x, y);
- if (window_copy_update_selection(wp->mode, 1))
- window_copy_redraw_selection(wp->mode, old_cy);
+ window_copy_update_cursor(wme, x, y);
+ if (window_copy_update_selection(wme, 1))
+ window_copy_redraw_selection(wme, old_cy);
}
diff --git a/window.c b/window.c
index fcc01eb7..c1660e78 100644
--- a/window.c
+++ b/window.c
@@ -808,7 +808,7 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
wp->fd = -1;
wp->event = NULL;
- wp->mode = NULL;
+ TAILQ_INIT(&wp->modes);
wp->layout_cell = NULL;
@@ -842,7 +842,7 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
static void
window_pane_destroy(struct window_pane *wp)
{
- window_pane_reset_mode(wp);
+ window_pane_reset_mode_all(wp);
free(wp->searchstr);
if (wp->fd != -1) {
@@ -1060,14 +1060,18 @@ window_pane_error_callback(__unused struct bufferevent *bufev,
void
window_pane_resize(struct window_pane *wp, u_int sx, u_int sy)
{
+ struct window_mode_entry *wme;
+
if (sx == wp->sx && sy == wp->sy)
return;
wp->sx = sx;
wp->sy = sy;
screen_resize(&wp->base, sx, sy, wp->saved_grid == NULL);
- if (wp->mode != NULL && wp->mode->mode->resize != NULL)
- wp->mode->mode->resize(wp->mode, sx, sy);
+
+ wme = TAILQ_FIRST(&wp->modes);
+ if (wme != NULL && wme->mode->resize != NULL)
+ wme->mode->resize(wme, sx, sy);
wp->flags |= PANE_RESIZE;
}
@@ -1221,7 +1225,7 @@ window_pane_mode_timer(__unused int fd, __unused short events, void *arg)
if (wp->modelast < time(NULL) - WINDOW_MODE_TIMEOUT) {
if (ioctl(wp->fd, FIONREAD, &n) == -1 || n > 0)
- window_pane_reset_mode(wp);
+ window_pane_reset_mode_all(wp);
}
}
@@ -1229,43 +1233,66 @@ int
window_pane_set_mode(struct window_pane *wp, const struct window_mode *mode,
struct cmd_find_state *fs, struct args *args)
{
- struct screen *s;
- struct timeval tv = { .tv_sec = 10 };
+ struct timeval tv = { .tv_sec = 10 };
+ struct window_mode_entry *wme;
- if (wp->mode != NULL)
+ if (!TAILQ_EMPTY(&wp->modes) && TAILQ_FIRST(&wp->modes)->mode == mode)
return (1);
- wp->mode = xcalloc(1, sizeof *wp->mode);
- wp->mode->wp = wp;
- wp->mode->mode = mode;
- wp->mode->prefix = 1;
-
wp->modelast = time(NULL);
- evtimer_set(&wp->modetimer, window_pane_mode_timer, wp);
- evtimer_add(&wp->modetimer, &tv);
+ if (TAILQ_EMPTY(&wp->modes)) {
+ evtimer_set(&wp->modetimer, window_pane_mode_timer, wp);
+ evtimer_add(&wp->modetimer, &tv);
+ }
- if ((s = wp->mode->mode->init(wp->mode, fs, args)) != NULL)
- wp->screen = s;
+ TAILQ_FOREACH(wme, &wp->modes, entry) {
+ if (wme->mode == mode)
+ break;
+ }
+ if (wme != NULL)
+ TAILQ_REMOVE(&wp->modes, wme, entry);
+ else {
+ wme = xcalloc(1, sizeof *wme);
+ wme->wp = wp;
+ wme->mode = mode;
+ wme->prefix = 1;
+ wme->screen = wme->mode->init(wme, fs, args);
+ }
+ TAILQ_INSERT_HEAD(&wp->modes, wme, entry);
+
+ wp->screen = wme->screen;
wp->flags |= (PANE_REDRAW|PANE_CHANGED);
server_status_window(wp->window);
notify_pane("pane-mode-changed", wp);
+
return (0);
}
void
window_pane_reset_mode(struct window_pane *wp)
{
- if (wp->mode == NULL)
- return;
+ struct window_mode_entry *wme, *next;
- evtimer_del(&wp->modetimer);
+ if (TAILQ_EMPTY(&wp->modes))
+ return;
- wp->mode->mode->free(wp->mode);
- free(wp->mode);
- wp->mode = NULL;
+ wme = TAILQ_FIRST(&wp->modes);
+ TAILQ_REMOVE(&wp->modes, wme, entry);
+ wme->mode->free(wme);
+ free(wme);
- wp->screen = &wp->base;
+ next = TAILQ_FIRST(&wp->modes);
+ if (next == NULL) {
+ log_debug("%s: no next mode", __func__);
+ evtimer_del(&wp->modetimer);
+ wp->screen = &wp->base;
+ } else {
+ log_debug("%s: next mode is %s", __func__, next->mode->name);
+ wp->screen = next->screen;
+ if (next != NULL && next->mode->resize != NULL)
+ next->mode->resize(next, wp->sx, wp->sy);
+ }
wp->flags |= (PANE_REDRAW|PANE_CHANGED);
server_status_window(wp->window);
@@ -1273,15 +1300,23 @@ window_pane_reset_mode(struct window_pane *wp)
}
void
+window_pane_reset_mode_all(struct window_pane *wp)
+{
+ while (!TAILQ_EMPTY(&wp->modes))
+ window_pane_reset_mode(wp);
+}
+
+void
window_pane_key(struct window_pane *wp, struct client *c, struct session *s,
struct winlink *wl, key_code key, struct mouse_event *m)
{
- struct window_mode_entry *wme = wp->mode;
+ struct window_mode_entry *wme;
struct window_pane *wp2;
if (KEYC_IS_MOUSE(key) && m == NULL)
return;
+ wme = TAILQ_FIRST(&wp->modes);
if (wme != NULL) {
wp->modelast = time(NULL);
if (wme->mode->key != NULL)
@@ -1299,7 +1334,7 @@ window_pane_key(struct window_pane *wp, struct client *c, struct session *s,
if (options_get_number(wp->window->options, "synchronize-panes")) {
TAILQ_FOREACH(wp2, &wp->window->panes, entry) {
if (wp2 != wp &&
- wp2->mode == NULL &&
+ TAILQ_EMPTY(&wp2->modes) &&
wp2->fd != -1 &&
(~wp2->flags & PANE_INPUTOFF) &&
window_pane_visible(wp2))