Detect properly when cursor position cannot be computed

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.
This commit is contained in:
Jean-Marc Lasgouttes 2015-12-04 23:26:16 +01:00
parent acadb4d608
commit 79bb97b1ba
3 changed files with 22 additions and 12 deletions

View File

@ -433,7 +433,7 @@ bool BufferView::needsFitCursor() const
void BufferView::processUpdateFlags(Update::flags flags) void BufferView::processUpdateFlags(Update::flags flags)
{ {
// This is close to a hot-path. // This is close to a hot-path.
LYXERR(Debug::DEBUG, "BufferView::processUpdateFlags()" LYXERR(Debug::PAINTING, "BufferView::processUpdateFlags()"
<< "[fitcursor = " << (flags & Update::FitCursor) << "[fitcursor = " << (flags & Update::FitCursor)
<< ", forceupdate = " << (flags & Update::Force) << ", forceupdate = " << (flags & Update::Force)
<< ", singlepar = " << (flags & Update::SinglePar) << ", singlepar = " << (flags & Update::SinglePar)
@ -2949,13 +2949,9 @@ void BufferView::checkCursorScrollOffset(PainterInfo & pi)
// Set the row on which the cursor lives. // Set the row on which the cursor lives.
setCurrentRowSlice(rowSlice); setCurrentRowSlice(rowSlice);
// Current x position of the cursor in pixels // If insets referred to by cursor are not all in the cache, the positions
int cur_x = getPos(d->cursor_).x_; // need to be recomputed.
if (!d->cursor_.inCoordCache()) {
// 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 /** FIXME: the code below adds an extraneous computation of
* inset positions, and can therefore be bad for performance * inset positions, and can therefore be bad for performance
* (think for example about a very large tabular inset. * (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 * cache. This would not happen if we did not have two-stage
* drawing. * 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 // Force the recomputation of inset positions
bool const drawing = pi.pain.isDrawingEnabled(); bool const drawing = pi.pain.isDrawingEnabled();
@ -2980,11 +2977,11 @@ void BufferView::checkCursorScrollOffset(PainterInfo & pi)
-d->horiz_scroll_offset_, 0); -d->horiz_scroll_offset_, 0);
rp.paintText(); rp.paintText();
pi.pain.setDrawingEnabled(drawing); 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 // Horizontal scroll offset of the cursor row in pixels
int offset = d->horiz_scroll_offset_; int offset = d->horiz_scroll_offset_;
int const MARGIN = 2 * theFontMetrics(d->cursor_.real_current_font).em() int const MARGIN = 2 * theFontMetrics(d->cursor_.real_current_font).em()

View 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 void Cursor::getPos(int & x, int & y) const
{ {
Point p = bv().getPos(*this); Point p = bv().getPos(*this);

View File

@ -216,6 +216,9 @@ public:
bool macromode() const { return macromode_; } bool macromode() const { return macromode_; }
/// are we entering a macro name? /// are we entering a macro name?
bool & macromode() { return macromode_; } bool & macromode() { return macromode_; }
/// returns true when all insets in cursor stack are in cache
bool inCoordCache() const;
/// returns x,y position /// returns x,y position
void getPos(int & x, int & y) const; void getPos(int & x, int & y) const;
/// return logical positions between which the cursor is situated /// return logical positions between which the cursor is situated