From 1db691c2f501c07c38ffaa69cd1af18e1f77f4dc Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Tue, 27 Oct 2015 11:37:50 +0100 Subject: [PATCH] Fix wrong reset of horizontal scolling of current row This partially reverts commit 0f1fdaaa9, but only redraws the current row when the value returns by getPos is obviously false. It would also be possible to check whether the current cursor has all its insets in cache instead. A better fix should be found, but this is unfortunately not 2.2 stuff. Fixes bugs #9796 and #9812. --- src/BufferView.cpp | 40 +++++++++++++++++++++++++++++++++++++--- src/BufferView.h | 2 +- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/BufferView.cpp b/src/BufferView.cpp index 663618af36..658fa0e600 100644 --- a/src/BufferView.cpp +++ b/src/BufferView.cpp @@ -46,6 +46,7 @@ #include "Paragraph.h" #include "ParagraphParameters.h" #include "ParIterator.h" +#include "RowPainter.h" #include "Session.h" #include "Text.h" #include "TextClass.h" @@ -2986,7 +2987,7 @@ void BufferView::setCurrentRowSlice(CursorSlice const & rowSlice) } -void BufferView::checkCursorScrollOffset() +void BufferView::checkCursorScrollOffset(PainterInfo & pi) { CursorSlice rowSlice = d->cursor_.bottom(); TextMetrics const & tm = textMetrics(rowSlice.text()); @@ -3004,7 +3005,40 @@ void BufferView::checkCursorScrollOffset() setCurrentRowSlice(rowSlice); // Current x position of the cursor in pixels - int const cur_x = getPos(d->cursor_).x_; + int cur_x = getPos(d->cursor_).x_; + + // If cursor offset is left margin and offset is not the leftmost + // position of the row, there is a cache problem. + if (cur_x == row.left_margin && !row.empty() + && d->cursor_.pos() != row.front().left_pos()) { + /** FIXME: the code below adds an extraneous computation of + * inset positions, and can therefore be bad for performance + * (think for example about a very large tabular inset. + * Redawing the row where it is means redrawing the whole + * screen). + * + * The bug that this fixes is the following: assume that there + * is a very large math inset. Upon entering the inset, when + * pressing `End', the row is not scrolled and the cursor is + * not visible. The extra row computation makes sure that the + * inset positions are correctly computed and set in the + * cache. This would not happen if we did not have two-stage + * drawing. + * + * A proper fix should be found and this code should be removed. + */ + // Force the recomputation of inset positions + bool const drawing = pi.pain.isDrawingEnabled(); + pi.pain.setDrawingEnabled(false); + // No need to care about vertical position. + RowPainter rp(pi, buffer().text(), d->cursor_.bottom().pit(), row, + -d->horiz_scroll_offset_, 0); + rp.paintText(); + pi.pain.setDrawingEnabled(drawing); + + // Recompute current Current x position of the cursor in pixels + cur_x = getPos(d->cursor_).x_; + } // Horizontal scroll offset of the cursor row in pixels int offset = d->horiz_scroll_offset_; @@ -3050,7 +3084,7 @@ void BufferView::draw(frontend::Painter & pain) // Check whether the row where the cursor lives needs to be scrolled. // Update the drawing strategy if needed. - checkCursorScrollOffset(); + checkCursorScrollOffset(pi); switch (d->update_strategy_) { diff --git a/src/BufferView.h b/src/BufferView.h index 15d2c6bd0f..31b6e94fc4 100644 --- a/src/BufferView.h +++ b/src/BufferView.h @@ -352,7 +352,7 @@ private: // Check whether the row where the cursor lives needs to be scrolled. // Update the drawing strategy if needed. - void checkCursorScrollOffset(); + void checkCursorScrollOffset(PainterInfo & pi); /// The minimal size of the document that is visible. Used /// when it is allowed to scroll below the document. -- 2.39.5