mirror of
https://github.com/tmux/tmux.git
synced 2025-10-07 02:16:32 +00: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:
10
cfg.c
10
cfg.c
@@ -341,17 +341,17 @@ cfg_print_causes(struct cmdq_item *item)
|
|||||||
void
|
void
|
||||||
cfg_show_causes(struct session *s)
|
cfg_show_causes(struct session *s)
|
||||||
{
|
{
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
u_int i;
|
struct window_mode_entry *wme;
|
||||||
|
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);
|
return (CMD_RETURN_NORMAL);
|
||||||
if (flag != 0)
|
if (args_has(args, 'M'))
|
||||||
return (CMD_RETURN_NORMAL);
|
|
||||||
}
|
|
||||||
if (args_has(args, 'M')) {
|
|
||||||
if (wp->mode != NULL && wp->mode->mode != &window_copy_mode)
|
|
||||||
return (CMD_RETURN_NORMAL);
|
|
||||||
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);
|
||||||
|
|
||||||
|
14
cmd-queue.c
14
cmd-queue.c
@@ -404,10 +404,11 @@ cmdq_guard(struct cmdq_item *item, const char *guard, int flags)
|
|||||||
void
|
void
|
||||||
cmdq_print(struct cmdq_item *item, const char *fmt, ...)
|
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;
|
||||||
va_list ap;
|
struct window_mode_entry *wme;
|
||||||
char *tmp, *msg;
|
va_list ap;
|
||||||
|
char *tmp, *msg;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
|
|
||||||
@@ -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,8 +106,13 @@ 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')) {
|
||||||
|
38
format.c
38
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)
|
||||||
@@ -1495,10 +1511,11 @@ format_defaults_winlink(struct format_tree *ft, struct winlink *wl)
|
|||||||
void
|
void
|
||||||
format_defaults_pane(struct format_tree *ft, struct window_pane *wp)
|
format_defaults_pane(struct format_tree *ft, struct window_pane *wp)
|
||||||
{
|
{
|
||||||
struct window *w = wp->window;
|
struct window *w = wp->window;
|
||||||
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);
|
||||||
|
@@ -921,18 +921,18 @@ server_client_assume_paste(struct session *s)
|
|||||||
void
|
void
|
||||||
server_client_handle_key(struct client *c, key_code key)
|
server_client_handle_key(struct client *c, key_code key)
|
||||||
{
|
{
|
||||||
struct mouse_event *m = &c->tty.mouse;
|
struct mouse_event *m = &c->tty.mouse;
|
||||||
struct session *s = c->session;
|
struct session *s = c->session;
|
||||||
struct winlink *wl;
|
struct winlink *wl;
|
||||||
struct window *w;
|
struct window *w;
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
struct timeval tv;
|
struct window_mode_entry *wme;
|
||||||
struct key_table *table, *first;
|
struct timeval tv;
|
||||||
const char *tablename;
|
struct key_table *table, *first;
|
||||||
struct key_binding *bd;
|
struct key_binding *bd;
|
||||||
int xtimeout, flags;
|
int xtimeout, flags;
|
||||||
struct cmd_find_state fs;
|
struct cmd_find_state fs;
|
||||||
key_code key0;
|
key_code key0;
|
||||||
|
|
||||||
/* Check the client is good to accept input. */
|
/* Check the client is good to accept input. */
|
||||||
if (s == NULL || (c->flags & (CLIENT_DEAD|CLIENT_SUSPENDED)) != 0)
|
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) &&
|
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
|
||||||
@@ -2540,34 +2540,38 @@ window_copy_rectangle_toggle(struct window_mode_entry *wme)
|
|||||||
static void
|
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;
|
||||||
u_int x, y;
|
struct window_mode_entry *wme;
|
||||||
|
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;
|
||||||
u_int x, y;
|
struct window_mode_entry *wme;
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
87
window.c
87
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);
|
||||||
evtimer_set(&wp->modetimer, window_pane_mode_timer, wp);
|
if (TAILQ_EMPTY(&wp->modes)) {
|
||||||
evtimer_add(&wp->modetimer, &tv);
|
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)
|
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;
|
||||||
|
|
||||||
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);
|
next = TAILQ_FIRST(&wp->modes);
|
||||||
free(wp->mode);
|
if (next == NULL) {
|
||||||
wp->mode = NULL;
|
log_debug("%s: no next mode", __func__);
|
||||||
|
evtimer_del(&wp->modetimer);
|
||||||
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))
|
||||||
|
Reference in New Issue
Block a user