diff --git a/cmd-queue.c b/cmd-queue.c index 671f1e95..243f73dd 100644 --- a/cmd-queue.c +++ b/cmd-queue.c @@ -157,14 +157,17 @@ int cmdq_guard(struct cmd_q *cmdq, const char *guard) { struct client *c = cmdq->client; + int flags; if (c == NULL) return 0; if (!(c->flags & CLIENT_CONTROL)) return 0; - evbuffer_add_printf(c->stdout_data, "%%%s %ld %u\n", guard, - (long) cmdq->time, cmdq->number); + flags = !!(cmdq->cmd->flags & CMD_CONTROL); + + evbuffer_add_printf(c->stdout_data, "%%%s %ld %u %d\n", guard, + (long) cmdq->time, cmdq->number, flags); server_push_stdout(c); return 1; } diff --git a/compat/forkpty-sunos.c b/compat/forkpty-sunos.c index 90452f8d..7b254d82 100644 --- a/compat/forkpty-sunos.c +++ b/compat/forkpty-sunos.c @@ -21,6 +21,7 @@ #include #include +#include #include #include diff --git a/compat/imsg-buffer.c b/compat/imsg-buffer.c index 24db311d..2ddf0f77 100644 --- a/compat/imsg-buffer.c +++ b/compat/imsg-buffer.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "tmux.h" diff --git a/compat/imsg.c b/compat/imsg.c index 0feff660..c4dd191d 100644 --- a/compat/imsg.c +++ b/compat/imsg.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "tmux.h" diff --git a/control.c b/control.c index ba243fd3..aa79085a 100644 --- a/control.c +++ b/control.c @@ -55,6 +55,7 @@ control_callback(struct client *c, int closed, unused void *data) { char *line, *cause; struct cmd_list *cmdlist; + struct cmd *cmd; if (closed) c->flags |= CLIENT_EXIT; @@ -78,6 +79,8 @@ control_callback(struct client *c, int closed, unused void *data) free(cause); } else { + TAILQ_FOREACH(cmd, &cmdlist->list, qentry) + cmd->flags |= CMD_CONTROL; cmdq_run(c->cmdq, cmdlist); cmd_list_free(cmdlist); } diff --git a/input.c b/input.c index 4aa02e90..30d3bb98 100644 --- a/input.c +++ b/input.c @@ -1333,7 +1333,7 @@ input_csi_dispatch(struct input_ctx *ictx) if (s->mode & MODE_FOCUSON) break; screen_write_mode_set(&ictx->ctx, MODE_FOCUSON); - wp->flags &= ~PANE_FOCUSED; /* force update if needed */ + wp->flags |= PANE_FOCUSPUSH; /* force update */ break; case 1005: screen_write_mode_set(&ictx->ctx, MODE_MOUSE_UTF8); diff --git a/options-table.c b/options-table.c index fe21f165..2281d652 100644 --- a/options-table.c +++ b/options-table.c @@ -75,6 +75,11 @@ const struct options_table_entry server_options_table[] = { .default_num = 0 }, + { .name = "focus-events", + .type = OPTIONS_TABLE_FLAG, + .default_num = 0 + }, + { .name = "quiet", .type = OPTIONS_TABLE_FLAG, .default_num = 0 /* overridden in main() */ diff --git a/server-client.c b/server-client.c index 1c15a555..01616cbf 100644 --- a/server-client.c +++ b/server-client.c @@ -548,6 +548,15 @@ server_client_check_focus(struct window_pane *wp) { u_int i; struct client *c; + int push; + + /* Are focus events off? */ + if (!options_get_number(&global_options, "focus-events")) + return; + + /* Do we need to push the focus state? */ + push = wp->flags & PANE_FOCUSPUSH; + wp->flags &= ~PANE_FOCUSPUSH; /* If we don't care about focus, forget it. */ if (!(wp->base.mode & MODE_FOCUSON)) @@ -580,13 +589,13 @@ server_client_check_focus(struct window_pane *wp) } not_focused: - if (wp->flags & PANE_FOCUSED) + if (push || (wp->flags & PANE_FOCUSED)) bufferevent_write(wp->event, "\033[O", 3); wp->flags &= ~PANE_FOCUSED; return; focused: - if (!(wp->flags & PANE_FOCUSED)) + if (push || !(wp->flags & PANE_FOCUSED)) bufferevent_write(wp->event, "\033[I", 3); wp->flags |= PANE_FOCUSED; } diff --git a/tmux.1 b/tmux.1 index f644587b..0aeb5a17 100644 --- a/tmux.1 +++ b/tmux.1 @@ -2096,6 +2096,14 @@ The default is 500 milliseconds. .Op Ic on | off .Xc If enabled, the server will exit when there are no attached clients. +.It Xo Ic focus-events +.Op Ic on | off +.Xc +When enabled, focus events are requested from the terminal if supported and +passed through to applications running in +.Nm . +Attached clients should be detached and attached again after changing this +option. .It Xo Ic quiet .Op Ic on | off .Xc diff --git a/tmux.h b/tmux.h index 12310361..5dd86d38 100644 --- a/tmux.h +++ b/tmux.h @@ -39,9 +39,6 @@ extern char *__progname; extern char **environ; -/* Default global configuration file. */ -#define TMUX_CONF "/etc/tmux.conf" - /* Default prompt history length. */ #define PROMPT_HISTORY 100 @@ -937,6 +934,7 @@ struct window_pane { #define PANE_DROP 0x2 #define PANE_FOCUSED 0x4 #define PANE_RESIZE 0x8 +#define PANE_FOCUSPUSH 0x10 char *cmd; char *shell; @@ -1228,6 +1226,7 @@ struct tty { #define TTY_UTF8 0x8 #define TTY_STARTED 0x10 #define TTY_OPENED 0x20 +#define TTY_FOCUS 0x40 int flags; int term_flags; @@ -1379,6 +1378,9 @@ struct cmd { char *file; u_int line; +#define CMD_CONTROL 0x1 + int flags; + TAILQ_ENTRY(cmd) qentry; }; struct cmd_list { diff --git a/tty.c b/tty.c index 79887fb3..d5b1aec0 100644 --- a/tty.c +++ b/tty.c @@ -219,8 +219,13 @@ tty_start_tty(struct tty *tty) if (tty_term_has(tty->term, TTYC_KMOUS)) tty_puts(tty, "\033[?1000l\033[?1006l\033[?1005l"); - if (tty_term_has(tty->term, TTYC_XT)) + if (tty_term_has(tty->term, TTYC_XT)) { + if (options_get_number(&global_options, "focus-events")) { + tty->flags |= TTY_FOCUS; + tty_puts(tty, "\033[?1004h"); + } tty_puts(tty, "\033[c\033[>4;1m\033[m"); + } tty->cx = UINT_MAX; tty->cy = UINT_MAX; @@ -282,8 +287,13 @@ tty_stop_tty(struct tty *tty) if (tty_term_has(tty->term, TTYC_KMOUS)) tty_raw(tty, "\033[?1000l\033[?1006l\033[?1005l"); - if (tty_term_has(tty->term, TTYC_XT)) + if (tty_term_has(tty->term, TTYC_XT)) { + if (tty->flags & TTY_FOCUS) { + tty->flags &= ~TTY_FOCUS; + tty_puts(tty, "\033[?1004l"); + } tty_raw(tty, "\033[>4m\033[m"); + } tty_raw(tty, tty_term_string(tty->term, TTYC_RMCUP));