aboutsummaryrefslogtreecommitdiffstats
path: root/src/dispnew.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dispnew.c')
-rw-r--r--src/dispnew.c82
1 files changed, 70 insertions, 12 deletions
diff --git a/src/dispnew.c b/src/dispnew.c
index b920693688c..e21f565fb3a 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -612,7 +612,6 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
612 row->glyphs[LAST_AREA] 612 row->glyphs[LAST_AREA]
613 = row->glyphs[LEFT_MARGIN_AREA] + dim.width; 613 = row->glyphs[LEFT_MARGIN_AREA] + dim.width;
614 } 614 }
615 xassert (!row->enabled_p || verify_row_hash (row));
616 ++row; 615 ++row;
617 } 616 }
618 } 617 }
@@ -3580,12 +3579,11 @@ update_window (struct window *w, int force_p)
3580 3579
3581 rif->update_window_begin_hook (w); 3580 rif->update_window_begin_hook (w);
3582 yb = window_text_bottom_y (w); 3581 yb = window_text_bottom_y (w);
3583
3584 /* If window has a header line, update it before everything else.
3585 Adjust y-positions of other rows by the header line height. */
3586 row = desired_matrix->rows; 3582 row = desired_matrix->rows;
3587 end = row + desired_matrix->nrows - 1; 3583 end = row + desired_matrix->nrows - 1;
3588 3584
3585 /* Take note of the header line, if there is one. We will
3586 update it below, after updating all of the window's lines. */
3589 if (row->mode_line_p) 3587 if (row->mode_line_p)
3590 { 3588 {
3591 header_line_row = row; 3589 header_line_row = row;
@@ -3630,6 +3628,8 @@ update_window (struct window *w, int force_p)
3630 3628
3631 /* Update the rest of the lines. */ 3629 /* Update the rest of the lines. */
3632 for (; row < end && (force_p || !input_pending); ++row) 3630 for (; row < end && (force_p || !input_pending); ++row)
3631 /* scrolling_window resets the enabled_p flag of the rows it
3632 reuses from current_matrix. */
3633 if (row->enabled_p) 3633 if (row->enabled_p)
3634 { 3634 {
3635 int vpos = MATRIX_ROW_VPOS (row, desired_matrix); 3635 int vpos = MATRIX_ROW_VPOS (row, desired_matrix);
@@ -4564,18 +4564,69 @@ scrolling_window (struct window *w, int header_line_p)
4564 { 4564 {
4565 rif->clear_window_mouse_face (w); 4565 rif->clear_window_mouse_face (w);
4566 rif->scroll_run_hook (w, r); 4566 rif->scroll_run_hook (w, r);
4567 }
4568
4569 /* Truncate runs that copy to where we copied to, and
4570 invalidate runs that copy from where we copied to. */
4571 for (j = nruns - 1; j > i; --j)
4572 {
4573 struct run *p = runs[j];
4574 int truncated_p = 0;
4567 4575
4568 /* Invalidate runs that copy from where we copied to. */ 4576 if (p->nrows > 0
4569 for (j = i + 1; j < nruns; ++j) 4577 && p->desired_y < r->desired_y + r->height
4578 && p->desired_y + p->height > r->desired_y)
4570 { 4579 {
4571 struct run *p = runs[j]; 4580 if (p->desired_y < r->desired_y)
4581 {
4582 p->nrows = r->desired_vpos - p->desired_vpos;
4583 p->height = r->desired_y - p->desired_y;
4584 truncated_p = 1;
4585 }
4586 else
4587 {
4588 int nrows_copied = (r->desired_vpos + r->nrows
4589 - p->desired_vpos);
4590
4591 if (p->nrows <= nrows_copied)
4592 p->nrows = 0;
4593 else
4594 {
4595 int height_copied = (r->desired_y + r->height
4596 - p->desired_y);
4597
4598 p->current_vpos += nrows_copied;
4599 p->desired_vpos += nrows_copied;
4600 p->nrows -= nrows_copied;
4601 p->current_y += height_copied;
4602 p->desired_y += height_copied;
4603 p->height -= height_copied;
4604 truncated_p = 1;
4605 }
4606 }
4607 }
4572 4608
4573 if ((p->current_y >= r->desired_y 4609 if (r->current_y != r->desired_y
4610 /* The condition below is equivalent to
4611 ((p->current_y >= r->desired_y
4574 && p->current_y < r->desired_y + r->height) 4612 && p->current_y < r->desired_y + r->height)
4575 || (p->current_y + p->height >= r->desired_y 4613 || (p->current_y + p->height > r->desired_y
4576 && (p->current_y + p->height 4614 && (p->current_y + p->height
4577 < r->desired_y + r->height))) 4615 <= r->desired_y + r->height)))
4578 p->nrows = 0; 4616 because we have 0 < p->height <= r->height. */
4617 && p->current_y < r->desired_y + r->height
4618 && p->current_y + p->height > r->desired_y)
4619 p->nrows = 0;
4620
4621 /* Reorder runs by copied pixel lines if truncated. */
4622 if (truncated_p && p->nrows > 0)
4623 {
4624 int k = nruns - 1;
4625
4626 while (runs[k]->nrows == 0 || runs[k]->height < p->height)
4627 k--;
4628 memmove (runs + j, runs + j + 1, (k - j) * sizeof (*runs));
4629 runs[k] = p;
4579 } 4630 }
4580 } 4631 }
4581 4632
@@ -4590,7 +4641,14 @@ scrolling_window (struct window *w, int header_line_p)
4590 to_overlapped_p = to->overlapped_p; 4641 to_overlapped_p = to->overlapped_p;
4591 from->redraw_fringe_bitmaps_p = from->fringe_bitmap_periodic_p; 4642 from->redraw_fringe_bitmaps_p = from->fringe_bitmap_periodic_p;
4592 assign_row (to, from); 4643 assign_row (to, from);
4593 to->enabled_p = 1, from->enabled_p = 0; 4644 /* The above `assign_row' actually does swap, so if we had
4645 an overlap in the copy destination of two runs, then
4646 the second run would assign a previously disabled bogus
4647 row. But thanks to the truncation code in the
4648 preceding for-loop, we no longer have such an overlap,
4649 and thus the assigned row should always be enabled. */
4650 xassert (to->enabled_p);
4651 from->enabled_p = 0;
4594 to->overlapped_p = to_overlapped_p; 4652 to->overlapped_p = to_overlapped_p;
4595 } 4653 }
4596 } 4654 }