summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
authorVova Mshanetskiy <vovams163@gmail.com>2019-05-06 15:00:55 +0300
committerVova Mshanetskiy <vovams163@gmail.com>2019-06-05 17:38:32 +0300
commit710435ee81c4cf48d66f07eff3cbad3eaef80ab8 (patch)
tree88221c9a8c2c2b8360ed7e4a4e975381357a8e4e /src/plugins/platforms
parent0c1831178540462da31fd7a4b6d2e446bc84498b (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.cpp63
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)