diff --git a/cmd-break-pane.c b/cmd-break-pane.c index a5582e46..add3743b 100644 --- a/cmd-break-pane.c +++ b/cmd-break-pane.c @@ -85,7 +85,10 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item) options_set_number(w->options, "automatic-rename", 0); } server_unlink_window(src_s, wl); - return (CMD_RETURN_NORMAL); + wl = winlink_find_by_window(&dst_s->windows, w); + if (wl == NULL) + return (CMD_RETURN_ERROR); + goto out; } if (idx != -1 && winlink_find_by_index(&dst_s->windows, idx) != NULL) { cmdq_error(item, "index in use: %d", idx); @@ -132,6 +135,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item) if (src_s != dst_s) server_status_session_group(dst_s); +out: if (args_has(args, 'P')) { if ((template = args_get(args, 'F')) == NULL) template = BREAK_PANE_TEMPLATE; diff --git a/cmd-display-menu.c b/cmd-display-menu.c index ce1f1ccc..075744e1 100644 --- a/cmd-display-menu.c +++ b/cmd-display-menu.c @@ -54,8 +54,8 @@ const struct cmd_entry cmd_display_popup_entry = { .name = "display-popup", .alias = "popup", - .args = { "Bb:Cc:d:e:Eh:s:S:t:T:w:x:y:", 0, -1, NULL }, - .usage = "[-BCE] [-b border-lines] [-c target-client] " + .args = { "Bb:Cc:d:e:Eh:ks:S:t:T:w:x:y:", 0, -1, NULL }, + .usage = "[-BCEk] [-b border-lines] [-c target-client] " "[-d start-directory] [-e environment] [-h height] " "[-s style] [-S border-style] " CMD_TARGET_PANE_USAGE " [-T title] [-w width] [-x position] [-y position] " @@ -484,6 +484,8 @@ cmd_display_popup_exec(struct cmd *self, struct cmdq_item *item) flags |= POPUP_CLOSEEXITZERO; else if (args_has(args, 'E')) flags |= POPUP_CLOSEEXIT; + if (args_has(args, 'k')) + flags |= POPUP_CLOSEANYKEY; if (popup_display(flags, lines, item, px, py, w, h, env, shellcmd, argc, argv, cwd, title, tc, s, style, border_style, NULL, NULL) != 0) { cmd_free_argv(argc, argv); diff --git a/popup.c b/popup.c index 2f02dbe8..4d837a9b 100644 --- a/popup.c +++ b/popup.c @@ -548,6 +548,9 @@ popup_key_cb(struct client *c, void *data, struct key_event *event) pd->job == NULL) && (event->key == '\033' || event->key == ('c'|KEYC_CTRL))) return (1); + if (pd->job == NULL && (pd->flags & POPUP_CLOSEANYKEY) && + !KEYC_IS_MOUSE(event->key) && !KEYC_IS_PASTE(event->key)) + return (1); if (pd->job != NULL) { if (KEYC_IS_MOUSE(event->key)) { /* Must be inside, checked already. */ diff --git a/server-client.c b/server-client.c index 8e670869..b3af0314 100644 --- a/server-client.c +++ b/server-client.c @@ -3354,7 +3354,7 @@ server_client_dispatch(struct imsg *imsg, void *arg) break; server_client_update_latest(c); tty_resize(&c->tty); - tty_repeat_requests(&c->tty); + tty_repeat_requests(&c->tty, 0); recalculate_sizes(); if (c->overlay_resize == NULL) server_client_clear_overlay(c); @@ -3959,5 +3959,5 @@ server_client_report_theme(struct client *c, enum client_theme theme) * Request foreground and background colour again. Don't forward 2031 to * panes until a response is received. */ - tty_puts(&c->tty, "\033]10;?\033\\\033]11;?\033\\"); + tty_repeat_requests(&c->tty, 1); } diff --git a/tmux.1 b/tmux.1 index f4749d09..5d42f8ae 100644 --- a/tmux.1 +++ b/tmux.1 @@ -6969,7 +6969,7 @@ forwards any input read from stdin to the empty pane given by .Ar target-pane . .Tg popup .It Xo Ic display-popup -.Op Fl BCE +.Op Fl BCEk .Op Fl b Ar border-lines .Op Fl c Ar target-client .Op Fl d Ar start-directory @@ -7003,6 +7003,11 @@ Two closes the popup only if .Ar shell-command exited with success. +.Fl k +allows any key to dismiss the popup instead of only +.Ql Escape +or +.Ql C-c . .Pp .Fl x and diff --git a/tmux.h b/tmux.h index 0a8bd188..4276ce8b 100644 --- a/tmux.h +++ b/tmux.h @@ -1577,10 +1577,10 @@ struct tty { #define TTY_SYNCING 0x400 #define TTY_HAVEDA2 0x800 #define TTY_WINSIZEQUERY 0x1000 -#define TTY_HAVEFG 0x2000 -#define TTY_HAVEBG 0x4000 +#define TTY_WAITFG 0x2000 +#define TTY_WAITBG 0x4000 #define TTY_ALL_REQUEST_FLAGS \ - (TTY_HAVEDA|TTY_HAVEDA2|TTY_HAVEXDA|TTY_HAVEFG|TTY_HAVEBG) + (TTY_HAVEDA|TTY_HAVEDA2|TTY_HAVEXDA) int flags; struct tty_term *term; @@ -2508,7 +2508,7 @@ void tty_set_size(struct tty *, u_int, u_int, u_int, u_int); void tty_invalidate(struct tty *); void tty_start_tty(struct tty *); void tty_send_requests(struct tty *); -void tty_repeat_requests(struct tty *); +void tty_repeat_requests(struct tty *, int); void tty_stop_tty(struct tty *); void tty_set_title(struct tty *, const char *); void tty_set_path(struct tty *, const char *); @@ -3572,6 +3572,7 @@ int menu_key_cb(struct client *, void *, struct key_event *); #define POPUP_CLOSEEXIT 0x1 #define POPUP_CLOSEEXITZERO 0x2 #define POPUP_INTERNAL 0x4 +#define POPUP_CLOSEANYKEY 0x8 typedef void (*popup_close_cb)(int, void *); typedef void (*popup_finish_edit_cb)(char *, size_t, void *); int popup_display(int, enum box_lines, struct cmdq_item *, u_int, diff --git a/tty-keys.c b/tty-keys.c index 267b5379..a367d022 100644 --- a/tty-keys.c +++ b/tty-keys.c @@ -937,7 +937,8 @@ partial_key: delay = options_get_number(global_options, "escape-time"); if (delay == 0) delay = 1; - if ((tty->flags & TTY_ALL_REQUEST_FLAGS) != TTY_ALL_REQUEST_FLAGS) { + if ((tty->flags & (TTY_WAITFG|TTY_WAITBG) || + (tty->flags & TTY_ALL_REQUEST_FLAGS) != TTY_ALL_REQUEST_FLAGS)) { log_debug("%s: increasing delay for active query", c->name); if (delay < 500) delay = 500; @@ -1686,14 +1687,14 @@ tty_keys_colours(struct tty *tty, const char *buf, size_t len, size_t *size, else log_debug("fg is %s", colour_tostring(n)); *fg = n; - tty->flags |= TTY_HAVEFG; + tty->flags &= ~TTY_WAITFG; } else if (n != -1) { if (c != NULL) log_debug("%s bg is %s", c->name, colour_tostring(n)); else log_debug("bg is %s", colour_tostring(n)); *bg = n; - tty->flags |= TTY_HAVEBG; + tty->flags &= ~TTY_WAITBG; } return (0); diff --git a/tty.c b/tty.c index 19e55757..58254bc1 100644 --- a/tty.c +++ b/tty.c @@ -44,11 +44,11 @@ static void tty_cursor_pane_unless_wrap(struct tty *, const struct tty_ctx *, u_int, u_int); static void tty_colours(struct tty *, const struct grid_cell *); static void tty_check_fg(struct tty *, struct colour_palette *, - struct grid_cell *); + struct grid_cell *); static void tty_check_bg(struct tty *, struct colour_palette *, - struct grid_cell *); + struct grid_cell *); static void tty_check_us(struct tty *, struct colour_palette *, - struct grid_cell *); + struct grid_cell *); static void tty_colours_fg(struct tty *, const struct grid_cell *); static void tty_colours_bg(struct tty *, const struct grid_cell *); static void tty_colours_us(struct tty *, const struct grid_cell *); @@ -311,9 +311,23 @@ tty_start_timer_callback(__unused int fd, __unused short events, void *data) struct client *c = tty->client; log_debug("%s: start timer fired", c->name); + if ((tty->flags & (TTY_HAVEDA|TTY_HAVEDA2|TTY_HAVEXDA)) == 0) tty_update_features(tty); tty->flags |= TTY_ALL_REQUEST_FLAGS; + + tty->flags &= ~(TTY_WAITBG|TTY_WAITFG); +} + +static void +tty_start_start_timer(struct tty *tty) +{ + struct client *c = tty->client; + struct timeval tv = { .tv_sec = TTY_QUERY_TIMEOUT }; + + log_debug("%s: start timer started", c->name); + evtimer_set(&tty->start_timer, tty_start_timer_callback, tty); + evtimer_add(&tty->start_timer, &tv); } void @@ -321,7 +335,6 @@ tty_start_tty(struct tty *tty) { struct client *c = tty->client; struct termios tio; - struct timeval tv = { .tv_sec = TTY_QUERY_TIMEOUT }; setblocking(c->fd, 0); event_add(&tty->event_in, NULL); @@ -361,8 +374,7 @@ tty_start_tty(struct tty *tty) tty_puts(tty, "\033[?2031h\033[?996n"); } - evtimer_set(&tty->start_timer, tty_start_timer_callback, tty); - evtimer_add(&tty->start_timer, &tv); + tty_start_start_timer(tty); tty->flags |= TTY_STARTED; tty_invalidate(tty); @@ -388,29 +400,35 @@ tty_send_requests(struct tty *tty) tty_puts(tty, "\033[>c"); if (~tty->flags & TTY_HAVEXDA) tty_puts(tty, "\033[>q"); - tty_puts(tty, "\033]10;?\033\\"); - tty_puts(tty, "\033]11;?\033\\"); + tty_puts(tty, "\033]10;?\033\\\033]11;?\033\\"); + tty->flags |= (TTY_WAITBG|TTY_WAITFG); } else tty->flags |= TTY_ALL_REQUEST_FLAGS; tty->last_requests = time(NULL); } void -tty_repeat_requests(struct tty *tty) +tty_repeat_requests(struct tty *tty, int force) { + struct client *c = tty->client; time_t t = time(NULL); + u_int n = t - tty->last_requests; if (~tty->flags & TTY_STARTED) return; - if (t - tty->last_requests <= TTY_REQUEST_LIMIT) + if (!force && n <= TTY_REQUEST_LIMIT) { + log_debug("%s: not repeating requests (%u seconds)", c->name, n); return; + } + log_debug("%s: %srepeating requests (%u seconds)", c->name, force ? "(force) " : "" , n); tty->last_requests = t; if (tty->term->flags & TERM_VT100LIKE) { - tty_puts(tty, "\033]10;?\033\\"); - tty_puts(tty, "\033]11;?\033\\"); - } + tty_puts(tty, "\033]10;?\033\\\033]11;?\033\\"); + tty->flags |= (TTY_WAITBG|TTY_WAITFG); + } + tty_start_start_timer(tty); } void @@ -1700,7 +1718,7 @@ tty_sync_end(struct tty *tty) tty->flags &= ~TTY_SYNCING; if (tty_term_has(tty->term, TTYC_SYNC)) { - log_debug("%s sync end", tty->client->name); + log_debug("%s sync end", tty->client->name); tty_putcode_i(tty, TTYC_SYNC, 2); } }