diff --git a/lib/RELEASE-NOTES b/lib/RELEASE-NOTES index a5760387ef..f05fdd1299 100644 --- a/lib/RELEASE-NOTES +++ b/lib/RELEASE-NOTES @@ -1,3 +1,14 @@ +!Important Change in LyX 2.3.7 + +The following pref variable was added: + +* \draw_strategy partial|backingstore: when this is set to + "backingstore", the drawing code will force the use of an + intermediate surface, instead of just drawing changed regions on + screen. Note that "backingstore" is actually always enforced on + macOS and Wayland (default: partial). + + !Important Change in LyX 2.3.1 * A change to how math macros are output can break some documents that use diff --git a/src/LyXRC.cpp b/src/LyXRC.cpp index e8e66e221d..0753534cf3 100644 --- a/src/LyXRC.cpp +++ b/src/LyXRC.cpp @@ -105,6 +105,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 }, @@ -1244,6 +1245,20 @@ LyXRC::ReturnValues LyXRC::read(Lexer & lexrc, bool check_format) lexrc >> mouse_middlebutton_paste; 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 } @@ -2064,10 +2079,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: @@ -2963,6 +2996,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 7049bf8d5e..6e494d0786 100644 --- a/src/LyXRC.h +++ b/src/LyXRC.h @@ -183,6 +183,7 @@ public: RC_VIEWER_ALTERNATIVES, RC_VISUAL_CURSOR, RC_CLOSE_BUFFER_WITH_LAST_VIEW, + RC_DRAW_STRATEGY, RC_LAST }; @@ -533,6 +534,17 @@ public: int cursor_width; /// One of: yes, no, ask std::string close_buffer_with_last_view; + + 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/qt4/GuiApplication.cpp b/src/frontends/qt4/GuiApplication.cpp index 271e4c7d4d..246b45671e 100644 --- a/src/frontends/qt4/GuiApplication.cpp +++ b/src/frontends/qt4/GuiApplication.cpp @@ -2509,6 +2509,26 @@ 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. + */ +#if QT_VERSION >= 0x050000 + return platformName() == "cocoa" || platformName().contains("wayland"); +#else +# ifdef Q_OS_MAC + return true; +# else + return false; +# endif // Q_OS_MAC +#endif // QT_VERSION +} + + QList GuiApplication::viewIds() const { return d->views_.keys(); diff --git a/src/frontends/qt4/GuiApplication.h b/src/frontends/qt4/GuiApplication.h index eb25bc1b1e..8c6b0e06b2 100644 --- a/src/frontends/qt4/GuiApplication.h +++ b/src/frontends/qt4/GuiApplication.h @@ -103,6 +103,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/qt4/GuiWorkArea.cpp b/src/frontends/qt4/GuiWorkArea.cpp index a16a9c8ffe..731802087e 100644 --- a/src/frontends/qt4/GuiWorkArea.cpp +++ b/src/frontends/qt4/GuiWorkArea.cpp @@ -245,20 +245,10 @@ GuiWorkArea::Private::Private(GuiWorkArea * parent) dialog_mode_(false), shell_escape_(false), read_only_(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 - * 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 + 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) { diff --git a/status.23x b/status.23x index 12af42228a..5f56fee592 100644 --- a/status.23x +++ b/status.23x @@ -44,6 +44,9 @@ What's new - Fix broken modifier handling for Qt-5.12 on Mac (bug 12247). +- Add new pref variable \draw_strategy to fix some cases where display + is blinking (bug 12119). + * DOCUMENTATION AND LOCALIZATION