From b44f4e49749738b1dca17706e185278f6f8142a2 Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Fri, 28 Feb 2020 15:21:40 +0100 Subject: [PATCH] Do not display caret when we're not ready Using a dialog may trigger a redraw at times where the metrics caches have not been updated yet. To fix this, do as in paintEvent() and abort caret blinking if there is an open undo group. Move the decision to skip the caret painting to showCaret(), closer to where real work happens. hideCaret () is now an alias for showCaret(false), which allows some code refactoring. See also commit c7496a11b2. Fixes bug #11763 (although it does not trigger on master). --- src/frontends/qt/GuiWorkArea.cpp | 36 +++++++++++--------------- src/frontends/qt/GuiWorkArea_Private.h | 6 ++--- 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/src/frontends/qt/GuiWorkArea.cpp b/src/frontends/qt/GuiWorkArea.cpp index ab13c687d7..2500afe4db 100644 --- a/src/frontends/qt/GuiWorkArea.cpp +++ b/src/frontends/qt/GuiWorkArea.cpp @@ -439,14 +439,6 @@ void GuiWorkArea::stopBlinkingCaret() void GuiWorkArea::startBlinkingCaret() { - // do not show the cursor if the view is busy - if (view().busy()) - return; - - // Don't start blinking if the cursor isn't on screen. - if (!d->buffer_view_->caretInView()) - return; - d->showCaret(); // Avoid blinking when debugging PAINTING, since it creates too much noise @@ -641,24 +633,26 @@ void GuiWorkArea::Private::updateCaretGeometry() } -void GuiWorkArea::Private::showCaret() +void GuiWorkArea::Private::showCaret(bool show) { - if (caret_visible_) + if (caret_visible_ == show) return; + caret_visible_ = show; - updateCaretGeometry(); - p->viewport()->update(); -} - - -void GuiWorkArea::Private::hideCaret() -{ - if (!caret_visible_) + /** + * Do not trigger the painting machinery if either + * 1. the view is busy (no updates at all) + * 2. The we are not ready because document is being modified (see bug #11763) + * 3. The caret is outside of screen anyway. + */ + if (p->view().busy() + || buffer_view_->buffer().undo().activeUndoGroup() + || !buffer_view_->caretInView()) return; - caret_visible_ = false; - //if (!qApp->focusWidget()) - p->viewport()->update(); + if (caret_visible_) + updateCaretGeometry(); + p->viewport()->update(); } diff --git a/src/frontends/qt/GuiWorkArea_Private.h b/src/frontends/qt/GuiWorkArea_Private.h index 6342eaba4a..75ad98dbdc 100644 --- a/src/frontends/qt/GuiWorkArea_Private.h +++ b/src/frontends/qt/GuiWorkArea_Private.h @@ -87,10 +87,10 @@ struct GuiWorkArea::Private void dispatch(FuncRequest const & cmd0); /// recompute the shape and position of the caret void updateCaretGeometry(); - /// show the caret if it is not visible - void showCaret(); + /// show the caret if it is not visible. Same as \c hideCaret when \c show is false. + void showCaret(bool show = true); /// hide the caret if it is visible - void hideCaret(); + void hideCaret() { showCaret(false); } /// Set the range and value of the scrollbar and connect to its valueChanged /// signal. void updateScrollbar(); -- 2.39.5