[vte/vte-0-34] Fix resize handling



commit 6e65d90d50862ca8a9e9686b7b582f22e13e8768
Author: Behdad Esfahbod <behdad behdad org>
Date:   Fri Sep 27 15:34:27 2013 -0400

    Fix resize handling
    
    Patch from Egmont Koblinger.  At least it's readable...
    
    Bug 707572 - Aborts on assertion (debug mode)
    Bug 708213 - zsh - lots of blank space upon resizing VTE based terminals

 src/debug.c |    3 +-
 src/debug.h |    3 +-
 src/vte.c   |   68 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 3 files changed, 64 insertions(+), 10 deletions(-)
---
diff --git a/src/debug.c b/src/debug.c
index 54997b9..71908ba 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -50,7 +50,8 @@ _vte_debug_init(void)
     { "ally",         VTE_DEBUG_ALLY         },
     { "pangocairo",   VTE_DEBUG_PANGOCAIRO   },
     { "widget-size",  VTE_DEBUG_WIDGET_SIZE  },
-    { "bg",           VTE_DEBUG_BG           }
+    { "bg",           VTE_DEBUG_BG           },
+    { "resize",       VTE_DEBUG_RESIZE       }
   };
 
   _vte_debug_flags = g_parse_debug_string (g_getenv("VTE_DEBUG"),
diff --git a/src/debug.h b/src/debug.h
index eee72cb..0b7ec8e 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -50,7 +50,8 @@ typedef enum {
        VTE_DEBUG_ADJ           = 1 << 19,
        VTE_DEBUG_PANGOCAIRO    = 1 << 20,
        VTE_DEBUG_WIDGET_SIZE   = 1 << 21,
-        VTE_DEBUG_BG            = 1 << 22
+       VTE_DEBUG_BG            = 1 << 22,
+       VTE_DEBUG_RESIZE        = 1 << 23
 } VteDebugFlags;
 
 void _vte_debug_init(void);
diff --git a/src/vte.c b/src/vte.c
index 0882c29..7f78450 100644
--- a/src/vte.c
+++ b/src/vte.c
@@ -8027,7 +8027,7 @@ vte_terminal_set_size(VteTerminal *terminal, glong columns, glong rows)
 
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
 
-       _vte_debug_print(VTE_DEBUG_MISC,
+       _vte_debug_print(VTE_DEBUG_RESIZE,
                        "Setting PTY size to %ldx%ld.\n",
                        columns, rows);
 
@@ -8051,14 +8051,66 @@ vte_terminal_set_size(VteTerminal *terminal, glong columns, glong rows)
        }
        if (old_rows != terminal->row_count || old_columns != terminal->column_count) {
                VteScreen *screen = terminal->pvt->screen;
-               glong visible_rows = MIN (old_rows, _vte_ring_length (screen->row_data));
-               if (terminal->row_count < visible_rows) {
-                       glong delta = visible_rows - terminal->row_count;
-                       screen->insert_delta += delta;
-                       vte_terminal_queue_adjustment_value_changed (
-                                       terminal,
-                                       screen->scroll_delta + delta);
+               VteRing *ring = screen->row_data;
+               gboolean was_scrolled_to_top = (screen->scroll_delta == _vte_ring_delta(ring));
+               gboolean was_scrolled_to_bottom = (screen->scroll_delta == screen->insert_delta);
+               glong new_scroll_delta;
+
+               _vte_debug_print(VTE_DEBUG_RESIZE,
+                               "Old  ring_delta=%ld  ring_next=%ld\n"
+                               "Old  insert_delta=%ld  scroll_delta=%ld\n",
+                               _vte_ring_delta(ring), _vte_ring_next(ring),
+                               screen->insert_delta, screen->scroll_delta);
+
+               if (old_rows > terminal->row_count &&
+                   screen->insert_delta + old_rows > screen->cursor_current.row + 1) {
+                       /* Shrinking the window, cursor was not at the bottom.
+                          Drop lines from the bottom as XTerm does, see bug 708213 */
+                       int drop_lines = MIN(
+                                       old_rows - terminal->row_count,
+                                       (screen->insert_delta + old_rows) - (screen->cursor_current.row + 1));
+                       int new_ring_next = screen->insert_delta + old_rows - drop_lines;
+                       _vte_debug_print(VTE_DEBUG_RESIZE,
+                                       "Dropping %d rows at the bottom\n",
+                                       drop_lines);
+                       _vte_ring_shrink(ring, new_ring_next - _vte_ring_delta(ring));
+               }
+               if (_vte_ring_length(ring) <= terminal->row_count) {
+                       /* Everything fits without scrollbars. Align at top. */
+                       screen->insert_delta = _vte_ring_delta(ring);
+                       new_scroll_delta = screen->insert_delta;
+                       _vte_debug_print(VTE_DEBUG_RESIZE,
+                                       "Everything fits without scrollbars\n");
+               } else {
+                       /* Scrollbar required. Can't afford unused lines at bottom. */
+                       screen->insert_delta = _vte_ring_next(ring) - terminal->row_count;
+                       if (was_scrolled_to_bottom) {
+                               /* Was scrolled to bottom, keep this way. */
+                               new_scroll_delta = screen->insert_delta;
+                               _vte_debug_print(VTE_DEBUG_RESIZE,
+                                               "Scroll to bottom\n");
+                       } else if (was_scrolled_to_top) {
+                               /* Was scrolled to top, keep this way. Not sure if this special case is worth 
it. */
+                               new_scroll_delta = _vte_ring_delta(ring);
+                               _vte_debug_print(VTE_DEBUG_RESIZE,
+                                               "Scroll to top\n");
+                       } else {
+                               /* Try to scroll so that the bottom visible row stays. */
+                               new_scroll_delta = screen->scroll_delta + old_rows - terminal->row_count;
+                               _vte_debug_print(VTE_DEBUG_RESIZE,
+                                               "Scroll so bottom row stays\n");
+                       }
                }
+
+               _vte_debug_print(VTE_DEBUG_RESIZE,
+                               "New  ring_delta=%ld  ring_next=%ld\n"
+                               "New  insert_delta=%ld  scroll_delta=%ld\n\n",
+                               _vte_ring_delta(ring), _vte_ring_next(ring),
+                               screen->insert_delta, new_scroll_delta);
+
+               vte_terminal_queue_adjustment_value_changed (
+                               terminal,
+                               new_scroll_delta);
                gtk_widget_queue_resize_no_redraw (&terminal->widget);
                /* Our visible text changed. */
                vte_terminal_emit_text_modified(terminal);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]