Code

Fix scrolling bugs in gnome-terminal and (u)xterm
authorJonas Fonseca <fonseca@diku.dk>
Mon, 2 Feb 2009 14:18:12 +0000 (15:18 +0100)
committerJonas Fonseca <fonseca@diku.dk>
Mon, 2 Feb 2009 14:18:12 +0000 (15:18 +0100)
Introduces workarounds to fix glitches appearing after the recent screen
drawing optimizations.

BUGS
tig.c

diff --git a/BUGS b/BUGS
index c6fbc0cb9d748fa7119ec04d85838b88dd432f35..35c834450a11067d21b47254308757514f5f9643 100644 (file)
--- a/BUGS
+++ b/BUGS
@@ -5,10 +5,3 @@ Known bugs and problems:
  - Proper locale support: in it's current state tig is pretty much UTF-8 only.
 
  - Horizontal scrolling.
-
- - In the gnome-terminal-emulator, the message from scrolling up one line
-   when impossible followed by scrolling down one line causes corruption of
-   the status line.
-
- - When scrolling in xterm (and uxterm) the last line in the scrolling
-   direction will update slowly.
diff --git a/tig.c b/tig.c
index b4e4b596078919afdb620efb922590ab9f0e3620..657fe10f8920daced8c35f716a7a4e1142fce79c 100644 (file)
--- a/tig.c
+++ b/tig.c
@@ -1766,6 +1766,7 @@ struct view {
        struct line *curline;   /* Line currently being drawn. */
        enum line_type curtype; /* Attribute currently used for drawing. */
        unsigned long col;      /* Column when drawing. */
+       bool has_scrolled;      /* View was scrolled. */
 
        /* Loading */
        struct io io;
@@ -2278,6 +2279,7 @@ do_scroll_view(struct view *view, int lines)
                wnoutrefresh(view->win);
        }
 
+       view->has_scrolled = TRUE;
        report("");
 }
 
@@ -6100,6 +6102,10 @@ utf8_length(const char *string, int *width, size_t max_width, int *trimmed, bool
 /* Whether or not the curses interface has been initialized. */
 static bool cursed = FALSE;
 
+/* Terminal hacks and workarounds. */
+static bool use_scroll_redrawwin;
+static bool use_scroll_status_wclear;
+
 /* The status window is used for polling keystrokes. */
 static WINDOW *status_win;
 
@@ -6138,6 +6144,8 @@ report(const char *msg, ...)
                va_start(args, msg);
 
                wmove(status_win, 0, 0);
+               if (view->has_scrolled && use_scroll_status_wclear)
+                       wclear(status_win);
                if (*msg) {
                        vwprintw(status_win, msg, args);
                        status_empty = FALSE;
@@ -6167,6 +6175,7 @@ set_nonblocking_input(bool loading)
 static void
 init_display(void)
 {
+       const char *term;
        int x, y;
 
        /* Initialize the curses library */
@@ -6205,6 +6214,27 @@ init_display(void)
        if (opt_line_graphics) {
                line_graphics[LINE_GRAPHIC_VLINE] = ACS_VLINE;
        }
+
+       term = getenv("XTERM_VERSION") ? NULL : getenv("COLORTERM");
+       if (term && !strcmp(term, "gnome-terminal")) {
+               /* In the gnome-terminal-emulator, the message from
+                * scrolling up one line when impossible followed by
+                * scrolling down one line causes corruption of the
+                * status line. This is fixed by calling wclear. */
+               use_scroll_status_wclear = TRUE;
+               use_scroll_redrawwin = FALSE;
+
+       } else if (term && !strcmp(term, "xrvt-xpm")) {
+               /* No problems with full optimizations in xrvt-(unicode)
+                * and aterm. */
+               use_scroll_status_wclear = use_scroll_redrawwin = FALSE;
+
+       } else {
+               /* When scrolling in (u)xterm the last line in the
+                * scrolling direction will update slowly. */
+               use_scroll_redrawwin = TRUE;
+               use_scroll_status_wclear = FALSE;
+       }
 }
 
 static int
@@ -6217,8 +6247,13 @@ get_input(int prompt_position)
                input_mode = TRUE;
 
        while (TRUE) {
-               foreach_view (view, i)
+               foreach_view (view, i) {
                        update_view(view);
+                       if (view_is_displayed(view) && view->has_scrolled &&
+                           use_scroll_redrawwin)
+                               redrawwin(view->win);
+                       view->has_scrolled = FALSE;
+               }
 
                /* Update the cursor position. */
                if (prompt_position) {