summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/android
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/android')
-rw-r--r--src/plugins/platforms/android/androidjniinput.cpp4
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp14
-rw-r--r--src/plugins/platforms/android/androidjnimain.h1
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.cpp63
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.h2
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.cpp5
6 files changed, 68 insertions, 21 deletions
diff --git a/src/plugins/platforms/android/androidjniinput.cpp b/src/plugins/platforms/android/androidjniinput.cpp
index fe1aff0cc4..d0b5e4a12a 100644
--- a/src/plugins/platforms/android/androidjniinput.cpp
+++ b/src/plugins/platforms/android/androidjniinput.cpp
@@ -59,7 +59,6 @@ using namespace QtAndroid;
namespace QtAndroidInput
{
static bool m_ignoreMouseEvents = false;
- static bool m_softwareKeyboardVisible = false;
static QRect m_softwareKeyboardRect;
static QList<QWindowSystemInterface::TouchPoint> m_touchPoints;
@@ -115,7 +114,7 @@ namespace QtAndroidInput
bool isSoftwareKeyboardVisible()
{
- return m_softwareKeyboardVisible;
+ return QJNIObjectPrivate::callStaticMethod<jboolean>(applicationClass(), "isSoftwareKeyboardVisible");
}
QRect softwareKeyboardRect()
@@ -806,7 +805,6 @@ namespace QtAndroidInput
static void keyboardVisibilityChanged(JNIEnv */*env*/, jobject /*thiz*/, jboolean visibility)
{
- m_softwareKeyboardVisible = visibility;
if (!visibility)
m_softwareKeyboardRect = QRect();
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index 9e4007b37a..8ef009041f 100644
--- a/src/plugins/platforms/android/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -238,6 +238,11 @@ namespace QtAndroid
QJNIObjectPrivate::callStaticMethod<void>(m_applicationClass, "notifyObjectFocus","(I)V", accessibilityObjectId);
}
+ void notifyQtAndroidPluginRunning(bool running)
+ {
+ QJNIObjectPrivate::callStaticMethod<void>(m_applicationClass, "notifyQtAndroidPluginRunning","(Z)V", running);
+ }
+
jobject createBitmap(QImage img, JNIEnv *env)
{
if (!m_bitmapClass)
@@ -644,11 +649,12 @@ static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/,
jint widthPixels, jint heightPixels,
jint desktopWidthPixels, jint desktopHeightPixels,
jdouble xdpi, jdouble ydpi,
- jdouble scaledDensity, jdouble density)
+ jdouble scaledDensity, jdouble density, bool forceUpdate)
{
// Android does not give us the correct screen size for immersive mode, but
// the surface does have the right size
+ bool updateDesktopSize = m_desktopWidthPixels != desktopWidthPixels;
widthPixels = qMax(widthPixels, desktopWidthPixels);
heightPixels = qMax(heightPixels, desktopHeightPixels);
@@ -669,7 +675,9 @@ static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/,
m_androidPlatformIntegration->setDisplayMetrics(qRound(double(widthPixels) / xdpi * 25.4),
qRound(double(heightPixels) / ydpi * 25.4));
m_androidPlatformIntegration->setScreenSize(widthPixels, heightPixels);
- m_androidPlatformIntegration->setDesktopSize(desktopWidthPixels, desktopHeightPixels);
+ if (updateDesktopSize || forceUpdate) {
+ m_androidPlatformIntegration->setDesktopSize(desktopWidthPixels, desktopHeightPixels);
+ }
}
}
@@ -795,7 +803,7 @@ static JNINativeMethod methods[] = {
{"quitQtCoreApplication", "()V", (void *)quitQtCoreApplication},
{"terminateQt", "()V", (void *)terminateQt},
{"waitForServiceSetup", "()V", (void *)waitForServiceSetup},
- {"setDisplayMetrics", "(IIIIDDDD)V", (void *)setDisplayMetrics},
+ {"setDisplayMetrics", "(IIIIDDDDZ)V", (void *)setDisplayMetrics},
{"setSurface", "(ILjava/lang/Object;II)V", (void *)setSurface},
{"updateWindow", "()V", (void *)updateWindow},
{"updateApplicationState", "(I)V", (void *)updateApplicationState},
diff --git a/src/plugins/platforms/android/androidjnimain.h b/src/plugins/platforms/android/androidjnimain.h
index 72b864de19..641b2dbdb4 100644
--- a/src/plugins/platforms/android/androidjnimain.h
+++ b/src/plugins/platforms/android/androidjnimain.h
@@ -98,6 +98,7 @@ namespace QtAndroid
void notifyAccessibilityLocationChange();
void notifyObjectHide(uint accessibilityObjectId);
void notifyObjectFocus(uint accessibilityObjectId);
+ void notifyQtAndroidPluginRunning(bool running);
const char *classErrorMsgFmt();
const char *methodErrorMsgFmt();
diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp
index 687cced1e2..96eee24c2f 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.cpp
+++ b/src/plugins/platforms/android/qandroidinputcontext.cpp
@@ -95,6 +95,7 @@ private:
static QAndroidInputContext *m_androidInputContext = 0;
static char const *const QtNativeInputConnectionClassName = "org/qtproject/qt5/android/QtNativeInputConnection";
static char const *const QtExtractedTextClassName = "org/qtproject/qt5/android/QtExtractedText";
+static char const *const QtObjectType = "QDialog";
static jclass m_extractedTextClass = 0;
static jmethodID m_classConstructorMethodID = 0;
static jfieldID m_partialEndOffsetFieldID = 0;
@@ -646,7 +647,7 @@ void QAndroidInputContext::updateSelectionHandles()
}
auto curRect = im->cursorRectangle();
- QPoint cursorPoint = qGuiApp->focusWindow()->mapToGlobal(QPoint(curRect.x() + (curRect.width() / 2), curRect.y() + curRect.height()));
+ QPoint cursorPoint(window->mapToGlobal(QPoint(curRect.x() + (curRect.width() / 2), curRect.y() + curRect.height())));
QPoint editMenuPoint(cursorPoint.x(), cursorPoint.y());
m_handleMode &= ShowEditPopup;
m_handleMode |= ShowCursor;
@@ -666,10 +667,12 @@ void QAndroidInputContext::updateSelectionHandles()
if (cpos > anchor)
std::swap(leftRect, rightRect);
- QPoint leftPoint(leftRect.bottomLeft().toPoint() * pixelDensity);
- QPoint righPoint(rightRect.bottomRight().toPoint() * pixelDensity);
- QPoint editPoint(leftRect.united(rightRect).topLeft().toPoint() * pixelDensity);
- QtAndroidInput::updateHandles(m_handleMode, editPoint, EditContext::AllButtons, leftPoint, righPoint,
+ QPoint leftPoint(window->mapToGlobal(leftRect.bottomLeft().toPoint()));
+ QPoint righPoint(window->mapToGlobal(rightRect.bottomRight().toPoint()));
+ QPoint editPoint(window->mapToGlobal(leftRect.united(rightRect)
+ .topLeft().toPoint()));
+ QtAndroidInput::updateHandles(m_handleMode, editPoint * pixelDensity, EditContext::AllButtons,
+ leftPoint * pixelDensity, righPoint * pixelDensity,
query.value(Qt::ImCurrentSelection).toString().isRightToLeft());
m_hideCursorHandleTimer.stop();
}
@@ -693,7 +696,17 @@ void QAndroidInputContext::handleLocationChanged(int handleId, int x, int y)
double pixelDensity = window
? QHighDpiScaling::factor(window)
: QHighDpiScaling::factor(QtAndroid::androidPlatformIntegration()->screen());
- QPointF point(x / pixelDensity, y / pixelDensity);
+ auto object = m_focusObject->parent();
+ int dialogMoveX = 0;
+ while (object) {
+ if (QString::compare(object->metaObject()->className(),
+ QtObjectType, Qt::CaseInsensitive) == 0) {
+ dialogMoveX += object->property("x").toInt();
+ }
+ object = object->parent();
+ };
+
+ QPointF point((x / pixelDensity) - dialogMoveX, y / pixelDensity);
point.setY(point.y() - leftRect.width() / 2);
QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImAnchorPosition
@@ -892,7 +905,34 @@ void QAndroidInputContext::update(Qt::InputMethodQueries queries)
QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery(queries);
if (query.isNull())
return;
-#warning TODO extract the needed data from query
+
+ if (query->value(Qt::ImCursorPosition).toInt() >= 0 &&
+ query->value(Qt::ImSurroundingText).toString() != nullptr &&
+ query->value(Qt::ImSurroundingText).toString()
+ .left(query->value(Qt::ImCursorPosition).toInt()).length()>=0) {
+ // Cursos position should be always valid
+ // when object is composing
+ if (focusObjectIsComposing())
+ return;
+ if (m_focusObject->isWidgetType())
+ updateCursorPosition();
+ else
+ updateCursorPositionInRange(query);
+ }
+}
+
+void QAndroidInputContext::updateCursorPositionInRange(const QSharedPointer<QInputMethodQueryEvent> &query)
+{
+ QObject *input = qGuiApp->focusObject();
+ QList<QInputMethodEvent::Attribute> attributes;
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor,
+ query->value(Qt::ImCursorPosition).toInt(), 1));
+
+ QInputMethodEvent event(QString(), attributes);
+ QCoreApplication::sendEvent(input, &event);
+ QtAndroidInput::updateSelection(query->value(Qt::ImCursorPosition).toInt(),
+ query->value(Qt::ImCursorPosition).toInt(), 0,
+ query->value(Qt::ImSurroundingText).toString().length());
}
void QAndroidInputContext::invokeAction(QInputMethod::Action action, int cursorPosition)
@@ -925,14 +965,9 @@ void QAndroidInputContext::showInputPanel()
if (query.isNull())
return;
- disconnect(m_updateCursorPosConnection);
- if (qGuiApp->focusObject()->metaObject()->indexOfSignal("cursorPositionChanged(int,int)") >= 0) // QLineEdit breaks the pattern
- m_updateCursorPosConnection = connect(qGuiApp->focusObject(), SIGNAL(cursorPositionChanged(int,int)), this, SLOT(updateCursorPosition()));
- else
- m_updateCursorPosConnection = connect(qGuiApp->focusObject(), SIGNAL(cursorPositionChanged()), this, SLOT(updateCursorPosition()));
-
QRect rect = cursorRect();
- QtAndroidInput::showSoftwareKeyboard(rect.left(), rect.top(), rect.width(), rect.height(),
+ if (!isInputPanelVisible())
+ QtAndroidInput::showSoftwareKeyboard(rect.left(), rect.top(), rect.width(), rect.height(),
inputItemRectangle().height(),
query->value(Qt::ImHints).toUInt(),
query->value(Qt::ImEnterKeyType).toUInt());
diff --git a/src/plugins/platforms/android/qandroidinputcontext.h b/src/plugins/platforms/android/qandroidinputcontext.h
index 02a66c367a..521061b02c 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.h
+++ b/src/plugins/platforms/android/qandroidinputcontext.h
@@ -156,13 +156,13 @@ private:
void focusObjectStartComposing();
bool focusObjectStopComposing();
QRect cursorRect();
+ void updateCursorPositionInRange(const QSharedPointer<QInputMethodQueryEvent> &query);
private:
ExtractedText m_extractedText;
QString m_composingText;
int m_composingTextStart;
int m_composingCursor;
- QMetaObject::Connection m_updateCursorPosConnection;
HandleModes m_handleMode;
int m_batchEditNestingLevel;
QObject *m_focusObject;
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp
index aaeb9199d8..3074dee26f 100644
--- a/src/plugins/platforms/android/qandroidplatformintegration.cpp
+++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp
@@ -90,6 +90,7 @@ Qt::ScreenOrientation QAndroidPlatformIntegration::m_orientation = Qt::PrimaryOr
Qt::ScreenOrientation QAndroidPlatformIntegration::m_nativeOrientation = Qt::PrimaryOrientation;
bool QAndroidPlatformIntegration::m_showPasswordEnabled = false;
+static bool m_running = false;
void *QAndroidPlatformNativeInterface::nativeResourceForIntegration(const QByteArray &resource)
{
@@ -158,6 +159,10 @@ void QAndroidPlatformNativeInterface::customEvent(QEvent *event)
api->accessibility()->setActive(QtAndroidAccessibility::isActive());
#endif // QT_NO_ACCESSIBILITY
+ if (!m_running) {
+ m_running = true;
+ QtAndroid::notifyQtAndroidPluginRunning(m_running);
+ }
api->flushPendingUpdates();
}