[LyX/master] Make system IM focus color shown when IM focus color is set transparent
Koji Yokota
yokota at lyx.org
Thu Jun 11 10:04:19 UTC 2026
commit ac81d8173fde58254c7ed1ce02bcb2d7bbee6927
Author: Koji Yokota <yokota at lyx.org>
Date: Thu Jun 11 18:59:14 2026 +0900
Make system IM focus color shown when IM focus color is set transparent
and other small fixes
---
src/frontends/qt/ColorCache.cpp | 19 ++++++++-
src/frontends/qt/ColorCache.h | 2 +
src/frontends/qt/GuiInputMethod.cpp | 80 +++++++++++++++++++++----------------
3 files changed, 64 insertions(+), 37 deletions(-)
diff --git a/src/frontends/qt/ColorCache.cpp b/src/frontends/qt/ColorCache.cpp
index a666c529bd..0949c2f3da 100644
--- a/src/frontends/qt/ColorCache.cpp
+++ b/src/frontends/qt/ColorCache.cpp
@@ -35,6 +35,7 @@ QPalette::ColorRole role(ColorCode col)
case Color_mathmacrobg:
case Color_mathcorners:
case Color_preeditbg:
+ case Color_preeditfocus:
return QPalette::Base;
break;
@@ -44,16 +45,15 @@ QPalette::ColorRole role(ColorCode col)
case Color_tabularline:
case Color_previewframe:
case Color_preedittext:
+ case lyx::Color_preeditfocustext:
return QPalette::Text;
break;
case Color_selection:
- case Color_preeditfocus:
return QPalette::Highlight;
break;
case Color_selectionmath:
case Color_selectiontext:
- case lyx::Color_preeditfocustext:
return QPalette::HighlightedText;
break;
case Color_urllabel:
@@ -233,5 +233,20 @@ QColor const argb2qcolor(ARGBColor const & argb)
return QColor(argb.r, argb.g, argb.b, argb.a);
}
+const QColor qcolorOverlay(const QColor &fg, const QColor &bg)
+{
+ int red, green, blue, alpha;
+
+ float fg_weight = fg.alphaF();
+ float bg_weight = (1 - fg.alphaF()) * bg.alphaF();
+
+ red = std::round((fg_weight*fg.redF() + bg_weight*bg.redF() ) * 255);
+ green = std::round((fg_weight*fg.greenF() + bg_weight*bg.greenF()) * 255);
+ blue = std::round((fg_weight*fg.blueF() + bg_weight*bg.blueF() ) * 255);
+ alpha = std::round((1 - (1 - fg.alphaF()) * (1 - bg.alphaF())) * 255);
+
+ return QColor(red, green, blue, alpha);
+}
+
} // namespace lyx
diff --git a/src/frontends/qt/ColorCache.h b/src/frontends/qt/ColorCache.h
index b0d140e147..617bae8e56 100644
--- a/src/frontends/qt/ColorCache.h
+++ b/src/frontends/qt/ColorCache.h
@@ -78,6 +78,8 @@ private:
QColor const rgb2qcolor(RGBColor const &);
///
QColor const argb2qcolor(ARGBColor const &);
+///
+QColor const qcolorOverlay(QColor const & fg, QColor const & bg);
} // namespace lyx
diff --git a/src/frontends/qt/GuiInputMethod.cpp b/src/frontends/qt/GuiInputMethod.cpp
index 43059024ac..e36fa31475 100644
--- a/src/frontends/qt/GuiInputMethod.cpp
+++ b/src/frontends/qt/GuiInputMethod.cpp
@@ -205,7 +205,7 @@ void GuiInputMethod::inputMethodEvent(QInputMethodEvent* ev)
d->font_color_ = d->color_cache_.get(fg);
d->font_brush_.setColor(d->font_color_);
LYXERR(Debug::KEY,
- "Preedit font color is set to " << d->font_color_.name());
+ "Preedit font color is set to " << d->font_color_.name(QColor::HexArgb));
d->locale_ = d->sys_im_->locale();
d->style_.lang_ = d->locale_;
@@ -524,11 +524,11 @@ pos_type GuiInputMethod::setTextFormat(const QInputMethodEvent::Attribute & it,
LYXERR(Debug::KEY,
"QInputMethodEvent::TextFormat start: " << it.start <<
- " end: " << it.start + it.length - 1 <<
+ " length: " << it.length <<
" underline? " << char_format.font().underline() <<
" UnderlineStyle: " << char_format.underlineStyle() <<
- " fg: " << char_format.foreground().color().name() <<
- " bg: " << char_format.background().color().name());
+ " fg: " << char_format.foreground().color().name(QColor::HexArgb) <<
+ " bg: " << char_format.background().color().name(QColor::HexArgb));
//
// Fit and adjust arrived text formats
@@ -541,18 +541,28 @@ pos_type GuiInputMethod::setTextFormat(const QInputMethodEvent::Attribute & it,
#endif
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
- // set the style of a focused sector as specified by color themes
- // it uses a system color if "Use system colors" is checked
+ QColor fg, bg;
+ QColor im_fg = char_format.foreground().color();
+ QColor im_bg = char_format.background().color();
+ // if incoming char_format doesn't specify the color (#000000)
+ // just use the text background as a base color
+ if (im_bg == QColorConstants::Black)
+ im_bg = guiApp->colorCache().get(Color_background);
+
+ // overlay theme's color on char_format's base color
+ // theme's color is the system color if "Use system colors" is checked
// NOTE: brush size is assumed to be four
// if it is to be changed, change the declaration of array in
// setPreeditStyle()
if (it.start == d->caret_rel_pos_) {
- char_format.setForeground(brush[0]);
- char_format.setBackground(brush[1]);
+ fg = qcolorOverlay(brush[0].color(), im_fg);
+ bg = qcolorOverlay(brush[1].color(), im_bg);
} else {
- char_format.setForeground(brush[2]);
- char_format.setBackground(brush[3]);
+ fg = qcolorOverlay(brush[2].color(), im_fg);
+ bg = qcolorOverlay(brush[3].color(), im_bg);
}
+ char_format.setForeground(fg);
+ char_format.setBackground(bg);
#else
// avoid unused-parameter warning.
(void) brush;
@@ -567,9 +577,9 @@ pos_type GuiInputMethod::setTextFormat(const QInputMethodEvent::Attribute & it,
pickNextSegFromTurnout(next_seg_pos, &char_format);
if (updated_pos == next_seg_pos) {
// no matching segment in the turnout
- LYXERR(Debug::KEY, "Pushing to preedit register: (" << it.start
- << ", " << it.start + it.length - 1 << ") bg color: "
- << char_format.background().color().name());
+ LYXERR(Debug::KEY, "Pushing to preedit register: [" << it.start
+ << ", " << it.start + it.length << ") bg color: "
+ << char_format.background().color().name(QColor::HexArgb));
next_seg_pos = registerSegment(it.start, (size_type)it.length,
char_format);
} else
@@ -577,19 +587,19 @@ pos_type GuiInputMethod::setTextFormat(const QInputMethodEvent::Attribute & it,
} else {
// push the constructed char format together with start and length
// to the list
- LYXERR(Debug::KEY, "Pushing to preedit register: (" << it.start
- << ", " << it.start + it.length - 1
+ LYXERR(Debug::KEY, "Pushing to preedit register: [" << it.start
+ << ", " << it.start + it.length
<< ") fg: "
- << char_format.foreground().color().name()
+ << char_format.foreground().color().name(QColor::HexArgb)
<< " bg: "
- << char_format.background().color().name());
+ << char_format.background().color().name(QColor::HexArgb));
next_seg_pos =
registerSegment(it.start, (size_type)it.length, char_format);
}
next_seg_pos = pickNextSegFromTurnout(next_seg_pos);
} else if ((it.start > next_seg_pos || d->initial_tf_entry_) && it.length > 0) {
- LYXERR(Debug::KEY, "Pushing to preedit turnout: (" << it.start << ", "
- << it.start + it.length - 1 << ")");
+ LYXERR(Debug::KEY, "Pushing to preedit turnout: [" << it.start << ", "
+ << it.start + it.length << ")");
PreeditSegment turnout = {it.start, (size_type)it.length, char_format};
d->seg_turnout_.push_back(turnout);
d->initial_tf_entry_ = false;
@@ -608,25 +618,25 @@ pos_type GuiInputMethod::pickNextSegFromTurnout(pos_type next_seg_pos,
// but typically only one is used
for (auto past_attr = d->seg_turnout_.begin();
past_attr != d->seg_turnout_.end(); past_attr++) {
- if ((*past_attr).start_ == next_seg_pos) {
+ if (past_attr->start_ == next_seg_pos) {
PreeditSegment seg;
if (cf != nullptr) {
- cf->merge((*past_attr).char_format_);
- seg = {(*past_attr).start_,
- (size_type)(*past_attr).length_, *cf};
+ cf->merge(past_attr->char_format_);
+ seg = {past_attr->start_,
+ (size_type)past_attr->length_, *cf};
} else
- seg = {(*past_attr).start_,
- (size_type)(*past_attr).length_,
- (*past_attr).char_format_};
+ seg = {past_attr->start_,
+ (size_type)past_attr->length_,
+ past_attr->char_format_};
LYXERR(Debug::KEY,
- "Pushing to preedit register: (" << (*past_attr).start_
- << ", " << (*past_attr).start_ + (*past_attr).length_ - 1
+ "Pushing to preedit register: [" << past_attr->start_
+ << ", " << past_attr->start_ + past_attr->length_
<< ") fg: "
- << (*past_attr).char_format_.foreground().color().name()
+ << past_attr->char_format_.foreground().color().name(QColor::HexArgb)
<< " bg: "
- << (*past_attr).char_format_.background().color().name());
+ << past_attr->char_format_.background().color().name(QColor::HexArgb));
d->style_.segments_.push_back(seg);
- next_seg_pos += (*past_attr).length_;
+ next_seg_pos += past_attr->length_;
if (d->seg_turnout_.size() > 1)
to_erase = past_attr;
is_matched = true;
@@ -636,15 +646,15 @@ pos_type GuiInputMethod::pickNextSegFromTurnout(pos_type next_seg_pos,
// Clear d->seg_turnout_
if (is_matched) {
if (d->seg_turnout_.size() == 1) {
- LYXERR(Debug::KEY, "Preedit turnout clearing: ("
+ LYXERR(Debug::KEY, "Preedit turnout clearing: ["
<< d->seg_turnout_.back().start_ << ", "
<< d->seg_turnout_.back().start_
- + d->seg_turnout_.back().length_ - 1 << ")");
+ + d->seg_turnout_.back().length_ << ")");
d->seg_turnout_.pop_back();
} else if (d->seg_turnout_.size() > 1) {
- LYXERR(Debug::KEY, "Preedit turnout clearing: ("
+ LYXERR(Debug::KEY, "Preedit turnout clearing: ["
<< (*to_erase).start_ << ", "
- << (*to_erase).start_ + (*to_erase).length_ - 1 << ")");
+ << (*to_erase).start_ + (*to_erase).length_ << ")");
d->seg_turnout_.erase(to_erase);
}
}
More information about the lyx-cvs
mailing list