From 1a2b1a3bfad7ce48e2a025d3a3dab7103fd0039c Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Mon, 20 May 2019 18:36:24 +0200 Subject: [PATCH] backing store --- src/frontends/qt4/GuiWorkArea.cpp | 63 ++++++++++++++++++++++--- src/frontends/qt4/GuiWorkArea_Private.h | 50 ++++---------------- 2 files changed, 65 insertions(+), 48 deletions(-) diff --git a/src/frontends/qt4/GuiWorkArea.cpp b/src/frontends/qt4/GuiWorkArea.cpp index 7955731ad3..5c0ae40e22 100644 --- a/src/frontends/qt4/GuiWorkArea.cpp +++ b/src/frontends/qt4/GuiWorkArea.cpp @@ -235,13 +235,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() == "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); @@ -1261,6 +1275,41 @@ void GuiWorkArea::Private::paintPreeditText(GuiPainter & pain) } +void GuiWorkArea::Private::resetScreen() +{ + if (use_backingstore_) { + int const pr = p->pixelRatio(); + screen_ = QImage(static_cast(pr * p->viewport()->width()), + static_cast(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 diff --git a/src/frontends/qt4/GuiWorkArea_Private.h b/src/frontends/qt4/GuiWorkArea_Private.h index 83012fa99f..6342eaba4a 100644 --- a/src/frontends/qt4/GuiWorkArea_Private.h +++ b/src/frontends/qt4/GuiWorkArea_Private.h @@ -20,14 +20,6 @@ #include #include -#ifdef Q_OS_MAC -/* Qt on macOS 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 this case */ -#define LYX_BACKINGSTORE 1 -#include -#endif - namespace lyx { class Buffer; @@ -107,37 +99,12 @@ struct GuiWorkArea::Private void paintPreeditText(GuiPainter & pain); - void resetScreen() { -#ifdef LYX_BACKINGSTORE - int const pr = p->pixelRatio(); - screen_ = QImage(static_cast(pr * p->viewport()->width()), - static_cast(pr * p->viewport()->height()), - QImage::Format_ARGB32_Premultiplied); -# if QT_VERSION >= 0x050000 - screen_.setDevicePixelRatio(pr); -# endif -#endif - } - - QPaintDevice * screenDevice() { -#ifdef LYX_BACKINGSTORE - return &screen_; -#else - return p->viewport(); -#endif - } - -#ifdef LYX_BACKINGSTORE - void updateScreen(QRectF const & rc) { - 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); - } -#else - void updateScreen(QRectF const & ) {} -#endif + /// Prepare screen for next painting + void resetScreen(); + /// Where painting takes place + QPaintDevice * screenDevice(); + /// Put backingstore to screen if necessary + void updateScreen(QRectF const & rc); /// GuiWorkArea * p; @@ -146,10 +113,11 @@ struct GuiWorkArea::Private /// GuiView * lyx_view_; -#ifdef LYX_BACKINGSTORE + /// Do we need an intermediate image when painting (for now macOS and Wayland) + bool use_backingstore_; /// QImage screen_; -#endif + /// CaretWidget * caret_; /// is the caret currently displayed -- 2.39.2