Change focus to be driven by events rather than walking all panes at end

of event loop, this way the ordering of in and out can be enforced.
GitHub issue 2808.
This commit is contained in:
nicm
2021-08-13 06:52:51 +00:00
parent a2b8506917
commit 2bb0b9d6c5
10 changed files with 115 additions and 122 deletions

View File

@ -458,6 +458,52 @@ window_has_pane(struct window *w, struct window_pane *wp)
return (0);
}
void
window_update_focus(struct window *w)
{
if (w != NULL) {
log_debug("%s: @%u", __func__, w->id);
window_pane_update_focus(w->active);
}
}
void
window_pane_update_focus(struct window_pane *wp)
{
struct client *c;
int focused = 0;
if (wp != NULL) {
if (wp != wp->window->active)
focused = 0;
else {
TAILQ_FOREACH(c, &clients, entry) {
if (c->session != NULL &&
c->session->attached != 0 &&
(c->flags & CLIENT_FOCUSED) &&
c->session->curw->window == wp->window) {
focused = 1;
break;
}
}
}
if (!focused && (wp->flags & PANE_FOCUSED)) {
log_debug("%s: %%%u focus out", __func__, wp->id);
if (wp->base.mode & MODE_FOCUSON)
bufferevent_write(wp->event, "\033[O", 3);
notify_pane("pane-focus-out", wp);
wp->flags &= ~PANE_FOCUSED;
} else if (focused && (~wp->flags & PANE_FOCUSED)) {
log_debug("%s: %%%u focus in", __func__, wp->id);
if (wp->base.mode & MODE_FOCUSON)
bufferevent_write(wp->event, "\033[I", 3);
notify_pane("pane-focus-in", wp);
wp->flags |= PANE_FOCUSED;
} else
log_debug("%s: %%%u focus unchanged", __func__, wp->id);
}
}
int
window_set_active_pane(struct window *w, struct window_pane *wp, int notify)
{
@ -471,6 +517,11 @@ window_set_active_pane(struct window *w, struct window_pane *wp, int notify)
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(w->active);
}
tty_update_window_offset(w);
if (notify)