1
0
mirror of https://github.com/openbsd/src.git synced 2025-01-10 06:47:55 -08:00

Allow multiple modes to be open in a pane. A stack of open modes is kept

and the previous restored when the top is exited. If a mode that is
already on the stack is entered, the existing instance is moved to the
top as the active mode rather than being opened new.
This commit is contained in:
nicm 2019-03-12 11:16:49 +00:00
parent 818e463522
commit 2c8678f77a
15 changed files with 197 additions and 131 deletions

View File

@ -1,4 +1,4 @@
/* $OpenBSD: cfg.c,v 1.65 2019/03/08 10:34:20 nicm Exp $ */
/* $OpenBSD: cfg.c,v 1.66 2019/03/12 11:16:49 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
@ -341,17 +341,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]);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: cmd-capture-pane.c,v 1.45 2019/03/07 20:24:21 nicm Exp $ */
/* $OpenBSD: cmd-capture-pane.c,v 1.46 2019/03/12 11:16:49 nicm Exp $ */
/*
* Copyright (c) 2009 Jonathan Alvarado <radobobo@users.sourceforge.net>
@ -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);
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: cmd-copy-mode.c,v 1.36 2019/03/08 10:34:20 nicm Exp $ */
/* $OpenBSD: cmd-copy-mode.c,v 1.37 2019/03/12 11:16:49 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@ -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);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: cmd-queue.c,v 1.60 2019/03/08 10:34:20 nicm Exp $ */
/* $OpenBSD: cmd-queue.c,v 1.61 2019/03/12 11:16:50 nicm Exp $ */
/*
* Copyright (c) 2013 Nicholas Marriott <nicholas.marriott@gmail.com>
@ -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);
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: cmd-respawn-pane.c,v 1.26 2017/07/21 09:17:19 nicm Exp $ */
/* $OpenBSD: cmd-respawn-pane.c,v 1.27 2019/03/12 11:16:50 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
@ -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);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: cmd-respawn-window.c,v 1.36 2017/07/21 09:17:19 nicm Exp $ */
/* $OpenBSD: cmd-respawn-window.c,v 1.37 2019/03/12 11:16:50 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
@ -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);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: cmd-run-shell.c,v 1.57 2019/03/08 10:34:20 nicm Exp $ */
/* $OpenBSD: cmd-run-shell.c,v 1.58 2019/03/12 11:16:50 nicm Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@ -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);
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: cmd-send-keys.c,v 1.45 2019/03/07 20:24:21 nicm Exp $ */
/* $OpenBSD: cmd-send-keys.c,v 1.46 2019/03/12 11:16:50 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
@ -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')) {

View File

@ -1,4 +1,4 @@
/* $OpenBSD: format.c,v 1.167 2019/03/07 20:24:21 nicm Exp $ */
/* $OpenBSD: format.c,v 1.168 2019/03/12 11:16:50 nicm Exp $ */
/*
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
@ -617,6 +617,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)
@ -1495,10 +1511,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;
@ -1533,9 +1550,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"));
@ -1552,9 +1573,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);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: input.c,v 1.141 2019/03/12 07:39:27 nicm Exp $ */
/* $OpenBSD: input.c,v 1.142 2019/03/12 11:16:50 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@ -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);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: server-client.c,v 1.266 2019/03/07 20:24:21 nicm Exp $ */
/* $OpenBSD: server-client.c,v 1.267 2019/03/12 11:16:50 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
@ -921,18 +921,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)
@ -1009,11 +1009,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;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: tmux.h,v 1.857 2019/03/12 07:39:27 nicm Exp $ */
/* $OpenBSD: tmux.h,v 1.858 2019/03/12 11:16:50 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@ -722,7 +722,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. */
@ -768,6 +771,7 @@ struct window_pane {
int fd;
struct bufferevent *event;
u_int disabled;
struct event resize_timer;
@ -793,7 +797,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;
@ -2208,6 +2212,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 *);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: window-clock.c,v 1.26 2019/03/07 20:24:21 nicm Exp $ */
/* $OpenBSD: window-clock.c,v 1.27 2019/03/12 11:16:50 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
@ -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 *

View File

@ -1,4 +1,4 @@
/* $OpenBSD: window-copy.c,v 1.210 2019/03/08 10:34:20 nicm Exp $ */
/* $OpenBSD: window-copy.c,v 1.211 2019/03/12 11:16:50 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@ -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;
wp = cmd_mouse_pane(m, NULL, NULL);
if (wp == NULL ||
wp->mode == NULL ||
wp->mode->mode != &window_copy_mode)
if (c == NULL)
return;
data = wp->mode->data;
wp = cmd_mouse_pane(m, NULL, NULL);
if (wp == NULL)
return;
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);
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: window.c,v 1.217 2019/03/07 20:24:21 nicm Exp $ */
/* $OpenBSD: window.c,v 1.218 2019/03/12 11:16:50 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@ -810,7 +810,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;
@ -844,7 +844,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) {
@ -1047,14 +1047,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;
}
@ -1208,7 +1212,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);
}
}
@ -1216,59 +1220,90 @@ 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)
struct window_mode_entry *wme, *next;
if (TAILQ_EMPTY(&wp->modes))
return;
evtimer_del(&wp->modetimer);
wme = TAILQ_FIRST(&wp->modes);
TAILQ_REMOVE(&wp->modes, wme, entry);
wme->mode->free(wme);
free(wme);
wp->mode->mode->free(wp->mode);
free(wp->mode);
wp->mode = NULL;
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);
notify_pane("pane-mode-changed", 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)
@ -1286,7 +1321,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))