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).
void GuiWorkArea::startBlinkingCaret()
{
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
d->showCaret();
// Avoid blinking when debugging PAINTING, since it creates too much noise
-void GuiWorkArea::Private::showCaret()
+void GuiWorkArea::Private::showCaret(bool show)
+ if (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())
- caret_visible_ = false;
- //if (!qApp->focusWidget())
- p->viewport()->update();
+ if (caret_visible_)
+ updateCaretGeometry();
+ p->viewport()->update();
void dispatch(FuncRequest const & cmd0);
/// recompute the shape and position of the caret
void updateCaretGeometry();
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
/// hide the caret if it is visible
+ void hideCaret() { showCaret(false); }
/// Set the range and value of the scrollbar and connect to its valueChanged
/// signal.
void updateScrollbar();
/// Set the range and value of the scrollbar and connect to its valueChanged
/// signal.
void updateScrollbar();