From e6b54ea4d2e28d55565699ded45da971278b23bf Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Sun, 14 Jul 2019 23:20:29 +0200 Subject: [PATCH] Fix assertion in caret display code 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. This bug is not in 2.3.x. --- src/BufferView.cpp | 11 ++++++++--- src/BufferView.h | 4 ++-- src/frontends/qt4/GuiWorkArea.cpp | 15 +++++---------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/BufferView.cpp b/src/BufferView.cpp index 2068f050cf..97adab820c 100644 --- a/src/BufferView.cpp +++ b/src/BufferView.cpp @@ -3044,11 +3044,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; } diff --git a/src/BufferView.h b/src/BufferView.h index 45928f256e..40dd0d29c3 100644 --- a/src/BufferView.h +++ b/src/BufferView.h @@ -307,8 +307,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; /// get the position and height of the caret void caretPosAndHeight(Point & p, int & h) const; diff --git a/src/frontends/qt4/GuiWorkArea.cpp b/src/frontends/qt4/GuiWorkArea.cpp index 02c56c2fdb..6a7c995da9 100644 --- a/src/frontends/qt4/GuiWorkArea.cpp +++ b/src/frontends/qt4/GuiWorkArea.cpp @@ -439,11 +439,8 @@ void GuiWorkArea::startBlinkingCaret() if (view().busy()) return; - 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)) + if (!d->buffer_view_->caretInView()) return; d->showCaret(); @@ -583,10 +580,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(); @@ -610,11 +604,12 @@ void GuiWorkArea::Private::resizeBufferView() void GuiWorkArea::Private::updateCaretGeometry() { + if (!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;