diff options
Diffstat (limited to 'src/plugins/platforms/android')
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(); } |