summaryrefslogtreecommitdiffstats
path: root/window.c
diff options
context:
space:
mode:
Diffstat (limited to 'window.c')
-rw-r--r--window.c101
1 files changed, 75 insertions, 26 deletions
diff --git a/window.c b/window.c
index c0cd9bd..77ce41d 100644
--- a/window.c
+++ b/window.c
@@ -64,6 +64,7 @@ static u_int next_active_point;
struct window_pane_input_data {
struct cmdq_item *item;
u_int wp;
+ struct client_file *file;
};
static struct window_pane *window_pane_create(struct window *, u_int, u_int,
@@ -245,21 +246,15 @@ winlink_stack_push(struct winlink_stack *stack, struct winlink *wl)
winlink_stack_remove(stack, wl);
TAILQ_INSERT_HEAD(stack, wl, sentry);
+ wl->flags |= WINLINK_VISITED;
}
void
winlink_stack_remove(struct winlink_stack *stack, struct winlink *wl)
{
- struct winlink *wl2;
-
- if (wl == NULL)
- return;
-
- TAILQ_FOREACH(wl2, stack, sentry) {
- if (wl2 == wl) {
- TAILQ_REMOVE(stack, wl, sentry);
- return;
- }
+ if (wl != NULL && (wl->flags & WINLINK_VISITED)) {
+ TAILQ_REMOVE(stack, wl, sentry);
+ wl->flags &= ~WINLINK_VISITED;
}
}
@@ -309,6 +304,7 @@ window_create(u_int sx, u_int sy, u_int xpixel, u_int ypixel)
w->flags = 0;
TAILQ_INIT(&w->panes);
+ TAILQ_INIT(&w->last_panes);
w->active = NULL;
w->lastlayout = -1;
@@ -342,6 +338,7 @@ window_destroy(struct window *w)
{
log_debug("window @%u destroyed (%d references)", w->id, w->references);
+ window_unzoom(w);
RB_REMOVE(windows, &windows, w);
if (w->layout_root != NULL)
@@ -518,18 +515,23 @@ window_pane_update_focus(struct window_pane *wp)
int
window_set_active_pane(struct window *w, struct window_pane *wp, int notify)
{
+ struct window_pane *lastwp;
+
log_debug("%s: pane %%%u", __func__, wp->id);
if (wp == w->active)
return (0);
- w->last = w->active;
+ lastwp = w->active;
+
+ window_pane_stack_remove(&w->last_panes, wp);
+ window_pane_stack_push(&w->last_panes, lastwp);
w->active = wp;
w->active->active_point = next_active_point++;
w->active->flags |= PANE_CHANGED;
if (options_get_number(global_options, "focus-events")) {
- window_pane_update_focus(w->last);
+ window_pane_update_focus(lastwp);
window_pane_update_focus(w->active);
}
@@ -752,21 +754,21 @@ window_lost_pane(struct window *w, struct window_pane *wp)
if (wp == marked_pane.wp)
server_clear_marked();
+ window_pane_stack_remove(&w->last_panes, wp);
if (wp == w->active) {
- w->active = w->last;
- w->last = NULL;
+ w->active = TAILQ_FIRST(&w->last_panes);
if (w->active == NULL) {
w->active = TAILQ_PREV(wp, window_panes, entry);
if (w->active == NULL)
w->active = TAILQ_NEXT(wp, entry);
}
if (w->active != NULL) {
+ window_pane_stack_remove(&w->last_panes, w->active);
w->active->flags |= PANE_CHANGED;
notify_window("window-pane-changed", w);
window_update_focus(w);
}
- } else if (wp == w->last)
- w->last = NULL;
+ }
}
void
@@ -850,6 +852,11 @@ window_destroy_panes(struct window *w)
{
struct window_pane *wp;
+ while (!TAILQ_EMPTY(&w->last_panes)) {
+ wp = TAILQ_FIRST(&w->last_panes);
+ window_pane_stack_remove(&w->last_panes, wp);
+ }
+
while (!TAILQ_EMPTY(&w->panes)) {
wp = TAILQ_FIRST(&w->panes);
TAILQ_REMOVE(&w->panes, wp, entry);
@@ -940,6 +947,7 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
screen_init(&wp->base, sx, sy, hlimit);
wp->screen = &wp->base;
+ window_pane_default_cursor(wp);
screen_init(&wp->status_screen, 1, 1, 0);
@@ -1042,6 +1050,8 @@ window_pane_set_event(struct window_pane *wp)
wp->event = bufferevent_new(wp->fd, window_pane_read_callback,
NULL, window_pane_error_callback, wp);
+ if (wp->event == NULL)
+ fatalx("out of memory");
wp->ictx = input_init(wp, wp->event, &wp->palette);
bufferevent_enable(wp->event, EV_READ|EV_WRITE);
@@ -1126,6 +1136,7 @@ window_pane_reset_mode(struct window_pane *wp)
next = TAILQ_FIRST(&wp->modes);
if (next == NULL) {
+ wp->flags &= ~PANE_UNSEENCHANGES;
log_debug("%s: no next mode", __func__);
wp->screen = &wp->base;
} else {
@@ -1203,6 +1214,12 @@ window_pane_visible(struct window_pane *wp)
return (wp == wp->window->active);
}
+int
+window_pane_exited(struct window_pane *wp)
+{
+ return (wp->fd == -1 || (wp->flags & PANE_EXITED));
+}
+
u_int
window_pane_search(struct window_pane *wp, const char *term, int regex,
int ignore)
@@ -1483,6 +1500,25 @@ window_pane_find_right(struct window_pane *wp)
return (best);
}
+void
+window_pane_stack_push(struct window_panes *stack, struct window_pane *wp)
+{
+ if (wp != NULL) {
+ window_pane_stack_remove(stack, wp);
+ TAILQ_INSERT_HEAD(stack, wp, sentry);
+ wp->flags |= PANE_VISITED;
+ }
+}
+
+void
+window_pane_stack_remove(struct window_panes *stack, struct window_pane *wp)
+{
+ if (wp != NULL && (wp->flags & PANE_VISITED)) {
+ TAILQ_REMOVE(stack, wp, sentry);
+ wp->flags &= ~PANE_VISITED;
+ }
+}
+
/* Clear alert flags for a winlink */
void
winlink_clear_flags(struct winlink *wl)
@@ -1540,18 +1576,18 @@ window_pane_input_callback(struct client *c, __unused const char *path,
size_t len = EVBUFFER_LENGTH(buffer);
wp = window_pane_find_by_id(cdata->wp);
- if (wp == NULL || closed || error != 0 || (c->flags & CLIENT_DEAD)) {
- if (wp == NULL)
+ if (cdata->file != NULL && (wp == NULL || c->flags & CLIENT_DEAD)) {
+ if (wp == NULL) {
+ c->retval = 1;
c->flags |= CLIENT_EXIT;
-
- evbuffer_drain(buffer, len);
+ }
+ file_cancel(cdata->file);
+ } else if (cdata->file == NULL || closed || error != 0) {
cmdq_continue(cdata->item);
-
server_client_unref(c);
free(cdata);
- return;
- }
- input_parse_buffer(wp, buf, len);
+ } else
+ input_parse_buffer(wp, buf, len);
evbuffer_drain(buffer, len);
}
@@ -1574,9 +1610,8 @@ window_pane_start_input(struct window_pane *wp, struct cmdq_item *item,
cdata = xmalloc(sizeof *cdata);
cdata->item = item;
cdata->wp = wp->id;
-
+ cdata->file = file_read(c, "-", window_pane_input_callback, cdata);
c->references++;
- file_read(c, "-", window_pane_input_callback, cdata);
return (0);
}
@@ -1618,3 +1653,17 @@ window_set_fill_character(struct window *w)
w->fill_character = ud;
}
}
+
+void
+window_pane_default_cursor(struct window_pane *wp)
+{
+ struct screen *s = wp->screen;
+ int c;
+
+ c = options_get_number(wp->options, "cursor-colour");
+ s->default_ccolour = c;
+
+ c = options_get_number(wp->options, "cursor-style");
+ s->default_mode = 0;
+ screen_set_cursor_style(c, &s->default_cstyle, &s->default_mode);
+}