Skip to content

Commit

Permalink
macOS: Highlight selected part of preedit using platform theme palette
Browse files Browse the repository at this point in the history
QInputMethodEvent::Selection unfortunately doesn't apply to the
preedit text, and QInputMethodEvent::Cursor which does, doesn't
support setting a selection. Until we've introduced attributes
that allow us to propagate the preedit selection semantically
we resort to styling the selection via the TextFormat attribute,
so that the preedit selection is visible to the user.

This allows us to remove the fallback we had for thick and double
underline styles, where we mapped those to the wiggly underline style.
This was needed to distinguish the selected cluster when composing
CJK, but looked out of place.

One disadvantage of faking the selection via text format is that
we will not update the selection color on theme change, e.g. when
switching from light to dark mode, but this is a minor issue that we
can live with until we've introduced a proper QInputMethodEvent
attribute for the preedit selection.

Pick-to: 6.2
Change-Id: I1c45c310107697962e328a4db908d29d2358f756
Reviewed-by: Volker Hilsheimer <[email protected]>
  • Loading branch information
torarnv committed Aug 23, 2021
1 parent 7d45f2d commit 86d3383
Showing 1 changed file with 17 additions and 5 deletions.
22 changes: 17 additions & 5 deletions src/plugins/platforms/cocoa/qnsview_complextext.mm
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,22 @@ - (void)setMarkedText:(id)text selectedRange:(NSRange)selectedRange replacementR
preeditAttributes << QInputMethodEvent::Attribute(
QInputMethodEvent::Cursor, selectedRange.location + selectedRange.length, true);


// QInputMethodEvent::Selection unfortunately doesn't apply to the
// preedit text, and QInputMethodEvent::Cursor which does, doesn't
// support setting a selection. Until we've introduced attributes
// that allow us to propagate the preedit selection semantically
// we resort to styling the selection via the TextFormat attribute,
// so that the preedit selection is visible to the user.
QTextCharFormat selectionFormat;
auto *platformTheme = QGuiApplicationPrivate::platformTheme();
auto *systemPalette = platformTheme->palette();
selectionFormat.setBackground(systemPalette->color(QPalette::Highlight));
preeditAttributes << QInputMethodEvent::Attribute(
QInputMethodEvent::TextFormat,
selectedRange.location, selectedRange.length,
selectionFormat);

int index = 0;
int composingLength = preeditString.length();
while (index < composingLength) {
Expand Down Expand Up @@ -166,11 +182,7 @@ - (void)setMarkedText:(id)text selectedRange:(NSRange)selectedRange replacementR

// Unfortunately QTextCharFormat::UnderlineStyle does not distinguish
// between NSUnderlineStyle{Single,Thick,Double}, which is used by CJK
// input methods to highlight the selected clause segments, so we fake
// it using QTextCharFormat::WaveUnderline.
if ((style & NSUnderlineStyleThick) == NSUnderlineStyleThick
|| (style & NSUnderlineStyleDouble) == NSUnderlineStyleDouble)
format.setUnderlineStyle(QTextCharFormat::WaveUnderline);
// input methods to highlight the selected clause segments.
}
if (NSColor *underlineColor = attributes[NSUnderlineColorAttributeName])
format.setUnderlineColor(qt_mac_toQColor(underlineColor));
Expand Down

0 comments on commit 86d3383

Please sign in to comment.