--- rxvt-unicode/src/screen.C 2011/07/07 23:18:13 1.387 +++ rxvt-unicode/src/screen.C 2011/07/08 00:08:40 1.388 @@ -640,24 +640,36 @@ && row1 == 0 && (current_screen == PRIMARY || option (Opt_secondaryScroll))) { - min_it (count, row2 + total_rows); + min_it (count, total_rows - (nrow - (row2 + 1))); top_row = max (top_row - count, -saveLines); - // scroll everything up 'count' lines - term_start = (term_start + count) % total_rows; - // sever bottommost line { - line_t &l = ROW(row2 - count); + line_t &l = ROW(row2 - 1); l.is_longer (0); l.touch (); } + // scroll everything up 'count' lines + term_start = (term_start + count) % total_rows; + + // now copy lines below the scroll region bottom to the + // bottom of the screen again, so they look as if they + // hadn't moved. + for (int i = nrow; --i > row2; ) + { + line_t &l1 = ROW(i - count); + line_t &l2 = ROW(i); + + ::swap (l1, l2); + l2.touch (); + } + // erase newly scrolled-in lines for (int i = count; i--; ) { - line_t &l = ROW(nrow - 1 - i); + line_t &l = ROW(row2 - i); // optimise if already cleared, can be significant on slow machines // could be rolled into scr_blank_screen_mem @@ -671,18 +683,6 @@ scr_blank_screen_mem (l, rstyle); } - // now copy lines below the scroll region bottom to the - // bottom of the screen again, so they look as if they - // hadn't moved. - for (int i = nrow; --i > row2; ) - { - line_t &l1 = ROW(i - count); - line_t &l2 = ROW(i); - - ::swap (l1, l2); - l2.touch (); - } - // move and/or clear selection, if any if (selection.op && current_screen == selection.screen) {