=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/window.c,v retrieving revision 1.99 retrieving revision 1.100 diff -c -r1.99 -r1.100 *** src/usr.bin/tmux/window.c 2013/10/10 12:26:37 1.99 --- src/usr.bin/tmux/window.c 2014/01/28 22:19:17 1.100 *************** *** 1,4 **** ! /* $OpenBSD: window.c,v 1.99 2013/10/10 12:26:37 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott --- 1,4 ---- ! /* $OpenBSD: window.c,v 1.100 2014/01/28 22:19:17 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott *************** *** 61,66 **** --- 61,70 ---- u_int next_window_pane_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_read_callback(struct bufferevent *, void *); void window_pane_error_callback(struct bufferevent *, short, void *); *************** *** 386,398 **** --- 390,456 ---- 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 window_set_active_pane(struct window *w, struct window_pane *wp) { if (wp == w->active) return; w->last = w->active; w->active = wp; + window_pane_active_lost(w->last, wp); while (!window_pane_visible(w->active)) { w->active = TAILQ_PREV(w->active, window_panes, entry); if (w->active == NULL) *************** *** 707,712 **** --- 765,780 ---- void 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); if (event_initialized(&wp->changes_timer)) *************** *** 1130,1136 **** if (wp2->yoff + wp2->sy + 1 != top) continue; if (left >= wp2->xoff && left <= wp2->xoff + wp2->sx) ! return (wp2); } return (NULL); } --- 1198,1204 ---- if (wp2->yoff + wp2->sy + 1 != top) continue; if (left >= wp2->xoff && left <= wp2->xoff + wp2->sx) ! return (window_pane_active_set(wp, wp2)); } return (NULL); } *************** *** 1156,1162 **** if (wp2->yoff != bottom) continue; if (left >= wp2->xoff && left <= wp2->xoff + wp2->sx) ! return (wp2); } return (NULL); } --- 1224,1230 ---- if (wp2->yoff != bottom) continue; if (left >= wp2->xoff && left <= wp2->xoff + wp2->sx) ! return (window_pane_active_set(wp, wp2)); } return (NULL); } *************** *** 1185,1191 **** if (wp2->xoff + wp2->sx + 1 != left) continue; if (top >= wp2->yoff && top <= wp2->yoff + wp2->sy) ! return (wp2); } return (NULL); } --- 1253,1259 ---- if (wp2->xoff + wp2->sx + 1 != left) continue; if (top >= wp2->yoff && top <= wp2->yoff + wp2->sy) ! return (window_pane_active_set(wp, wp2)); } return (NULL); } *************** *** 1214,1220 **** if (wp2->xoff != right) continue; if (top >= wp2->yoff && top <= wp2->yoff + wp2->sy) ! return (wp2); } return (NULL); } --- 1282,1288 ---- if (wp2->xoff != right) continue; if (top >= wp2->yoff && top <= wp2->yoff + wp2->sy) ! return (window_pane_active_set(wp, wp2)); } return (NULL); }