summaryrefslogtreecommitdiffstats
path: root/window.c
diff options
context:
space:
mode:
authornicm <nicm>2021-08-13 06:52:51 +0000
committernicm <nicm>2021-08-13 06:52:51 +0000
commit2bb0b9d6c5edd7c4127c971f5ccebed969f86c1c (patch)
treedc1ce41c165065e588de274dd754113bd0cb8a3f /window.c
parenta2b85069171413aa30c812d44bf8ee4d32a2f834 (diff)
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.
Diffstat (limited to 'window.c')
-rw-r--r--window.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/window.c b/window.c
index f94acfcb..446898cb 100644
--- a/window.c
+++ b/window.c
@@ -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)