Always resize the original screen before copying when exiting the
authornicm <nicm@openbsd.org>
Tue, 26 Jan 2021 09:32:52 +0000 (09:32 +0000)
committernicm <nicm@openbsd.org>
Tue, 26 Jan 2021 09:32:52 +0000 (09:32 +0000)
alternate screen, GitHub issue 2536.

usr.bin/tmux/screen.c

index 6189e9c..d5dfbff 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: screen.c,v 1.68 2020/10/30 11:33:41 nicm Exp $ */
+/* $OpenBSD: screen.c,v 1.69 2021/01/26 09:32:52 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -574,7 +574,14 @@ screen_alternate_on(struct screen *s, struct grid_cell *gc, int cursor)
 void
 screen_alternate_off(struct screen *s, struct grid_cell *gc, int cursor)
 {
-       u_int   sx, sy;
+       u_int   sx = screen_size_x(s), sy = screen_size_y(s);
+
+       /*
+        * If the current size is different, temporarily resize to the old size
+        * before copying back.
+        */
+       if (s->saved_grid != NULL)
+               screen_resize(s, s->saved_grid->sx, s->saved_grid->sy, 1);
 
        /*
         * Restore the cursor position and cell. This happens even if not
@@ -582,29 +589,23 @@ screen_alternate_off(struct screen *s, struct grid_cell *gc, int cursor)
         */
        if (cursor && s->saved_cx != UINT_MAX && s->saved_cy != UINT_MAX) {
                s->cx = s->saved_cx;
-               if (s->cx > screen_size_x(s) - 1)
-                       s->cx = screen_size_x(s) - 1;
                s->cy = s->saved_cy;
-               if (s->cy > screen_size_y(s) - 1)
-                       s->cy = screen_size_y(s) - 1;
                if (gc != NULL)
                        memcpy(gc, &s->saved_cell, sizeof *gc);
        }
 
-       if (s->saved_grid == NULL)
+       /* If not in the alternate screen, do nothing more. */
+       if (s->saved_grid == NULL) {
+               if (s->cx > screen_size_x(s) - 1)
+                       s->cx = screen_size_x(s) - 1;
+               if (s->cy > screen_size_y(s) - 1)
+                       s->cy = screen_size_y(s) - 1;
                return;
-       sx = screen_size_x(s);
-       sy = screen_size_y(s);
-
-       /*
-        * If the current size is bigger, temporarily resize to the old size
-        * before copying back.
-        */
-       if (sy > s->saved_grid->sy)
-               screen_resize(s, sx, s->saved_grid->sy, 1);
+       }
 
        /* Restore the saved grid. */
-       grid_duplicate_lines(s->grid, screen_hsize(s), s->saved_grid, 0, sy);
+       grid_duplicate_lines(s->grid, screen_hsize(s), s->saved_grid, 0,
+           s->saved_grid->sy);
 
        /*
         * Turn history back on (so resize can use it) and then resize back to
@@ -612,9 +613,13 @@ screen_alternate_off(struct screen *s, struct grid_cell *gc, int cursor)
         */
        if (s->saved_flags & GRID_HISTORY)
                s->grid->flags |= GRID_HISTORY;
-       if (sy > s->saved_grid->sy || sx != s->saved_grid->sx)
-               screen_resize(s, sx, sy, 1);
+       screen_resize(s, sx, sy, 1);
 
        grid_destroy(s->saved_grid);
        s->saved_grid = NULL;
+
+       if (s->cx > screen_size_x(s) - 1)
+               s->cx = screen_size_x(s) - 1;
+       if (s->cy > screen_size_y(s) - 1)
+               s->cy = screen_size_y(s) - 1;
 }