]> git.lyx.org Git - features.git/commitdiff
Detect properly when cursor position cannot be computed
authorJean-Marc Lasgouttes <lasgouttes@lyx.org>
Fri, 4 Dec 2015 22:26:16 +0000 (23:26 +0100)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Mon, 7 Dec 2015 12:25:10 +0000 (13:25 +0100)
Replace old ad-hoc test by a better one that inspects the coordcache to see whether all the insets in the cursor are known.

Fixes bug #9881.

src/BufferView.cpp
src/Cursor.cpp
src/Cursor.h

index 0030f33f4c1d19f11c19dfef172014f1b6fb3c52..06ea9ea6c964e9a73afda6a8e75cad07e82d44a0 100644 (file)
@@ -433,7 +433,7 @@ bool BufferView::needsFitCursor() const
 void BufferView::processUpdateFlags(Update::flags flags)
 {
        // This is close to a hot-path.
-       LYXERR(Debug::DEBUG, "BufferView::processUpdateFlags()"
+       LYXERR(Debug::PAINTING, "BufferView::processUpdateFlags()"
                << "[fitcursor = " << (flags & Update::FitCursor)
                << ", forceupdate = " << (flags & Update::Force)
                << ", singlepar = " << (flags & Update::SinglePar)
@@ -2949,13 +2949,9 @@ void BufferView::checkCursorScrollOffset(PainterInfo & pi)
        // Set the row on which the cursor lives.
        setCurrentRowSlice(rowSlice);
 
-       // Current x position of the cursor in pixels
-       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()) {
+       // If insets referred to by cursor are not all in the cache, the positions
+       // need to be recomputed.
+       if (!d->cursor_.inCoordCache()) {
                /** 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.
@@ -2970,7 +2966,8 @@ void BufferView::checkCursorScrollOffset(PainterInfo & pi)
                 * 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.
+                * A proper fix would be to always have proper inset positions
+                * at this point.
                 */
                // Force the recomputation of inset positions
                bool const drawing = pi.pain.isDrawingEnabled();
@@ -2980,11 +2977,11 @@ void BufferView::checkCursorScrollOffset(PainterInfo & pi)
                              -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_;
        }
 
+       // Current x position of the cursor in pixels
+       int cur_x = getPos(d->cursor_).x_;
+
        // Horizontal scroll offset of the cursor row in pixels
        int offset = d->horiz_scroll_offset_;
        int const MARGIN = 2 * theFontMetrics(d->cursor_.real_current_font).em()
index cd796458de12c4f551aea72f5e4d2d4094488082..c1458dc8a7a0cfc757870775cb2095e748ede087 100644 (file)
@@ -548,6 +548,16 @@ int Cursor::currentMode()
 }
 
 
+bool Cursor::inCoordCache() const
+{
+       CoordCache::Insets const & icache = bv_->coordCache().getInsets();
+       for (size_t i = 0 ; i < depth() ; ++i)
+               if (!icache.has(&(*this)[i].inset()))
+                       return false;
+       return true;
+}
+
+
 void Cursor::getPos(int & x, int & y) const
 {
        Point p = bv().getPos(*this);
index 1cd51c2d11a7f7fc229d55bbbdbe4de2dfd8538b..a0f5ec14bf14f4ac434163f7690f6e264bbe17b6 100644 (file)
@@ -216,6 +216,9 @@ public:
        bool macromode() const { return macromode_; }
        /// are we entering a macro name?
        bool & macromode() { return macromode_; }
+
+       /// returns true when all insets in cursor stack are in cache
+       bool inCoordCache() const;
        /// returns x,y position
        void getPos(int & x, int & y) const;
        /// return logical positions between which the cursor is situated