diff options
Diffstat (limited to 'src/dispnew.c')
| -rw-r--r-- | src/dispnew.c | 82 |
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 | } |