[vte/vte-0-34] Fix resize handling
- From: Behdad Esfahbod <behdad src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte/vte-0-34] Fix resize handling
- Date: Fri, 27 Sep 2013 19:37:06 +0000 (UTC)
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]