1
0
mirror of https://github.com/tmux/tmux.git synced 2025-04-10 11:08:49 +00:00

Remember the last active pane in the top-bottom or left-right cell so

that it can be restored when moving back to that cell with selectp
-L/-R/etc. From Suraj N Kurapati.
This commit is contained in:
nicm 2014-01-28 22:19:17 +00:00
parent dda70d4ef1
commit c930fd5ff6
2 changed files with 74 additions and 4 deletions

2
tmux.h
View File

@ -1028,6 +1028,8 @@ struct layout_cell {
u_int yoff; u_int yoff;
struct window_pane *wp; struct window_pane *wp;
struct window_pane *lastwp;
struct layout_cells cells; struct layout_cells cells;
TAILQ_ENTRY(layout_cell) entry; TAILQ_ENTRY(layout_cell) entry;

View File

@ -61,6 +61,10 @@ struct window_pane_tree all_window_panes;
u_int next_window_pane_id; u_int next_window_pane_id;
u_int next_window_id; u_int next_window_id;
struct window_pane *window_pane_active_set(struct window_pane *,
struct window_pane *);
void window_pane_active_lost(struct window_pane *, struct window_pane *);
void window_pane_timer_callback(int, short, void *); void window_pane_timer_callback(int, short, void *);
void window_pane_read_callback(struct bufferevent *, void *); void window_pane_read_callback(struct bufferevent *, void *);
void window_pane_error_callback(struct bufferevent *, short, void *); void window_pane_error_callback(struct bufferevent *, short, void *);
@ -386,6 +390,59 @@ window_resize(struct window *w, u_int sx, u_int sy)
w->sy = sy; w->sy = sy;
} }
/*
* Restore previously active pane when changing from wp to nextwp. The intended
* pane is in nextwp and it returns the previously focused pane.
*/
struct window_pane *
window_pane_active_set(struct window_pane *wp, struct window_pane *nextwp)
{
struct layout_cell *lc;
struct window_pane *lastwp;
/* Target pane's parent must not be an ancestor of source pane. */
for (lc = wp->layout_cell->parent; lc != NULL; lc = lc->parent) {
if (lc == nextwp->layout_cell->parent)
return (nextwp);
}
/*
* Previously active pane, if any, must not be the same as the source
* pane.
*/
if (nextwp->layout_cell->parent != NULL) {
lastwp = nextwp->layout_cell->parent->lastwp;
if (lastwp != wp && window_pane_visible(lastwp))
return (lastwp);
}
return (nextwp);
}
/* Remember previously active pane when changing from wp to nextwp. */
void
window_pane_active_lost(struct window_pane *wp, struct window_pane *nextwp)
{
struct layout_cell *lc, *lc2;
/* Save the target pane in its parent. */
nextwp->layout_cell->parent->lastwp = nextwp;
/*
* Save the source pane in all of its parents up to, but not including,
* the common ancestor of itself and the target panes.
*/
if (wp == NULL)
return;
for (lc = wp->layout_cell->parent; lc != NULL; lc = lc->parent) {
lc2 = nextwp->layout_cell->parent;
for (; lc2 != NULL; lc2 = lc2->parent) {
if (lc == lc2)
return;
}
lc->lastwp = wp;
}
}
void void
window_set_active_pane(struct window *w, struct window_pane *wp) window_set_active_pane(struct window *w, struct window_pane *wp)
{ {
@ -393,6 +450,7 @@ window_set_active_pane(struct window *w, struct window_pane *wp)
return; return;
w->last = w->active; w->last = w->active;
w->active = wp; w->active = wp;
window_pane_active_lost(w->last, wp);
while (!window_pane_visible(w->active)) { while (!window_pane_visible(w->active)) {
w->active = TAILQ_PREV(w->active, window_panes, entry); w->active = TAILQ_PREV(w->active, window_panes, entry);
if (w->active == NULL) if (w->active == NULL)
@ -707,6 +765,16 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
void void
window_pane_destroy(struct window_pane *wp) window_pane_destroy(struct window_pane *wp)
{ {
struct window_pane *wp2;
/* Forget removed pane in all layout cells that remember it. */
RB_FOREACH(wp2, window_pane_tree, &all_window_panes) {
if (wp2->layout_cell != NULL &&
wp2->layout_cell->parent != NULL &&
wp2->layout_cell->parent->lastwp == wp)
wp2->layout_cell->parent->lastwp = NULL;
}
window_pane_reset_mode(wp); window_pane_reset_mode(wp);
if (event_initialized(&wp->changes_timer)) if (event_initialized(&wp->changes_timer))
@ -1130,7 +1198,7 @@ window_pane_find_up(struct window_pane *wp)
if (wp2->yoff + wp2->sy + 1 != top) if (wp2->yoff + wp2->sy + 1 != top)
continue; continue;
if (left >= wp2->xoff && left <= wp2->xoff + wp2->sx) if (left >= wp2->xoff && left <= wp2->xoff + wp2->sx)
return (wp2); return (window_pane_active_set(wp, wp2));
} }
return (NULL); return (NULL);
} }
@ -1156,7 +1224,7 @@ window_pane_find_down(struct window_pane *wp)
if (wp2->yoff != bottom) if (wp2->yoff != bottom)
continue; continue;
if (left >= wp2->xoff && left <= wp2->xoff + wp2->sx) if (left >= wp2->xoff && left <= wp2->xoff + wp2->sx)
return (wp2); return (window_pane_active_set(wp, wp2));
} }
return (NULL); return (NULL);
} }
@ -1185,7 +1253,7 @@ window_pane_find_left(struct window_pane *wp)
if (wp2->xoff + wp2->sx + 1 != left) if (wp2->xoff + wp2->sx + 1 != left)
continue; continue;
if (top >= wp2->yoff && top <= wp2->yoff + wp2->sy) if (top >= wp2->yoff && top <= wp2->yoff + wp2->sy)
return (wp2); return (window_pane_active_set(wp, wp2));
} }
return (NULL); return (NULL);
} }
@ -1214,7 +1282,7 @@ window_pane_find_right(struct window_pane *wp)
if (wp2->xoff != right) if (wp2->xoff != right)
continue; continue;
if (top >= wp2->yoff && top <= wp2->yoff + wp2->sy) if (top >= wp2->yoff && top <= wp2->yoff + wp2->sy)
return (wp2); return (window_pane_active_set(wp, wp2));
} }
return (NULL); return (NULL);
} }