]> git.lyx.org Git - features.git/commitdiff
Fixup 5202d44e: make caret geometry update lazy
authorJean-Marc Lasgouttes <lasgouttes@lyx.org>
Mon, 7 Sep 2020 13:45:30 +0000 (15:45 +0200)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Mon, 7 Sep 2020 13:52:43 +0000 (15:52 +0200)
Instead of working around crashes in update of caret geometry, only
request it as needed. The actual computaiton will take place just
before painting the caret.

It might be that this is overkill and that caret geometry should be
updated unconditionally. One would have to to some timing while idle to
ascertain that.

Fixes bug #11912.

src/frontends/qt/GuiWorkArea.cpp
src/frontends/qt/GuiWorkArea_Private.h

index a2af82d92309241703a5d016c5702f59dcf09a00..40a98c5e890e9c73f082deb91365719100100ec0 100644 (file)
@@ -243,7 +243,7 @@ GuiWorkArea::Private::Private(GuiWorkArea * parent)
   caret_visible_(false), need_resize_(false), preedit_lines_(1),
   last_pixel_ratio_(1.0), completer_(new GuiCompleter(p, p)),
   dialog_mode_(false), shell_escape_(false), read_only_(false),
-  clean_(true), externally_modified_(false)
+  clean_(true), externally_modified_(false), needs_caret_geometry_update_(true)
 {
 /* Qt on macOS and Wayland does not respect the
  * Qt::WA_OpaquePaintEvent attribute and resets the widget backing
@@ -487,7 +487,8 @@ void GuiWorkArea::scheduleRedraw(bool update_metrics)
 
        // update caret position, because otherwise it has to wait until
        // the blinking interval is over
-       d->updateCaretGeometry();
+       d->needs_caret_geometry_update_ = true;
+       d->caret_visible_ = true;
 
        LYXERR(Debug::WORKAREA, "WorkArea::redraw screen");
        viewport()->update();
@@ -587,7 +588,8 @@ void GuiWorkArea::Private::resizeBufferView()
        buffer_view_->resize(p->viewport()->width(), p->viewport()->height());
        if (caret_in_view)
                buffer_view_->scrollToCursor();
-       updateCaretGeometry();
+       needs_caret_geometry_update_ = true;
+       caret_visible_ = true;
 
        // Update scrollbars which might have changed due different
        // BufferView dimension. This is especially important when the
@@ -637,18 +639,20 @@ void GuiWorkArea::Private::updateCaretGeometry()
                && completer_->completionAvailable()
                && !completer_->popupVisible()
                && !completer_->inlineVisible();
-       caret_visible_ = true;
 
        caret_->update(point.x_, point.y_, h, l_shape, isrtl, completable);
+       needs_caret_geometry_update_ = false;
 }
 
 
+
 void GuiWorkArea::Private::showCaret()
 {
        if (caret_visible_)
                return;
 
-       updateCaretGeometry();
+       needs_caret_geometry_update_ = true;
+       caret_visible_ = true;
        p->viewport()->update();
 }
 
@@ -1356,8 +1360,14 @@ void GuiWorkArea::paintEvent(QPaintEvent * ev)
        d->paintPreeditText(pain);
 
        // and the caret
-       if (d->caret_visible_)
+       // FIXME: the code would be a little bit simpler if caret geometry
+       // was updated unconditionally. Some profiling is required to see
+       // how expensive this is (especially when idle).
+       if (d->caret_visible_) {
+               if (d->needs_caret_geometry_update_)
+                       d->updateCaretGeometry();
                d->caret_->draw(pain, d->buffer_view_->horizScrollOffset());
+       }
 
        d->updateScreen(ev->rect());
 
index 6342eaba4ac153fc7b1bf6201453ba39f5bd140b..75fad9b3e67c55716f9a5c08596e11e11d0e435f 100644 (file)
@@ -169,6 +169,8 @@ struct GuiWorkArea::Private
        bool clean_;
        ///
        bool externally_modified_;
+       ///
+       bool needs_caret_geometry_update_;
 
 }; // GuiWorkArea