mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 09:26:05 +00:00 
			
		
		
		
	Merge branch 'obsd-master'
This commit is contained in:
		
							
								
								
									
										18
									
								
								cmd-find.c
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								cmd-find.c
									
									
									
									
									
								
							@@ -903,6 +903,23 @@ cmd_find_from_winlink(struct cmd_find_state *fs, struct session *s,
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Find state from a session and window. */
 | 
			
		||||
int
 | 
			
		||||
cmd_find_from_session_window(struct cmd_find_state *fs, struct session *s,
 | 
			
		||||
    struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	cmd_find_clear_state(fs, NULL, 0);
 | 
			
		||||
 | 
			
		||||
	fs->s = s;
 | 
			
		||||
	fs->w = w;
 | 
			
		||||
	if (cmd_find_best_winlink_with_window(fs) != 0)
 | 
			
		||||
		return (-1);
 | 
			
		||||
	fs->wp = fs->w->active;
 | 
			
		||||
 | 
			
		||||
	cmd_find_log_state(__func__, fs);
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Find state from a window. */
 | 
			
		||||
int
 | 
			
		||||
cmd_find_from_window(struct cmd_find_state *fs, struct window *w)
 | 
			
		||||
@@ -914,6 +931,7 @@ cmd_find_from_window(struct cmd_find_state *fs, struct window *w)
 | 
			
		||||
		return (-1);
 | 
			
		||||
	if (cmd_find_best_winlink_with_window(fs) != 0)
 | 
			
		||||
		return (-1);
 | 
			
		||||
	fs->wp = fs->w->active;
 | 
			
		||||
 | 
			
		||||
	cmd_find_log_state(__func__, fs);
 | 
			
		||||
	return (0);
 | 
			
		||||
 
 | 
			
		||||
@@ -248,10 +248,8 @@ cmdq_continue(struct cmd_q *cmdq)
 | 
			
		||||
	enum cmd_retval		 retval;
 | 
			
		||||
	int			 empty;
 | 
			
		||||
 | 
			
		||||
	cmdq->references++;
 | 
			
		||||
	notify_disable();
 | 
			
		||||
 | 
			
		||||
	log_debug("continuing cmdq %p: flags %#x (%p)", cmdq, cmdq->flags, c);
 | 
			
		||||
	cmdq->references++;
 | 
			
		||||
 | 
			
		||||
	empty = TAILQ_EMPTY(&cmdq->queue);
 | 
			
		||||
	if (empty)
 | 
			
		||||
@@ -296,9 +294,7 @@ empty:
 | 
			
		||||
	empty = 1;
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
	notify_enable();
 | 
			
		||||
	cmdq_free(cmdq);
 | 
			
		||||
 | 
			
		||||
	return (empty);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -196,7 +196,7 @@ control_notify_session_created(__unused struct session *s)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
control_notify_session_close(__unused struct session *s)
 | 
			
		||||
control_notify_session_closed(__unused struct session *s)
 | 
			
		||||
{
 | 
			
		||||
	struct client	*c;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										73
									
								
								notify.c
									
									
									
									
									
								
							
							
						
						
									
										73
									
								
								notify.c
									
									
									
									
									
								
							@@ -33,6 +33,17 @@ enum notify_type {
 | 
			
		||||
	NOTIFY_SESSION_CLOSED
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const char *notify_hooks[] = {
 | 
			
		||||
	"window-layout-changed",
 | 
			
		||||
	NULL, /* "window-unlinked", */
 | 
			
		||||
	NULL, /* "window-linked", */
 | 
			
		||||
	"window-renamed",
 | 
			
		||||
	NULL, /* "attached-session-changed", */
 | 
			
		||||
	"session-renamed",
 | 
			
		||||
	NULL, /* "session-created", */
 | 
			
		||||
	NULL, /* "session-closed" */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct notify_entry {
 | 
			
		||||
	enum notify_type	 type;
 | 
			
		||||
 | 
			
		||||
@@ -44,23 +55,45 @@ struct notify_entry {
 | 
			
		||||
};
 | 
			
		||||
TAILQ_HEAD(notify_queue, notify_entry);
 | 
			
		||||
static struct notify_queue notify_queue = TAILQ_HEAD_INITIALIZER(notify_queue);
 | 
			
		||||
static int	notify_enabled = 1;
 | 
			
		||||
 | 
			
		||||
static void	notify_drain(void);
 | 
			
		||||
static void	notify_add(enum notify_type, struct client *, struct session *,
 | 
			
		||||
		    struct window *);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
notify_enable(void)
 | 
			
		||||
static void
 | 
			
		||||
notify_hook(struct notify_entry *ne)
 | 
			
		||||
{
 | 
			
		||||
	notify_enabled = 1;
 | 
			
		||||
	notify_drain();
 | 
			
		||||
}
 | 
			
		||||
	const char		*name;
 | 
			
		||||
	struct cmd_find_state	 fs;
 | 
			
		||||
	struct hook		*hook;
 | 
			
		||||
	struct cmd_q		*hooks_cmdq;
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
notify_disable(void)
 | 
			
		||||
{
 | 
			
		||||
	notify_enabled = 0;
 | 
			
		||||
	name = notify_hooks[ne->type];
 | 
			
		||||
	if (name == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	cmd_find_clear_state(&fs, NULL, 0);
 | 
			
		||||
	if (ne->session != NULL && ne->window != NULL)
 | 
			
		||||
		cmd_find_from_session_window(&fs, ne->session, ne->window);
 | 
			
		||||
	else if (ne->window != NULL)
 | 
			
		||||
		cmd_find_from_window(&fs, ne->window);
 | 
			
		||||
	else if (ne->session != NULL)
 | 
			
		||||
		cmd_find_from_session(&fs, ne->session);
 | 
			
		||||
	if (cmd_find_empty_state(&fs) || !cmd_find_valid_state(&fs))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	hook = hooks_find(fs.s->hooks, name);
 | 
			
		||||
	if (hook == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
	log_debug("notify hook %s", name);
 | 
			
		||||
 | 
			
		||||
	hooks_cmdq = cmdq_new(NULL);
 | 
			
		||||
	hooks_cmdq->flags |= CMD_Q_NOHOOKS;
 | 
			
		||||
 | 
			
		||||
	cmd_find_copy_state(&hooks_cmdq->current, &fs);
 | 
			
		||||
	hooks_cmdq->parent = NULL;
 | 
			
		||||
 | 
			
		||||
	cmdq_run(hooks_cmdq, hook->cmdlist, NULL);
 | 
			
		||||
	cmdq_free(hooks_cmdq);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -84,14 +117,11 @@ notify_add(enum notify_type type, struct client *c, struct session *s,
 | 
			
		||||
		w->references++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
void
 | 
			
		||||
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:
 | 
			
		||||
@@ -116,9 +146,11 @@ notify_drain(void)
 | 
			
		||||
			control_notify_session_created(ne->session);
 | 
			
		||||
			break;
 | 
			
		||||
		case NOTIFY_SESSION_CLOSED:
 | 
			
		||||
			control_notify_session_close(ne->session);
 | 
			
		||||
			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);
 | 
			
		||||
@@ -126,8 +158,6 @@ notify_drain(void)
 | 
			
		||||
			session_unref(ne->session);
 | 
			
		||||
		if (ne->window != NULL)
 | 
			
		||||
			window_remove_ref(ne->window);
 | 
			
		||||
 | 
			
		||||
		TAILQ_REMOVE(¬ify_queue, ne, entry);
 | 
			
		||||
		free(ne);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -137,13 +167,6 @@ notify_input(struct window_pane *wp, struct evbuffer *input)
 | 
			
		||||
{
 | 
			
		||||
	struct client	*c;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * notify_input() is not queued and only does anything when
 | 
			
		||||
	 * notifications are enabled.
 | 
			
		||||
	 */
 | 
			
		||||
	if (!notify_enabled)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	TAILQ_FOREACH(c, &clients, entry) {
 | 
			
		||||
		if (c->flags & CLIENT_CONTROL)
 | 
			
		||||
			control_notify_input(c, wp, input);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								server.c
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								server.c
									
									
									
									
									
								
							@@ -194,6 +194,7 @@ server_loop(void)
 | 
			
		||||
	struct client	*c;
 | 
			
		||||
 | 
			
		||||
	server_client_loop();
 | 
			
		||||
	notify_drain();
 | 
			
		||||
 | 
			
		||||
	if (!options_get_number(global_options, "exit-unattached")) {
 | 
			
		||||
		if (!RB_EMPTY(&sessions))
 | 
			
		||||
 
 | 
			
		||||
@@ -210,6 +210,7 @@ session_destroy(struct session *s)
 | 
			
		||||
	struct winlink	*wl;
 | 
			
		||||
 | 
			
		||||
	log_debug("session %s destroyed", s->name);
 | 
			
		||||
	s->curw = NULL;
 | 
			
		||||
 | 
			
		||||
	RB_REMOVE(sessions, &sessions, s);
 | 
			
		||||
	notify_session_closed(s);
 | 
			
		||||
@@ -384,14 +385,17 @@ int
 | 
			
		||||
session_detach(struct session *s, struct winlink *wl)
 | 
			
		||||
{
 | 
			
		||||
	if (s->curw == wl &&
 | 
			
		||||
	    session_last(s) != 0 && session_previous(s, 0) != 0)
 | 
			
		||||
	    session_last(s) != 0 &&
 | 
			
		||||
	    session_previous(s, 0) != 0)
 | 
			
		||||
		session_next(s, 0);
 | 
			
		||||
 | 
			
		||||
	wl->flags &= ~WINLINK_ALERTFLAGS;
 | 
			
		||||
	notify_window_unlinked(s, wl->window);
 | 
			
		||||
	winlink_stack_remove(&s->lastw, wl);
 | 
			
		||||
	winlink_remove(&s->windows, wl);
 | 
			
		||||
 | 
			
		||||
	session_group_synchronize_from(s);
 | 
			
		||||
 | 
			
		||||
	if (RB_EMPTY(&s->windows)) {
 | 
			
		||||
		session_destroy(s);
 | 
			
		||||
		return (1);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								tmux.1
									
									
									
									
									
								
							@@ -3248,6 +3248,10 @@ Run when the program running in a pane exits, but
 | 
			
		||||
is on so the pane has not closed.
 | 
			
		||||
.It pane-exited
 | 
			
		||||
Run when the program running in a pane exits.
 | 
			
		||||
.It session-renamed
 | 
			
		||||
Run when a session is renamed.
 | 
			
		||||
.It window-renamed
 | 
			
		||||
Run when a window is renamed.
 | 
			
		||||
.El
 | 
			
		||||
.Pp
 | 
			
		||||
Hooks are managed with these commands:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										7
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								tmux.h
									
									
									
									
									
								
							@@ -1579,8 +1579,7 @@ void	mode_key_init(struct mode_key_data *, struct mode_key_tree *);
 | 
			
		||||
enum mode_key_cmd mode_key_lookup(struct mode_key_data *, key_code);
 | 
			
		||||
 | 
			
		||||
/* notify.c */
 | 
			
		||||
void	notify_enable(void);
 | 
			
		||||
void	notify_disable(void);
 | 
			
		||||
void	notify_drain(void);
 | 
			
		||||
void	notify_input(struct window_pane *, struct evbuffer *);
 | 
			
		||||
void	notify_window_layout_changed(struct window *);
 | 
			
		||||
void	notify_window_unlinked(struct session *, struct window *);
 | 
			
		||||
@@ -1745,6 +1744,8 @@ int		 cmd_find_from_session(struct cmd_find_state *,
 | 
			
		||||
		     struct session *);
 | 
			
		||||
int		 cmd_find_from_winlink(struct cmd_find_state *,
 | 
			
		||||
		     struct session *, struct winlink *);
 | 
			
		||||
int		 cmd_find_from_session_window(struct cmd_find_state *,
 | 
			
		||||
		     struct session *, struct window *);
 | 
			
		||||
int		 cmd_find_from_window(struct cmd_find_state *, struct window *);
 | 
			
		||||
int		 cmd_find_from_pane(struct cmd_find_state *,
 | 
			
		||||
		     struct window_pane *);
 | 
			
		||||
@@ -2209,7 +2210,7 @@ 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 *);
 | 
			
		||||
void	control_notify_session_closed(struct session *);
 | 
			
		||||
 | 
			
		||||
/* session.c */
 | 
			
		||||
extern struct sessions sessions;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user