From c028762869ed7f1b8fce97e1e368a7bbb8d3bbd0 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 21 Jul 2021 08:06:36 +0000 Subject: [PATCH] Do not close popups on resize, instead adjust them to fit, from Anindya Mukherjee. --- usr.bin/tmux/cmd-display-panes.c | 6 +-- usr.bin/tmux/menu.c | 4 +- usr.bin/tmux/popup.c | 66 +++++++++++++++++++++++++++++--- usr.bin/tmux/server-client.c | 10 +++-- usr.bin/tmux/tmux.h | 6 ++- 5 files changed, 77 insertions(+), 15 deletions(-) diff --git a/usr.bin/tmux/cmd-display-panes.c b/usr.bin/tmux/cmd-display-panes.c index ec7cef19aaa..fa44a80048d 100644 --- a/usr.bin/tmux/cmd-display-panes.c +++ b/usr.bin/tmux/cmd-display-panes.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-display-panes.c,v 1.38 2020/11/26 09:19:10 nicm Exp $ */ +/* $OpenBSD: cmd-display-panes.c,v 1.39 2021/07/21 08:06:36 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -286,12 +286,12 @@ cmd_display_panes_exec(struct cmd *self, struct cmdq_item *item) if (args_has(args, 'N')) { server_client_set_overlay(tc, delay, NULL, NULL, - cmd_display_panes_draw, NULL, cmd_display_panes_free, + cmd_display_panes_draw, NULL, cmd_display_panes_free, NULL, cdata); } else { server_client_set_overlay(tc, delay, NULL, NULL, cmd_display_panes_draw, cmd_display_panes_key, - cmd_display_panes_free, cdata); + cmd_display_panes_free, NULL, cdata); } if (args_has(args, 'b')) diff --git a/usr.bin/tmux/menu.c b/usr.bin/tmux/menu.c index abd0496baca..d102b294563 100644 --- a/usr.bin/tmux/menu.c +++ b/usr.bin/tmux/menu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: menu.c,v 1.33 2020/10/30 12:00:01 nicm Exp $ */ +/* $OpenBSD: menu.c,v 1.34 2021/07/21 08:06:36 nicm Exp $ */ /* * Copyright (c) 2019 Nicholas Marriott @@ -390,6 +390,6 @@ menu_display(struct menu *menu, int flags, struct cmdq_item *item, u_int px, md->data = data; server_client_set_overlay(c, 0, NULL, menu_mode_cb, menu_draw_cb, - menu_key_cb, menu_free_cb, md); + menu_key_cb, menu_free_cb, NULL, md); return (0); } diff --git a/usr.bin/tmux/popup.c b/usr.bin/tmux/popup.c index f7d716a18d3..5ff93772c69 100644 --- a/usr.bin/tmux/popup.c +++ b/usr.bin/tmux/popup.c @@ -1,4 +1,4 @@ -/* $OpenBSD: popup.c,v 1.22 2021/03/02 10:56:45 nicm Exp $ */ +/* $OpenBSD: popup.c,v 1.23 2021/07/21 08:06:36 nicm Exp $ */ /* * Copyright (c) 2020 Nicholas Marriott @@ -39,11 +39,18 @@ struct popup_data { popup_close_cb cb; void *arg; + /* Current position and size. */ u_int px; u_int py; u_int sx; u_int sy; + /* Preferred position and size. */ + u_int ppx; + u_int ppy; + u_int psx; + u_int psy; + enum { OFF, MOVE, SIZE } dragging; u_int dx; u_int dy; @@ -133,9 +140,14 @@ popup_draw_cb(struct client *c, __unused struct screen_redraw_ctx *ctx0) screen_init(&s, pd->sx, pd->sy, 0); screen_write_start(&ctx, &s); screen_write_clearscreen(&ctx, 8); - screen_write_box(&ctx, pd->sx, pd->sy); - screen_write_cursormove(&ctx, 1, 1, 0); - screen_write_fast_copy(&ctx, &pd->s, 0, 0, pd->sx - 2, pd->sy - 2); + + /* Skip drawing popup if the terminal is too small. */ + if (pd->sx > 2 && pd->sy > 2) { + screen_write_box(&ctx, pd->sx, pd->sy); + screen_write_cursormove(&ctx, 1, 1, 0); + screen_write_fast_copy(&ctx, &pd->s, 0, 0, pd->sx - 2, + pd->sy - 2); + } screen_write_stop(&ctx); c->overlay_check = NULL; @@ -171,6 +183,41 @@ popup_free_cb(struct client *c) free(pd); } +static void +popup_resize_cb(struct client *c) +{ + struct popup_data *pd = c->overlay_data; + struct tty *tty = &c->tty; + + if (pd == NULL) + return; + + /* Adjust position and size. */ + if (pd->psy > tty->sy) + pd->sy = tty->sy; + else + pd->sy = pd->psy; + if (pd->psx > tty->sx) + pd->sx = tty->sx; + else + pd->sx = pd->psx; + if (pd->ppy + pd->sy > tty->sy) + pd->py = tty->sy - pd->sy; + else + pd->py = pd->ppy; + if (pd->ppx + pd->sx > tty->sx) + pd->px = tty->sx - pd->sx; + else + pd->px = pd->ppx; + + /* Avoid zero size screens. */ + if (pd->sx > 2 && pd->sy > 2) { + screen_resize(&pd->s, pd->sx - 2, pd->sy - 2, 0); + if (pd->job != NULL) + job_resize(pd->job, pd->sx - 2, pd->sy - 2); + } +} + static void popup_handle_drag(struct client *c, struct popup_data *pd, struct mouse_event *m) @@ -196,6 +243,8 @@ popup_handle_drag(struct client *c, struct popup_data *pd, pd->py = py; pd->dx = m->x - pd->px; pd->dy = m->y - pd->py; + pd->ppx = px; + pd->ppy = py; server_redraw_client(c); } else if (pd->dragging == SIZE) { if (m->x < pd->px + 3) @@ -204,6 +253,8 @@ popup_handle_drag(struct client *c, struct popup_data *pd, return; pd->sx = m->x - pd->px; pd->sy = m->y - pd->py; + pd->psx = pd->sx; + pd->psy = pd->sy; screen_resize(&pd->s, pd->sx - 2, pd->sy - 2, 0); if (pd->job != NULL) @@ -348,13 +399,18 @@ popup_display(int flags, struct cmdq_item *item, u_int px, u_int py, u_int sx, pd->sx = sx; pd->sy = sy; + pd->ppx = px; + pd->ppy = py; + pd->psx = sx; + pd->psy = sy; + pd->job = job_run(shellcmd, argc, argv, s, cwd, popup_job_update_cb, popup_job_complete_cb, NULL, pd, JOB_NOWAIT|JOB_PTY|JOB_KEEPWRITE, pd->sx - 2, pd->sy - 2); pd->ictx = input_init(NULL, job_get_event(pd->job)); server_client_set_overlay(c, 0, popup_check_cb, popup_mode_cb, - popup_draw_cb, popup_key_cb, popup_free_cb, pd); + popup_draw_cb, popup_key_cb, popup_free_cb, popup_resize_cb, pd); return (0); } diff --git a/usr.bin/tmux/server-client.c b/usr.bin/tmux/server-client.c index ea50b55dfb1..a5604ab5171 100644 --- a/usr.bin/tmux/server-client.c +++ b/usr.bin/tmux/server-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server-client.c,v 1.375 2021/06/10 07:43:44 nicm Exp $ */ +/* $OpenBSD: server-client.c,v 1.376 2021/07/21 08:06:36 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -93,7 +93,7 @@ void server_client_set_overlay(struct client *c, u_int delay, overlay_check_cb checkcb, overlay_mode_cb modecb, overlay_draw_cb drawcb, overlay_key_cb keycb, overlay_free_cb freecb, - void *data) + overlay_resize_cb resizecb, void *data) { struct timeval tv; @@ -114,6 +114,7 @@ server_client_set_overlay(struct client *c, u_int delay, c->overlay_draw = drawcb; c->overlay_key = keycb; c->overlay_free = freecb; + c->overlay_resize = resizecb; c->overlay_data = data; c->tty.flags |= TTY_FREEZE; @@ -2061,9 +2062,12 @@ server_client_dispatch(struct imsg *imsg, void *arg) if (c->flags & CLIENT_CONTROL) break; server_client_update_latest(c); - server_client_clear_overlay(c); tty_resize(&c->tty); recalculate_sizes(); + if (c->overlay_resize == NULL) + server_client_clear_overlay(c); + else + c->overlay_resize(c); server_redraw_client(c); if (c->session != NULL) notify_client("client-resized", c); diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index 18ec5747268..99dbaf40a6a 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1111 2021/07/14 08:56:00 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.1112 2021/07/21 08:06:36 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -1629,6 +1629,7 @@ typedef struct screen *(*overlay_mode_cb)(struct client *, u_int *, u_int *); typedef void (*overlay_draw_cb)(struct client *, struct screen_redraw_ctx *); typedef int (*overlay_key_cb)(struct client *, struct key_event *); typedef void (*overlay_free_cb)(struct client *); +typedef void (*overlay_resize_cb)(struct client *); struct client { const char *name; struct tmuxpeer *peer; @@ -1776,6 +1777,7 @@ struct client { overlay_draw_cb overlay_draw; overlay_key_cb overlay_key; overlay_free_cb overlay_free; + overlay_resize_cb overlay_resize; void *overlay_data; struct event overlay_timer; @@ -2483,7 +2485,7 @@ RB_PROTOTYPE(client_windows, client_window, entry, server_client_window_cmp); u_int server_client_how_many(void); void server_client_set_overlay(struct client *, u_int, overlay_check_cb, overlay_mode_cb, overlay_draw_cb, overlay_key_cb, - overlay_free_cb, void *); + overlay_free_cb, overlay_resize_cb, void *); void server_client_clear_overlay(struct client *); void server_client_set_key_table(struct client *, const char *); const char *server_client_get_key_table(struct client *); -- 2.20.1