mirror of https://github.com/tmux/tmux.git
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.pull/1628/head
parent
ff4c80d53d
commit
3f6bfbaf2b
6
cfg.c
6
cfg.c
|
@ -342,16 +342,16 @@ void
|
||||||
cfg_show_causes(struct session *s)
|
cfg_show_causes(struct session *s)
|
||||||
{
|
{
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
|
struct window_mode_entry *wme;
|
||||||
u_int i;
|
u_int i;
|
||||||
|
|
||||||
if (s == NULL || cfg_ncauses == 0)
|
if (s == NULL || cfg_ncauses == 0)
|
||||||
return;
|
return;
|
||||||
wp = s->curw->window->active;
|
wp = s->curw->window->active;
|
||||||
|
|
||||||
if (wp->mode == NULL || wp->mode->mode != &window_view_mode) {
|
wme = TAILQ_FIRST(&wp->modes);
|
||||||
window_pane_reset_mode(wp);
|
if (wme == NULL || wme->mode != &window_view_mode)
|
||||||
window_pane_set_mode(wp, &window_view_mode, NULL, NULL);
|
window_pane_set_mode(wp, &window_view_mode, NULL, NULL);
|
||||||
}
|
|
||||||
for (i = 0; i < cfg_ncauses; i++) {
|
for (i = 0; i < cfg_ncauses; i++) {
|
||||||
window_copy_add(wp, "%s", cfg_causes[i]);
|
window_copy_add(wp, "%s", cfg_causes[i]);
|
||||||
free(cfg_causes[i]);
|
free(cfg_causes[i]);
|
||||||
|
|
|
@ -199,8 +199,7 @@ cmd_capture_pane_exec(struct cmd *self, struct cmdq_item *item)
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
if (self->entry == &cmd_clear_history_entry) {
|
if (self->entry == &cmd_clear_history_entry) {
|
||||||
if (wp->mode != NULL && wp->mode->mode == &window_copy_mode)
|
window_pane_reset_mode_all(wp);
|
||||||
window_pane_reset_mode(wp);
|
|
||||||
grid_clear_history(wp->base.grid);
|
grid_clear_history(wp->base.grid);
|
||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,6 @@ cmd_copy_mode_exec(struct cmd *self, struct cmdq_item *item)
|
||||||
struct client *c = item->client;
|
struct client *c = item->client;
|
||||||
struct session *s;
|
struct session *s;
|
||||||
struct window_pane *wp = item->target.wp;
|
struct window_pane *wp = item->target.wp;
|
||||||
int flag;
|
|
||||||
|
|
||||||
if (args_has(args, 'M')) {
|
if (args_has(args, 'M')) {
|
||||||
if ((wp = cmd_mouse_pane(&shared->mouse, &s, NULL)) == NULL)
|
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);
|
return (CMD_RETURN_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wp->mode == NULL || wp->mode->mode != &window_copy_mode) {
|
if (window_pane_set_mode(wp, &window_copy_mode, NULL, args) != 0)
|
||||||
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);
|
return (CMD_RETURN_NORMAL);
|
||||||
|
if (args_has(args, 'M'))
|
||||||
window_copy_start_drag(c, &shared->mouse);
|
window_copy_start_drag(c, &shared->mouse);
|
||||||
}
|
|
||||||
if (args_has(self->args, 'u'))
|
if (args_has(self->args, 'u'))
|
||||||
window_copy_pageup(wp, 0);
|
window_copy_pageup(wp, 0);
|
||||||
|
|
||||||
|
|
|
@ -406,6 +406,7 @@ cmdq_print(struct cmdq_item *item, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
struct client *c = item->client;
|
struct client *c = item->client;
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
|
struct window_mode_entry *wme;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
char *tmp, *msg;
|
char *tmp, *msg;
|
||||||
|
|
||||||
|
@ -426,10 +427,9 @@ cmdq_print(struct cmdq_item *item, const char *fmt, ...)
|
||||||
server_client_push_stdout(c);
|
server_client_push_stdout(c);
|
||||||
} else {
|
} else {
|
||||||
wp = c->session->curw->window->active;
|
wp = c->session->curw->window->active;
|
||||||
if (wp->mode == NULL || wp->mode->mode != &window_view_mode) {
|
wme = TAILQ_FIRST(&wp->modes);
|
||||||
window_pane_reset_mode(wp);
|
if (wme == NULL || wme->mode != &window_view_mode)
|
||||||
window_pane_set_mode(wp, &window_view_mode, NULL, NULL);
|
window_pane_set_mode(wp, &window_view_mode, NULL, NULL);
|
||||||
}
|
|
||||||
window_copy_vadd(wp, fmt, ap);
|
window_copy_vadd(wp, fmt, ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmdq_item *item)
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
window_pane_reset_mode(wp);
|
window_pane_reset_mode_all(wp);
|
||||||
screen_reinit(&wp->base);
|
screen_reinit(&wp->base);
|
||||||
input_init(wp);
|
input_init(wp);
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,7 @@ cmd_respawn_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||||
free(cwd);
|
free(cwd);
|
||||||
|
|
||||||
layout_init(w, wp);
|
layout_init(w, wp);
|
||||||
window_pane_reset_mode(wp);
|
window_pane_reset_mode_all(wp);
|
||||||
screen_reinit(&wp->base);
|
screen_reinit(&wp->base);
|
||||||
input_init(wp);
|
input_init(wp);
|
||||||
window_set_active_pane(w, wp);
|
window_set_active_pane(w, wp);
|
||||||
|
|
|
@ -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 cmd_run_shell_data *cdata = job_get_data(job);
|
||||||
struct window_pane *wp = NULL;
|
struct window_pane *wp = NULL;
|
||||||
struct cmd_find_state fs;
|
struct cmd_find_state fs;
|
||||||
|
struct window_mode_entry *wme;
|
||||||
|
|
||||||
if (cdata->wp_id != -1)
|
if (cdata->wp_id != -1)
|
||||||
wp = window_pane_find_by_id(cdata->wp_id);
|
wp = window_pane_find_by_id(cdata->wp_id);
|
||||||
|
@ -75,10 +76,9 @@ cmd_run_shell_print(struct job *job, const char *msg)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wp->mode == NULL || wp->mode->mode != &window_view_mode) {
|
wme = TAILQ_FIRST(&wp->modes);
|
||||||
window_pane_reset_mode(wp);
|
if (wme == NULL || wme->mode != &window_view_mode)
|
||||||
window_pane_set_mode(wp, &window_view_mode, NULL, NULL);
|
window_pane_set_mode(wp, &window_view_mode, NULL, NULL);
|
||||||
}
|
|
||||||
window_copy_add(wp, "%s", msg);
|
window_copy_add(wp, "%s", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 window_pane *wp = item->target.wp;
|
||||||
struct session *s = item->target.s;
|
struct session *s = item->target.s;
|
||||||
struct winlink *wl = item->target.wl;
|
struct winlink *wl = item->target.wl;
|
||||||
struct window_mode_entry *wme = wp->mode;
|
struct window_mode_entry *wme;
|
||||||
struct key_table *table;
|
struct key_table *table;
|
||||||
struct key_binding *bd;
|
struct key_binding *bd;
|
||||||
|
|
||||||
|
wme = TAILQ_FIRST(&wp->modes);
|
||||||
if (wme == NULL || wme->mode->key_table == NULL) {
|
if (wme == NULL || wme->mode->key_table == NULL) {
|
||||||
if (options_get_number(wp->window->options, "xterm-keys"))
|
if (options_get_number(wp->window->options, "xterm-keys"))
|
||||||
key |= KEYC_XTERM;
|
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 session *s = item->target.s;
|
||||||
struct winlink *wl = item->target.wl;
|
struct winlink *wl = item->target.wl;
|
||||||
struct mouse_event *m = &item->shared->mouse;
|
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;
|
struct utf8_data *ud, *uc;
|
||||||
wchar_t wc;
|
wchar_t wc;
|
||||||
int i, literal;
|
int i, literal;
|
||||||
|
@ -105,9 +106,14 @@ cmd_send_keys_exec(struct cmd *self, struct cmdq_item *item)
|
||||||
free(cause);
|
free(cause);
|
||||||
return (CMD_RETURN_ERROR);
|
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;
|
wme->prefix = np;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (args_has(args, 'X')) {
|
if (args_has(args, 'X')) {
|
||||||
if (wme == NULL || wme->mode->command == NULL) {
|
if (wme == NULL || wme->mode->command == NULL) {
|
||||||
|
|
30
format.c
30
format.c
|
@ -617,6 +617,22 @@ format_cb_session_group_list(struct format_tree *ft, struct format_entry *fe)
|
||||||
evbuffer_free(buffer);
|
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. */
|
/* Merge a format tree. */
|
||||||
static void
|
static void
|
||||||
format_merge(struct format_tree *ft, struct format_tree *from)
|
format_merge(struct format_tree *ft, struct format_tree *from)
|
||||||
|
@ -1499,6 +1515,7 @@ format_defaults_pane(struct format_tree *ft, struct window_pane *wp)
|
||||||
struct grid *gd = wp->base.grid;
|
struct grid *gd = wp->base.grid;
|
||||||
int status = wp->status;
|
int status = wp->status;
|
||||||
u_int idx;
|
u_int idx;
|
||||||
|
struct window_mode_entry *wme;
|
||||||
|
|
||||||
if (ft->w == NULL)
|
if (ft->w == NULL)
|
||||||
ft->w = w;
|
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_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_at_bottom", "%d", wp->yoff + wp->sy == w->sy);
|
||||||
|
|
||||||
format_add(ft, "pane_in_mode", "%d", wp->screen != &wp->base);
|
wme = TAILQ_FIRST(&wp->modes);
|
||||||
if (wp->mode != NULL)
|
if (wme != NULL) {
|
||||||
format_add(ft, "pane_mode", "%s", wp->mode->mode->name);
|
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",
|
format_add(ft, "pane_synchronized", "%d",
|
||||||
!!options_get_number(w->options, "synchronize-panes"));
|
!!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_upper", "%u", wp->base.rupper);
|
||||||
format_add(ft, "scroll_region_lower", "%u", wp->base.rlower);
|
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_on", "%d", wp->saved_grid ? 1 : 0);
|
||||||
format_add(ft, "alternate_saved_x", "%u", wp->saved_cx);
|
format_add(ft, "alternate_saved_x", "%u", wp->saved_cx);
|
||||||
format_add(ft, "alternate_saved_y", "%u", wp->saved_cy);
|
format_add(ft, "alternate_saved_y", "%u", wp->saved_cy);
|
||||||
|
|
4
input.c
4
input.c
|
@ -805,7 +805,7 @@ input_reset(struct window_pane *wp, int clear)
|
||||||
input_reset_cell(ictx);
|
input_reset_cell(ictx);
|
||||||
|
|
||||||
if (clear) {
|
if (clear) {
|
||||||
if (wp->mode == NULL)
|
if (TAILQ_EMPTY(&wp->modes))
|
||||||
screen_write_start(&ictx->ctx, wp, &wp->base);
|
screen_write_start(&ictx->ctx, wp, &wp->base);
|
||||||
else
|
else
|
||||||
screen_write_start(&ictx->ctx, NULL, &wp->base);
|
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
|
* Open the screen. Use NULL wp if there is a mode set as don't want to
|
||||||
* update the tty.
|
* update the tty.
|
||||||
*/
|
*/
|
||||||
if (wp->mode == NULL)
|
if (TAILQ_EMPTY(&wp->modes))
|
||||||
screen_write_start(&ictx->ctx, wp, &wp->base);
|
screen_write_start(&ictx->ctx, wp, &wp->base);
|
||||||
else
|
else
|
||||||
screen_write_start(&ictx->ctx, NULL, &wp->base);
|
screen_write_start(&ictx->ctx, NULL, &wp->base);
|
||||||
|
|
|
@ -926,9 +926,9 @@ server_client_handle_key(struct client *c, key_code key)
|
||||||
struct winlink *wl;
|
struct winlink *wl;
|
||||||
struct window *w;
|
struct window *w;
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
|
struct window_mode_entry *wme;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
struct key_table *table, *first;
|
struct key_table *table, *first;
|
||||||
const char *tablename;
|
|
||||||
struct key_binding *bd;
|
struct key_binding *bd;
|
||||||
int xtimeout, flags;
|
int xtimeout, flags;
|
||||||
struct cmd_find_state fs;
|
struct cmd_find_state fs;
|
||||||
|
@ -1009,11 +1009,9 @@ server_client_handle_key(struct client *c, key_code key)
|
||||||
*/
|
*/
|
||||||
if (server_client_is_default_key_table(c, c->keytable) &&
|
if (server_client_is_default_key_table(c, c->keytable) &&
|
||||||
wp != NULL &&
|
wp != NULL &&
|
||||||
wp->mode != NULL &&
|
(wme = TAILQ_FIRST(&wp->modes)) != NULL &&
|
||||||
wp->mode->mode->key_table != NULL) {
|
wme->mode->key_table != NULL)
|
||||||
tablename = wp->mode->mode->key_table(wp->mode);
|
table = key_bindings_get_table(wme->mode->key_table(wme), 1);
|
||||||
table = key_bindings_get_table(tablename, 1);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
table = c->keytable;
|
table = c->keytable;
|
||||||
first = table;
|
first = table;
|
||||||
|
|
7
tmux.h
7
tmux.h
|
@ -722,7 +722,10 @@ struct window_mode_entry {
|
||||||
const struct window_mode *mode;
|
const struct window_mode *mode;
|
||||||
void *data;
|
void *data;
|
||||||
|
|
||||||
|
struct screen *screen;
|
||||||
u_int prefix;
|
u_int prefix;
|
||||||
|
|
||||||
|
TAILQ_ENTRY (window_mode_entry) entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Child window structure. */
|
/* Child window structure. */
|
||||||
|
@ -768,6 +771,7 @@ struct window_pane {
|
||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
struct bufferevent *event;
|
struct bufferevent *event;
|
||||||
|
u_int disabled;
|
||||||
|
|
||||||
struct event resize_timer;
|
struct event resize_timer;
|
||||||
|
|
||||||
|
@ -793,7 +797,7 @@ struct window_pane {
|
||||||
struct grid *saved_grid;
|
struct grid *saved_grid;
|
||||||
struct grid_cell saved_cell;
|
struct grid_cell saved_cell;
|
||||||
|
|
||||||
struct window_mode_entry *mode;
|
TAILQ_HEAD (, window_mode_entry) modes;
|
||||||
struct event modetimer;
|
struct event modetimer;
|
||||||
time_t modelast;
|
time_t modelast;
|
||||||
char *searchstr;
|
char *searchstr;
|
||||||
|
@ -2208,6 +2212,7 @@ int window_pane_set_mode(struct window_pane *,
|
||||||
const struct window_mode *, struct cmd_find_state *,
|
const struct window_mode *, struct cmd_find_state *,
|
||||||
struct args *);
|
struct args *);
|
||||||
void window_pane_reset_mode(struct window_pane *);
|
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 *,
|
void window_pane_key(struct window_pane *, struct client *,
|
||||||
struct session *, struct winlink *, key_code,
|
struct session *, struct winlink *, key_code,
|
||||||
struct mouse_event *);
|
struct mouse_event *);
|
||||||
|
|
|
@ -136,6 +136,9 @@ window_clock_timer_callback(__unused int fd, __unused short events, void *arg)
|
||||||
evtimer_del(&data->timer);
|
evtimer_del(&data->timer);
|
||||||
evtimer_add(&data->timer, &tv);
|
evtimer_add(&data->timer, &tv);
|
||||||
|
|
||||||
|
if (TAILQ_FIRST(&wp->modes) != wme)
|
||||||
|
return;
|
||||||
|
|
||||||
t = time(NULL);
|
t = time(NULL);
|
||||||
gmtime_r(&t, &now);
|
gmtime_r(&t, &now);
|
||||||
gmtime_r(&data->tim, &then);
|
gmtime_r(&data->tim, &then);
|
||||||
|
@ -144,7 +147,7 @@ window_clock_timer_callback(__unused int fd, __unused short events, void *arg)
|
||||||
data->tim = t;
|
data->tim = t;
|
||||||
|
|
||||||
window_clock_draw_screen(wme);
|
window_clock_draw_screen(wme);
|
||||||
server_redraw_window(wp->window);
|
wp->flags |= PANE_REDRAW;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct screen *
|
static struct screen *
|
||||||
|
|
|
@ -258,7 +258,7 @@ window_copy_init(struct window_mode_entry *wme,
|
||||||
|
|
||||||
data = window_copy_common_init(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);
|
bufferevent_disable(wp->event, EV_READ|EV_WRITE);
|
||||||
|
|
||||||
data->backing = &wp->base;
|
data->backing = &wp->base;
|
||||||
|
@ -302,7 +302,7 @@ window_copy_free(struct window_mode_entry *wme)
|
||||||
struct window_pane *wp = wme->wp;
|
struct window_pane *wp = wme->wp;
|
||||||
struct window_copy_mode_data *data = wme->data;
|
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);
|
bufferevent_enable(wp->event, EV_READ|EV_WRITE);
|
||||||
|
|
||||||
free(data->searchmark);
|
free(data->searchmark);
|
||||||
|
@ -330,7 +330,7 @@ window_copy_add(struct window_pane *wp, const char *fmt, ...)
|
||||||
void
|
void
|
||||||
window_copy_vadd(struct window_pane *wp, const char *fmt, va_list ap)
|
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 window_copy_mode_data *data = wme->data;
|
||||||
struct screen *backing = data->backing;
|
struct screen *backing = data->backing;
|
||||||
struct screen_write_ctx back_ctx, ctx;
|
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
|
void
|
||||||
window_copy_pageup(struct window_pane *wp, int half_page)
|
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
|
static void
|
||||||
|
@ -2541,33 +2541,37 @@ static void
|
||||||
window_copy_move_mouse(struct mouse_event *m)
|
window_copy_move_mouse(struct mouse_event *m)
|
||||||
{
|
{
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
|
struct window_mode_entry *wme;
|
||||||
u_int x, y;
|
u_int x, y;
|
||||||
|
|
||||||
wp = cmd_mouse_pane(m, NULL, NULL);
|
wp = cmd_mouse_pane(m, NULL, NULL);
|
||||||
if (wp == NULL ||
|
if (wp == NULL)
|
||||||
wp->mode == NULL ||
|
return;
|
||||||
wp->mode->mode != &window_copy_mode)
|
wme = TAILQ_FIRST(&wp->modes);
|
||||||
|
if (wme == NULL || wme->mode != &window_copy_mode)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (cmd_mouse_at(wp, m, &x, &y, 0) != 0)
|
if (cmd_mouse_at(wp, m, &x, &y, 0) != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
window_copy_update_cursor(wp->mode, x, y);
|
window_copy_update_cursor(wme, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_copy_start_drag(struct client *c, struct mouse_event *m)
|
window_copy_start_drag(struct client *c, struct mouse_event *m)
|
||||||
{
|
{
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
|
struct window_mode_entry *wme;
|
||||||
u_int x, y;
|
u_int x, y;
|
||||||
|
|
||||||
if (c == NULL)
|
if (c == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wp = cmd_mouse_pane(m, NULL, NULL);
|
wp = cmd_mouse_pane(m, NULL, NULL);
|
||||||
if (wp == NULL ||
|
if (wp == NULL)
|
||||||
wp->mode == NULL ||
|
return;
|
||||||
wp->mode->mode != &window_copy_mode)
|
wme = TAILQ_FIRST(&wp->modes);
|
||||||
|
if (wme == NULL || wme->mode != &window_copy_mode)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (cmd_mouse_at(wp, m, &x, &y, 1) != 0)
|
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_update = window_copy_drag_update;
|
||||||
c->tty.mouse_drag_release = NULL; /* will fire MouseDragEnd key */
|
c->tty.mouse_drag_release = NULL; /* will fire MouseDragEnd key */
|
||||||
|
|
||||||
window_copy_update_cursor(wp->mode, x, y);
|
window_copy_update_cursor(wme, x, y);
|
||||||
window_copy_start_selection(wp->mode);
|
window_copy_start_selection(wme);
|
||||||
window_copy_redraw_screen(wp->mode);
|
window_copy_redraw_screen(wme);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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_pane *wp;
|
||||||
|
struct window_mode_entry *wme;
|
||||||
struct window_copy_mode_data *data;
|
struct window_copy_mode_data *data;
|
||||||
u_int x, y, old_cy;
|
u_int x, y, old_cy;
|
||||||
|
|
||||||
wp = cmd_mouse_pane(m, NULL, NULL);
|
if (c == NULL)
|
||||||
if (wp == NULL ||
|
|
||||||
wp->mode == NULL ||
|
|
||||||
wp->mode->mode != &window_copy_mode)
|
|
||||||
return;
|
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)
|
if (cmd_mouse_at(wp, m, &x, &y, 0) != 0)
|
||||||
return;
|
return;
|
||||||
old_cy = data->cy;
|
old_cy = data->cy;
|
||||||
|
|
||||||
window_copy_update_cursor(wp->mode, x, y);
|
window_copy_update_cursor(wme, x, y);
|
||||||
if (window_copy_update_selection(wp->mode, 1))
|
if (window_copy_update_selection(wme, 1))
|
||||||
window_copy_redraw_selection(wp->mode, old_cy);
|
window_copy_redraw_selection(wme, old_cy);
|
||||||
}
|
}
|
||||||
|
|
79
window.c
79
window.c
|
@ -810,7 +810,7 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
|
||||||
wp->fd = -1;
|
wp->fd = -1;
|
||||||
wp->event = NULL;
|
wp->event = NULL;
|
||||||
|
|
||||||
wp->mode = NULL;
|
TAILQ_INIT(&wp->modes);
|
||||||
|
|
||||||
wp->layout_cell = NULL;
|
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
|
static void
|
||||||
window_pane_destroy(struct window_pane *wp)
|
window_pane_destroy(struct window_pane *wp)
|
||||||
{
|
{
|
||||||
window_pane_reset_mode(wp);
|
window_pane_reset_mode_all(wp);
|
||||||
free(wp->searchstr);
|
free(wp->searchstr);
|
||||||
|
|
||||||
if (wp->fd != -1) {
|
if (wp->fd != -1) {
|
||||||
|
@ -1047,14 +1047,18 @@ window_pane_error_callback(__unused struct bufferevent *bufev,
|
||||||
void
|
void
|
||||||
window_pane_resize(struct window_pane *wp, u_int sx, u_int sy)
|
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)
|
if (sx == wp->sx && sy == wp->sy)
|
||||||
return;
|
return;
|
||||||
wp->sx = sx;
|
wp->sx = sx;
|
||||||
wp->sy = sy;
|
wp->sy = sy;
|
||||||
|
|
||||||
screen_resize(&wp->base, sx, sy, wp->saved_grid == NULL);
|
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;
|
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 (wp->modelast < time(NULL) - WINDOW_MODE_TIMEOUT) {
|
||||||
if (ioctl(wp->fd, FIONREAD, &n) == -1 || n > 0)
|
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,
|
window_pane_set_mode(struct window_pane *wp, const struct window_mode *mode,
|
||||||
struct cmd_find_state *fs, struct args *args)
|
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);
|
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);
|
wp->modelast = time(NULL);
|
||||||
|
if (TAILQ_EMPTY(&wp->modes)) {
|
||||||
evtimer_set(&wp->modetimer, window_pane_mode_timer, wp);
|
evtimer_set(&wp->modetimer, window_pane_mode_timer, wp);
|
||||||
evtimer_add(&wp->modetimer, &tv);
|
evtimer_add(&wp->modetimer, &tv);
|
||||||
|
}
|
||||||
|
|
||||||
if ((s = wp->mode->mode->init(wp->mode, fs, args)) != NULL)
|
TAILQ_FOREACH(wme, &wp->modes, entry) {
|
||||||
wp->screen = s;
|
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);
|
wp->flags |= (PANE_REDRAW|PANE_CHANGED);
|
||||||
|
|
||||||
server_status_window(wp->window);
|
server_status_window(wp->window);
|
||||||
notify_pane("pane-mode-changed", wp);
|
notify_pane("pane-mode-changed", wp);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_pane_reset_mode(struct window_pane *wp)
|
window_pane_reset_mode(struct window_pane *wp)
|
||||||
{
|
{
|
||||||
if (wp->mode == NULL)
|
struct window_mode_entry *wme, *next;
|
||||||
|
|
||||||
|
if (TAILQ_EMPTY(&wp->modes))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
wme = TAILQ_FIRST(&wp->modes);
|
||||||
|
TAILQ_REMOVE(&wp->modes, wme, entry);
|
||||||
|
wme->mode->free(wme);
|
||||||
|
free(wme);
|
||||||
|
|
||||||
|
next = TAILQ_FIRST(&wp->modes);
|
||||||
|
if (next == NULL) {
|
||||||
|
log_debug("%s: no next mode", __func__);
|
||||||
evtimer_del(&wp->modetimer);
|
evtimer_del(&wp->modetimer);
|
||||||
|
|
||||||
wp->mode->mode->free(wp->mode);
|
|
||||||
free(wp->mode);
|
|
||||||
wp->mode = NULL;
|
|
||||||
|
|
||||||
wp->screen = &wp->base;
|
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);
|
wp->flags |= (PANE_REDRAW|PANE_CHANGED);
|
||||||
|
|
||||||
server_status_window(wp->window);
|
server_status_window(wp->window);
|
||||||
notify_pane("pane-mode-changed", wp);
|
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
|
void
|
||||||
window_pane_key(struct window_pane *wp, struct client *c, struct session *s,
|
window_pane_key(struct window_pane *wp, struct client *c, struct session *s,
|
||||||
struct winlink *wl, key_code key, struct mouse_event *m)
|
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;
|
struct window_pane *wp2;
|
||||||
|
|
||||||
if (KEYC_IS_MOUSE(key) && m == NULL)
|
if (KEYC_IS_MOUSE(key) && m == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
wme = TAILQ_FIRST(&wp->modes);
|
||||||
if (wme != NULL) {
|
if (wme != NULL) {
|
||||||
wp->modelast = time(NULL);
|
wp->modelast = time(NULL);
|
||||||
if (wme->mode->key != 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")) {
|
if (options_get_number(wp->window->options, "synchronize-panes")) {
|
||||||
TAILQ_FOREACH(wp2, &wp->window->panes, entry) {
|
TAILQ_FOREACH(wp2, &wp->window->panes, entry) {
|
||||||
if (wp2 != wp &&
|
if (wp2 != wp &&
|
||||||
wp2->mode == NULL &&
|
TAILQ_EMPTY(&wp2->modes) &&
|
||||||
wp2->fd != -1 &&
|
wp2->fd != -1 &&
|
||||||
(~wp2->flags & PANE_INPUTOFF) &&
|
(~wp2->flags & PANE_INPUTOFF) &&
|
||||||
window_pane_visible(wp2))
|
window_pane_visible(wp2))
|
||||||
|
|
Loading…
Reference in New Issue