diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2012-09-03 09:32:39 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2012-09-03 09:32:39 +0000 |
commit | dcbd7d70d7618d94ea0e2a7066fdc550a599f02f (patch) | |
tree | bb8613dab3edd49acd7e9bd9a9621c75730fb0f9 /usr.bin/tmux | |
parent | da3560bfe41be49fc07fe264351543d7ea0dc98f (diff) |
Send notifications to control clients. Also don't redraw client when
suspended.
Diffstat (limited to 'usr.bin/tmux')
-rw-r--r-- | usr.bin/tmux/Makefile | 3 | ||||
-rw-r--r-- | usr.bin/tmux/control-notify.c | 183 | ||||
-rw-r--r-- | usr.bin/tmux/control.c | 3 | ||||
-rw-r--r-- | usr.bin/tmux/notify.c | 18 | ||||
-rw-r--r-- | usr.bin/tmux/server-client.c | 6 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.h | 13 |
6 files changed, 212 insertions, 14 deletions
diff --git a/usr.bin/tmux/Makefile b/usr.bin/tmux/Makefile index 66db9ddb6df..cb75e9b73b2 100644 --- a/usr.bin/tmux/Makefile +++ b/usr.bin/tmux/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.59 2012/07/08 16:04:38 nicm Exp $ +# $OpenBSD: Makefile,v 1.60 2012/09/03 09:32:38 nicm Exp $ PROG= tmux SRCS= arguments.c \ @@ -81,6 +81,7 @@ SRCS= arguments.c \ cmd.c \ colour.c \ control.c \ + control-notify.c \ environ.c \ format.c \ grid-utf8.c \ diff --git a/usr.bin/tmux/control-notify.c b/usr.bin/tmux/control-notify.c new file mode 100644 index 00000000000..4e05dc944e6 --- /dev/null +++ b/usr.bin/tmux/control-notify.c @@ -0,0 +1,183 @@ +/* $OpenBSD: control-notify.c,v 1.1 2012/09/03 09:32:38 nicm Exp $ */ + +/* + * Copyright (c) 2012 Nicholas Marriott <nicm@users.sourceforge.net> + * Copyright (c) 2012 George Nachman <tmux@georgester.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> + +#include "tmux.h" + +#define CONTROL_SHOULD_NOTIFY_CLIENT(c) \ + ((c) != NULL && ((c)->flags & CLIENT_CONTROL)) + +void +control_notify_window_layout_changed(struct window *w) +{ + struct client *c; + struct session *s; + struct format_tree *ft; + struct winlink *wl; + u_int i; + const char *template; + + for (i = 0; i < ARRAY_LENGTH(&clients); i++) { + c = ARRAY_ITEM(&clients, i); + if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL) + continue; + s = c->session; + + if (winlink_find_by_window_id(&s->windows, w->id) == NULL) + continue; + + /* + * When the last pane in a window is closed it won't have a + * layout root and we don't need to inform the client about the + * layout change because the whole window will go away soon. + */ + if (w->layout_root == NULL) + continue; + template = "%layout-change #{window_id} #{window_layout}"; + + ft = format_create(); + wl = winlink_find_by_window(&s->windows, w); + if (wl != NULL) { + format_winlink(ft, c->session, wl); + control_write(c, "%s", format_expand(ft, template)); + } + format_free(ft); + } +} + +void +control_notify_window_unlinked(unused struct session *s, struct window *w) +{ + struct client *c; + struct session *cs; + u_int i; + + for (i = 0; i < ARRAY_LENGTH(&clients); i++) { + c = ARRAY_ITEM(&clients, i); + if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL) + continue; + cs = c->session; + + if (winlink_find_by_window_id(&cs->windows, w->id) != NULL) + control_write(c, "%%window-close %u", w->id); + else + control_write(c, "%%unlinked-window-close %u", w->id); + } +} + +void +control_notify_window_linked(unused struct session *s, struct window *w) +{ + struct client *c; + struct session *cs; + u_int i; + + for (i = 0; i < ARRAY_LENGTH(&clients); i++) { + c = ARRAY_ITEM(&clients, i); + if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL) + continue; + cs = c->session; + + if (winlink_find_by_window_id(&cs->windows, w->id) != NULL) + control_write(c, "%%window-add %u", w->id); + else + control_write(c, "%%unlinked-window-add %u", w->id); + } +} + +void +control_notify_window_renamed(struct window *w) +{ + struct client *c; + struct session *s; + u_int i; + + for (i = 0; i < ARRAY_LENGTH(&clients); i++) { + c = ARRAY_ITEM(&clients, i); + if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL) + continue; + s = c->session; + + if (winlink_find_by_window_id(&s->windows, w->id) != NULL) { + control_write(c, "%%window-renamed %u %s", + w->id, w->name); + } else { + control_write(c, "%%unlinked-window-renamed %u %s", + w->id, w->name); + } + } +} + +void +control_notify_attached_session_changed(struct client *c) +{ + struct session *s; + + if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL) + return; + s = c->session; + + control_write(c, "%%session-changed %d %s", s->idx, s->name); +} + +void +control_notify_session_renamed(struct session *s) +{ + struct client *c; + u_int i; + + for (i = 0; i < ARRAY_LENGTH(&clients); i++) { + c = ARRAY_ITEM(&clients, i); + if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session != s) + continue; + + control_write(c, "%%session-renamed %s", s->name); + } +} + +void +control_notify_session_created(unused struct session *s) +{ + struct client *c; + u_int i; + + for (i = 0; i < ARRAY_LENGTH(&clients); i++) { + c = ARRAY_ITEM(&clients, i); + if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL) + continue; + + control_write(c, "%%sessions-changed"); + } +} + +void +control_notify_session_close(unused struct session *s) +{ + struct client *c; + u_int i; + + for (i = 0; i < ARRAY_LENGTH(&clients); i++) { + c = ARRAY_ITEM(&clients, i); + if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL) + continue; + + control_write(c, "%%sessions-changed"); + } +} diff --git a/usr.bin/tmux/control.c b/usr.bin/tmux/control.c index d5e45b1e2ff..c858a55a47e 100644 --- a/usr.bin/tmux/control.c +++ b/usr.bin/tmux/control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.2 2012/07/10 11:53:01 nicm Exp $ */ +/* $OpenBSD: control.c,v 1.3 2012/09/03 09:32:38 nicm Exp $ */ /* * Copyright (c) 2012 Nicholas Marriott <nicm@users.sourceforge.net> @@ -28,7 +28,6 @@ void printflike2 control_msg_error(struct cmd_ctx *, const char *, ...); void printflike2 control_msg_print(struct cmd_ctx *, const char *, ...); void printflike2 control_msg_info(struct cmd_ctx *, const char *, ...); -void printflike2 control_write(struct client *, const char *, ...); /* Command error callback. */ void printflike2 diff --git a/usr.bin/tmux/notify.c b/usr.bin/tmux/notify.c index a157eb0dfd2..d0157dced55 100644 --- a/usr.bin/tmux/notify.c +++ b/usr.bin/tmux/notify.c @@ -1,4 +1,4 @@ -/* $OpenBSD: notify.c,v 1.3 2012/08/21 10:00:33 nicm Exp $ */ +/* $OpenBSD: notify.c,v 1.4 2012/09/03 09:32:38 nicm Exp $ */ /* * Copyright (c) 2012 George Nachman <tmux@georgester.com> @@ -95,28 +95,28 @@ notify_drain(void) TAILQ_FOREACH_SAFE(ne, ¬ify_queue, entry, ne1) { switch (ne->type) { case NOTIFY_WINDOW_LAYOUT_CHANGED: - /* control_notify_window_layout_changed(ne->window); */ + control_notify_window_layout_changed(ne->window); break; case NOTIFY_WINDOW_UNLINKED: - /* control_notify_window_unlinked(ne->session, ne->window); */ + control_notify_window_unlinked(ne->session, ne->window); break; case NOTIFY_WINDOW_LINKED: - /* control_notify_window_linked(ne->session, ne->window); */ + control_notify_window_linked(ne->session, ne->window); break; case NOTIFY_WINDOW_RENAMED: - /* control_notify_window_renamed(ne->window); */ + control_notify_window_renamed(ne->window); break; case NOTIFY_ATTACHED_SESSION_CHANGED: - /* control_notify_attached_session_changed(ne->client, ne->session); */ + control_notify_attached_session_changed(ne->client); break; case NOTIFY_SESSION_RENAMED: - /* control_notify_session_renamed(ne->session); */ + control_notify_session_renamed(ne->session); break; case NOTIFY_SESSION_CREATED: - /* control_notify_session_created(ne->session); */ + control_notify_session_created(ne->session); break; case NOTIFY_SESSION_CLOSED: - /* control_notify_session_close(ne->session); */ + control_notify_session_close(ne->session); break; } diff --git a/usr.bin/tmux/server-client.c b/usr.bin/tmux/server-client.c index ca937bd8549..16449d02f30 100644 --- a/usr.bin/tmux/server-client.c +++ b/usr.bin/tmux/server-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server-client.c,v 1.78 2012/07/11 07:10:15 nicm Exp $ */ +/* $OpenBSD: server-client.c,v 1.79 2012/09/03 09:32:38 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> @@ -603,6 +603,9 @@ server_client_check_redraw(struct client *c) struct window_pane *wp; int flags, redraw; + if (c->flags & CLIENT_SUSPENDED) + return; + flags = c->tty.flags & TTY_FREEZE; c->tty.flags &= ~TTY_FREEZE; @@ -900,6 +903,7 @@ server_client_msg_identify( if (data->flags & IDENTIFY_CONTROL) { c->stdin_callback = control_callback; c->flags |= (CLIENT_CONTROL|CLIENT_SUSPENDED); + server_write_client(c, MSG_STDIN, NULL, 0); c->tty.fd = -1; c->tty.log_fd = -1; diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index 6fda58fbfe3..a70e06c2a80 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.352 2012/08/21 10:00:33 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.353 2012/09/03 09:32:38 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -2215,6 +2215,17 @@ void clear_signals(int); /* control.c */ void control_callback(struct client *, int, void*); +void printflike2 control_write(struct client *, const char *, ...); + +/* control-notify.c */ +void control_notify_window_layout_changed(struct window *); +void control_notify_window_unlinked(struct session *, struct window *); +void control_notify_window_linked(struct session *, struct window *); +void control_notify_window_renamed(struct window *); +void control_notify_attached_session_changed(struct client *); +void control_notify_session_renamed(struct session *); +void control_notify_session_created(struct session *); +void control_notify_session_close(struct session *); /* session.c */ extern struct sessions sessions; |