aboutsummaryrefslogtreecommitdiff
path: root/window.c
diff options
context:
space:
mode:
authorThomas Adam <thomas@xteddy.org>2014-01-31 21:39:56 +0000
committerThomas Adam <thomas@xteddy.org>2014-01-31 21:39:56 +0000
commitd50e47fc4ab5cbbdbe6bbebdc2c36ce3aae6e987 (patch)
tree397f4999444c2eef367f884b815bec2a14697c3c /window.c
parentcbf9224c5f7bcf07352f6ea128c90c12cb0af22e (diff)
parent9f02feb9d089b1a4639afb52ab0e8212eeb55a7c (diff)
downloadrtmux-d50e47fc4ab5cbbdbe6bbebdc2c36ce3aae6e987.tar.gz
rtmux-d50e47fc4ab5cbbdbe6bbebdc2c36ce3aae6e987.tar.bz2
rtmux-d50e47fc4ab5cbbdbe6bbebdc2c36ce3aae6e987.zip
Merge branch 'obsd-master'
Conflicts: Makefile cmd-server-info.c cmd-start-server.c
Diffstat (limited to 'window.c')
-rw-r--r--window.c86
1 files changed, 72 insertions, 14 deletions
diff --git a/window.c b/window.c
index 9f47f444..858463cf 100644
--- a/window.c
+++ b/window.c
@@ -58,6 +58,10 @@ struct window_pane_tree all_window_panes;
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 *);
@@ -383,6 +387,59 @@ window_resize(struct window *w, u_int sx, u_int 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
window_set_active_pane(struct window *w, struct window_pane *wp)
{
@@ -390,6 +447,7 @@ window_set_active_pane(struct window *w, struct window_pane *wp)
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)
@@ -704,6 +762,16 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
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))
@@ -1131,7 +1199,7 @@ window_pane_find_up(struct window_pane *wp)
if (wp2->yoff + wp2->sy + 1 != top)
continue;
if (left >= wp2->xoff && left <= wp2->xoff + wp2->sx)
- return (wp2);
+ return (window_pane_active_set(wp, wp2));
}
return (NULL);
}
@@ -1157,7 +1225,7 @@ window_pane_find_down(struct window_pane *wp)
if (wp2->yoff != bottom)
continue;
if (left >= wp2->xoff && left <= wp2->xoff + wp2->sx)
- return (wp2);
+ return (window_pane_active_set(wp, wp2));
}
return (NULL);
}
@@ -1186,7 +1254,7 @@ window_pane_find_left(struct window_pane *wp)
if (wp2->xoff + wp2->sx + 1 != left)
continue;
if (top >= wp2->yoff && top <= wp2->yoff + wp2->sy)
- return (wp2);
+ return (window_pane_active_set(wp, wp2));
}
return (NULL);
}
@@ -1215,7 +1283,7 @@ window_pane_find_right(struct window_pane *wp)
if (wp2->xoff != right)
continue;
if (top >= wp2->yoff && top <= wp2->yoff + wp2->sy)
- return (wp2);
+ return (window_pane_active_set(wp, wp2));
}
return (NULL);
}
@@ -1248,13 +1316,3 @@ winlink_clear_flags(struct winlink *wl)
}
}
}
-
-/* Set the grid_cell with fg/bg/attr information when window is in a mode. */
-void
-window_mode_attrs(struct grid_cell *gc, struct options *oo)
-{
- memcpy(gc, &grid_default_cell, sizeof *gc);
- colour_set_fg(gc, options_get_number(oo, "mode-fg"));
- colour_set_bg(gc, options_get_number(oo, "mode-bg"));
- gc->attr |= options_get_number(oo, "mode-attr");
-}