From c493546a0a1bbf1455f67092364bdba18e43ba01 Mon Sep 17 00:00:00 2001 From: Eike Hein Date: Mon, 13 Oct 2014 21:33:57 +0200 Subject: Merge TextFormat attributes for identical ranges in QInputMethodEvents IBus can hand us multiple attributes for different formatting properties of the same text range for events. The IBus input method plugin used to convert these straight into multiple QInputMethodEvent::Attributes, each with their own QTextCharFormat instance. According to the QInputMethodEvent documentation, behavior with multiple TextFormat attributes for the same text range is undefined. In at least one known user, KDE's Kate text editor, it causes invisible text for pre-edit text events as the QTextCharFormats are applied in turn with partially default-constructed foreground/background brushes: https://bugs.kde.org/show_bug.cgi?id=339467 This patch makes an effort to merge formatting information for identical text ranges into a single QTextCharFomat, while otherwise preserving existing behavior (attribute order is unchanged and attributes deseria- lized from D-Bus as having invalid QTextFormats remain untouched). No attempt is made to cope with overlapping text ranges. Segmenting into smaller ranges and merging for the overlaps would be conceivable, but until a case of an input method creating events with overlapping ranges is known seems not worth the effort. It's worth noting that the IBus input method plugin for Qt 4 also attempts to merge formatting information into a single QTextCharFormat, but with a distinct implementation from this one. Change-Id: Ie3dc38b353724ffb7b5f2d7f316393027373baf2 Task-number: 41640 Reviewed-by: Simon Hausmann --- .../platforminputcontexts/ibus/qibustypes.cpp | 26 +++++++++++++++++++--- .../platforminputcontexts/ibus/qibustypes.h | 3 ++- 2 files changed, 25 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/plugins/platforminputcontexts/ibus/qibustypes.cpp b/src/plugins/platforminputcontexts/ibus/qibustypes.cpp index 9bc53ed5c0..ec8c746b2d 100644 --- a/src/plugins/platforminputcontexts/ibus/qibustypes.cpp +++ b/src/plugins/platforminputcontexts/ibus/qibustypes.cpp @@ -32,7 +32,6 @@ ****************************************************************************/ #include "qibustypes.h" -#include #include #include @@ -134,7 +133,7 @@ const QDBusArgument &operator>>(const QDBusArgument &argument, QIBusAttribute &a return argument; } -QTextFormat QIBusAttribute::format() const +QTextCharFormat QIBusAttribute::format() const { QTextCharFormat fmt; switch (type) { @@ -225,11 +224,32 @@ const QDBusArgument &operator>>(const QDBusArgument &arg, QIBusAttributeList &at QList QIBusAttributeList::imAttributes() const { + QHash, QTextCharFormat> rangeAttrs; + + // Merge text fomats for identical ranges into a single QTextFormat. + for (int i = 0; i < attributes.size(); ++i) { + const QIBusAttribute &attr = attributes.at(i); + const QTextCharFormat &format = attr.format(); + + if (format.isValid()) { + const QPair range(attr.start, attr.end); + rangeAttrs[range].merge(format); + } + } + + // Assemble list in original attribute order. QList imAttrs; + for (int i = 0; i < attributes.size(); ++i) { const QIBusAttribute &attr = attributes.at(i); - imAttrs += QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, attr.start, attr.end - attr.start, attr.format()); + const QTextFormat &format = attr.format(); + + imAttrs += QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, + attr.start, + attr.end - attr.start, + format.isValid() ? rangeAttrs[QPair(attr.start, attr.end)] : format); } + return imAttrs; } diff --git a/src/plugins/platforminputcontexts/ibus/qibustypes.h b/src/plugins/platforminputcontexts/ibus/qibustypes.h index 2ec3b019ff..96791b17a1 100644 --- a/src/plugins/platforminputcontexts/ibus/qibustypes.h +++ b/src/plugins/platforminputcontexts/ibus/qibustypes.h @@ -36,6 +36,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -70,7 +71,7 @@ public: QIBusAttribute(); ~QIBusAttribute(); - QTextFormat format() const; + QTextCharFormat format() const; Type type; quint32 value; -- cgit v1.2.3