Commit c493546a authored by Eike Hein's avatar Eike Hein Committed by Simon Hausmann
Browse files

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: default avatarSimon Hausmann <simon.hausmann@digia.com>
Showing with 25 additions and 4 deletions
......@@ -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 = attributes.at(i);
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 = 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<int, int>(attr.start, attr.end)] : format);
}
return imAttrs;
}
......
......@@ -36,6 +36,7 @@
#include <qvector.h>
#include <qevent.h>
#include <QDBusArgument>
#include <QTextCharFormat>
QT_BEGIN_NAMESPACE
......@@ -70,7 +71,7 @@ public:
QIBusAttribute();
~QIBusAttribute();
QTextFormat format() const;
QTextCharFormat format() const;
Type type;
quint32 value;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment