This patch allows to enforce the use of of a backing store for display. This has no effect for Wayland and macOS, when backing store is always on.

The main use for it is x11 with a window manager theme with translucent windows (KDE)
https://www.lyx.org/trac/ticket/12119

At this point, there is no UI for this, because I think this is a niche case. I would be open to the idea of adding a checkbox somewhere.

Note that this is candidate for 2.3.x too.

In 2.5.x, the plan is to rewrite painting to be more Qt-like, so that this thing will not be necessary anymore.

JMarc
From 764886f2bda64286af2e79feb7f79024d38f2d68 Mon Sep 17 00:00:00 2001
From: Jean-Marc Lasgouttes <lasgout...@lyx.org>
Date: Thu, 16 Dec 2021 12:38:19 +0100
Subject: [PATCH] Add lyxrc option to force the use of backing store

LyX relies on a a backing store to draw when running under macOS or
Wayland, because Qt arbitrarily overwrites parts of the workarea
before we paint (and we paint only the parts that need to be painted).
However it seems that this is also necessary on X11 when the WM theme
is translucid. Since there is no way that I know of to detect this
situation, this patch adds a LyXRC setting to manually select this
drawing strategy.

Note that using a backing store is not always a good solution, since
this disables subpixel aliasing.

At this point there is no UI for the variable.

Fixes bug #12119
---
 src/LyXRC.cpp                    | 37 ++++++++++++++++++++++++++++++--
 src/LyXRC.h                      | 12 +++++++++++
 src/frontends/qt/GuiWorkArea.cpp |  6 ++++--
 3 files changed, 51 insertions(+), 4 deletions(-)

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/GuiWorkArea.cpp b/src/frontends/qt/GuiWorkArea.cpp
index 1d6cd07b8e..c85c24e776 100644
--- a/src/frontends/qt/GuiWorkArea.cpp
+++ b/src/frontends/qt/GuiWorkArea.cpp
@@ -135,9 +135,11 @@ GuiWorkArea::Private::Private(GuiWorkArea * parent)
 	/* 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.
+	 * in these two cases. It is also possible to force the use of the
+	 * backing store for cases like x11 with transparent WM themes.
 	 */
-	use_backingstore_ = guiApp->platformName() == "cocoa"
+	use_backingstore_ = lyxrc.draw_strategy == LyXRC::DS_BACKINGSTORE
+		|| guiApp->platformName() == "cocoa"
 		|| guiApp->platformName().contains("wayland");
 
 	int const time = QApplication::cursorFlashTime() / 2;
-- 
2.32.0

-- 
lyx-devel mailing list
lyx-devel@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-devel

Reply via email to