Details
-
Bug
-
Resolution: Unresolved
-
P2: Important
-
None
-
5.15.7, 6.4.0
-
None
Description
QTextDocument has signal contentsChange
And when you enter or change anything this signal will let you know how many characters are added and removed and where
But this don't work when I use some imput method (for example japanies IME on windows)
contentsChange contains position 0 and added removed is whole text lenght
I spend some time to debug source of this problem and I found that
void QWidgetTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
https://code.qt.io/cgit/qt/qtbase.git/tree/src/widgets/widgets/qwidgettextcontrol.cpp#n2013
call setPreeditArea
https://code.qt.io/cgit/qt/qtbase.git/tree/src/gui/text/qtextlayout.cpp#n459
and in setPreeditArea there is call for documentChange for whole block
Any idea why for whole block and not just only for part that actualy contais preedit text?
if (QTextDocumentPrivate::get(d->block) != nullptr)
QTextDocumentPrivate::get(d->block)->documentChange(d->block.position() + position, text.length());
This don't fix problem as there is call layout->setFormats(overrides);
https://code.qt.io/cgit/qt/qtbase.git/tree/src/gui/text/qtextlayout.cpp#n498
That also generate documentChange for whole block
But I think that this check will be good enough
void QTextLayout::setFormats(const QList<FormatRange> &formats) { auto computeDocumentChangePositions = [](const QList<FormatRange> &formats, int &changeStart, int &changeEnd) { for (const auto &format : qAsConst(formats)) { if (changeStart < 0) { changeStart = format.start; changeEnd = format.start + format.length; } else { changeStart = qMin(changeStart, format.start); changeEnd = qMax(changeEnd, format.start + format.length); } } }; int documentChangeStartPos = -1; int documentChangeEndPos = -1; if (QTextDocumentPrivate::get(d->block) != nullptr) { computeDocumentChangePositions(d->formats(), documentChangeStartPos, documentChangeEndPos); computeDocumentChangePositions(formats, documentChangeStartPos, documentChangeEndPos); } d->setFormats(formats); if (QTextDocumentPrivate::get(d->block) != nullptr) { if (documentChangeStartPos >= 0) { QTextDocumentPrivate::get(d->block)->documentChange( d->block.position() + documentChangeStartPos, documentChangeEndPos - documentChangeStartPos); } } }
So any suggestions ?