path: root/src/plugins/platforminputcontexts/ibus/qibustypes.cpp
diff options
authorEike Hein <>2014-10-13 21:33:57 +0200
committerSimon Hausmann <>2014-11-06 14:07:09 +0100
commitc493546a0a1bbf1455f67092364bdba18e43ba01 (patch)
treee95b03e9b3eab91412e49246c01f70a9ff89e464 /src/plugins/platforminputcontexts/ibus/qibustypes.cpp
parent79f832594dc103ef4a663153f8b9a88691e46233 (diff)
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: 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 <>
Diffstat (limited to 'src/plugins/platforminputcontexts/ibus/qibustypes.cpp')
1 files changed, 23 insertions, 3 deletions
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 <qtextformat.h>
#include <QtDBus>
#include <QHash>
@@ -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<QInputMethodEvent::Attribute> QIBusAttributeList::imAttributes() const
+ QHash<QPair<int, int>, QTextCharFormat> rangeAttrs;
+ // Merge text fomats for identical ranges into a single QTextFormat.
+ for (int i = 0; i < attributes.size(); ++i) {
+ const QIBusAttribute &attr =;
+ const QTextCharFormat &format = attr.format();
+ if (format.isValid()) {
+ const QPair<int, int> range(attr.start, attr.end);
+ rangeAttrs[range].merge(format);
+ }
+ }
+ // Assemble list in original attribute order.
QList<QInputMethodEvent::Attribute> imAttrs;
for (int i = 0; i < attributes.size(); ++i) {
const QIBusAttribute &attr =;
- 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<int, int>(attr.start, attr.end)] : format);
return imAttrs;