]> git.lyx.org Git - features.git/commitdiff
Do not display caret when we're not ready
authorJean-Marc Lasgouttes <lasgouttes@lyx.org>
Fri, 28 Feb 2020 14:21:40 +0000 (15:21 +0100)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Fri, 13 Mar 2020 15:02:36 +0000 (16:02 +0100)
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
src/frontends/qt/GuiWorkArea_Private.h

index ab13c687d7c9d549299508303bea29a33371f30f..2500afe4db9621f46ceeca772b6c5c20b1987e5a 100644 (file)
@@ -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();
 }
 
 
index 6342eaba4ac153fc7b1bf6201453ba39f5bd140b..75ad98dbdc55beac16a28b9d6a19eae5822e274d 100644 (file)
@@ -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();