mirror of
https://github.com/tmux/tmux.git
synced 2025-12-17 00:02:23 -05:00
Add -P flag to display-popup for passthrough/non-blocking mode
Add a new -P flag to display-popup that makes the popup non-blocking: keyboard input is passed through to the underlying pane instead of being captured by the popup. This allows users to continue typing while the popup is displayed. Escape and Ctrl-C still close the popup in passthrough mode. This is useful for toast-style notifications that should not steal focus. Combined with -E, popups can auto-dismiss when their command exits while allowing uninterrupted typing. Example usage: display-popup -P -E "echo 'Task completed'; sleep 2"
This commit is contained in:
parent
ef0a7e328c
commit
c46e2b2937
@ -54,8 +54,8 @@ const struct cmd_entry cmd_display_popup_entry = {
|
||||
.name = "display-popup",
|
||||
.alias = "popup",
|
||||
|
||||
.args = { "Bb:Cc:d:e:Eh:kNs:S:t:T:w:x:y:", 0, -1, NULL },
|
||||
.usage = "[-BCEkN] [-b border-lines] [-c target-client] "
|
||||
.args = { "Bb:Cc:d:e:Eh:kNPs:S:t:T:w:x:y:", 0, -1, NULL },
|
||||
.usage = "[-BCEkNP] [-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] "
|
||||
@ -504,6 +504,11 @@ cmd_display_popup_exec(struct cmd *self, struct cmdq_item *item)
|
||||
flags = 0;
|
||||
flags |= POPUP_CLOSEANYKEY;
|
||||
}
|
||||
if (args_has(args, 'P')) {
|
||||
if (flags == -1)
|
||||
flags = 0;
|
||||
flags |= POPUP_PASSTHROUGH;
|
||||
}
|
||||
|
||||
if (modify) {
|
||||
popup_modify(tc, title, style, border_style, lines, flags);
|
||||
|
||||
12
popup.c
12
popup.c
@ -153,6 +153,10 @@ popup_mode_cb(__unused struct client *c, void *data, u_int *cx, u_int *cy)
|
||||
if (pd->md != NULL)
|
||||
return (menu_mode_cb(c, pd->md, cx, cy));
|
||||
|
||||
/* In passthrough mode, keep cursor in underlying pane. */
|
||||
if (pd->flags & POPUP_PASSTHROUGH)
|
||||
return (NULL);
|
||||
|
||||
if (pd->border_lines == BOX_LINES_NONE) {
|
||||
*cx = pd->px + pd->s.cx;
|
||||
*cy = pd->py + pd->s.cy;
|
||||
@ -504,6 +508,14 @@ popup_key_cb(struct client *c, void *data, struct key_event *event)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Passthrough mode: pass non-mouse keys to underlying pane. */
|
||||
if ((pd->flags & POPUP_PASSTHROUGH) && !KEYC_IS_MOUSE(event->key)) {
|
||||
/* Still allow Escape and Ctrl-C to close the popup. */
|
||||
if (event->key == '\033' || event->key == ('c'|KEYC_CTRL))
|
||||
return (1);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (KEYC_IS_MOUSE(event->key)) {
|
||||
if (pd->dragging != OFF) {
|
||||
popup_handle_drag(c, pd, m);
|
||||
|
||||
@ -2636,9 +2636,14 @@ server_client_handle_key(struct client *c, struct key_event *event)
|
||||
case 1:
|
||||
server_client_clear_overlay(c);
|
||||
return (0);
|
||||
case -1:
|
||||
break; /* passthrough to underlying pane */
|
||||
default:
|
||||
server_client_clear_overlay(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
server_client_clear_overlay(c);
|
||||
} else
|
||||
server_client_clear_overlay(c);
|
||||
if (c->prompt_string != NULL) {
|
||||
if (status_prompt_key(c, event->key) == 0)
|
||||
return (0);
|
||||
@ -2920,6 +2925,8 @@ server_client_reset_state(struct client *c)
|
||||
if (c->overlay_draw != NULL) {
|
||||
if (c->overlay_mode != NULL)
|
||||
s = c->overlay_mode(c, c->overlay_data, &cx, &cy);
|
||||
if (s == NULL && c->prompt_string == NULL)
|
||||
s = wp->screen;
|
||||
} else if (c->prompt_string == NULL)
|
||||
s = wp->screen;
|
||||
else
|
||||
@ -2948,7 +2955,7 @@ server_client_reset_state(struct client *c)
|
||||
cy = tty->sy - 1;
|
||||
}
|
||||
cx = c->prompt_cursor;
|
||||
} else if (c->overlay_draw == NULL) {
|
||||
} else if (c->overlay_draw == NULL || s == wp->screen) {
|
||||
cursor = 0;
|
||||
tty_window_offset(tty, &ox, &oy, &sx, &sy);
|
||||
if (wp->xoff + s->cx >= ox && wp->xoff + s->cx <= ox + sx &&
|
||||
|
||||
12
tmux.1
12
tmux.1
@ -7020,7 +7020,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 BCEkN
|
||||
.Op Fl BCEkNP
|
||||
.Op Fl b Ar border-lines
|
||||
.Op Fl c Ar target-client
|
||||
.Op Fl d Ar start-directory
|
||||
@ -7053,6 +7053,7 @@ Only the
|
||||
.Fl EE ,
|
||||
.Fl K ,
|
||||
.Fl N ,
|
||||
.Fl P ,
|
||||
.Fl s ,
|
||||
and
|
||||
.Fl S
|
||||
@ -7073,6 +7074,15 @@ allows any key to dismiss the popup instead of only
|
||||
.Ql Escape
|
||||
or
|
||||
.Ql C-c .
|
||||
.Fl P
|
||||
makes the popup non-blocking: keyboard input is sent to the underlying pane
|
||||
instead of the popup, allowing the user to continue typing while the popup
|
||||
is displayed.
|
||||
.Ql Escape
|
||||
and
|
||||
.Ql C-c
|
||||
will still close the popup.
|
||||
This is useful for toast-style notifications that should not steal focus.
|
||||
.Pp
|
||||
.Fl x
|
||||
and
|
||||
|
||||
1
tmux.h
1
tmux.h
@ -3607,6 +3607,7 @@ int menu_key_cb(struct client *, void *, struct key_event *);
|
||||
#define POPUP_CLOSEEXITZERO 0x2
|
||||
#define POPUP_INTERNAL 0x4
|
||||
#define POPUP_CLOSEANYKEY 0x8
|
||||
#define POPUP_PASSTHROUGH 0x10
|
||||
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,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user