summaryrefslogtreecommitdiff
path: root/usr.bin/tmux/window.c
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2021-08-13 06:52:52 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2021-08-13 06:52:52 +0000
commited494901095f45650fd129e1f8a6f4c3eceab503 (patch)
tree03fbcabdb314bffc3ffee9e7348f720036e0816c /usr.bin/tmux/window.c
parenteed9256d707e6d4d197e53024454b58138b4fed8 (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 'usr.bin/tmux/window.c')
-rw-r--r--usr.bin/tmux/window.c53
1 files changed, 52 insertions, 1 deletions
diff --git a/usr.bin/tmux/window.c b/usr.bin/tmux/window.c
index fbf3da32fbe..69257a3ddff 100644
--- a/usr.bin/tmux/window.c
+++ b/usr.bin/tmux/window.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: window.c,v 1.273 2021/08/11 20:49:55 nicm Exp $ */
+/* $OpenBSD: window.c,v 1.274 2021/08/13 06:52:51 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -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)