From 0e2c9d0f0effc1d2ee144f302bcdacd2fbafa082 Mon Sep 17 00:00:00 2001 From: nicm Date: Sat, 22 Apr 2017 08:56:24 +0000 Subject: [PATCH] Mouse bindings and hooks set up an initial current state when running a command. This is used for the session, window and pane for all commands in the command sequence if there is no -t or -s. However, using it for all commands in the command sequence means that if the active pane or current session is changed, subsequent commands still use the previous state. So make commands which explicitly change the current state (such as neww and selectp) update it themselves for later commands. Commands which may invalidate the state (like killp) are already OK because an invalid state will be ignored. Also fill in the current state for all key bindings rather than just the mouse, so that any omissions are easier to spot. --- usr.bin/tmux/cmd-attach-session.c | 7 ++++++- usr.bin/tmux/cmd-break-pane.c | 7 +++++-- usr.bin/tmux/cmd-find-window.c | 7 +++++-- usr.bin/tmux/cmd-join-pane.c | 4 +++- usr.bin/tmux/cmd-new-session.c | 6 ++++-- usr.bin/tmux/cmd-new-window.c | 4 +++- usr.bin/tmux/cmd-select-pane.c | 6 ++++-- usr.bin/tmux/cmd-select-window.c | 17 +++++++++++------ usr.bin/tmux/cmd-split-window.c | 4 +++- usr.bin/tmux/cmd-switch-client.c | 3 ++- usr.bin/tmux/server-client.c | 18 ++++++------------ 11 files changed, 52 insertions(+), 31 deletions(-) diff --git a/usr.bin/tmux/cmd-attach-session.c b/usr.bin/tmux/cmd-attach-session.c index d9af1a2cd15..0ba69f49c65 100644 --- a/usr.bin/tmux/cmd-attach-session.c +++ b/usr.bin/tmux/cmd-attach-session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-attach-session.c,v 1.71 2017/04/21 14:01:19 nicm Exp $ */ +/* $OpenBSD: cmd-attach-session.c,v 1.72 2017/04/22 08:56:24 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -50,6 +50,7 @@ enum cmd_retval cmd_attach_session(struct cmdq_item *item, int dflag, int rflag, const char *cflag, int Eflag) { + struct cmd_find_state *current = &item->shared->current; struct session *s = item->state.tflag.s; struct client *c = item->client, *c_loop; struct winlink *wl = item->state.tflag.wl; @@ -73,6 +74,10 @@ cmd_attach_session(struct cmdq_item *item, int dflag, int rflag, if (wp != NULL) window_set_active_pane(wp->window, wp); session_set_current(s, wl); + if (wp != NULL) + cmd_find_from_winlink_pane(current, wl, wp); + else + cmd_find_from_winlink(current, wl); } if (cflag != NULL) { diff --git a/usr.bin/tmux/cmd-break-pane.c b/usr.bin/tmux/cmd-break-pane.c index ebb72193bfd..6b7d2780f0f 100644 --- a/usr.bin/tmux/cmd-break-pane.c +++ b/usr.bin/tmux/cmd-break-pane.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-break-pane.c,v 1.43 2017/03/08 13:36:12 nicm Exp $ */ +/* $OpenBSD: cmd-break-pane.c,v 1.44 2017/04/22 08:56:24 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -48,6 +48,7 @@ static enum cmd_retval cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item) { struct args *args = self->args; + struct cmd_find_state *current = &item->shared->current; struct client *c = item->state.c; struct winlink *wl = item->state.sflag.wl; struct session *src_s = item->state.sflag.s; @@ -93,8 +94,10 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item) if (idx == -1) idx = -1 - options_get_number(dst_s->options, "base-index"); wl = session_attach(dst_s, w, idx, &cause); /* can't fail */ - if (!args_has(self->args, 'd')) + if (!args_has(self->args, 'd')) { session_select(dst_s, wl->idx); + cmd_find_from_session(current, dst_s); + } server_redraw_session(src_s); if (src_s != dst_s) diff --git a/usr.bin/tmux/cmd-find-window.c b/usr.bin/tmux/cmd-find-window.c index 8be8d6a43df..0ece6fd8dc3 100644 --- a/usr.bin/tmux/cmd-find-window.c +++ b/usr.bin/tmux/cmd-find-window.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-find-window.c,v 1.39 2016/10/16 19:04:05 nicm Exp $ */ +/* $OpenBSD: cmd-find-window.c,v 1.40 2017/04/22 08:56:24 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -142,6 +142,7 @@ static enum cmd_retval cmd_find_window_exec(struct cmd *self, struct cmdq_item *item) { struct args *args = self->args; + struct cmd_find_state *current = &item->shared->current; struct client *c = item->state.c; struct window_choose_data *cdata; struct session *s = item->state.tflag.s; @@ -177,8 +178,10 @@ cmd_find_window_exec(struct cmd *self, struct cmdq_item *item) } if (TAILQ_NEXT(TAILQ_FIRST(&find_list), entry) == NULL) { - if (session_select(s, TAILQ_FIRST(&find_list)->wl->idx) == 0) + if (session_select(s, TAILQ_FIRST(&find_list)->wl->idx) == 0) { + cmd_find_from_session(current, s); server_redraw_session(s); + } recalculate_sizes(); goto out; } diff --git a/usr.bin/tmux/cmd-join-pane.c b/usr.bin/tmux/cmd-join-pane.c index 36b0d648a11..e1bcc330db4 100644 --- a/usr.bin/tmux/cmd-join-pane.c +++ b/usr.bin/tmux/cmd-join-pane.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-join-pane.c,v 1.30 2016/10/16 22:06:40 nicm Exp $ */ +/* $OpenBSD: cmd-join-pane.c,v 1.31 2017/04/22 08:56:24 nicm Exp $ */ /* * Copyright (c) 2011 George Nachman @@ -63,6 +63,7 @@ static enum cmd_retval cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item) { struct args *args = self->args; + struct cmd_find_state *current = &item->shared->current; struct session *dst_s; struct winlink *src_wl, *dst_wl; struct window *src_w, *dst_w; @@ -146,6 +147,7 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item) if (!args_has(args, 'd')) { window_set_active_pane(dst_w, src_wp); session_select(dst_s, dst_idx); + cmd_find_from_session(current, dst_s); server_redraw_session(dst_s); } else server_status_session(dst_s); diff --git a/usr.bin/tmux/cmd-new-session.c b/usr.bin/tmux/cmd-new-session.c index 341dd8f6bde..4cc4eecf86e 100644 --- a/usr.bin/tmux/cmd-new-session.c +++ b/usr.bin/tmux/cmd-new-session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-new-session.c,v 1.103 2017/04/21 14:01:19 nicm Exp $ */ +/* $OpenBSD: cmd-new-session.c,v 1.104 2017/04/22 08:56:24 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -324,8 +324,10 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item) free(cp); } - if (!detached) + if (!detached) { c->flags |= CLIENT_ATTACHED; + cmd_find_from_session(&item->shared->current, s); + } if (to_free != NULL) free((void *)to_free); diff --git a/usr.bin/tmux/cmd-new-window.c b/usr.bin/tmux/cmd-new-window.c index fd6617436e4..798aa5c1c03 100644 --- a/usr.bin/tmux/cmd-new-window.c +++ b/usr.bin/tmux/cmd-new-window.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-new-window.c,v 1.68 2017/04/21 14:09:44 nicm Exp $ */ +/* $OpenBSD: cmd-new-window.c,v 1.69 2017/04/22 08:56:24 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -52,6 +52,7 @@ static enum cmd_retval cmd_new_window_exec(struct cmd *self, struct cmdq_item *item) { struct args *args = self->args; + struct cmd_find_state *current = &item->shared->current; struct session *s = item->state.tflag.s; struct winlink *wl = item->state.tflag.wl; struct client *c = item->state.c; @@ -132,6 +133,7 @@ cmd_new_window_exec(struct cmd *self, struct cmdq_item *item) } if (!detached) { session_select(s, wl->idx); + cmd_find_from_winlink(current, wl); server_redraw_session_group(s); } else server_status_session_group(s); diff --git a/usr.bin/tmux/cmd-select-pane.c b/usr.bin/tmux/cmd-select-pane.c index 0eb651bbb82..cebf81f4c9e 100644 --- a/usr.bin/tmux/cmd-select-pane.c +++ b/usr.bin/tmux/cmd-select-pane.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-select-pane.c,v 1.36 2017/04/21 21:02:26 nicm Exp $ */ +/* $OpenBSD: cmd-select-pane.c,v 1.37 2017/04/22 08:56:24 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -56,6 +56,7 @@ static enum cmd_retval cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item) { struct args *args = self->args; + struct cmd_find_state *current = &item->shared->current; struct winlink *wl = item->state.tflag.wl; struct window *w = wl->window; struct session *s = item->state.tflag.s; @@ -68,7 +69,6 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item) cmdq_error(item, "no last pane"); return (CMD_RETURN_ERROR); } - if (args_has(self->args, 'e')) lastwp->flags &= ~PANE_INPUTOFF; else if (args_has(self->args, 'd')) @@ -77,6 +77,7 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item) server_unzoom_window(w); window_redraw_active_switch(w, lastwp); if (window_set_active_pane(w, lastwp)) { + cmd_find_from_winlink(current, wl); server_status_window(w); server_redraw_window_borders(w); } @@ -155,6 +156,7 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item) } window_redraw_active_switch(w, wp); if (window_set_active_pane(w, wp)) { + cmd_find_from_winlink(current, wl); server_status_window(w); server_redraw_window_borders(w); } diff --git a/usr.bin/tmux/cmd-select-window.c b/usr.bin/tmux/cmd-select-window.c index 44b2f76bbb1..5d7d4296abe 100644 --- a/usr.bin/tmux/cmd-select-window.c +++ b/usr.bin/tmux/cmd-select-window.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-select-window.c,v 1.18 2016/10/16 19:04:05 nicm Exp $ */ +/* $OpenBSD: cmd-select-window.c,v 1.19 2017/04/22 08:56:24 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -84,9 +84,10 @@ const struct cmd_entry cmd_last_window_entry = { static enum cmd_retval cmd_select_window_exec(struct cmd *self, struct cmdq_item *item) { - struct winlink *wl = item->state.tflag.wl; - struct session *s = item->state.tflag.s; - int next, previous, last, activity; + struct cmd_find_state *current = &item->shared->current; + struct winlink *wl = item->state.tflag.wl; + struct session *s = item->state.tflag.s; + int next, previous, last, activity; next = self->entry == &cmd_next_window_entry; if (args_has(self->args, 'n')) @@ -116,7 +117,7 @@ cmd_select_window_exec(struct cmd *self, struct cmdq_item *item) return (CMD_RETURN_ERROR); } } - + cmd_find_from_session(&item->shared->current, s); server_redraw_session(s); } else { /* @@ -128,9 +129,13 @@ cmd_select_window_exec(struct cmd *self, struct cmdq_item *item) cmdq_error(item, "no last window"); return (-1); } + if (current->s == s) + cmd_find_from_session(current, s); server_redraw_session(s); - } else if (session_select(s, wl->idx) == 0) + } else if (session_select(s, wl->idx) == 0) { + cmd_find_from_session(current, s); server_redraw_session(s); + } } recalculate_sizes(); diff --git a/usr.bin/tmux/cmd-split-window.c b/usr.bin/tmux/cmd-split-window.c index 94bd1b676e7..9a963db3b80 100644 --- a/usr.bin/tmux/cmd-split-window.c +++ b/usr.bin/tmux/cmd-split-window.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-split-window.c,v 1.81 2017/04/21 17:22:20 nicm Exp $ */ +/* $OpenBSD: cmd-split-window.c,v 1.82 2017/04/22 08:56:24 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -53,6 +53,7 @@ const struct cmd_entry cmd_split_window_entry = { static enum cmd_retval cmd_split_window_exec(struct cmd *self, struct cmdq_item *item) { + struct cmd_find_state *current = &item->shared->current; struct args *args = self->args; struct client *c = item->state.c; struct session *s = item->state.tflag.s; @@ -156,6 +157,7 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item) if (!args_has(args, 'd')) { window_set_active_pane(w, new_wp); session_select(s, wl->idx); + cmd_find_from_session(current, s); server_redraw_session(s); } else server_status_session(s); diff --git a/usr.bin/tmux/cmd-switch-client.c b/usr.bin/tmux/cmd-switch-client.c index 71837df72be..4b5d48a52bc 100644 --- a/usr.bin/tmux/cmd-switch-client.c +++ b/usr.bin/tmux/cmd-switch-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-switch-client.c,v 1.49 2017/04/21 14:01:19 nicm Exp $ */ +/* $OpenBSD: cmd-switch-client.c,v 1.50 2017/04/22 08:56:24 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -99,6 +99,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item) if (wp != NULL) window_set_active_pane(wp->window, wp); session_set_current(s, state->tflag.wl); + cmd_find_from_session(&item->shared->current, s); } } diff --git a/usr.bin/tmux/server-client.c b/usr.bin/tmux/server-client.c index 12fb0c8cf56..d16b15a01a1 100644 --- a/usr.bin/tmux/server-client.c +++ b/usr.bin/tmux/server-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server-client.c,v 1.226 2017/04/21 22:23:24 nicm Exp $ */ +/* $OpenBSD: server-client.c,v 1.227 2017/04/22 08:56:24 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -856,10 +856,9 @@ server_client_handle_key(struct client *c, key_code key) m->valid = 0; /* Find affected pane. */ - if (KEYC_IS_MOUSE(key) && m->valid) - wp = cmd_mouse_pane(m, NULL, NULL); - else - wp = w->active; + if (!KEYC_IS_MOUSE(key) || cmd_find_from_mouse(&fs, m) != 0) + cmd_find_from_session(&fs, s); + wp = fs.wp; /* Forward mouse keys if disabled. */ if (KEYC_IS_MOUSE(key) && !options_get_number(s->options, "mouse")) @@ -946,13 +945,8 @@ retry: } server_status_client(c); - /* Find default state if the pane is known. */ - if (KEYC_IS_MOUSE(key) && m->valid && wp != NULL) { - cmd_find_from_winlink_pane(&fs, s->curw, wp); - cmd_find_log_state(__func__, &fs); - key_bindings_dispatch(bd, c, m, &fs); - } else - key_bindings_dispatch(bd, c, m, NULL); + /* Execute the key binding. */ + key_bindings_dispatch(bd, c, m, &fs); key_bindings_unref_table(table); return; } -- 2.20.1