From c8849ac990af34eef6b3516c392d1796b4fbeba3 Mon Sep 17 00:00:00 2001 From: Tiago Cunha Date: Sun, 12 Aug 2012 19:23:01 +0000 Subject: [PATCH] Sync OpenBSD patchset 1153: Add a queue of notifys and a way to turn them off and on (we do not want notifys to happen during some commands). Based on code from George Nachman. --- cmd-list.c | 4 ++ notify.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++++++--- tmux.h | 8 +-- 3 files changed, 146 insertions(+), 11 deletions(-) diff --git a/cmd-list.c b/cmd-list.c index 0557000e..1717ec3b 100644 --- a/cmd-list.c +++ b/cmd-list.c @@ -91,6 +91,8 @@ cmd_list_exec(struct cmd_list *cmdlist, struct cmd_ctx *ctx) if (c != NULL && c->session != NULL) guards = c->flags & CLIENT_CONTROL; + notify_disable(); + retval = 0; TAILQ_FOREACH(cmd, &cmdlist->list, qentry) { if (guards) @@ -128,6 +130,8 @@ cmd_list_exec(struct cmd_list *cmdlist, struct cmd_ctx *ctx) break; } } + + notify_enable(); return (retval); } diff --git a/notify.c b/notify.c index ddce6d76..7d7491b6 100644 --- a/notify.c +++ b/notify.c @@ -16,44 +16,173 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include +#include + +#include + #include "tmux.h" +enum notify_type { + NOTIFY_WINDOW_LAYOUT_CHANGED, + NOTIFY_WINDOW_UNLINKED, + NOTIFY_WINDOW_LINKED, + NOTIFY_WINDOW_RENAMED, + NOTIFY_ATTACHED_SESSION_CHANGED, + NOTIFY_SESSION_RENAMED, + NOTIFY_SESSION_CREATED, + NOTIFY_SESSION_CLOSED +}; + +struct notify_entry { + enum notify_type type; + + struct client *client; + struct session *session; + struct window *window; + + TAILQ_ENTRY(notify_entry) entry; +}; +TAILQ_HEAD(, notify_entry) notify_queue = TAILQ_HEAD_INITIALIZER(notify_queue); +int notify_enabled = 1; + +void notify_drain(void); +void notify_add(enum notify_type, struct client *, struct session *, + struct window *); + void -notify_window_layout_changed(unused struct window *w) +notify_enable(void) { + notify_enabled = 1; + notify_drain(); } void -notify_window_unlinked(unused struct session *s, unused struct window *w) +notify_disable(void) { + notify_enabled = 0; } void -notify_window_linked(unused struct session *s, unused struct window *w) +notify_add(enum notify_type type, struct client *c, struct session *s, + struct window *w) { + struct notify_entry *ne; + + ne = xcalloc(1, sizeof *ne); + ne->type = type; + ne->client = c; + ne->session = s; + ne->window = w; + TAILQ_INSERT_TAIL(¬ify_queue, ne, entry); + + if (c != NULL) + c->references++; + if (s != NULL) + s->references++; + if (w != NULL) + w->references++; } void -notify_window_renamed(unused struct window *w) +notify_drain(void) { + struct notify_entry *ne, *ne1; + + if (!notify_enabled) + return; + + TAILQ_FOREACH_SAFE(ne, ¬ify_queue, entry, ne1) { + switch (ne->type) { + case NOTIFY_WINDOW_LAYOUT_CHANGED: + /* control_notify_window_layout_changed(ne->window); */ + break; + case NOTIFY_WINDOW_UNLINKED: + /* control_notify_window_unlinked(ne->session, ne->window); */ + break; + case NOTIFY_WINDOW_LINKED: + /* control_notify_window_linked(ne->session, ne->window); */ + break; + case NOTIFY_WINDOW_RENAMED: + /* control_notify_window_renamed(ne->window); */ + break; + case NOTIFY_ATTACHED_SESSION_CHANGED: + /* control_notify_attached_session_changed(ne->client, ne->session); */ + break; + case NOTIFY_SESSION_RENAMED: + /* control_notify_session_renamed(ne->session); */ + break; + case NOTIFY_SESSION_CREATED: + /* control_notify_session_created(ne->session); */ + break; + case NOTIFY_SESSION_CLOSED: + /* control_notify_session_close(ne->session); */ + break; + } + + if (ne->client != NULL) + ne->client->references--; + if (ne->session != NULL) + ne->session->references--; + if (ne->window != NULL) + ne->window->references--; + TAILQ_REMOVE(¬ify_queue, ne, entry); + free(ne); + } } void -notify_attached_session_changed(unused struct client *c) +notify_window_layout_changed(struct window *w) { + notify_add(NOTIFY_WINDOW_LAYOUT_CHANGED, NULL, NULL, w); + notify_drain(); } void -notify_session_renamed(unused struct session *s) +notify_window_unlinked(struct session *s, struct window *w) { + notify_add(NOTIFY_WINDOW_UNLINKED, NULL, s, w); + notify_drain(); } void -notify_session_created(unused struct session *s) +notify_window_linked(struct session *s, struct window *w) { + notify_add(NOTIFY_WINDOW_LINKED, NULL, s, w); + notify_drain(); } void -notify_session_closed(unused struct session *s) +notify_window_renamed(struct window *w) { + notify_add(NOTIFY_WINDOW_RENAMED, NULL, NULL, w); + notify_drain(); +} + +void +notify_attached_session_changed(struct client *c) +{ + notify_add(NOTIFY_ATTACHED_SESSION_CHANGED, c, NULL, NULL); + notify_drain(); +} + +void +notify_session_renamed(struct session *s) +{ + notify_add(NOTIFY_SESSION_RENAMED, NULL, s, NULL); + notify_drain(); +} + +void +notify_session_created(struct session *s) +{ + notify_add(NOTIFY_SESSION_CREATED, NULL, s, NULL); + notify_drain(); +} + +void +notify_session_closed(struct session *s) +{ + notify_add(NOTIFY_SESSION_CLOSED, NULL, s, NULL); + notify_drain(); } diff --git a/tmux.h b/tmux.h index 49f053f3..223d5e94 100644 --- a/tmux.h +++ b/tmux.h @@ -1480,6 +1480,8 @@ void mode_key_init(struct mode_key_data *, struct mode_key_tree *); enum mode_key_cmd mode_key_lookup(struct mode_key_data *, int); /* notify.c */ +void notify_enable(void); +void notify_disable(void); void notify_window_layout_changed(struct window *); void notify_window_unlinked(struct session *, struct window *); void notify_window_linked(struct session *, struct window *); @@ -2158,11 +2160,11 @@ void queue_window_name(struct window *); char *default_window_name(struct window *); /* signal.c */ -void set_signals(void(*)(int, short, void *)); -void clear_signals(int); +void set_signals(void(*)(int, short, void *)); +void clear_signals(int); /* control.c */ -void control_callback(struct client *, int, void*); +void control_callback(struct client *, int, void*); /* session.c */ extern struct sessions sessions;