version 1.14, 2016/10/16 19:04:05 |
version 1.15, 2016/10/16 19:15:02 |
|
|
struct client *client; |
struct client *client; |
struct session *session; |
struct session *session; |
struct window *window; |
struct window *window; |
|
|
TAILQ_ENTRY(notify_entry) entry; |
|
}; |
}; |
TAILQ_HEAD(notify_queue, notify_entry); |
|
static struct notify_queue notify_queue = TAILQ_HEAD_INITIALIZER(notify_queue); |
|
|
|
static void notify_add(enum notify_type, struct client *, struct session *, |
|
struct window *); |
|
|
|
static void |
static void |
notify_hook(struct notify_entry *ne) |
notify_hook(struct cmdq_item *item, struct notify_entry *ne) |
{ |
{ |
const char *name; |
const char *name; |
struct cmd_find_state fs; |
struct cmd_find_state fs; |
|
|
cmd_find_from_window(&fs, ne->window); |
cmd_find_from_window(&fs, ne->window); |
else if (ne->session != NULL) |
else if (ne->session != NULL) |
cmd_find_from_session(&fs, ne->session); |
cmd_find_from_session(&fs, ne->session); |
|
else |
|
cmd_find_current(&fs, item, CMD_FIND_QUIET); |
if (cmd_find_empty_state(&fs) || !cmd_find_valid_state(&fs)) |
if (cmd_find_empty_state(&fs) || !cmd_find_valid_state(&fs)) |
return; |
return; |
|
|
|
|
for (loop = new_item; loop != NULL; loop = loop->next) |
for (loop = new_item; loop != NULL; loop = loop->next) |
loop->hook = xstrdup(name); |
loop->hook = xstrdup(name); |
|
|
cmdq_append(NULL, new_item); |
cmdq_insert_after(item, new_item); |
} |
} |
|
|
|
static enum cmd_retval |
|
notify_callback(struct cmdq_item *item, void *data) |
|
{ |
|
struct notify_entry *ne = data; |
|
|
|
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); |
|
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_closed(ne->session); |
|
break; |
|
} |
|
notify_hook(item, ne); |
|
|
|
if (ne->client != NULL) |
|
server_client_unref(ne->client); |
|
if (ne->session != NULL) |
|
session_unref(ne->session); |
|
if (ne->window != NULL) |
|
window_remove_ref(ne->window); |
|
free(ne); |
|
|
|
return (CMD_RETURN_NORMAL); |
|
} |
|
|
static void |
static void |
notify_add(enum notify_type type, struct client *c, struct session *s, |
notify_add(enum notify_type type, struct client *c, struct session *s, |
struct window *w) |
struct window *w) |
{ |
{ |
struct notify_entry *ne; |
struct notify_entry *ne; |
|
struct cmdq_item *new_item; |
|
|
ne = xcalloc(1, sizeof *ne); |
ne = xcalloc(1, sizeof *ne); |
ne->type = type; |
ne->type = type; |
ne->client = c; |
ne->client = c; |
ne->session = s; |
ne->session = s; |
ne->window = w; |
ne->window = w; |
TAILQ_INSERT_TAIL(¬ify_queue, ne, entry); |
|
|
|
if (c != NULL) |
if (c != NULL) |
c->references++; |
c->references++; |
|
|
s->references++; |
s->references++; |
if (w != NULL) |
if (w != NULL) |
w->references++; |
w->references++; |
} |
|
|
|
void |
new_item = cmdq_get_callback(notify_callback, ne); |
notify_drain(void) |
cmdq_append(NULL, new_item); |
{ |
|
struct notify_entry *ne, *ne1; |
|
|
|
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); |
|
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_closed(ne->session); |
|
break; |
|
} |
|
TAILQ_REMOVE(¬ify_queue, ne, entry); |
|
notify_hook(ne); |
|
|
|
if (ne->client != NULL) |
|
server_client_unref(ne->client); |
|
if (ne->session != NULL) |
|
session_unref(ne->session); |
|
if (ne->window != NULL) |
|
window_remove_ref(ne->window); |
|
free(ne); |
|
} |
|
} |
} |
|
|
void |
void |
|
|
notify_window_layout_changed(struct window *w) |
notify_window_layout_changed(struct window *w) |
{ |
{ |
notify_add(NOTIFY_WINDOW_LAYOUT_CHANGED, NULL, NULL, w); |
notify_add(NOTIFY_WINDOW_LAYOUT_CHANGED, NULL, NULL, w); |
notify_drain(); |
|
} |
} |
|
|
void |
void |
notify_window_unlinked(struct session *s, struct window *w) |
notify_window_unlinked(struct session *s, struct window *w) |
{ |
{ |
notify_add(NOTIFY_WINDOW_UNLINKED, NULL, s, w); |
notify_add(NOTIFY_WINDOW_UNLINKED, NULL, s, w); |
notify_drain(); |
|
} |
} |
|
|
void |
void |
notify_window_linked(struct session *s, struct window *w) |
notify_window_linked(struct session *s, struct window *w) |
{ |
{ |
notify_add(NOTIFY_WINDOW_LINKED, NULL, s, w); |
notify_add(NOTIFY_WINDOW_LINKED, NULL, s, w); |
notify_drain(); |
|
} |
} |
|
|
void |
void |
notify_window_renamed(struct window *w) |
notify_window_renamed(struct window *w) |
{ |
{ |
notify_add(NOTIFY_WINDOW_RENAMED, NULL, NULL, w); |
notify_add(NOTIFY_WINDOW_RENAMED, NULL, NULL, w); |
notify_drain(); |
|
} |
} |
|
|
void |
void |
notify_attached_session_changed(struct client *c) |
notify_attached_session_changed(struct client *c) |
{ |
{ |
notify_add(NOTIFY_ATTACHED_SESSION_CHANGED, c, NULL, NULL); |
notify_add(NOTIFY_ATTACHED_SESSION_CHANGED, c, NULL, NULL); |
notify_drain(); |
|
} |
} |
|
|
void |
void |
notify_session_renamed(struct session *s) |
notify_session_renamed(struct session *s) |
{ |
{ |
notify_add(NOTIFY_SESSION_RENAMED, NULL, s, NULL); |
notify_add(NOTIFY_SESSION_RENAMED, NULL, s, NULL); |
notify_drain(); |
|
} |
} |
|
|
void |
void |
notify_session_created(struct session *s) |
notify_session_created(struct session *s) |
{ |
{ |
notify_add(NOTIFY_SESSION_CREATED, NULL, s, NULL); |
notify_add(NOTIFY_SESSION_CREATED, NULL, s, NULL); |
notify_drain(); |
|
} |
} |
|
|
void |
void |
notify_session_closed(struct session *s) |
notify_session_closed(struct session *s) |
{ |
{ |
notify_add(NOTIFY_SESSION_CLOSED, NULL, s, NULL); |
notify_add(NOTIFY_SESSION_CLOSED, NULL, s, NULL); |
notify_drain(); |
|
} |
} |