]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt4/GuiWorkArea.cpp
Do not compute caret geometry when we are not ready to do so.
[lyx.git] / src / frontends / qt4 / GuiWorkArea.cpp
index 5ef177dc37fb12bb8f5685f1459d015d90a3ebc1..95cff6d5ec30f8c7d8de4903e3750115022cff16 100644 (file)
@@ -239,13 +239,27 @@ SyntheticMouseEvent::SyntheticMouseEvent()
 
 
 GuiWorkArea::Private::Private(GuiWorkArea * parent)
-: p(parent), buffer_view_(0), lyx_view_(0),
-  caret_(0), 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)
-{
+: p(parent), buffer_view_(0), lyx_view_(0), caret_(0),
+  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)
+{
+/* Qt on macOS and Wayland does not respect the
+ * Qt::WA_OpaquePaintEvent attribute and resets the widget backing
+ * store at each update. Therefore, we use our own backing store in
+ * these two cases. */
+#if QT_VERSION >= 0x050000
+       use_backingstore_ = guiApp->platformName() == "cocoa"
+               || guiApp->platformName().contains("wayland");
+#else
+#  ifdef Q_OS_MAC
+       use_backingstore_ = true;
+#  else
+       use_backingstore_ = false;
+#  endif
+#endif
+
        int const time = QApplication::cursorFlashTime() / 2;
        if (time > 0) {
                caret_timeout_.setInterval(time);
@@ -429,12 +443,16 @@ 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))
-               return;
+       // we cannot update geometry if not ready and we do not need to if
+       // caret is not in view.
+       if (!d->buffer_view_->buffer().undo().activeUndoGroup()) {
+               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))
+                       return;
+       }
 
        d->showCaret();
 
@@ -597,6 +615,11 @@ void GuiWorkArea::Private::resizeBufferView()
 
 void GuiWorkArea::Private::updateCaretGeometry()
 {
+       // we cannot update geometry if not ready and we do not need to if
+       // caret is not in view.
+       if (buffer_view_->buffer().undo().activeUndoGroup())
+               return;
+
        Point point;
        int h = 0;
        buffer_view_->caretPosAndHeight(point, h);
@@ -1257,6 +1280,41 @@ void GuiWorkArea::Private::paintPreeditText(GuiPainter & pain)
 }
 
 
+void GuiWorkArea::Private::resetScreen()
+{
+       if (use_backingstore_) {
+               int const pr = p->pixelRatio();
+               screen_ = QImage(static_cast<int>(pr * p->viewport()->width()),
+                                static_cast<int>(pr * p->viewport()->height()),
+                                QImage::Format_ARGB32_Premultiplied);
+#  if QT_VERSION >= 0x050000
+               screen_.setDevicePixelRatio(pr);
+#  endif
+       }
+}
+
+
+QPaintDevice * GuiWorkArea::Private::screenDevice()
+{
+       if (use_backingstore_)
+               return &screen_;
+       else
+               return p->viewport();
+}
+
+
+void GuiWorkArea::Private::updateScreen(QRectF const & rc)
+{
+       if (use_backingstore_) {
+               QPainter qpain(p->viewport());
+               double const pr = p->pixelRatio();
+               QRectF const rcs = QRectF(rc.x() * pr, rc.y() * pr,
+                                         rc.width() * pr, rc.height() * pr);
+               qpain.drawImage(rc, screen_, rcs);
+       }
+}
+
+
 void GuiWorkArea::paintEvent(QPaintEvent * ev)
 {
        // Do not trigger the painting machinery if we are not ready (see