billiob pushed a commit to branch master.

http://git.enlightenment.org/apps/terminology.git/commit/?id=cbc92a55fc89e4a21fef0462b31c19597a5a1c02

commit cbc92a55fc89e4a21fef0462b31c19597a5a1c02
Author: Boris Faure <bill...@gmail.com>
Date:   Sun Dec 7 23:51:23 2014 +0100

    Fix screen mangling from prompt redraws on resize. Closes T1193
    
    There are still some oddities because the shell doesn't expect us to
    reflow.
    
    Let's say we have the following where X is the cursor.
    
    +-------+
    |foobar$|
    |X      |
    +-------+
    Here, the shell explicitly told us to go to a new line after '$'. We don't
    consider '$' is on the same line as 'foobar'.
    Decrease the width of that window.
    +------+
    |foobar|
    |$     |
    |X     |
    +------+
    Let the shell know the new size. It decides to redraw the prompt. It
    remembers it told us to go to a new line, so the first thing it tells us
    is to go one line up: to '$' and not 'foobar'. Then it tells us to clear
    the screen downward from there and to print "foobar$" (and go to new
    line).
    
    Thus we have the following:
    +------+
    |foobar|
    |foobar|
    |$     |
    |X     |
    +------+
---
 src/bin/termpty.c    | 94 +++++++++++++++++++++++++++++-----------------------
 src/bin/termptyesc.c |  2 +-
 2 files changed, 53 insertions(+), 43 deletions(-)

diff --git a/src/bin/termpty.c b/src/bin/termpty.c
index 90ffd92..e8a8ac1 100644
--- a/src/bin/termpty.c
+++ b/src/bin/termpty.c
@@ -657,13 +657,15 @@ termpty_line_find_top(Termpty *ty, int y_end, int *top)
 
 static int
 termpty_line_rewrap(Termpty *ty, int y_start, int y_end,
-                    Termcell *screen2, Termsave **back2,
-                    int w2, int y2_end, int *new_y2_start)
+                    Termcell *new_screen, Termsave **new_back,
+                    int new_w, int new_y_end, int *new_y_startp,
+                    int *new_cyp)
 {
-   int x, x2, y, y2, y2_start;
-   int len, len_last, len_remaining, copy_width, ts2_width;
-   Termsave *ts, *ts2;
-   Termcell *line, *line2 = NULL;
+   /* variables prefixed by new_ are about the resized term being built up */
+   int x, y, new_x, new_y, new_y_start;
+   int len, len_last, len_remaining, copy_width, new_ts_width;
+   Termsave *ts, *new_ts;
+   Termcell *line, *new_line = NULL;
 
    if (y_end >= 0)
      {
@@ -679,32 +681,32 @@ termpty_line_rewrap(Termpty *ty, int y_start, int y_end,
         len_last = ts->w;
      }
    len_remaining = len_last + (y_end - y_start) * ty->w;
-   y2_start = y2_end;
+   new_y_start = new_y_end;
    if (len_remaining)
      {
-        y2_start -= (len_remaining + w2 - 1) / w2 - 1;
+        new_y_start -= (len_remaining + new_w - 1) / new_w - 1;
      }
    else
      {
-        if (y2_start < 0)
-          back2[y2_start + ty->backmax] = termpty_save_new(0);
-        *new_y2_start = y2_start;
+        if (new_y_start < 0)
+          new_back[new_y_start + ty->backmax] = termpty_save_new(0);
+        *new_y_startp = new_y_start;
         return 0;
      }
-   if (-y2_start > ty->backmax)
+   if (-new_y_start > ty->backmax)
      {
-        y_start += ((-y2_start - ty->backmax) * w2) / ty->w;
-        x = ((-y2_start - ty->backmax) * w2) % ty->w;
-        len_remaining -= (-y2_start - ty->backmax) * w2;
-        y2_start = -ty->backmax;
+        y_start += ((-new_y_start - ty->backmax) * new_w) / ty->w;
+        x = ((-new_y_start - ty->backmax) * new_w) % ty->w;
+        len_remaining -= (-new_y_start - ty->backmax) * new_w;
+        new_y_start = -ty->backmax;
      }
    else
      {
         x = 0;
      }
    y = y_start;
-   x2 = 0;
-   y2 = y2_start;
+   new_x = 0;
+   new_y = new_y_start;
 
    while (y <= y_end)
      {
@@ -728,41 +730,45 @@ termpty_line_rewrap(Termpty *ty, int y_start, int y_end,
         line[len - 1].att.autowrapped = 0;
         while (x < len)
           {
-             copy_width = MIN(len - x, w2 - x2);
-             if (x2 == 0)
+             copy_width = MIN(len - x, new_w - new_x);
+             if (new_x == 0)
                {
-                  if (y2 >= 0)
+                  if (new_y >= 0)
                     {
-                       line2 = screen2 + (y2 * w2);
+                       new_line = new_screen + (new_y * new_w);
                     }
                   else
                     {
-                       ts2_width = MIN(len_remaining, w2);
-                       ts2 = termpty_save_new(ts2_width);
-                       if (!ts2)
+                       new_ts_width = MIN(len_remaining, new_w);
+                       new_ts = termpty_save_new(new_ts_width);
+                       if (!new_ts)
                          return -1;
-                       line2 = ts2->cell;
-                       back2[y2 + ty->backmax] = ts2;
+                       new_line = new_ts->cell;
+                       new_back[new_y + ty->backmax] = new_ts;
                     }
                }
-             if (line2)
+             if (y == ty->state.cy)
                {
-                  termpty_cell_copy(ty, line + x, line2 + x2, copy_width);
+                  *new_cyp = new_y_start;
+               }
+             if (new_line)
+               {
+                  termpty_cell_copy(ty, line + x, new_line + new_x, 
copy_width);
                   x += copy_width;
-                  x2 += copy_width;
+                  new_x += copy_width;
                   len_remaining -= copy_width;
-                  if ((x2 == w2) && (y2 != y2_end))
+                  if ((new_x == new_w) && (new_y != new_y_end))
                     {
-                       line2[x2 - 1].att.autowrapped = 1;
-                       x2 = 0;
-                       y2++;
+                       new_line[new_x - 1].att.autowrapped = 1;
+                       new_x = 0;
+                       new_y++;
                     }
                }
           }
         x = 0;
         y++;
      }
-   *new_y2_start = y2_start;
+   *new_y_startp = new_y_start;
    return 0;
 }
 
@@ -772,7 +778,8 @@ termpty_resize(Termpty *ty, int new_w, int new_h)
 {
    Termcell *new_screen = NULL;
    Termsave **new_back = NULL;
-   int y_start, y_end, new_y_start = 0, new_y_end;
+   int y_start = 0, y_end = 0, new_y_start = 0, new_y_end,
+       new_cy = ty->state.cy;
    int i, altbuf = 0;
 
    if ((ty->w == new_w) && (ty->h == new_h)) return;
@@ -798,14 +805,18 @@ termpty_resize(Termpty *ty, int new_w, int new_h)
 
    y_end = ty->state.cy;
    new_y_end = new_h - 1;
+   /* For each "full line" in old buffers, revrap.
+    * From most recent to oldest */
    while ((y_end >= -ty->backscroll_num) && (new_y_end >= -ty->backmax))
      {
         if (termpty_line_find_top(ty, y_end, &y_start) < 0)
           goto bad;
-        if (termpty_line_rewrap(ty, y_start, y_end, new_screen,
-                                new_back, new_w, new_y_end,
-                                &new_y_start) < 0)
+        if (termpty_line_rewrap(ty, y_start, y_end,
+                                new_screen, new_back,
+                                new_w, new_y_end,
+                                &new_y_start, &new_cy) < 0)
           goto bad;
+
         y_end = y_start - 1;
         new_y_end = new_y_start - 1;
      }
@@ -819,14 +830,13 @@ termpty_resize(Termpty *ty, int new_w, int new_h)
 
    ty->w = new_w;
    ty->h = new_h;
-   ty->state.cy = MIN((new_h - 1) - new_y_start, new_h - 1);
-   ty->state.cx = termpty_line_length(new_screen + ((new_h - 1) * new_w),
-                                      new_w);
    ty->circular_offset = MAX(new_y_start, 0);
    ty->backpos = 0;
    ty->backscroll_num = MAX(-new_y_start, 0);
    ty->state.had_cr = 0;
 
+   ty->state.cy = (new_cy + new_h - ty->circular_offset) % new_h;
+
    if (altbuf) termpty_screen_swap(ty);
 
    _limit_coord(ty, &(ty->state));
diff --git a/src/bin/termptyesc.c b/src/bin/termptyesc.c
index b242011..d0fd99e 100644
--- a/src/bin/termptyesc.c
+++ b/src/bin/termptyesc.c
@@ -99,8 +99,8 @@ _handle_cursor_control(Termpty *ty, const Eina_Unicode *cc)
            {
               ty->state.had_cr_x = ty->state.cx;
               ty->state.had_cr_y = ty->state.cy;
+              ty->state.wrapnext = 0;
            }
-         ty->state.wrapnext = 0;
          ty->state.cx = 0;
 //         ty->state.had_cr = 1;
          return;

-- 


Reply via email to