[LyX/master] Adapt cursor color to background color (part of #13312)
Juergen Spitzmueller
spitz at lyx.org
Sat May 16 07:05:03 UTC 2026
commit 78754b0d9c09dafe551ed719c976792173065a01
Author: Juergen Spitzmueller <spitz at lyx.org>
Date: Sat May 16 09:03:41 2026 +0200
Adapt cursor color to background color (part of #13312)
I.e., in dark mode with a light inset background, use a dark cursor
Co-production with JMarc
---
src/BufferView.cpp | 13 +++++++++++++
src/BufferView.h | 3 +++
src/Color.cpp | 1 +
src/ColorCode.h | 2 ++
src/Cursor.cpp | 6 +++---
src/CursorSlice.cpp | 14 +++++++++++++-
src/CursorSlice.h | 4 +++-
src/DocIterator.cpp | 22 ++++++++++------------
src/DocIterator.h | 5 ++++-
src/frontends/qt/GuiWorkArea.cpp | 16 ++++++++++++++--
src/insets/InsetText.cpp | 4 ++--
src/mathed/InsetMath.h | 2 ++
src/mathed/InsetMathHull.cpp | 2 +-
13 files changed, 71 insertions(+), 23 deletions(-)
diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 995ea8a85d..c64eb8a8ae 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -21,6 +21,7 @@
#include "BufferList.h"
#include "BufferParams.h"
#include "BiblioInfo.h"
+#include "ColorSet.h"
#include "CoordCache.h"
#include "Cursor.h"
#include "CutAndPaste.h"
@@ -3479,6 +3480,18 @@ int BufferView::updateMetrics(bool force)
}
+string BufferView::getCaretBackground()
+{
+ Inset const * covering_inset = cursor().realInset();
+ if (!covering_inset)
+ return "background";
+
+ frontend::NullPainter np;
+ PainterInfo pi(this, np);
+ return lcolor.getLyXName(covering_inset->backgroundColor(pi));
+}
+
+
void BufferView::updatePosCache()
{
// this is the "nodraw" drawing stage: only set the positions of the
diff --git a/src/BufferView.h b/src/BufferView.h
index 9823fccea7..91fe571b96 100644
--- a/src/BufferView.h
+++ b/src/BufferView.h
@@ -416,6 +416,9 @@ public:
/// Inserted label from ref dialog
std::string const & insertedLabel() const { return inserted_label_; }
+ ///
+ std::string getCaretBackground();
+
private:
/// noncopyable
BufferView(BufferView const &);
diff --git a/src/Color.cpp b/src/Color.cpp
index 36629c015b..4e33541db8 100644
--- a/src/Color.cpp
+++ b/src/Color.cpp
@@ -261,6 +261,7 @@ ColorSet::ColorSet()
{ Color_violet, N_("violet"), "violet", violet, violet, "violet" },
{ Color_yellow, N_("yellow"), "yellow", yellow, yellow, "yellow" },
{ Color_cursor, N_("cursor"), "cursor", black, Linen, "cursor" },
+ { Color_cursor_inverted, N_("cursor (inverted background)"), "cursor_inverted", Linen, black, "cursor_inverted" },
{ Color_background, N_("background"), "background", Linen, black, "background" },
{ Color_foreground, N_("text"), "foreground", black, Linen, "foreground" },
{ Color_foreground_inverted, N_("text (inverted background)"), "foreground_inverted", Linen, black, "foreground_inverted" },
diff --git a/src/ColorCode.h b/src/ColorCode.h
index 60837a3c2c..4a20ca2955 100644
--- a/src/ColorCode.h
+++ b/src/ColorCode.h
@@ -65,6 +65,8 @@ enum ColorCode {
Color_foreground,
/// Foreground color in inverted background
Color_foreground_inverted,
+ /// Cursor color on inverted background
+ Color_cursor_inverted,
/// Background color of selected text
Color_selection,
/// Foreground color of selected math
diff --git a/src/Cursor.cpp b/src/Cursor.cpp
index 52c8bf2821..3141660515 100644
--- a/src/Cursor.cpp
+++ b/src/Cursor.cpp
@@ -2456,7 +2456,7 @@ bool notifyCursorLeavesOrEnters(Cursor const & old, Cursor & cur)
// find inset in common
size_type i;
for (i = 0; i < old.depth() && i < cur.depth(); ++i) {
- if (&old[i].inset() != &cur[i].inset())
+ if (old[i].realInset() != cur[i].realInset())
break;
}
@@ -2473,14 +2473,14 @@ bool notifyCursorLeavesOrEnters(Cursor const & old, Cursor & cur)
for (size_type j = i; j < old.depth(); ++j) {
Cursor inset_pos = old;
inset_pos.resize(j + 1);
- if (old[j].inset().notifyCursorLeaves(inset_pos, cur))
+ if (old[j].realInset()->notifyCursorLeaves(inset_pos, cur))
return true;
}
// notify everything on top of the common part in new cursor,
// but stop if the inset claims the cursor to be invalid now
for (; i < cur.depth(); ++i) {
- if (cur[i].inset().notifyCursorEnters(old, cur))
+ if (cur[i].realInset()->notifyCursorEnters(old, cur))
return true;
}
diff --git a/src/CursorSlice.cpp b/src/CursorSlice.cpp
index 522e35b7b8..e6f941e1c5 100644
--- a/src/CursorSlice.cpp
+++ b/src/CursorSlice.cpp
@@ -19,12 +19,13 @@
#include "Paragraph.h"
#include "ParagraphList.h"
-#include "support/debug.h"
+#include "insets/InsetTabular.h"
#include "mathed/InsetMath.h"
#include "mathed/InsetMathMacro.h"
#include "mathed/MathData.h"
+#include "support/debug.h"
#include "support/lassert.h"
#include <ostream>
@@ -52,6 +53,17 @@ MathData & CursorSlice::cell() const
}
+Inset * CursorSlice::realInset() const
+{
+ // if we are in a tabular, we need the cell
+ if (inset().lyxCode() == TABULAR_CODE) {
+ InsetTabular * tabular = inset().asInsetTabular();
+ return tabular->cell(idx()).get();
+ }
+ return &inset();
+}
+
+
Paragraph & CursorSlice::paragraph() const
{
return text()->getPar(pit_);
diff --git a/src/CursorSlice.h b/src/CursorSlice.h
index 6eb6ff5aba..794c5b1e91 100644
--- a/src/CursorSlice.h
+++ b/src/CursorSlice.h
@@ -59,8 +59,10 @@ public:
/// return true if the slice has not been initialized
bool empty() const { return !inset_; }
- /// the current inset
+ /// the containing inset
Inset & inset() const { return *inset_; }
+ /// the containing inset or the (tabular) cell, respectively
+ Inset * realInset() const;
/// return the cell this cursor is in
idx_type idx() const { return idx_; }
/// return the cell this cursor is in
diff --git a/src/DocIterator.cpp b/src/DocIterator.cpp
index 7d18c36547..2024bcc00c 100644
--- a/src/DocIterator.cpp
+++ b/src/DocIterator.cpp
@@ -127,18 +127,6 @@ Inset * DocIterator::prevInset() const
}
-Inset * DocIterator::realInset() const
-{
- LASSERT(inTexted(), return nullptr);
- // if we are in a tabular, we need the cell
- if (inset().lyxCode() == TABULAR_CODE) {
- InsetTabular * tabular = inset().asInsetTabular();
- return tabular->cell(idx()).get();
- }
- return &inset();
-}
-
-
InsetMath & DocIterator::nextMath()
{
return *nextAtom().nucleus();
@@ -714,6 +702,16 @@ size_type DocIterator::find(Inset const * inset) const
}
+size_type DocIterator::findInsetOrRealInset(Inset const * inset) const
+{
+ for (size_t l = 0; l != slices_.size(); ++l) {
+ if (&slices_[l].inset() == inset || slices_[l].realInset() == inset)
+ return l;
+ }
+ return lyx::npos;
+}
+
+
void DocIterator::resize(size_type count, vector<CursorSlice> & cut)
{
LASSERT(count <= depth(), return);
diff --git a/src/DocIterator.h b/src/DocIterator.h
index f46d57598f..61ad46ab97 100644
--- a/src/DocIterator.h
+++ b/src/DocIterator.h
@@ -182,7 +182,7 @@ public:
///
Text * text() const;
/// the containing inset or the cell, respectively
- Inset * realInset() const;
+ Inset * realInset() const { return top().realInset(); }
///
Inset * innerInsetOfType(int code) const;
///
@@ -265,6 +265,9 @@ public:
size_type find(MathData const & cell) const;
/// find index of CursorSlice with inset() == inset (or lyx::npos of not found)
size_type find(Inset const * inset) const;
+ /// find index of CursorSlice with inset() == inset or realInset() == inset
+ /// (or lyx::npos of not found)
+ size_type findInsetOrRealInset(Inset const * inset) const;
/// push CursorSlices on top
void append(std::vector<CursorSlice> const & x);
/// push one CursorSlice on top and set its index and position
diff --git a/src/frontends/qt/GuiWorkArea.cpp b/src/frontends/qt/GuiWorkArea.cpp
index 9e1cbb4655..5a067ef9aa 100644
--- a/src/frontends/qt/GuiWorkArea.cpp
+++ b/src/frontends/qt/GuiWorkArea.cpp
@@ -15,7 +15,6 @@
#include "GuiWorkArea.h"
#include "GuiWorkArea_Private.h"
-#include "ColorCache.h"
#include "GuiApplication.h"
#include "GuiCompleter.h"
#include "GuiKeySymbol.h"
@@ -28,6 +27,7 @@
#include "BufferList.h"
#include "BufferParams.h"
#include "BufferView.h"
+#include "ColorCache.h"
#include "CoordCache.h"
#include "Cursor.h"
#include "Font.h"
@@ -576,7 +576,19 @@ void GuiWorkArea::Private::drawCaret(QPainter & painter, int horiz_offset) const
if (buffer_view_->caretGeometry().shapes.empty())
return;
- QColor const color = guiApp->colorCache().get(Color_cursor);
+ QColor const color = (
+ !buffer_view_->getCaretBackground().empty()
+ && buffer_view_->getCaretBackground() != "none"
+ && ((guiApp->colorCache().isDarkMode()
+ && guiApp->colorCache().isLightColor(
+ rgbFromHexName(lcolor.getX11HexName(
+ buffer_view_->getCaretBackground(), true))))
+ || (!guiApp->colorCache().isDarkMode()
+ && !guiApp->colorCache().isLightColor(rgbFromHexName(
+ lcolor.getX11HexName(
+ buffer_view_->getCaretBackground()))))))
+ ? guiApp->colorCache().get(Color_cursor_inverted)
+ : guiApp->colorCache().get(Color_cursor);
painter.setPen(color);
painter.setRenderHint(QPainter::Antialiasing, true);
for (auto const & shape : buffer_view_->caretGeometry().shapes) {
diff --git a/src/insets/InsetText.cpp b/src/insets/InsetText.cpp
index f01b0fbf3c..4e92a1236d 100644
--- a/src/insets/InsetText.cpp
+++ b/src/insets/InsetText.cpp
@@ -1324,12 +1324,12 @@ bool InsetText::notifyCursorLeaves(Cursor const & old, Cursor & cur)
// find text inset in old cursor
Cursor insetCur = old;
- size_type scriptSlice = insetCur.find(this);
+ size_type scriptSlice = insetCur.findInsetOrRealInset(this);
// we can try to continue here. returning true means
// the cursor is "now" invalid. which it was.
LASSERT(scriptSlice != lyx::npos, return true);
insetCur.resize(scriptSlice + 1);
- LASSERT(&insetCur.inset() == this, return true);
+ LASSERT(&insetCur.inset() == this || insetCur.realInset() == this, return true);
// update the old paragraph's words
insetCur.paragraph().updateWords();
diff --git a/src/mathed/InsetMath.h b/src/mathed/InsetMath.h
index 6f580c3def..03adeb820f 100644
--- a/src/mathed/InsetMath.h
+++ b/src/mathed/InsetMath.h
@@ -277,6 +277,8 @@ public:
InsetCode lyxCode() const override { return MATH_CODE; }
///
uid_type id() const { return this; }
+ ///
+ ColorCode backgroundColor(PainterInfo const &) const override { return Color_mathbg; };
};
///
diff --git a/src/mathed/InsetMathHull.cpp b/src/mathed/InsetMathHull.cpp
index 8e98b75e46..9ba086a715 100644
--- a/src/mathed/InsetMathHull.cpp
+++ b/src/mathed/InsetMathHull.cpp
@@ -617,7 +617,7 @@ ColorCode InsetMathHull::backgroundColor(PainterInfo const & pi) const
return Color_error;
return graphics::PreviewLoader::backgroundColor();
}
- return Color_mathbg;
+ return InsetMath::backgroundColor(pi);
}
More information about the lyx-cvs
mailing list