Annotation of src/usr.bin/tmux/control-notify.c, Revision 1.30
1.30 ! nicm 1: /* $OpenBSD: control-notify.c,v 1.29 2021/03/16 09:14:58 nicm Exp $ */
1.1 nicm 2:
3: /*
1.16 nicm 4: * Copyright (c) 2012 Nicholas Marriott <nicholas.marriott@gmail.com>
1.1 nicm 5: * Copyright (c) 2012 George Nachman <tmux@georgester.com>
6: *
7: * Permission to use, copy, modify, and distribute this software for any
8: * purpose with or without fee is hereby granted, provided that the above
9: * copyright notice and this permission notice appear in all copies.
10: *
11: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15: * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
16: * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
17: * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18: */
19:
20: #include <sys/types.h>
21:
1.12 nicm 22: #include <stdlib.h>
23:
1.1 nicm 24: #include "tmux.h"
25:
26: #define CONTROL_SHOULD_NOTIFY_CLIENT(c) \
27: ((c) != NULL && ((c)->flags & CLIENT_CONTROL))
28:
29: void
1.21 nicm 30: control_notify_pane_mode_changed(int pane)
31: {
32: struct client *c;
33:
34: TAILQ_FOREACH(c, &clients, entry) {
35: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
36: continue;
37:
38: control_write(c, "%%pane-mode-changed %%%u", pane);
39: }
40: }
41:
42: void
1.1 nicm 43: control_notify_window_layout_changed(struct window *w)
44: {
1.21 nicm 45: struct client *c;
46: struct session *s;
47: struct winlink *wl;
48: const char *template;
49: char *cp;
1.12 nicm 50:
51: template = "%layout-change #{window_id} #{window_layout} "
1.28 nicm 52: "#{window_visible_layout} #{window_raw_flags}";
1.1 nicm 53:
1.11 nicm 54: TAILQ_FOREACH(c, &clients, entry) {
1.1 nicm 55: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
56: continue;
57: s = c->session;
58:
59: if (winlink_find_by_window_id(&s->windows, w->id) == NULL)
60: continue;
61:
62: /*
63: * When the last pane in a window is closed it won't have a
64: * layout root and we don't need to inform the client about the
65: * layout change because the whole window will go away soon.
66: */
67: if (w->layout_root == NULL)
68: continue;
69:
70: wl = winlink_find_by_window(&s->windows, w);
71: if (wl != NULL) {
1.20 nicm 72: cp = format_single(NULL, template, c, NULL, wl, NULL);
73: control_write(c, "%s", cp);
74: free(cp);
1.1 nicm 75: }
76: }
77: }
78:
79: void
1.21 nicm 80: control_notify_window_pane_changed(struct window *w)
81: {
82: struct client *c;
83:
84: TAILQ_FOREACH(c, &clients, entry) {
85: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
86: continue;
87:
88: control_write(c, "%%window-pane-changed @%u %%%u", w->id,
89: w->active->id);
90: }
91: }
92:
93: void
1.13 nicm 94: control_notify_window_unlinked(__unused struct session *s, struct window *w)
1.1 nicm 95: {
96: struct client *c;
1.9 nicm 97: struct session *cs;
1.1 nicm 98:
1.11 nicm 99: TAILQ_FOREACH(c, &clients, entry) {
1.1 nicm 100: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
101: continue;
1.9 nicm 102: cs = c->session;
1.1 nicm 103:
1.9 nicm 104: if (winlink_find_by_window_id(&cs->windows, w->id) != NULL)
105: control_write(c, "%%window-close @%u", w->id);
106: else
107: control_write(c, "%%unlinked-window-close @%u", w->id);
1.1 nicm 108: }
109: }
110:
111: void
1.13 nicm 112: control_notify_window_linked(__unused struct session *s, struct window *w)
1.1 nicm 113: {
114: struct client *c;
115: struct session *cs;
116:
1.11 nicm 117: TAILQ_FOREACH(c, &clients, entry) {
1.1 nicm 118: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
119: continue;
120: cs = c->session;
121:
122: if (winlink_find_by_window_id(&cs->windows, w->id) != NULL)
1.7 nicm 123: control_write(c, "%%window-add @%u", w->id);
1.1 nicm 124: else
1.7 nicm 125: control_write(c, "%%unlinked-window-add @%u", w->id);
1.1 nicm 126: }
127: }
128:
129: void
130: control_notify_window_renamed(struct window *w)
131: {
132: struct client *c;
1.9 nicm 133: struct session *cs;
1.1 nicm 134:
1.11 nicm 135: TAILQ_FOREACH(c, &clients, entry) {
1.1 nicm 136: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
137: continue;
1.9 nicm 138: cs = c->session;
1.1 nicm 139:
1.9 nicm 140: if (winlink_find_by_window_id(&cs->windows, w->id) != NULL) {
141: control_write(c, "%%window-renamed @%u %s", w->id,
142: w->name);
143: } else {
144: control_write(c, "%%unlinked-window-renamed @%u %s",
145: w->id, w->name);
146: }
1.1 nicm 147: }
148: }
149:
150: void
1.21 nicm 151: control_notify_client_session_changed(struct client *cc)
1.1 nicm 152: {
1.21 nicm 153: struct client *c;
1.1 nicm 154: struct session *s;
155:
1.21 nicm 156: if (cc->session == NULL)
1.1 nicm 157: return;
1.21 nicm 158: s = cc->session;
1.1 nicm 159:
1.21 nicm 160: TAILQ_FOREACH(c, &clients, entry) {
161: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
162: continue;
163:
164: if (cc == c) {
165: control_write(c, "%%session-changed $%u %s", s->id,
166: s->name);
167: } else {
168: control_write(c, "%%client-session-changed %s $%u %s",
169: cc->name, s->id, s->name);
170: }
1.29 nicm 171: }
172: }
173:
174: void
175: control_notify_client_detached(struct client *cc)
176: {
177: struct client *c;
178:
179: TAILQ_FOREACH(c, &clients, entry) {
180: if (CONTROL_SHOULD_NOTIFY_CLIENT(c))
181: control_write(c, "%%client-detached %s", cc->name);
1.21 nicm 182: }
1.1 nicm 183: }
184:
185: void
186: control_notify_session_renamed(struct session *s)
187: {
188: struct client *c;
189:
1.11 nicm 190: TAILQ_FOREACH(c, &clients, entry) {
1.7 nicm 191: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
1.1 nicm 192: continue;
193:
1.7 nicm 194: control_write(c, "%%session-renamed $%u %s", s->id, s->name);
1.1 nicm 195: }
196: }
197:
198: void
1.13 nicm 199: control_notify_session_created(__unused struct session *s)
1.1 nicm 200: {
201: struct client *c;
202:
1.11 nicm 203: TAILQ_FOREACH(c, &clients, entry) {
1.7 nicm 204: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
1.1 nicm 205: continue;
206:
207: control_write(c, "%%sessions-changed");
208: }
209: }
210:
211: void
1.17 nicm 212: control_notify_session_closed(__unused struct session *s)
1.1 nicm 213: {
214: struct client *c;
215:
1.11 nicm 216: TAILQ_FOREACH(c, &clients, entry) {
1.7 nicm 217: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
1.1 nicm 218: continue;
219:
220: control_write(c, "%%sessions-changed");
1.21 nicm 221: }
222: }
223:
224: void
225: control_notify_session_window_changed(struct session *s)
226: {
227: struct client *c;
228:
229: TAILQ_FOREACH(c, &clients, entry) {
230: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
231: continue;
232:
233: control_write(c, "%%session-window-changed $%u @%u", s->id,
234: s->curw->window->id);
1.30 ! nicm 235: }
! 236: }
! 237:
! 238: void
! 239: control_notify_paste_buffer_changed(const char *name)
! 240: {
! 241: struct client *c;
! 242:
! 243: TAILQ_FOREACH(c, &clients, entry) {
! 244: if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
! 245: continue;
! 246:
! 247: control_write(c, "%%paste-changed %s", name);
1.1 nicm 248: }
249: }