]> git.lyx.org Git - features.git/commitdiff
Fix wrong reset of horizontal scolling of current row
authorJean-Marc Lasgouttes <lasgouttes@lyx.org>
Tue, 27 Oct 2015 10:37:50 +0000 (11:37 +0100)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Mon, 2 Nov 2015 10:11:39 +0000 (11:11 +0100)
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
src/BufferView.h

index 663618af36f185d7d08439c72294763bf0b3abf8..658fa0e6000225e237618af2789092dfb961857e 100644 (file)
@@ -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_) {
 
index 15d2c6bd0fb67c359ebaed132bd1297f4c527344..31b6e94fc484d70f451592857780e07cabc7c6b9 100644 (file)
@@ -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.