From: Jean-Marc Lasgouttes Date: Tue, 27 Oct 2015 10:37:50 +0000 (+0100) Subject: Fix wrong reset of horizontal scolling of current row X-Git-Tag: 2.2.0alpha1~99 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=1db691c2f501c07c38ffaa69cd1af18e1f77f4dc;p=features.git 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. --- 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.