Index: vte-0.26.0/src/vte.c =================================================================== --- vte-0.26.0.orig/src/vte.c 2010-11-30 19:59:13.000000000 -0800 +++ vte-0.26.0/src/vte.c 2010-11-30 20:03:17.856750024 -0800 @@ -3862,6 +3862,7 @@ vte_terminal_process_incoming(VteTermina long wcount, start, delta; gboolean leftovers, modified, bottom, again; gboolean invalidated_text; + gboolean in_scroll_region; GArray *unichars; struct _vte_incoming_chunk *chunk, *next_chunk, *achunk = NULL; @@ -3881,6 +3882,10 @@ vte_terminal_process_incoming(VteTermina cursor = screen->cursor_current; cursor_visible = terminal->pvt->cursor_visible; + in_scroll_region = screen->scrolling_restricted + && (screen->cursor_current.row >= (screen->insert_delta + screen->scrolling_region.start)) + && (screen->cursor_current.row <= (screen->insert_delta + screen->scrolling_region.end)); + /* We should only be called when there's data to process. */ g_assert(terminal->pvt->incoming || (terminal->pvt->pending->len > 0)); @@ -3979,6 +3984,8 @@ skip_chunk: * points to the first character which isn't part of this * sequence. */ if ((match != NULL) && (match[0] != '\0')) { + gboolean new_in_scroll_region; + /* Call the right sequence handler for the requested * behavior. */ _vte_terminal_handle_sequence(terminal, @@ -3989,12 +3996,18 @@ skip_chunk: start = (next - wbuf); modified = TRUE; - /* if we have moved during the sequence handler, restart the bbox */ + new_in_scroll_region = screen->scrolling_restricted + && (screen->cursor_current.row >= (screen->insert_delta + screen->scrolling_region.start)) + && (screen->cursor_current.row <= (screen->insert_delta + screen->scrolling_region.end)); + + /* if we have moved greatly during the sequence handler, or moved into a scroll_region + * from outside it, restart the bbox */ if (invalidated_text && - (screen->cursor_current.col > bbox_bottomright.x + VTE_CELL_BBOX_SLACK || - screen->cursor_current.col < bbox_topleft.x - VTE_CELL_BBOX_SLACK || - screen->cursor_current.row > bbox_bottomright.y + VTE_CELL_BBOX_SLACK || - screen->cursor_current.row < bbox_topleft.y - VTE_CELL_BBOX_SLACK)) { + ((new_in_scroll_region && !in_scroll_region) || + (screen->cursor_current.col > bbox_bottomright.x + VTE_CELL_BBOX_SLACK || + screen->cursor_current.col < bbox_topleft.x - VTE_CELL_BBOX_SLACK || + screen->cursor_current.row > bbox_bottomright.y + VTE_CELL_BBOX_SLACK || + screen->cursor_current.row < bbox_topleft.y - VTE_CELL_BBOX_SLACK))) { /* Clip off any part of the box which isn't already on-screen. */ bbox_topleft.x = MAX(bbox_topleft.x, 0); bbox_topleft.y = MAX(bbox_topleft.y, delta); @@ -4014,6 +4027,8 @@ skip_chunk: bbox_bottomright.x = bbox_bottomright.y = -G_MAXINT; bbox_topleft.x = bbox_topleft.y = G_MAXINT; } + + in_scroll_region = new_in_scroll_region; } else /* Second, we have a NULL match, and next points to the very * next character in the buffer. Insert the character which