When removing a pane, don't change the active pane unless the active
[tmux-openbsd.git] / server-window.c
blob634a1b8a74799eee73ac7aee1b7259947414f949
1 /* $OpenBSD$ */
3 /*
4 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include <sys/types.h>
21 #include <event.h>
22 #include <unistd.h>
24 #include "tmux.h"
26 int server_window_backoff(struct window_pane *);
27 int server_window_check_bell(struct session *, struct winlink *);
28 int server_window_check_activity(struct session *, struct winlink *);
29 int server_window_check_content(
30 struct session *, struct winlink *, struct window_pane *);
32 /* Window functions that need to happen every loop. */
33 void
34 server_window_loop(void)
36 struct window *w;
37 struct winlink *wl;
38 struct window_pane *wp;
39 struct session *s;
40 u_int i, j;
42 for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
43 w = ARRAY_ITEM(&windows, i);
44 if (w == NULL)
45 continue;
47 for (j = 0; j < ARRAY_LENGTH(&sessions); j++) {
48 s = ARRAY_ITEM(&sessions, j);
49 if (s == NULL)
50 continue;
51 wl = session_has(s, w);
52 if (wl == NULL)
53 continue;
55 if (server_window_check_bell(s, wl) ||
56 server_window_check_activity(s, wl))
57 server_status_session(s);
58 TAILQ_FOREACH(wp, &w->panes, entry)
59 server_window_check_content(s, wl, wp);
61 w->flags &= ~(WINDOW_BELL|WINDOW_ACTIVITY);
65 /* Check for bell in window. */
66 int
67 server_window_check_bell(struct session *s, struct winlink *wl)
69 struct client *c;
70 struct window *w = wl->window;
71 u_int i;
72 int action, visual;
74 if (!(w->flags & WINDOW_BELL) || wl->flags & WINLINK_BELL)
75 return (0);
76 if (s->curw != wl)
77 wl->flags |= WINLINK_BELL;
79 action = options_get_number(&s->options, "bell-action");
80 switch (action) {
81 case BELL_ANY:
82 if (s->flags & SESSION_UNATTACHED)
83 break;
84 visual = options_get_number(&s->options, "visual-bell");
85 for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
86 c = ARRAY_ITEM(&clients, i);
87 if (c == NULL || c->session != s)
88 continue;
89 if (!visual) {
90 tty_putcode(&c->tty, TTYC_BEL);
91 continue;
93 if (c->session->curw->window == w) {
94 status_message_set(c, "Bell in current window");
95 continue;
97 status_message_set(c, "Bell in window %u",
98 winlink_find_by_window(&s->windows, w)->idx);
100 break;
101 case BELL_CURRENT:
102 if (s->flags & SESSION_UNATTACHED)
103 break;
104 visual = options_get_number(&s->options, "visual-bell");
105 for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
106 c = ARRAY_ITEM(&clients, i);
107 if (c == NULL || c->session != s)
108 continue;
109 if (c->session->curw->window != w)
110 continue;
111 if (!visual) {
112 tty_putcode(&c->tty, TTYC_BEL);
113 continue;
115 status_message_set(c, "Bell in current window");
117 break;
120 return (1);
123 /* Check for activity in window. */
125 server_window_check_activity(struct session *s, struct winlink *wl)
127 struct client *c;
128 struct window *w = wl->window;
129 u_int i;
131 if (!(w->flags & WINDOW_ACTIVITY) || wl->flags & WINLINK_ACTIVITY)
132 return (0);
133 if (s->curw == wl)
134 return (0);
136 if (!options_get_number(&w->options, "monitor-activity"))
137 return (0);
139 wl->flags |= WINLINK_ACTIVITY;
141 if (options_get_number(&s->options, "visual-activity")) {
142 for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
143 c = ARRAY_ITEM(&clients, i);
144 if (c == NULL || c->session != s)
145 continue;
146 status_message_set(c, "Activity in window %u",
147 winlink_find_by_window(&s->windows, w)->idx);
151 return (1);
154 /* Check for content change in window. */
156 server_window_check_content(
157 struct session *s, struct winlink *wl, struct window_pane *wp)
159 struct client *c;
160 struct window *w = wl->window;
161 u_int i;
162 char *found, *ptr;
164 /* Activity flag must be set for new content. */
165 if (!(w->flags & WINDOW_ACTIVITY) || wl->flags & WINLINK_CONTENT)
166 return (0);
167 if (s->curw == wl)
168 return (0);
170 ptr = options_get_string(&w->options, "monitor-content");
171 if (ptr == NULL || *ptr == '\0')
172 return (0);
173 if ((found = window_pane_search(wp, ptr, NULL)) == NULL)
174 return (0);
175 xfree(found);
177 wl->flags |= WINLINK_CONTENT;
179 if (options_get_number(&s->options, "visual-content")) {
180 for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
181 c = ARRAY_ITEM(&clients, i);
182 if (c == NULL || c->session != s)
183 continue;
184 status_message_set(c, "Content in window %u",
185 winlink_find_by_window(&s->windows, w)->idx);
189 return (1);