[LyX/master] Add "full" drawing strategy

Jean-Marc Lasgouttes lasgouttes at lyx.org
Tue Jun 11 13:17:33 UTC 2024


commit f48cf461010daa8aceb220a6762cb50c1192db0d
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date:   Sat Jul 15 11:46:25 2023 +0200

    Add "full" drawing strategy
    
    With this patch, 3 draw strategies (set in prefs with
    \draw_strategy partial|backingstore|full) are available:
    
    - "partial": only draw the parts of text that have changed since last
      paint event (default for X11 and windows)
    
    - "backingstore": the same, but drawing happens on an offspring
      pixmap; this breaks subpixel rendering (default for Wayland and
      macOS)
    
    - "full": the screen is fully redrawn at each paint event and should
      therefore always be correct; this is presumably slower but
      introducing it will allow to test it.
    
    This would deserve a proper UI eventually.
---
 src/BufferView.cpp                  |  3 +++
 src/LyXRC.cpp                       |  6 +++++-
 src/LyXRC.h                         |  4 ++--
 src/frontends/qt/GuiApplication.cpp |  9 +++++----
 src/frontends/qt/GuiApplication.h   |  4 ++--
 src/frontends/qt/GuiWorkArea.cpp    | 10 +++++++---
 6 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 755e2f7b4e..4e81bcbe3f 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -592,6 +592,9 @@ void BufferView::processUpdateFlags(Update::flags flags)
 		flags = (flags & ~Update::FitCursor) | Update::ForceDraw;
 	}
 
+	if (lyxrc.draw_strategy == LyXRC::DS_FULL)
+		flags = flags | Update::ForceDraw;
+
 	// Add flags to the the update flags. These will be reset to None
 	// after the redraw is actually done
 	d->update_flags_ = d->update_flags_ | flags;
diff --git a/src/LyXRC.cpp b/src/LyXRC.cpp
index 9c8decab43..edd9a58240 100644
--- a/src/LyXRC.cpp
+++ b/src/LyXRC.cpp
@@ -1147,8 +1147,9 @@ LyXRC::ReturnValues LyXRC::read(Lexer & lexrc, bool check_format)
 					draw_strategy = DS_PARTIAL;
 				else if (tmp == "backingstore")
 					draw_strategy = DS_BACKINGSTORE;
+				else if (tmp == "full")
+					draw_strategy = DS_FULL;
 				else {
-					draw_strategy = DS_PARTIAL;
 					LYXERR0("Unrecognized draw strategy " << tmp <<'"');
 				}
 			}
@@ -2055,6 +2056,9 @@ void LyXRC::write(ostream & os, bool ignore_system_lyxrc, string const & name) c
 			draw_strategy != system_lyxrc.draw_strategy) {
 			string status;
 			switch (draw_strategy) {
+			case DS_FULL:
+				status = "full";
+				break;
 			case DS_PARTIAL:
 				status = "partial";
 				break;
diff --git a/src/LyXRC.h b/src/LyXRC.h
index c437021c06..753a6f4f61 100644
--- a/src/LyXRC.h
+++ b/src/LyXRC.h
@@ -580,8 +580,8 @@ public:
 	BookmarksVisibility bookmarks_visibility = BMK_NONE;
 
 	enum DrawStrategy {
-		// draw all (not implemented yet)
-		// FS_FULL,
+		// draw all
+		DS_FULL,
 		// draw only what has changed
 		DS_PARTIAL,
 		// draw in backing store (only what has changed)
diff --git a/src/frontends/qt/GuiApplication.cpp b/src/frontends/qt/GuiApplication.cpp
index 516c970e71..d903e85f5d 100644
--- a/src/frontends/qt/GuiApplication.cpp
+++ b/src/frontends/qt/GuiApplication.cpp
@@ -2730,13 +2730,14 @@ Menus & GuiApplication::menus()
 }
 
 
-bool GuiApplication::needsBackingStore() const
+bool GuiApplication::noPartialDraw() 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.
+	 * store at each update. Therefore, if it not good to use
+	 * "partial" draw strategy in these 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");
 }
diff --git a/src/frontends/qt/GuiApplication.h b/src/frontends/qt/GuiApplication.h
index b27964dde4..67ba9590e5 100644
--- a/src/frontends/qt/GuiApplication.h
+++ b/src/frontends/qt/GuiApplication.h
@@ -113,8 +113,8 @@ public:
 	///
 	Menus & menus();
 
-	/// \returns true if painting the workarea requires a backing store.
-	bool needsBackingStore() const;
+	/// \returns true the "partial" draw strategy is known to be broken
+	bool noPartialDraw() const;
 
 	/// \name Methods inherited from QApplication class
 	//@{
diff --git a/src/frontends/qt/GuiWorkArea.cpp b/src/frontends/qt/GuiWorkArea.cpp
index 8b86615b4e..c136ffee14 100644
--- a/src/frontends/qt/GuiWorkArea.cpp
+++ b/src/frontends/qt/GuiWorkArea.cpp
@@ -131,9 +131,13 @@ GuiWorkArea::Private::Private(GuiWorkArea * parent)
 	: p(parent), completer_(new GuiCompleter(p, p))
 {
 	use_backingstore_ = lyxrc.draw_strategy == LyXRC::DS_BACKINGSTORE
-		|| guiApp->needsBackingStore();
-	LYXERR(Debug::WORKAREA, "Drawing strategy is: "
-	                        << (use_backingstore_ ? "backingstore" : "partial"));
+		|| (lyxrc.draw_strategy == LyXRC::DS_PARTIAL && guiApp->noPartialDraw());
+	if (use_backingstore_)
+		LYXERR(Debug::WORKAREA, "Drawing strategy: partial draw on backing store");
+	else
+		LYXERR(Debug::WORKAREA, "Drawing strategy: "
+			   << (lyxrc.draw_strategy == LyXRC::DS_PARTIAL ? "partial draw"
+				   : "full draw"));
 
 	int const time = QApplication::cursorFlashTime() / 2;
 	if (time > 0) {


More information about the lyx-cvs mailing list