Skip to content

Commit 8ea3300

Browse files
committed
QAndroidInputContext: Fix getTextBefore/AfterCursor() in mid. of preedit
getTextBeforeCursor() and getTextAfterCursor() were not properly handling the case when the cursor is in the middle of preedit string (just as TODO comments inside these functions were saying). This was causing problems with Gboard when the user focuses a text editor by tapping in the middle of a word. Fixes: QTBUG-58063 Change-Id: I4a580a74d79965816557bfb342337975348d1c45 Reviewed-by: Andy Shaw <[email protected]>
1 parent d0741f4 commit 8ea3300

File tree

1 file changed

+47
-30
lines changed

1 file changed

+47
-30
lines changed

src/plugins/platforms/android/qandroidinputcontext.cpp

+47-30
Original file line numberDiff line numberDiff line change
@@ -1129,46 +1129,63 @@ QString QAndroidInputContext::getSelectedText(jint /*flags*/)
11291129

11301130
QString QAndroidInputContext::getTextAfterCursor(jint length, jint /*flags*/)
11311131
{
1132-
//### the preedit text could theoretically be after the cursor
1133-
QVariant textAfter = QInputMethod::queryFocusObject(Qt::ImTextAfterCursor, QVariant(length));
1134-
if (textAfter.isValid()) {
1135-
return textAfter.toString().left(length);
1136-
}
1137-
1138-
//compatibility code for old controls that do not implement the new API
1139-
QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
1140-
if (query.isNull())
1132+
if (length <= 0)
11411133
return QString();
11421134

1143-
QString text = query->value(Qt::ImSurroundingText).toString();
1144-
if (!text.length())
1145-
return text;
1135+
QString text;
1136+
1137+
QVariant reportedTextAfter = QInputMethod::queryFocusObject(Qt::ImTextAfterCursor, length);
1138+
if (reportedTextAfter.isValid()) {
1139+
text = reportedTextAfter.toString();
1140+
} else {
1141+
// Compatibility code for old controls that do not implement the new API
1142+
QSharedPointer<QInputMethodQueryEvent> query =
1143+
focusObjectInputMethodQuery(Qt::ImCursorPosition | Qt::ImSurroundingText);
1144+
if (query) {
1145+
const int cursorPos = query->value(Qt::ImCursorPosition).toInt();
1146+
text = query->value(Qt::ImSurroundingText).toString().mid(cursorPos);
1147+
}
1148+
}
1149+
1150+
// Controls do not report preedit text, so we have to add it
1151+
if (!m_composingText.isEmpty()) {
1152+
const int cursorPosInsidePreedit = m_composingCursor - m_composingTextStart;
1153+
text = m_composingText.midRef(cursorPosInsidePreedit) + text;
1154+
}
11461155

1147-
int cursorPos = query->value(Qt::ImCursorPosition).toInt();
1148-
return text.mid(cursorPos, length);
1156+
text.truncate(length);
1157+
return text;
11491158
}
11501159

11511160
QString QAndroidInputContext::getTextBeforeCursor(jint length, jint /*flags*/)
11521161
{
1153-
QVariant textBefore = QInputMethod::queryFocusObject(Qt::ImTextBeforeCursor, QVariant(length));
1154-
if (textBefore.isValid())
1155-
return textBefore.toString().rightRef(length) + m_composingText;
1156-
1157-
//compatibility code for old controls that do not implement the new API
1158-
QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
1159-
if (query.isNull())
1162+
if (length <= 0)
11601163
return QString();
11611164

1162-
int cursorPos = query->value(Qt::ImCursorPosition).toInt();
1163-
QString text = query->value(Qt::ImSurroundingText).toString();
1164-
if (!text.length())
1165-
return text;
1165+
QString text;
11661166

1167-
//### the preedit text does not need to be immediately before the cursor
1168-
if (cursorPos <= length)
1169-
return text.leftRef(cursorPos) + m_composingText;
1170-
else
1171-
return text.midRef(cursorPos - length, length) + m_composingText;
1167+
QVariant reportedTextBefore = QInputMethod::queryFocusObject(Qt::ImTextBeforeCursor, length);
1168+
if (reportedTextBefore.isValid()) {
1169+
text = reportedTextBefore.toString();
1170+
} else {
1171+
// Compatibility code for old controls that do not implement the new API
1172+
QSharedPointer<QInputMethodQueryEvent> query =
1173+
focusObjectInputMethodQuery(Qt::ImCursorPosition | Qt::ImSurroundingText);
1174+
if (query) {
1175+
const int cursorPos = query->value(Qt::ImCursorPosition).toInt();
1176+
text = query->value(Qt::ImSurroundingText).toString().left(cursorPos);
1177+
}
1178+
}
1179+
1180+
// Controls do not report preedit text, so we have to add it
1181+
if (!m_composingText.isEmpty()) {
1182+
const int cursorPosInsidePreedit = m_composingCursor - m_composingTextStart;
1183+
text += m_composingText.leftRef(cursorPosInsidePreedit);
1184+
}
1185+
1186+
if (text.length() > length)
1187+
text = text.right(length);
1188+
return text;
11721189
}
11731190

11741191
/*

0 commit comments

Comments
 (0)