[LyX/master] Structural fix for #13326

Koji Yokota yokota at lyx.org
Wed Aug 12 03:32:10 UTC 2026


commit acaaa8003eb30057cb15a52308bba8c13a1483c2
Author: Koji Yokota <yokota at lyx.org>
Date:   Wed Aug 12 12:29:11 2026 +0900

    Structural fix for #13326
    
            settings
    
    Thanks to Pavel and Claude
---
 src/LyXRC.cpp                 | 18 ++++++++++--------
 src/LyXRC.h                   | 11 ++++++++---
 src/frontends/qt/GuiPrefs.cpp | 15 +++++++--------
 3 files changed, 25 insertions(+), 19 deletions(-)

diff --git a/src/LyXRC.cpp b/src/LyXRC.cpp
index eafac0a34f..2523961517 100644
--- a/src/LyXRC.cpp
+++ b/src/LyXRC.cpp
@@ -237,12 +237,12 @@ void oldFontFormat(string & family, string & foundry)
 } // namespace
 
 
-bool LyXRC::read(FileName const & filename, bool check_format)
+bool LyXRC::read(FileName const & filename, bool check_format, ColorSet * colors)
 {
 	Lexer lexrc(lyxrcTags);
 	lexrc.setFile(filename);
 	LYXERR(Debug::LYXRC, "Reading '" << filename << "'...");
-	ReturnValues retval = read(lexrc, check_format);
+	ReturnValues retval = read(lexrc, check_format, colors);
 	if (!check_format || retval != FormatMismatch)
 		return retval == ReadOK;
 
@@ -261,7 +261,7 @@ bool LyXRC::read(FileName const & filename, bool check_format)
 		Lexer lexrc2(lyxrcTags);
 		lexrc2.setFile(tempfile);
 		LYXERR(Debug::LYXRC, "Reading '" << tempfile << "'...");
-		retval = read(lexrc2, check_format);
+		retval = read(lexrc2, check_format, colors);
 		if (retval == FormatMismatch)
 			LYXERR0("Conversion failed for " << filename.absFileName());
 	}
@@ -271,17 +271,19 @@ bool LyXRC::read(FileName const & filename, bool check_format)
 
 // don't need to worry about conversion, because this is always
 // from an internal source
-bool LyXRC::read(istream & is)
+bool LyXRC::read(istream & is, ColorSet * colors)
 {
 	Lexer lexrc(lyxrcTags);
 	lexrc.setStream(is);
 	LYXERR(Debug::LYXRC, "Reading istream...");
-	return read(lexrc, false) == ReadOK;
+	return read(lexrc, false, colors) == ReadOK;
 }
 
 
-LyXRC::ReturnValues LyXRC::read(Lexer & lexrc, bool check_format)
+LyXRC::ReturnValues LyXRC::read(Lexer & lexrc, bool check_format, ColorSet * colors)
 {
+	// \set_color lines below mutate this set; default to the global lcolor
+	ColorSet & cs = colors ? *colors : lcolor;
 	if (lyxerr.debugging(Debug::PARSER))
 		lexrc.printTable(lyxerr);
 
@@ -677,13 +679,13 @@ LyXRC::ReturnValues LyXRC::read(Lexer & lexrc, bool check_format)
 				x11_darkname = lexrc.getString();
 
 			ColorCode const col =
-				lcolor.getFromLyXName(lyx_name);
+				cs.getFromLyXName(lyx_name);
 			if (col == Color_none ||
 			    col == Color_inherit ||
 			    col == Color_ignore)
 				break;
 
-			if (!lcolor.setColor(col, x11_name, x11_darkname))
+			if (!cs.setColor(col, x11_name, x11_darkname))
 				LYXERR0("Bad lyxrc set_color for " << lyx_name);
 			LYXERR(Debug::LYXRC, "Set " << lyx_name << "(" << col << ") to "
 			       << x11_name << " and " << x11_darkname);
diff --git a/src/LyXRC.h b/src/LyXRC.h
index 4172303531..49820eb715 100644
--- a/src/LyXRC.h
+++ b/src/LyXRC.h
@@ -36,6 +36,8 @@ class FileName;
 class Lexer;
 }
 
+class ColorSet;
+
 /// This contains the runtime configuration of LyX
 class LyXRC
 {
@@ -206,9 +208,11 @@ public:
 	/// \param check_format: whether to try to convert the file format,
 	/// if it is not current. this should only be true, really, for the
 	/// user's own preferences file.
-	bool read(support::FileName const & filename, bool check_format);
+	// colors: ColorSet that \set_color lines mutate; nullptr -> global lcolor
+	bool read(support::FileName const & filename, bool check_format,
+	          ColorSet * colors = nullptr);
 	///
-	bool read(std::istream &);
+	bool read(std::istream &, ColorSet * colors = nullptr);
 private:
 	enum ReturnValues {
 		ReadOK,
@@ -216,7 +220,8 @@ private:
 		FormatMismatch
 	};
 	///
-	ReturnValues read(support::Lexer &, bool check_format);
+	ReturnValues read(support::Lexer &, bool check_format,
+	                  ColorSet * colors = nullptr);
 public:
 	///
 	typedef std::set<std::string> CommandSet;
diff --git a/src/frontends/qt/GuiPrefs.cpp b/src/frontends/qt/GuiPrefs.cpp
index 7fcf0d91a3..868cfc120e 100644
--- a/src/frontends/qt/GuiPrefs.cpp
+++ b/src/frontends/qt/GuiPrefs.cpp
@@ -1705,15 +1705,12 @@ void PrefColors::cacheAllThemes()
 	guiApp->setOverrideCursor(QCursor(Qt::WaitCursor));
 	themes_cache_.clear();
 	theme_names_cache_.clear();
-	// back up lcolor since readTheme() and LyXRC::read() change lcolor
-	ColorSet const backup = lcolor;
 	LyXRC dummyrc;
 	for (int id = 0; id < themesLW->count(); ++id) {
 		FileName const fn(fromqstr(theme_fullpaths_[id]));
 		themes_cache_.push_back(readTheme(fn, dummyrc));
 		theme_names_cache_.push_back(themesLW->item(id)->text());
 	}
-	lcolor = backup;
 	guiApp->restoreOverrideCursor();
 }
 
@@ -1722,13 +1719,15 @@ ColorNamePairs PrefColors::readTheme(FileName const & fullpath, LyXRC & rc) cons
 {
 	ColorNamePairs colors;
 	colors.resize(lcolors_.size());
-	// read RC colors to extern ColorSet lcolor
-	rc.read(fullpath, true);
+	// Read the theme into a local ColorSet; the global lcolor is untouched.
+	// The copy preserves runtime-added (branch/index) color names so that
+	// \set_color lines for them still resolve.
+	ColorSet themeset = lcolor;
+	rc.read(fullpath, true, &themeset);
 	for (size_type row = 0; row < lcolors_.size(); ++row) {
-		// get colors from extern lcolor
 		colors[size_t(row)] =
-		    {getCurrentColor(lcolors_[row], false).name(QColor::HexArgb),
-		     getCurrentColor(lcolors_[row], true).name(QColor::HexArgb)};
+		    {toqstr(themeset.get32bitHexName(lcolors_[row], false)),
+		     toqstr(themeset.get32bitHexName(lcolors_[row], true))};
 	}
 	return colors;
 }


More information about the lyx-cvs mailing list