diff options
author | Vova Mshanetskiy <vovams163@gmail.com> | 2019-05-06 15:00:55 +0300 |
---|---|---|
committer | Vova Mshanetskiy <vovams163@gmail.com> | 2019-06-05 17:38:32 +0300 |
commit | 710435ee81c4cf48d66f07eff3cbad3eaef80ab8 (patch) | |
tree | 88221c9a8c2c2b8360ed7e4a4e975381357a8e4e /src/plugins/platforms | |
parent | 0c1831178540462da31fd7a4b6d2e446bc84498b (diff) |
QAndroidInputContext: Fix unneeded preedit commits when dragging handles
If the cursor handle was dragged by only a few pixels, position of the
cursor did not actually change, but finishComposingText() was called
anyway. So the keyboard was thinking that nothing changed and a word is
still being composed, but the app was thinking that there is no preedit
string. This was resulting in invalid handling of following key presses.
This commit essentially inlines
QPlatformInputContext::setSelectionOnFocusObject() into
QAndroidInputContext::handleLocationChanged(). This allows us to call
finishComposingText() and to send a QInputMethodEvent only when position
of the cursur actually changes. This also allows us to add a
QInputMethodEvent::Cursor attribute into the event for consistency with
QAndroidInputContext::longPress().
Change-Id: I2fc82f138f717991f34024cdf521236845dc0adf
Reviewed-by: BogDan Vatra <bogdan@kdab.com>
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r-- | src/plugins/platforms/android/qandroidinputcontext.cpp | 63 |
1 files changed, 52 insertions, 11 deletions
diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp index db40c30d7d..4c0b3315be 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.cpp +++ b/src/plugins/platforms/android/qandroidinputcontext.cpp @@ -671,8 +671,6 @@ void QAndroidInputContext::handleLocationChanged(int handleId, int x, int y) return; } - finishComposingText(); - auto im = qGuiApp->inputMethod(); auto leftRect = im->cursorRectangle(); // The handle is down of the cursor, but we want the position in the middle. @@ -682,12 +680,9 @@ void QAndroidInputContext::handleLocationChanged(int handleId, int x, int y) : QHighDpiScaling::factor(QtAndroid::androidPlatformIntegration()->screen()); QPointF point(x / pixelDensity, y / pixelDensity); point.setY(point.y() - leftRect.width() / 2); - if (handleId == 1) { - setSelectionOnFocusObject(point, point); - return; - } - QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImAnchorPosition | Qt::ImCurrentSelection); + QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImAnchorPosition + | Qt::ImAbsolutePosition | Qt::ImCurrentSelection); QCoreApplication::sendEvent(m_focusObject, &query); int cpos = query.value(Qt::ImCursorPosition).toInt(); int anchor = query.value(Qt::ImAnchorPosition).toInt(); @@ -729,16 +724,62 @@ void QAndroidInputContext::handleLocationChanged(int handleId, int x, int y) }; if (handleId == 2) { - QPointF rightPoint(rightRect.center()); if ((!rtl && !checkLeftHandle(point)) || (rtl && !checkRtlRightHandle(point))) return; - setSelectionOnFocusObject(point, rightPoint); } else if (handleId == 3) { - QPointF leftPoint(leftRect.center()); if ((!rtl && !checkRightHandle(point)) || (rtl && !checkRtlLeftHandle(point))) return; - setSelectionOnFocusObject(leftPoint, point); } + + const QPointF pointLocal = im->inputItemTransform().inverted().map(point); + bool ok; + const int handlePos = + QInputMethod::queryFocusObject(Qt::ImCursorPosition, pointLocal).toInt(&ok); + if (!ok) + return; + + int newCpos = cpos; + int newAnchor = anchor; + if (newAnchor > newCpos) + std::swap(newAnchor, newCpos); + + if (handleId == 1) { + newCpos = handlePos; + newAnchor = handlePos; + } else if (handleId == 2) { + newAnchor = handlePos; + } else if (handleId == 3) { + newCpos = handlePos; + } + + // Check if handle has been dragged far enough + if (m_composingText.isEmpty() && newCpos == cpos && newAnchor == anchor) + return; + + /* + If there is composing text, we have to compare newCpos with m_composingCursor instead of cpos. + And since there is nothing to compare with newAnchor, we perform the check only when user + drags the cursor handle. + */ + if (!m_composingText.isEmpty() && handleId == 1) { + int absoluteCpos = query.value(Qt::ImAbsolutePosition).toInt(&ok); + if (!ok) + absoluteCpos = cpos; + const int blockPos = absoluteCpos - cpos; + + if (blockPos + newCpos == m_composingCursor) + return; + } + + finishComposingText(); + + QList<QInputMethodEvent::Attribute> attributes; + attributes.append({ QInputMethodEvent::Selection, newAnchor, newCpos - newAnchor }); + if (newCpos != newAnchor) + attributes.append({ QInputMethodEvent::Cursor, 0, 0 }); + + QInputMethodEvent event(QString(), attributes); + QGuiApplication::sendEvent(m_focusObject, &event); } void QAndroidInputContext::touchDown(int x, int y) |