Introduce BufferView::caretInView()

It is not a good idea to call caretPosAndHeight when the caret is in a
paragraph that is not in cached metrics. This can happen when not
using "cursor follows scrollbar".

This commit refactor things a bit so that testing is done in
BufferView.

(cherry picked from commit e6b54ea4d2)
This commit is contained in:
Jean-Marc Lasgouttes 2019-07-14 23:20:29 +02:00
parent 195f307a39
commit 64e5a8c016
3 changed files with 18 additions and 22 deletions

View File

@ -3060,11 +3060,16 @@ void BufferView::caretPosAndHeight(Point & p, int & h) const
}
bool BufferView::cursorInView(Point const & p, int h) const
bool BufferView::caretInView() const
{
Cursor const & cur = cursor();
if (!paragraphVisible(cursor()))
return false;
Point p;
int h;
caretPosAndHeight(p, h);
// does the cursor touch the screen ?
if (p.y_ + h < 0 || p.y_ >= workHeight() || !paragraphVisible(cur))
if (p.y_ + h < 0 || p.y_ >= workHeight())
return false;
return true;
}

View File

@ -303,8 +303,8 @@ public:
Point getPos(DocIterator const & dit) const;
/// is the paragraph of the cursor visible ?
bool paragraphVisible(DocIterator const & dit) const;
/// is the cursor currently visible in the view
bool cursorInView(Point const & p, int h) const;
/// is the caret currently visible in the view
bool caretInView() const;
/// set the ascent and descent of the caret
void setCaretAscentDescent(int asc, int des);
/// get the position and height of the caret

View File

@ -443,16 +443,11 @@ void GuiWorkArea::startBlinkingCaret()
if (view().busy())
return;
// we cannot update geometry if not ready and we do not need to if
// caret is not in view.
if (!d->buffer_view_->buffer().undo().activeUndoGroup()) {
Point p;
int h = 0;
d->buffer_view_->caretPosAndHeight(p, h);
// Don't start blinking if the cursor isn't on screen.
if (!d->buffer_view_->cursorInView(p, h))
return;
}
// Don't start blinking if the cursor isn't on screen, unless we
// are not ready to know whether the cursor is on screen.
if (!d->buffer_view_->buffer().undo().activeUndoGroup()
&& !d->buffer_view_->caretInView())
return;
d->showCaret();
@ -588,10 +583,7 @@ void GuiWorkArea::Private::resizeBufferView()
// Warn our container (GuiView).
p->busy(true);
Point point;
int h = 0;
buffer_view_->caretPosAndHeight(point, h);
bool const caret_in_view = buffer_view_->cursorInView(point, h);
bool const caret_in_view = buffer_view_->caretInView();
buffer_view_->resize(p->viewport()->width(), p->viewport()->height());
if (caret_in_view)
buffer_view_->scrollToCursor();
@ -617,14 +609,13 @@ void GuiWorkArea::Private::updateCaretGeometry()
{
// we cannot update geometry if not ready and we do not need to if
// caret is not in view.
if (buffer_view_->buffer().undo().activeUndoGroup())
if (buffer_view_->buffer().undo().activeUndoGroup()
|| !buffer_view_->caretInView())
return;
Point point;
int h = 0;
buffer_view_->caretPosAndHeight(point, h);
if (!buffer_view_->cursorInView(point, h))
return;
// RTL or not RTL
bool l_shape = false;