summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/android/qandroidinputcontext.cpp
diff options
context:
space:
mode:
authorPiotr Mikolajczyk <piotr.mikolajczyk@qt.io>2020-12-18 10:51:30 +0100
committerVille Voutilainen <ville.voutilainen@qt.io>2021-03-05 07:57:14 +0000
commit5c6b10c3cee5737dbc041d0463220898c8120807 (patch)
treeaec06989da84711fa432899f84cd0adba9323e82 /src/plugins/platforms/android/qandroidinputcontext.cpp
parent9fb81fc28774cd4aa01a8b29d59150e1a7de8fd8 (diff)
Android: Place cursor correctly on screen when editing
When editing text the cursor is not placed correctly. So this has been achieved by tricking Android into thinking that the input area is only the line where the cursor is, so it is forced to keep it on screen. Fixes: QTBUG-91073 Pick-to: 5.15 Change-Id: Icc2e8315deb76ca1a84819d3fdceaa7b027b1174 Reviewed-by: Ville Voutilainen <ville.voutilainen@qt.io>
Diffstat (limited to 'src/plugins/platforms/android/qandroidinputcontext.cpp')
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.cpp44
1 files changed, 41 insertions, 3 deletions
diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp
index 29236667d3..378dfa03c8 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.cpp
+++ b/src/plugins/platforms/android/qandroidinputcontext.cpp
@@ -47,6 +47,7 @@
#include "qandroideventdispatcher.h"
#include "qandroidinputcontext.h"
#include "qandroidplatformintegration.h"
+#include "private/qhighdpiscaling_p.h"
#include <QTextBoundaryFinder>
#include <QTextCharFormat>
@@ -59,7 +60,6 @@
#include <qthread.h>
#include <qwindow.h>
#include <qpa/qplatformwindow.h>
-
QT_BEGIN_NAMESPACE
namespace {
@@ -491,7 +491,7 @@ QAndroidInputContext::QAndroidInputContext()
m_androidInputContext = this;
QObject::connect(QGuiApplication::inputMethod(), &QInputMethod::cursorRectangleChanged,
- this, &QAndroidInputContext::updateSelectionHandles);
+ this, &QAndroidInputContext::updateInputItemRectangle);
QObject::connect(QGuiApplication::inputMethod(), &QInputMethod::anchorRectangleChanged,
this, &QAndroidInputContext::updateSelectionHandles);
QObject::connect(QGuiApplication::inputMethod(), &QInputMethod::inputItemClipRectangleChanged, this, [this]{
@@ -889,12 +889,50 @@ void QAndroidInputContext::showInputPanel()
else
m_updateCursorPosConnection = connect(qGuiApp->focusObject(), SIGNAL(cursorPositionChanged()), this, SLOT(updateCursorPosition()));
- QRect rect = screenInputItemRectangle();
+ QRect rect = cursorRect();
QtAndroidInput::showSoftwareKeyboard(rect.left(), rect.top(), rect.width(), rect.height(),
+ screenInputItemRectangle().height(),
query->value(Qt::ImHints).toUInt(),
query->value(Qt::ImEnterKeyType).toUInt());
}
+QRect QAndroidInputContext::cursorRect()
+{
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
+ // if single line, we do not want to mess with the editor's position, as we do not
+ // have to follow the cursor in vertical axis
+ if (query.isNull()
+ || (query->value(Qt::ImHints).toUInt() & Qt::ImhMultiLine) != Qt::ImhMultiLine)
+ return {};
+
+ auto im = qGuiApp->inputMethod();
+ if (!im)
+ return {};
+
+ const auto cursorRect= im->cursorRectangle().toRect();
+ QRect finalRect(inputItemRectangle().toRect());
+ const QWindow *window = qGuiApp->focusWindow();
+ const double pd = window
+ ? QHighDpiScaling::factor(window)
+ : QHighDpiScaling::factor(QtAndroid::androidPlatformIntegration()->screen());
+ finalRect.setY(cursorRect.y() * pd);
+ finalRect.setHeight(cursorRect.height() * pd);
+ //fiddle a bit with vert margins, so the tracking rectangle is not too tight.
+ finalRect += QMargins(0, cursorRect.height() / 4, 0, cursorRect.height() / 4);
+ return finalRect;
+}
+
+void QAndroidInputContext::updateInputItemRectangle()
+{
+ QRect rect = cursorRect();
+
+ if (!rect.isValid())
+ return;
+ QtAndroidInput::updateInputItemRectangle(rect.left(), rect.top(),
+ rect.width(), rect.height());
+ updateSelectionHandles();
+}
+
void QAndroidInputContext::showInputPanelLater(Qt::ApplicationState state)
{
if (state != Qt::ApplicationActive)