diff --git a/src/LyXRC.cpp b/src/LyXRC.cpp index 62673f4a69..13164373f6 100644 --- a/src/LyXRC.cpp +++ b/src/LyXRC.cpp @@ -107,6 +107,7 @@ LexerKeyword lyxrcTags[] = { { "\\dialogs_iconify_with_main", LyXRC::RC_DIALOGS_ICONIFY_WITH_MAIN }, { "\\display_graphics", LyXRC::RC_DISPLAY_GRAPHICS }, { "\\document_path", LyXRC::RC_DOCUMENTPATH }, + { "\\draw_strategy", LyXRC::RC_DRAW_STRATEGY }, { "\\editor_alternatives", LyXRC::RC_EDITOR_ALTERNATIVES }, { "\\escape_chars", LyXRC::RC_ESC_CHARS }, { "\\example_path", LyXRC::RC_EXAMPLEPATH }, @@ -1134,6 +1135,19 @@ LyXRC::ReturnValues LyXRC::read(Lexer & lexrc, bool check_format) } break; + case RC_DRAW_STRATEGY: + if (lexrc.next()) { + string const tmp = lexrc.getString(); + if (tmp == "partial") + draw_strategy = DS_PARTIAL; + else if (tmp == "backingstore") + draw_strategy = DS_BACKINGSTORE; + else { + draw_strategy = DS_PARTIAL; + LYXERR0("Unrecognized draw strategy " << tmp <<'"'); + } + } + break; case RC_LAST: break; // this is just a dummy @@ -2021,10 +2035,28 @@ void LyXRC::write(ostream & os, bool ignore_system_lyxrc, string const & name) c } if (tag != RC_LAST) break; + // fall through + case RC_DRAW_STRATEGY: + if (ignore_system_lyxrc || + draw_strategy != system_lyxrc.draw_strategy) { + string status; + switch (draw_strategy) { + case DS_PARTIAL: + status = "partial"; + break; + case DS_BACKINGSTORE: + status = "backingstore"; + break; + } + os << "\\draw_strategy " << status << '\n'; + } + if (tag != RC_LAST) + break; + // fall through os << "\n#\n" - << "# COLOR SECTION ###################################\n" - << "#\n\n"; + << "# COLOR SECTION ###################################\n" + << "#\n\n"; // fall through case RC_SET_COLOR: @@ -2910,6 +2942,7 @@ void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new) package().document_dir() = FileName(lyxrc.document_path); } // fall through + case LyXRC::RC_DRAW_STRATEGY: case LyXRC::RC_EDITOR_ALTERNATIVES: case LyXRC::RC_ESC_CHARS: case LyXRC::RC_EXAMPLEPATH: diff --git a/src/LyXRC.h b/src/LyXRC.h index 74c0e4cfe1..6e82a6def9 100644 --- a/src/LyXRC.h +++ b/src/LyXRC.h @@ -189,6 +189,7 @@ public: RC_VIEWER_ALTERNATIVES, RC_VISUAL_CURSOR, RC_CLOSE_BUFFER_WITH_LAST_VIEW, + RC_DRAW_STRATEGY, RC_LAST }; @@ -573,6 +574,17 @@ public: /// BookmarksVisibility bookmarks_visibility = BMK_NONE; + + enum DrawStrategy { + // draw all (not implemented yet) + // FS_FULL, + // draw only what has changed + DS_PARTIAL, + // draw in backing store (only what has changed) + DS_BACKINGSTORE + }; + /// + DrawStrategy draw_strategy = DS_PARTIAL; }; diff --git a/src/frontends/qt/GuiApplication.cpp b/src/frontends/qt/GuiApplication.cpp index 9e6f18a333..5cd8f290d4 100644 --- a/src/frontends/qt/GuiApplication.cpp +++ b/src/frontends/qt/GuiApplication.cpp @@ -2710,6 +2710,18 @@ Menus & GuiApplication::menus() } +bool GuiApplication::needsBackingStore() const +{ + /* 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. It is also possible to force the use of the + * backing store for cases like x11 with transparent WM themes. + */ + return platformName() == "cocoa" || platformName().contains("wayland"); +} + + QList GuiApplication::viewIds() const { return d->views_.keys(); diff --git a/src/frontends/qt/GuiApplication.h b/src/frontends/qt/GuiApplication.h index 8afdd7f564..f0c3e1ea75 100644 --- a/src/frontends/qt/GuiApplication.h +++ b/src/frontends/qt/GuiApplication.h @@ -110,6 +110,9 @@ public: /// Menus & menus(); + /// \returns true if painting the workarea requires a backing store. + bool needsBackingStore() const; + /// \name Methods inherited from QApplication class //@{ bool notify(QObject * receiver, QEvent * event) override; diff --git a/src/frontends/qt/GuiWorkArea.cpp b/src/frontends/qt/GuiWorkArea.cpp index 1d6cd07b8e..e70563bc5a 100644 --- a/src/frontends/qt/GuiWorkArea.cpp +++ b/src/frontends/qt/GuiWorkArea.cpp @@ -132,13 +132,10 @@ SyntheticMouseEvent::SyntheticMouseEvent() GuiWorkArea::Private::Private(GuiWorkArea * parent) : p(parent), completer_(new GuiCompleter(p, p)) { - /* 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. - */ - use_backingstore_ = guiApp->platformName() == "cocoa" - || guiApp->platformName().contains("wayland"); + use_backingstore_ = lyxrc.draw_strategy == LyXRC::DS_BACKINGSTORE + || guiApp->needsBackingStore(); + LYXERR(Debug::WORKAREA, "Drawing strategy is: " + << (use_backingstore_ ? "backingstore" : "partial")); int const time = QApplication::cursorFlashTime() / 2; if (time > 0) {