From c073ff710bfe98095f55e35aeb9e7ceec8253365 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 6 Jul 2026 10:27:10 +0100 Subject: [PATCH] Get rid of notify. --- Makefile.am | 1 - alerts.c | 6 +-- cmd-attach-session.c | 2 +- cmd-break-pane.c | 2 +- cmd-join-pane.c | 12 ++--- cmd-new-session.c | 2 +- cmd-rename-session.c | 11 +++- cmd-resize-pane.c | 2 +- cmd-select-layout.c | 2 +- cmd-select-pane.c | 10 +++- cmd-split-window.c | 9 +++- cmd-swap-pane.c | 4 +- events.c | 85 ++++++++++++++++++++++++++++++ input.c | 25 +++++++-- layout-custom.c | 2 +- layout-set.c | 12 ++--- layout.c | 4 +- notify.c | 120 ------------------------------------------- paste.c | 22 +++++--- resize.c | 4 +- server-client.c | 12 ++--- server-fn.c | 32 ++++++++++-- session.c | 14 ++--- spawn.c | 6 +-- tmux.h | 14 ++--- tty-keys.c | 4 +- window-copy.c | 4 +- window.c | 58 +++++++++++++++++---- 28 files changed, 277 insertions(+), 204 deletions(-) delete mode 100644 notify.c diff --git a/Makefile.am b/Makefile.am index 305ce0d83..d0f3634f3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -184,7 +184,6 @@ dist_tmux_SOURCES = \ mode-tree.c \ monitor.c \ names.c \ - notify.c \ options-table.c \ options.c \ paste.c \ diff --git a/alerts.c b/alerts.c index 81c41fa6a..8e989820e 100644 --- a/alerts.c +++ b/alerts.c @@ -205,7 +205,7 @@ alerts_check_bell(struct window *w) } if (!alerts_action_applies(wl, "bell-action")) continue; - notify_winlink("alert-bell", wl); + events_fire_winlink("alert-bell", wl); if (s->flags & SESSION_ALERTED) continue; @@ -241,7 +241,7 @@ alerts_check_activity(struct window *w) } if (!alerts_action_applies(wl, "activity-action")) continue; - notify_winlink("alert-activity", wl); + events_fire_winlink("alert-activity", wl); if (s->flags & SESSION_ALERTED) continue; @@ -277,7 +277,7 @@ alerts_check_silence(struct window *w) } if (!alerts_action_applies(wl, "silence-action")) continue; - notify_winlink("alert-silence", wl); + events_fire_winlink("alert-silence", wl); if (s->flags & SESSION_ALERTED) continue; diff --git a/cmd-attach-session.c b/cmd-attach-session.c index 32b1e0cbd..3a537e4de 100644 --- a/cmd-attach-session.c +++ b/cmd-attach-session.c @@ -163,7 +163,7 @@ cmd_attach_session(struct cmdq_item *item, const char *tflag, int dflag, if (~c->flags & CLIENT_CONTROL) proc_send(c->peer, MSG_READY, -1, NULL, 0); - notify_client("client-attached", c); + events_fire_client("client-attached", c); c->flags |= CLIENT_ATTACHED; } diff --git a/cmd-break-pane.c b/cmd-break-pane.c index b49110bdb..f13f251ea 100644 --- a/cmd-break-pane.c +++ b/cmd-break-pane.c @@ -82,7 +82,7 @@ cmd_break_pane_float(struct cmdq_item *item, struct args *args, window_set_active_pane(w, wp, 1); layout_fix_offsets(w); layout_fix_panes(w, NULL); - notify_window("window-layout-changed", w); + events_fire_window("window-layout-changed", w); server_redraw_window(w); return (CMD_RETURN_NORMAL); diff --git a/cmd-join-pane.c b/cmd-join-pane.c index 99b2e80f7..060e4cdfe 100644 --- a/cmd-join-pane.c +++ b/cmd-join-pane.c @@ -185,7 +185,7 @@ cmd_join_pane_place(struct cmdq_item *item, struct winlink *wl, lc->yoff = yoff; layout_fix_panes(w, NULL); } - notify_window("window-layout-changed", w); + events_fire_window("window-layout-changed", w); server_redraw_window(w); return (CMD_RETURN_NORMAL); @@ -255,7 +255,7 @@ cmd_join_pane_move(struct cmdq_item *item, struct args *args, lc->xoff = xoff; lc->yoff = yoff; layout_fix_panes(w, NULL); - notify_window("window-layout-changed", w); + events_fire_window("window-layout-changed", w); server_redraw_window(w); } @@ -357,7 +357,7 @@ cmd_join_pane_zindex(struct cmdq_item *item, struct winlink *wl, else TAILQ_INSERT_TAIL(&w->z_index, wp, zentry); - notify_window("window-layout-changed", w); + events_fire_window("window-layout-changed", w); server_redraw_window(w); return (CMD_RETURN_NORMAL); @@ -395,7 +395,7 @@ cmd_join_pane_tile(struct cmdq_item *item, struct args *args, struct window *w, window_set_active_pane(w, wp, 1); layout_fix_offsets(w); layout_fix_panes(w, NULL); - notify_window("window-layout-changed", w); + events_fire_window("window-layout-changed", w); server_redraw_window(w); return (CMD_RETURN_NORMAL); @@ -499,8 +499,8 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item) if (window_count_panes(src_w, 1) == 0) server_kill_window(src_w, 1); else - notify_window("window-layout-changed", src_w); - notify_window("window-layout-changed", dst_w); + events_fire_window("window-layout-changed", src_w); + events_fire_window("window-layout-changed", dst_w); return (CMD_RETURN_NORMAL); } diff --git a/cmd-new-session.c b/cmd-new-session.c index ba02c72d4..01777ceaf 100644 --- a/cmd-new-session.c +++ b/cmd-new-session.c @@ -325,7 +325,7 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item) session_group_synchronize_to(s); session_select(s, RB_MIN(winlinks, &s->windows)->idx); } - notify_session("session-created", s); + events_fire_session("session-created", s); /* * Set the client to the new session. If a command client exists, it is diff --git a/cmd-rename-session.c b/cmd-rename-session.c index b399483b8..f8dcddfd5 100644 --- a/cmd-rename-session.c +++ b/cmd-rename-session.c @@ -49,6 +49,8 @@ cmd_rename_session_exec(struct cmd *self, struct cmdq_item *item) struct args *args = cmd_get_args(self); struct cmd_find_state *target = cmdq_get_target(item); struct session *s = target->s; + struct event_payload *ep; + struct cmd_find_state fs; char *newname, *tmp; tmp = format_single_from_target(item, args_string(args, 0)); @@ -69,13 +71,20 @@ cmd_rename_session_exec(struct cmd *self, struct cmdq_item *item) return (CMD_RETURN_ERROR); } + ep = event_payload_create(); + cmd_find_from_session(&fs, s, 0); + event_payload_set_target(ep, &fs); + event_payload_set_session(ep, "session", s); + event_payload_set_string(ep, "old_name", "%s", s->name); + event_payload_set_string(ep, "new_name", "%s", newname); + RB_REMOVE(sessions, &sessions, s); free(s->name); s->name = newname; RB_INSERT(sessions, &sessions, s); server_status_session(s); - notify_session("session-renamed", s); + events_fire("session-renamed", ep); return (CMD_RETURN_NORMAL); } diff --git a/cmd-resize-pane.c b/cmd-resize-pane.c index 348923528..2e605018a 100644 --- a/cmd-resize-pane.c +++ b/cmd-resize-pane.c @@ -182,7 +182,7 @@ cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item) if (lc->parent != NULL) layout_fix_offsets(w); layout_fix_panes(w, NULL); - notify_window("window-layout-changed", w); + events_fire_window("window-layout-changed", w); server_redraw_window(w); return (CMD_RETURN_NORMAL); diff --git a/cmd-select-layout.c b/cmd-select-layout.c index 417797472..f6455dad2 100644 --- a/cmd-select-layout.c +++ b/cmd-select-layout.c @@ -139,7 +139,7 @@ changed: free(oldlayout); recalculate_sizes(); server_redraw_window(w); - notify_window("window-layout-changed", w); + events_fire_window("window-layout-changed", w); return (CMD_RETURN_NORMAL); error: diff --git a/cmd-select-pane.c b/cmd-select-pane.c index d146ea6cf..3cc630d24 100644 --- a/cmd-select-pane.c +++ b/cmd-select-pane.c @@ -88,6 +88,8 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item) struct cmd_find_state *current = cmdq_get_current(item); struct cmd_find_state *target = cmdq_get_target(item); struct client *c = cmdq_get_client(item); + struct event_payload *ep; + struct cmd_find_state fs; struct winlink *wl = target->wl; struct window *w = wl->window; struct session *s = target->s; @@ -218,7 +220,13 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item) if (args_has(args, 'T')) { title = format_single_from_target(item, args_get(args, 'T')); if (screen_set_title(&wp->base, title, 0)) { - notify_pane("pane-title-changed", wp); + ep = event_payload_create(); + cmd_find_from_pane(&fs, wp, 0); + event_payload_set_target(ep, &fs); + event_payload_set_pane(ep, "pane", wp); + event_payload_set_window(ep, "window", wp->window); + event_payload_set_string(ep, "new_title", "%s", title); + events_fire("pane-title-changed", ep); server_redraw_window_borders(wp->window); server_status_window(wp->window); } diff --git a/cmd-split-window.c b/cmd-split-window.c index 4963d40f0..426038b86 100644 --- a/cmd-split-window.c +++ b/cmd-split-window.c @@ -83,6 +83,7 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item) struct window *w = wl->window; struct window_pane *wp = target->wp, *new_wp = NULL; struct layout_cell *lc = NULL; + struct event_payload *ep; struct cmd_find_state fs; int input, empty, is_floating, flags = 0; const char *template, *style, *value; @@ -217,7 +218,13 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item) if (args_has(args, 'T')) { title = format_single_from_target(item, args_get(args, 'T')); screen_set_title(&new_wp->base, title, 0); - notify_pane("pane-title-changed", new_wp); + ep = event_payload_create(); + cmd_find_from_pane(&fs, new_wp, 0); + event_payload_set_target(ep, &fs); + event_payload_set_pane(ep, "pane", new_wp); + event_payload_set_window(ep, "window", new_wp->window); + event_payload_set_string(ep, "new_title", "%s", title); + events_fire("pane-title-changed", ep); free(title); } diff --git a/cmd-swap-pane.c b/cmd-swap-pane.c index 7f5160e65..ebe5916a4 100644 --- a/cmd-swap-pane.c +++ b/cmd-swap-pane.c @@ -180,9 +180,9 @@ cmd_swap_pane_exec(struct cmd *self, struct cmdq_item *item) redraw_invalidate_scene(dst_w); server_redraw_window(dst_w); - notify_window("window-layout-changed", src_w); + events_fire_window("window-layout-changed", src_w); if (src_w != dst_w) - notify_window("window-layout-changed", dst_w); + events_fire_window("window-layout-changed", dst_w); out: if (window_pop_zoom(src_w)) diff --git a/events.c b/events.c index 4893c1f71..8ae5de102 100644 --- a/events.c +++ b/events.c @@ -110,3 +110,88 @@ events_fire(const char *name, struct event_payload *ep) events_free_dead(); event_payload_free(ep); } + +/* Fire a client event. */ +void +events_fire_client(const char *name, struct client *c) +{ + struct event_payload *ep; + struct cmd_find_state fs; + + ep = event_payload_create(); + cmd_find_from_client(&fs, c, 0); + event_payload_set_target(ep, &fs); + event_payload_set_client(ep, "client", c); + if (fs.s != NULL) + event_payload_set_session(ep, "session", fs.s); + if (fs.w != NULL) + event_payload_set_window(ep, "window", fs.w); + if (fs.wl != NULL) + event_payload_set_int(ep, "window_index", fs.wl->idx); + else if (fs.idx != -1) + event_payload_set_int(ep, "window_index", fs.idx); + if (fs.wp != NULL) + event_payload_set_pane(ep, "pane", fs.wp); + events_fire(name, ep); +} + +/* Fire a session event. */ +void +events_fire_session(const char *name, struct session *s) +{ + struct event_payload *ep; + struct cmd_find_state fs; + + ep = event_payload_create(); + if (session_alive(s)) { + cmd_find_from_session(&fs, s, 0); + event_payload_set_target(ep, &fs); + } + event_payload_set_session(ep, "session", s); + events_fire(name, ep); +} + +/* Fire a window event. */ +void +events_fire_window(const char *name, struct window *w) +{ + struct event_payload *ep; + struct cmd_find_state fs; + + ep = event_payload_create(); + cmd_find_from_window(&fs, w, 0); + event_payload_set_target(ep, &fs); + event_payload_set_window(ep, "window", w); + events_fire(name, ep); +} + +/* Fire a pane event. */ +void +events_fire_pane(const char *name, struct window_pane *wp) +{ + struct event_payload *ep; + struct cmd_find_state fs; + + ep = event_payload_create(); + cmd_find_from_pane(&fs, wp, 0); + event_payload_set_target(ep, &fs); + event_payload_set_pane(ep, "pane", wp); + event_payload_set_window(ep, "window", wp->window); + events_fire(name, ep); +} + +/* Fire a winlink event. */ +void +events_fire_winlink(const char *name, struct winlink *wl) +{ + struct event_payload *ep; + struct cmd_find_state fs; + + ep = event_payload_create(); + cmd_find_from_winlink(&fs, wl, 0); + event_payload_set_target(ep, &fs); + event_payload_set_session(ep, "session", wl->session); + event_payload_set_window(ep, "window", wl->window); + event_payload_set_int(ep, "window_index", wl->idx); + events_fire(name, ep); +} diff --git a/input.c b/input.c index 5f7f9d132..7741aca4f 100644 --- a/input.c +++ b/input.c @@ -174,6 +174,8 @@ static void input_osc_110(struct input_ctx *, const char *); static void input_osc_111(struct input_ctx *, const char *); static void input_osc_112(struct input_ctx *, const char *); static void input_osc_133(struct input_ctx *, const char *); +static void input_fire_pane_title_changed(struct window_pane *, + const char *); /* Transition entry/exit handlers. */ static void input_clear(struct input_ctx *); @@ -210,6 +212,21 @@ static int input_end_bel(struct input_ctx *); /* Command table comparison function. */ static int input_table_compare(const void *, const void *); +static void +input_fire_pane_title_changed(struct window_pane *wp, const char *title) +{ + struct event_payload *ep; + struct cmd_find_state fs; + + ep = event_payload_create(); + cmd_find_from_pane(&fs, wp, 0); + event_payload_set_target(ep, &fs); + event_payload_set_pane(ep, "pane", wp); + event_payload_set_window(ep, "window", wp->window); + event_payload_set_string(ep, "new_title", "%s", title); + events_fire("pane-title-changed", ep); +} + /* Command table entry. */ struct input_table_entry { int ch; @@ -2180,7 +2197,7 @@ input_csi_dispatch_winops(struct input_ctx *ictx) screen_pop_title(sctx->s); if (wp == NULL) break; - notify_pane("pane-title-changed", wp); + events_fire_pane("pane-title-changed", wp); server_redraw_window_borders(w); server_status_window(w); break; @@ -2700,7 +2717,7 @@ input_exit_osc(struct input_ctx *ictx) if (wp != NULL && options_get_number(wp->options, "allow-set-title") && screen_set_title(sctx->s, p, 1)) { - notify_pane("pane-title-changed", wp); + input_fire_pane_title_changed(wp, p); server_redraw_window_borders(wp->window); server_status_window(wp->window); } @@ -2778,7 +2795,7 @@ input_exit_apc(struct input_ctx *ictx) if (wp != NULL && options_get_number(wp->options, "allow-set-title") && screen_set_title(sctx->s, ictx->input_buf, 1)) { - notify_pane("pane-title-changed", wp); + input_fire_pane_title_changed(wp, ictx->input_buf); server_redraw_window_borders(wp->window); server_status_window(wp->window); } @@ -3289,7 +3306,7 @@ input_osc_52(struct input_ctx *ictx, const char *p) screen_write_start_pane(&ctx, wp, NULL); screen_write_setselection(&ctx, clip, out, outlen); screen_write_stop(&ctx); - notify_pane("pane-set-clipboard", wp); + events_fire_pane("pane-set-clipboard", wp); paste_add(NULL, out, outlen); } } diff --git a/layout-custom.c b/layout-custom.c index c5a348ac0..9ae07f28a 100644 --- a/layout-custom.c +++ b/layout-custom.c @@ -286,7 +286,7 @@ layout_parse(struct window *w, const char *layout, char **cause) recalculate_sizes(); layout_print_cell(tiled_lc, __func__, 0); - notify_window("window-layout-changed", w); + events_fire_window("window-layout-changed", w); return (0); diff --git a/layout-set.c b/layout-set.c index cf78585c2..337ee6fc7 100644 --- a/layout-set.c +++ b/layout-set.c @@ -183,7 +183,7 @@ layout_set_even(struct window *w, enum layout_type type) layout_print_cell(w->layout_root, __func__, 1); window_resize(w, lcroot->sx, lcroot->sy, -1, -1); - notify_window("window-layout-changed", w); + events_fire_window("window-layout-changed", w); server_redraw_window(w); } @@ -292,7 +292,7 @@ layout_set_main_h(struct window *w) layout_print_cell(w->layout_root, __func__, 1); window_resize(w, lcroot->sx, lcroot->sy, -1, -1); - notify_window("window-layout-changed", w); + events_fire_window("window-layout-changed", w); server_redraw_window(w); } @@ -389,7 +389,7 @@ layout_set_main_h_mirrored(struct window *w) layout_print_cell(w->layout_root, __func__, 1); window_resize(w, lcroot->sx, lcroot->sy, -1, -1); - notify_window("window-layout-changed", w); + events_fire_window("window-layout-changed", w); server_redraw_window(w); } @@ -486,7 +486,7 @@ layout_set_main_v(struct window *w) layout_print_cell(w->layout_root, __func__, 1); window_resize(w, lcroot->sx, lcroot->sy, -1, -1); - notify_window("window-layout-changed", w); + events_fire_window("window-layout-changed", w); server_redraw_window(w); } @@ -584,7 +584,7 @@ layout_set_main_v_mirrored(struct window *w) layout_print_cell(w->layout_root, __func__, 1); window_resize(w, lcroot->sx, lcroot->sy, -1, -1); - notify_window("window-layout-changed", w); + events_fire_window("window-layout-changed", w); server_redraw_window(w); } @@ -706,6 +706,6 @@ layout_set_tiled(struct window *w) layout_print_cell(w->layout_root, __func__, 1); window_resize(w, lcroot->sx, lcroot->sy, -1, -1); - notify_window("window-layout-changed", w); + events_fire_window("window-layout-changed", w); server_redraw_window(w); } diff --git a/layout.c b/layout.c index f020ef8ba..2012420d1 100644 --- a/layout.c +++ b/layout.c @@ -953,7 +953,7 @@ layout_resize_layout(struct window *w, struct layout_cell *lc, /* Fix cell offsets. */ layout_fix_offsets(w); layout_fix_panes(w, NULL); - notify_window("window-layout-changed", w); + events_fire_window("window-layout-changed", w); } /* Resize a single pane within the layout. */ @@ -1498,7 +1498,7 @@ layout_close_pane(struct window_pane *wp) layout_fix_offsets(w); layout_fix_panes(w, NULL); } - notify_window("window-layout-changed", w); + events_fire_window("window-layout-changed", w); } /* Spread out cells inside a parent cell. */ diff --git a/notify.c b/notify.c deleted file mode 100644 index 675cd9610..000000000 --- a/notify.c +++ /dev/null @@ -1,120 +0,0 @@ -/* $OpenBSD$ */ - -/* - * Copyright (c) 2012 George Nachman - * - * 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 - -#include "tmux.h" - -void -notify_client(const char *name, struct client *c) -{ - struct event_payload *ep; - struct cmd_find_state fs; - - ep = event_payload_create(); - cmd_find_from_client(&fs, c, 0); - event_payload_set_target(ep, &fs); - event_payload_set_client(ep, "client", c); - events_fire(name, ep); -} - -void -notify_session(const char *name, struct session *s) -{ - struct event_payload *ep; - struct cmd_find_state fs; - - ep = event_payload_create(); - if (session_alive(s)) { - cmd_find_from_session(&fs, s, 0); - event_payload_set_target(ep, &fs); - } - event_payload_set_session(ep, "session", s); - events_fire(name, ep); -} - -void -notify_winlink(const char *name, struct winlink *wl) -{ - struct event_payload *ep; - struct cmd_find_state fs; - - ep = event_payload_create(); - cmd_find_from_winlink(&fs, wl, 0); - event_payload_set_target(ep, &fs); - event_payload_set_session(ep, "session", wl->session); - event_payload_set_window(ep, "window", wl->window); - event_payload_set_int(ep, "window_index", wl->idx); - events_fire(name, ep); -} - -void -notify_session_window(const char *name, struct session *s, struct window *w) -{ - struct event_payload *ep; - struct cmd_find_state fs; - - ep = event_payload_create(); - if (session_alive(s)) { - cmd_find_from_session_window(&fs, s, w, 0); - event_payload_set_target(ep, &fs); - } - event_payload_set_session(ep, "session", s); - event_payload_set_window(ep, "window", w); - events_fire(name, ep); -} - -void -notify_window(const char *name, struct window *w) -{ - struct event_payload *ep; - struct cmd_find_state fs; - - ep = event_payload_create(); - cmd_find_from_window(&fs, w, 0); - event_payload_set_target(ep, &fs); - event_payload_set_window(ep, "window", w); - events_fire(name, ep); -} - -void -notify_pane(const char *name, struct window_pane *wp) -{ - struct event_payload *ep; - struct cmd_find_state fs; - - ep = event_payload_create(); - cmd_find_from_pane(&fs, wp, 0); - event_payload_set_target(ep, &fs); - event_payload_set_pane(ep, "pane", wp); - event_payload_set_window(ep, "window", wp->window); - events_fire(name, ep); -} - -void -notify_paste_buffer(const char *pbname, int deleted) -{ - struct event_payload *ep; - - ep = event_payload_create(); - event_payload_set_string(ep, "paste_buffer", "%s", pbname); - if (deleted) - events_fire("paste-buffer-deleted", ep); - else - events_fire("paste-buffer-changed", ep); -} diff --git a/paste.c b/paste.c index 5ee80afd1..caa591f3e 100644 --- a/paste.c +++ b/paste.c @@ -43,6 +43,16 @@ static int paste_cmp_times(const struct paste_buffer *, const struct paste_buffer *); RB_GENERATE_STATIC(paste_time_tree, paste_buffer, time_entry, paste_cmp_times); +static void +paste_fire_event(const char *name, const char *pbname) +{ + struct event_payload *ep; + + ep = event_payload_create(); + event_payload_set_string(ep, "paste_buffer", "%s", pbname); + events_fire(name, ep); +} + static int paste_cmp_names(const struct paste_buffer *a, const struct paste_buffer *b) { @@ -137,7 +147,7 @@ paste_get_name(const char *name) void paste_free(struct paste_buffer *pb) { - notify_paste_buffer(pb->name, 1); + paste_fire_event("paste-buffer-deleted", pb->name); RB_REMOVE(paste_name_tree, &paste_by_name, pb); RB_REMOVE(paste_time_tree, &paste_by_time, pb); @@ -195,7 +205,7 @@ paste_add(const char *prefix, char *data, size_t size) RB_INSERT(paste_name_tree, &paste_by_name, pb); RB_INSERT(paste_time_tree, &paste_by_time, pb); - notify_paste_buffer(pb->name, 0); + paste_fire_event("paste-buffer-changed", pb->name); } /* Rename a paste buffer. */ @@ -253,8 +263,8 @@ paste_rename(const char *oldname, const char *newname, char **cause) RB_INSERT(paste_name_tree, &paste_by_name, pb); - notify_paste_buffer(oldname, 1); - notify_paste_buffer(pb->name, 0); + paste_fire_event("paste-buffer-deleted", oldname); + paste_fire_event("paste-buffer-changed", pb->name); return (0); } @@ -311,7 +321,7 @@ paste_set(char *data, size_t size, const char *name, char **cause) RB_INSERT(paste_name_tree, &paste_by_name, pb); RB_INSERT(paste_time_tree, &paste_by_time, pb); - notify_paste_buffer(pb->name, 0); + paste_fire_event("paste-buffer-changed", pb->name); return (0); } @@ -324,7 +334,7 @@ paste_replace(struct paste_buffer *pb, char *data, size_t size) pb->data = data; pb->size = size; - notify_paste_buffer(pb->name, 0); + paste_fire_event("paste-buffer-changed", pb->name); } /* Convert start of buffer into a nice string. */ diff --git a/resize.c b/resize.c index 6cbc938dd..440a27b45 100644 --- a/resize.c +++ b/resize.c @@ -60,8 +60,8 @@ resize_window(struct window *w, u_int sx, u_int sy, int xpixel, int ypixel) tty_update_window_offset(w); server_redraw_window(w); - notify_window("window-layout-changed", w); - notify_window("window-resized", w); + events_fire_window("window-layout-changed", w); + events_fire_window("window-resized", w); w->flags &= ~WINDOW_RESIZE; } diff --git a/server-client.c b/server-client.c index 52c3c7f2d..4b839fe1a 100644 --- a/server-client.c +++ b/server-client.c @@ -429,7 +429,7 @@ server_client_set_session(struct client *c, struct session *s) alerts_check_session(s); tty_update_client_offset(c); status_timer_start(c); - notify_client("client-session-changed", c); + events_fire_client("client-session-changed", c); server_redraw_client(c); } @@ -464,7 +464,7 @@ server_client_lost(struct client *c) if (c->flags & CLIENT_ATTACHED) { server_client_attached_lost(c); - notify_client("client-detached", c); + events_fire_client("client-detached", c); } if (c->flags & CLIENT_CONTROL) @@ -1284,7 +1284,7 @@ server_client_update_latest(struct client *c) if (options_get_number(w->options, "window-size") == WINDOW_SIZE_LATEST) recalculate_size(w, 0); - notify_client("client-active", c); + events_fire_client("client-active", c); } /* Get repeat time. */ @@ -2468,7 +2468,7 @@ server_client_dispatch(struct imsg *imsg, void *arg) c->overlay_resize(c, c->overlay_data); server_redraw_client(c); if (c->session != NULL) - notify_client("client-resized", c); + events_fire_client("client-resized", c); break; case MSG_EXITING: if (datalen != 0) @@ -3088,10 +3088,10 @@ server_client_report_theme(struct client *c, enum client_theme theme) if (theme == THEME_LIGHT) { c->theme = THEME_LIGHT; - notify_client("client-light-theme", c); + events_fire_client("client-light-theme", c); } else { c->theme = THEME_DARK; - notify_client("client-dark-theme", c); + events_fire_client("client-dark-theme", c); } /* diff --git a/server-fn.c b/server-fn.c index 5f5474a1a..3f8feca79 100644 --- a/server-fn.c +++ b/server-fn.c @@ -29,6 +29,31 @@ #include "tmux.h" static void server_destroy_session_group(struct session *); +static void server_fire_pane_exit(const char *, struct window_pane *); + +static void +server_fire_pane_exit(const char *name, struct window_pane *wp) +{ + struct event_payload *ep; + struct cmd_find_state fs; + int status = wp->status; + const char *signame; + + if (WIFSIGNALED(status)) + signame = sig2name(WTERMSIG(status)); + + ep = event_payload_create(); + cmd_find_from_pane(&fs, wp, 0); + event_payload_set_target(ep, &fs); + event_payload_set_pane(ep, "pane", wp); + event_payload_set_window(ep, "window", wp->window); + if (WIFEXITED(status)) + event_payload_set_int(ep, "exit_status", WEXITSTATUS(status)); + else if (WIFSIGNALED(status)) + event_payload_set_string(ep, "exit_signal", "%s", signame); + event_payload_set_int(ep, "exit_success", status == 0); + events_fire(name, ep); +} void server_redraw_client(struct client *c) @@ -274,8 +299,7 @@ server_link_window(struct session *src, struct winlink *srcwl, * Can't use session_detach as it will destroy session * if this makes it empty. */ - notify_session_window("window-unlinked", dst, - dstwl->window); + events_fire_winlink("window-unlinked", dstwl); dstwl->flags &= ~WINLINK_ALERTFLAGS; winlink_stack_remove(&dst->lastw, dstwl); winlink_remove(&dst->windows, dstwl); @@ -353,7 +377,7 @@ server_destroy_pane(struct window_pane *wp, int notify) gettimeofday(&wp->dead_time, NULL); if (notify) - notify_pane("pane-died", wp); + server_fire_pane_exit("pane-died", wp); s = options_get_string(wp->options, "remain-on-exit-format"); if (*s != '\0') { @@ -376,7 +400,7 @@ server_destroy_pane(struct window_pane *wp, int notify) } if (notify) - notify_pane("pane-exited", wp); + server_fire_pane_exit("pane-exited", wp); server_unzoom_window(w); server_client_remove_pane(wp); diff --git a/session.c b/session.c index 445897e2a..d6dc4be84 100644 --- a/session.c +++ b/session.c @@ -206,7 +206,7 @@ session_destroy(struct session *s, int notify, const char *from) RB_REMOVE(sessions, &sessions, s); if (notify) - notify_session("session-closed", s); + events_fire_session("session-closed", s); free(s->tio); @@ -219,7 +219,7 @@ session_destroy(struct session *s, int notify, const char *from) winlink_stack_remove(&s->lastw, TAILQ_FIRST(&s->lastw)); while (!RB_EMPTY(&s->windows)) { wl = RB_ROOT(&s->windows); - notify_session_window("window-unlinked", s, wl->window); + events_fire_winlink("window-unlinked", wl); winlink_remove(&s->windows, wl); } @@ -330,7 +330,7 @@ session_attach(struct session *s, struct window *w, int idx, char **cause) } wl->session = s; winlink_set_window(wl, w); - notify_session_window("window-linked", s, w); + events_fire_winlink("window-linked", wl); session_group_synchronize_from(s); return (wl); @@ -346,7 +346,7 @@ session_detach(struct session *s, struct winlink *wl) session_next(s, 0); wl->flags &= ~WINLINK_ALERTFLAGS; - notify_session_window("window-unlinked", s, wl->window); + events_fire_winlink("window-unlinked", wl); winlink_stack_remove(&s->lastw, wl); winlink_remove(&s->windows, wl); @@ -493,7 +493,7 @@ session_set_current(struct session *s, struct winlink *wl) winlink_clear_flags(wl); window_update_activity(wl->window); tty_update_window_offset(wl->window); - notify_session("session-window-changed", s); + events_fire_session("session-window-changed", s); return (0); } @@ -657,7 +657,7 @@ session_group_synchronize1(struct session *target, struct session *s) wl2 = winlink_add(&s->windows, wl->idx); wl2->session = s; winlink_set_window(wl2, wl->window); - notify_session_window("window-linked", s, wl2->window); + events_fire_winlink("window-linked", wl2); wl2->flags |= wl->flags & WINLINK_ALERTFLAGS; } @@ -683,7 +683,7 @@ session_group_synchronize1(struct session *target, struct session *s) wl = RB_ROOT(&old_windows); wl2 = winlink_find_by_window_id(&s->windows, wl->window->id); if (wl2 == NULL) - notify_session_window("window-unlinked", s, wl->window); + events_fire_winlink("window-unlinked", wl); winlink_remove(&old_windows, wl); } } diff --git a/spawn.c b/spawn.c index 3ae9153b8..c42695f06 100644 --- a/spawn.c +++ b/spawn.c @@ -131,7 +131,7 @@ spawn_window(struct spawn_context *sc, char **cause) * if this makes it empty. */ wl->flags &= ~WINLINK_ALERTFLAGS; - notify_session_window("window-unlinked", s, wl->window); + events_fire_winlink("window-unlinked", wl); winlink_stack_remove(&s->lastw, wl); winlink_remove(&s->windows, wl); @@ -191,7 +191,7 @@ spawn_window(struct spawn_context *sc, char **cause) /* Fire notification if new window. */ if (~sc->flags & SPAWN_RESPAWN) - notify_session_window("window-linked", s, w); + events_fire_winlink("window-linked", sc->wl); session_group_synchronize_from(s); return (sc->wl); @@ -531,7 +531,7 @@ complete: window_set_active_pane(w, new_wp, 1); } if (~sc->flags & SPAWN_NONOTIFY) - notify_window("window-layout-changed", w); + events_fire_window("window-layout-changed", w); return (new_wp); } diff --git a/tmux.h b/tmux.h index 4aa6c5084..f6b0af387 100644 --- a/tmux.h +++ b/tmux.h @@ -2716,6 +2716,11 @@ typedef void (*events_cb)(const char *, struct event_payload *, void *); struct events_sink *events_add_sink(const char *, events_cb, void *); void events_remove_sink(struct events_sink *); void events_fire(const char *, struct event_payload *); +void events_fire_client(const char *, struct client *); +void events_fire_session(const char *, struct session *); +void events_fire_window(const char *, struct window *); +void events_fire_pane(const char *, struct window_pane *); +void events_fire_winlink(const char *, struct winlink *); /* format-draw.c */ void format_draw(struct screen_write_ctx *, const struct grid_cell *, @@ -2734,15 +2739,6 @@ void hooks_monitor_remove(struct options *, const char *); void hooks_monitor_free(void *); char *hooks_monitor_to_string(struct options_entry *); -/* notify.c */ -void notify_client(const char *, struct client *); -void notify_session(const char *, struct session *); -void notify_winlink(const char *, struct winlink *); -void notify_session_window(const char *, struct session *, struct window *); -void notify_window(const char *, struct window *); -void notify_pane(const char *, struct window_pane *); -void notify_paste_buffer(const char *, int); - /* options.c */ struct options *options_create(struct options *); void options_free(struct options *); diff --git a/tty-keys.c b/tty-keys.c index 209bbeeab..fdbf3547e 100644 --- a/tty-keys.c +++ b/tty-keys.c @@ -1011,10 +1011,10 @@ complete_key: if (key == KEYC_FOCUS_OUT) { c->flags &= ~CLIENT_FOCUSED; window_update_focus(c->session->curw->window); - notify_client("client-focus-out", c); + events_fire_client("client-focus-out", c); } else if (key == KEYC_FOCUS_IN) { c->flags |= CLIENT_FOCUSED; - notify_client("client-focus-in", c); + events_fire_client("client-focus-in", c); window_update_focus(c->session->curw->window); } diff --git a/window-copy.c b/window-copy.c index aedbba99b..aa0d7ee84 100644 --- a/window-copy.c +++ b/window-copy.c @@ -5746,7 +5746,7 @@ window_copy_copy_buffer(struct window_mode_entry *wme, const char *prefix, screen_write_setselection(&ctx, "", buf, len); screen_write_stop(&ctx); wp->flags |= redraw; - notify_pane("pane-set-clipboard", wp); + events_fire_pane("pane-set-clipboard", wp); } if (set_paste) @@ -5831,7 +5831,7 @@ window_copy_append_selection(struct window_mode_entry *wme) screen_write_start_pane(&ctx, wp, NULL); screen_write_setselection(&ctx, "", buf, len); screen_write_stop(&ctx); - notify_pane("pane-set-clipboard", wp); + events_fire_pane("pane-set-clipboard", wp); } pb = paste_get_top(&bufname); diff --git a/window.c b/window.c index d23adb064..91c72bfb2 100644 --- a/window.c +++ b/window.c @@ -75,6 +75,9 @@ static void window_pane_free(struct window_pane *); static void window_pane_scrollbar_timer(int, short, void *); static void window_pane_full_size_offset(struct window_pane *wp, int *xoff, int *yoff, u_int *sx, u_int *sy); +static void window_fire_renamed(struct window *, const char *); +static void window_fire_pane_changed(struct window *, struct window_pane *, + struct window_pane *); RB_GENERATE(windows, window, entry, window_cmp); RB_GENERATE(winlinks, winlink, entry, winlink_cmp); @@ -94,6 +97,39 @@ window_cmp(struct window *w1, struct window *w2) return (w1->id - w2->id); } +static void +window_fire_renamed(struct window *w, const char *old_name) +{ + struct event_payload *ep; + struct cmd_find_state fs; + + ep = event_payload_create(); + cmd_find_from_window(&fs, w, 0); + event_payload_set_target(ep, &fs); + event_payload_set_window(ep, "window", w); + event_payload_set_string(ep, "old_name", "%s", old_name); + event_payload_set_string(ep, "new_name", "%s", w->name); + events_fire("window-renamed", ep); +} + +static void +window_fire_pane_changed(struct window *w, struct window_pane *wp, + struct window_pane *lastwp) +{ + struct event_payload *ep; + struct cmd_find_state fs; + + ep = event_payload_create(); + cmd_find_from_pane(&fs, wp, 0); + event_payload_set_target(ep, &fs); + event_payload_set_window(ep, "window", w); + event_payload_set_pane(ep, "pane", wp); + event_payload_set_pane(ep, "new_pane", wp); + if (lastwp != NULL) + event_payload_set_pane(ep, "old_pane", lastwp); + events_fire("window-pane-changed", ep); +} + int winlink_cmp(struct winlink *wl1, struct winlink *wl2) { @@ -442,13 +478,15 @@ window_pane_remove_ref(struct window_pane *wp, const char *from) void window_set_name(struct window *w, const char *new_name, int untrusted) { - char *name; + char *last, *name; name = clean_name(new_name, untrusted); if (name != NULL) { + last = xstrdup(w->name); free(w->name); w->name = name; - notify_window("window-renamed", w); + window_fire_renamed(w, last); + free(last); } } @@ -558,13 +596,13 @@ window_pane_update_focus(struct window_pane *wp) log_debug("%s: %%%u focus out", __func__, wp->id); if (wp->base.mode & MODE_FOCUSON) bufferevent_write(wp->event, "\033[O", 3); - notify_pane("pane-focus-out", wp); + events_fire_pane("pane-focus-out", wp); wp->flags &= ~PANE_FOCUSED; } else if (focused && (~wp->flags & PANE_FOCUSED)) { log_debug("%s: %%%u focus in", __func__, wp->id); if (wp->base.mode & MODE_FOCUSON) bufferevent_write(wp->event, "\033[I", 3); - notify_pane("pane-focus-in", wp); + events_fire_pane("pane-focus-in", wp); wp->flags |= PANE_FOCUSED; } else log_debug("%s: %%%u focus unchanged", __func__, wp->id); @@ -600,7 +638,7 @@ window_set_active_pane(struct window *w, struct window_pane *wp, int notify) server_redraw_window(w); if (notify) - notify_window("window-pane-changed", w); + window_fire_pane_changed(w, w->active, lastwp); return (1); } @@ -790,7 +828,7 @@ window_zoom(struct window_pane *wp) w->saved_layout_root = w->layout_root; layout_init(w, wp); w->flags |= WINDOW_ZOOMED; - notify_window("window-layout-changed", w); + events_fire_window("window-layout-changed", w); redraw_invalidate_scene(w); return (0); @@ -817,7 +855,7 @@ window_unzoom(struct window *w, int notify) layout_fix_panes(w, NULL); if (notify) - notify_window("window-layout-changed", w); + events_fire_window("window-layout-changed", w); redraw_invalidate_scene(w); return (0); @@ -899,7 +937,7 @@ window_lost_pane(struct window *w, struct window_pane *wp) if (w->active != NULL) { window_pane_stack_remove(&w->last_panes, w->active); w->active->flags |= PANE_CHANGED; - notify_window("window-pane-changed", w); + events_fire_window("window-pane-changed", w); window_update_focus(w); } } @@ -1420,7 +1458,7 @@ window_pane_set_mode(struct window_pane *wp, struct window_pane *swp, server_redraw_window_borders(wp->window); server_status_window(wp->window); - notify_pane("pane-mode-changed", wp); + events_fire_pane("pane-mode-changed", wp); return (0); } @@ -1458,7 +1496,7 @@ window_pane_reset_mode(struct window_pane *wp) server_redraw_window_borders(wp->window); server_status_window(wp->window); - notify_pane("pane-mode-changed", wp); + events_fire_pane("pane-mode-changed", wp); if (kill) server_kill_pane(wp);