summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornicm <nicm>2016-11-16 00:24:03 +0000
committernicm <nicm>2016-11-16 00:24:03 +0000
commite88b74350fba9e35307f35a8645b23e3cde9200a (patch)
tree7e97f502b883765b11e70ef6425d95371fa2046c
parentc34a79b152e1d27ed87417e6a940358990ab9e79 (diff)
The target validity check used window_pane_visible but that may be false
if the pane is zoomed, so instead add a new function to just check if the pane is actually on screen (most commands still want to accept panes invisible by zoom). Also reject panes outside the window for various special targets. Problem reported by Sean Haugh.
-rw-r--r--cmd-find.c30
-rw-r--r--cmd-select-pane.c1
-rw-r--r--tmux.h1
-rw-r--r--window.c16
4 files changed, 30 insertions, 18 deletions
diff --git a/cmd-find.c b/cmd-find.c
index 8bad330b..2f28a028 100644
--- a/cmd-find.c
+++ b/cmd-find.c
@@ -658,7 +658,7 @@ cmd_find_get_pane(struct cmd_find_state *fs, const char *pane)
/* Check for pane ids starting with %. */
if (*pane == '%') {
fs->wp = window_pane_find_by_id_str(pane);
- if (fs->wp == NULL)
+ if (fs->wp == NULL || window_pane_outside(fs->wp))
return (-1);
fs->w = fs->wp->window;
return (cmd_find_best_session_with_window(fs));
@@ -695,7 +695,7 @@ cmd_find_get_pane_with_session(struct cmd_find_state *fs, const char *pane)
/* Check for pane ids starting with %. */
if (*pane == '%') {
fs->wp = window_pane_find_by_id_str(pane);
- if (fs->wp == NULL)
+ if (fs->wp == NULL || window_pane_outside(fs->wp))
return (-1);
fs->w = fs->wp->window;
return (cmd_find_best_winlink_with_window(fs));
@@ -727,7 +727,9 @@ cmd_find_get_pane_with_window(struct cmd_find_state *fs, const char *pane)
/* Check for pane ids starting with %. */
if (*pane == '%') {
fs->wp = window_pane_find_by_id_str(pane);
- if (fs->wp == NULL || fs->wp->window != fs->w)
+ if (fs->wp == NULL || window_pane_outside(fs->wp))
+ return (-1);
+ if (fs->wp->window != fs->w)
return (-1);
return (0);
}
@@ -737,25 +739,27 @@ cmd_find_get_pane_with_window(struct cmd_find_state *fs, const char *pane)
if (fs->w->last == NULL)
return (-1);
fs->wp = fs->w->last;
+ if (fs->wp == NULL || window_pane_outside(fs->wp))
+ return (-1);
return (0);
} else if (strcmp(pane, "{up-of}") == 0) {
fs->wp = window_pane_find_up(fs->w->active);
- if (fs->wp == NULL)
+ if (fs->wp == NULL || window_pane_outside(fs->wp))
return (-1);
return (0);
} else if (strcmp(pane, "{down-of}") == 0) {
fs->wp = window_pane_find_down(fs->w->active);
- if (fs->wp == NULL)
+ if (fs->wp == NULL || window_pane_outside(fs->wp))
return (-1);
return (0);
} else if (strcmp(pane, "{left-of}") == 0) {
fs->wp = window_pane_find_left(fs->w->active);
- if (fs->wp == NULL)
+ if (fs->wp == NULL || window_pane_outside(fs->wp))
return (-1);
return (0);
} else if (strcmp(pane, "{right-of}") == 0) {
fs->wp = window_pane_find_right(fs->w->active);
- if (fs->wp == NULL)
+ if (fs->wp == NULL || window_pane_outside(fs->wp))
return (-1);
return (0);
}
@@ -771,7 +775,7 @@ cmd_find_get_pane_with_window(struct cmd_find_state *fs, const char *pane)
fs->wp = window_pane_next_by_number(fs->w, wp, n);
else
fs->wp = window_pane_previous_by_number(fs->w, wp, n);
- if (fs->wp != NULL)
+ if (fs->wp != NULL && !window_pane_outside(fs->wp))
return (0);
}
@@ -779,13 +783,13 @@ cmd_find_get_pane_with_window(struct cmd_find_state *fs, const char *pane)
idx = strtonum(pane, 0, INT_MAX, &errstr);
if (errstr == NULL) {
fs->wp = window_pane_at_index(fs->w, idx);
- if (fs->wp != NULL)
+ if (fs->wp != NULL && !window_pane_outside(fs->wp))
return (0);
}
/* Try as a description. */
fs->wp = window_find_string(fs->w, pane);
- if (fs->wp != NULL)
+ if (fs->wp != NULL && !window_pane_outside(fs->wp))
return (0);
return (-1);
@@ -837,7 +841,7 @@ cmd_find_valid_state(struct cmd_find_state *fs)
if (!window_has_pane(fs->w, fs->wp))
return (0);
- return (window_pane_visible(fs->wp));
+ return (!window_pane_outside(fs->wp));
}
/* Copy a state. */
@@ -945,6 +949,8 @@ cmd_find_from_pane(struct cmd_find_state *fs, struct window_pane *wp)
{
if (cmd_find_from_window(fs, wp->window) != 0)
return (-1);
+ if (window_pane_outside(wp))
+ return (-1);
fs->wp = wp;
cmd_find_log_state(__func__, fs);
@@ -1012,7 +1018,7 @@ cmd_find_target(struct cmd_find_state *fs, struct cmd_find_state *current,
switch (type) {
case CMD_FIND_PANE:
fs->wp = cmd_mouse_pane(m, &fs->s, &fs->wl);
- if (fs->wp != NULL)
+ if (fs->wp != NULL && !window_pane_outside(fs->wp))
fs->w = fs->wl->window;
break;
case CMD_FIND_WINDOW:
diff --git a/cmd-select-pane.c b/cmd-select-pane.c
index c0374fa7..6ef83473 100644
--- a/cmd-select-pane.c
+++ b/cmd-select-pane.c
@@ -63,7 +63,6 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
const char *style;
if (self->entry == &cmd_last_pane_entry || args_has(args, 'l')) {
-
if (wl->window->last == NULL) {
cmdq_error(item, "no last pane");
return (CMD_RETURN_ERROR);
diff --git a/tmux.h b/tmux.h
index 41c6a092..18ff4bbb 100644
--- a/tmux.h
+++ b/tmux.h
@@ -2126,6 +2126,7 @@ int window_pane_set_mode(struct window_pane *,
void window_pane_reset_mode(struct window_pane *);
void window_pane_key(struct window_pane *, struct client *,
struct session *, key_code, struct mouse_event *);
+int window_pane_outside(struct window_pane *);
int window_pane_visible(struct window_pane *);
char *window_pane_search(struct window_pane *, const char *,
u_int *);
diff --git a/window.c b/window.c
index 56878a19..16929deb 100644
--- a/window.c
+++ b/window.c
@@ -1185,17 +1185,23 @@ window_pane_key(struct window_pane *wp, struct client *c, struct session *s,
}
int
-window_pane_visible(struct window_pane *wp)
+window_pane_outside(struct window_pane *wp)
{
struct window *w = wp->window;
- if (wp->layout_cell == NULL)
- return (0);
if (wp->xoff >= w->sx || wp->yoff >= w->sy)
- return (0);
+ return (1);
if (wp->xoff + wp->sx > w->sx || wp->yoff + wp->sy > w->sy)
+ return (1);
+ return (0);
+}
+
+int
+window_pane_visible(struct window_pane *wp)
+{
+ if (wp->layout_cell == NULL)
return (0);
- return (1);
+ return (!window_pane_outside(wp));
}
char *