Do not close popups on resize, instead adjust them to fit, from Anindya
authornicm <nicm@openbsd.org>
Wed, 21 Jul 2021 08:06:36 +0000 (08:06 +0000)
committernicm <nicm@openbsd.org>
Wed, 21 Jul 2021 08:06:36 +0000 (08:06 +0000)
Mukherjee.

usr.bin/tmux/cmd-display-panes.c
usr.bin/tmux/menu.c
usr.bin/tmux/popup.c
usr.bin/tmux/server-client.c
usr.bin/tmux/tmux.h

index ec7cef1..fa44a80 100644 (file)
@@ -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 <nicholas.marriott@gmail.com>
@@ -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'))
index abd0496..d102b29 100644 (file)
@@ -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 <nicholas.marriott@gmail.com>
@@ -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);
 }
index f7d716a..5ff9377 100644 (file)
@@ -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 <nicholas.marriott@gmail.com>
@@ -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);
 }
 
index ea50b55..a5604ab 100644 (file)
@@ -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 <nicholas.marriott@gmail.com>
@@ -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);
index 18ec574..99dbaf4 100644 (file)
@@ -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 <nicholas.marriott@gmail.com>
@@ -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 *);