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/androidjniaccessibility.cpp62
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp7
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.cpp20
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.cpp14
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.h1
-rw-r--r--src/plugins/platforms/android/qandroidplatformopenglcontext.cpp5
-rw-r--r--src/plugins/platforms/android/qandroidplatformopenglwindow.cpp33
-rw-r--r--src/plugins/platforms/android/qandroidplatformopenglwindow.h2
-rw-r--r--src/plugins/platforms/android/qandroidplatformrasterwindow.cpp2
-rw-r--r--src/plugins/platforms/android/qandroidplatformscreen.cpp15
-rw-r--r--src/plugins/platforms/android/qandroidplatformwindow.cpp4
11 files changed, 133 insertions, 32 deletions
diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp
index fa7e259460..d9f5cec27a 100644
--- a/src/plugins/platforms/android/androidjniaccessibility.cpp
+++ b/src/plugins/platforms/android/androidjniaccessibility.cpp
@@ -56,6 +56,18 @@ static const char m_methodErrorMsg[] = "Can't find method \"%s%s\"";
namespace QtAndroidAccessibility
{
+ static jmethodID m_addActionMethodID = 0;
+ static jmethodID m_setCheckableMethodID = 0;
+ static jmethodID m_setCheckedMethodID = 0;
+ static jmethodID m_setClickableMethodID = 0;
+ static jmethodID m_setContentDescriptionMethodID = 0;
+ static jmethodID m_setEnabledMethodID = 0;
+ static jmethodID m_setFocusableMethodID = 0;
+ static jmethodID m_setFocusedMethodID = 0;
+ static jmethodID m_setTextSelectionMethodID = 0;
+ static jmethodID m_setVisibleToUserMethodID = 0;
+
+
static void setActive(JNIEnv */*env*/, jobject /*thiz*/, jboolean active)
{
QAndroidPlatformIntegration *platformIntegration = QtAndroid::androidPlatformIntegration();
@@ -164,17 +176,6 @@ if (!clazz) { \
//__android_log_print(ANDROID_LOG_FATAL, m_qtTag, m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE);
-#define CALL_METHOD(OBJECT, METHOD_NAME, METHOD_SIGNATURE, ...) \
-{ \
- jclass clazz = env->GetObjectClass(OBJECT); \
- jmethodID method = env->GetMethodID(clazz, METHOD_NAME, METHOD_SIGNATURE); \
- if (!method) { \
- __android_log_print(ANDROID_LOG_WARN, m_qtTag, m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE); \
- return false; \
- } \
- env->CallVoidMethod(OBJECT, method, __VA_ARGS__); \
-}
-
static jstring descriptionForAccessibleObject(JNIEnv *env, jobject /*thiz*/, jint objectId)
{
@@ -210,30 +211,30 @@ if (!clazz) { \
int startSelection;
int endSelection;
textIface->selection(0, &startSelection, &endSelection);
- CALL_METHOD(node, "setTextSelection", "(II)V", startSelection, endSelection)
+ env->CallVoidMethod(node, m_setTextSelectionMethodID, startSelection, endSelection);
}
}
- CALL_METHOD(node, "setEnabled", "(Z)V", !state.disabled)
- CALL_METHOD(node, "setFocusable", "(Z)V", (bool)state.focusable)
- CALL_METHOD(node, "setFocused", "(Z)V", (bool)state.focused)
- CALL_METHOD(node, "setCheckable", "(Z)V", (bool)state.checkable)
- CALL_METHOD(node, "setChecked", "(Z)V", (bool)state.checked)
- CALL_METHOD(node, "setVisibleToUser", "(Z)V", !state.invisible)
+ env->CallVoidMethod(node, m_setEnabledMethodID, !state.disabled);
+ env->CallVoidMethod(node, m_setCheckedMethodID, (bool)state.checked);
+ env->CallVoidMethod(node, m_setFocusableMethodID, (bool)state.focusable);
+ env->CallVoidMethod(node, m_setFocusedMethodID, (bool)state.focused);
+ env->CallVoidMethod(node, m_setCheckableMethodID, (bool)state.checkable);
+ env->CallVoidMethod(node, m_setVisibleToUserMethodID, !state.invisible);
if (iface->actionInterface()) {
QStringList actions = iface->actionInterface()->actionNames();
bool clickable = actions.contains(QAccessibleActionInterface::pressAction());
bool toggle = actions.contains(QAccessibleActionInterface::toggleAction());
if (clickable || toggle) {
- CALL_METHOD(node, "setClickable", "(Z)V", (bool)clickable)
- CALL_METHOD(node, "addAction", "(I)V", 16) // ACTION_CLICK defined in AccessibilityNodeInfo
+ env->CallVoidMethod(node, m_setClickableMethodID, (bool)clickable);
+ env->CallVoidMethod(node, m_addActionMethodID, (int)16); // ACTION_CLICK defined in AccessibilityNodeInfo
}
}
jstring jdesc = env->NewString((jchar*) desc.constData(), (jsize) desc.size());
//CALL_METHOD(node, "setText", "(Ljava/lang/CharSequence;)V", jdesc)
- CALL_METHOD(node, "setContentDescription", "(Ljava/lang/CharSequence;)V", jdesc)
+ env->CallVoidMethod(node, m_setContentDescriptionMethodID, jdesc);
return true;
}
@@ -249,6 +250,13 @@ if (!clazz) { \
{"clickAction", "(I)Z", (void*)clickAction},
};
+#define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \
+ VAR = env->GetMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \
+ if (!VAR) { \
+ __android_log_print(ANDROID_LOG_FATAL, QtAndroid::qtTagText(), QtAndroid::methodErrorMsgFmt(), METHOD_NAME, METHOD_SIGNATURE); \
+ return false; \
+ }
+
bool registerNatives(JNIEnv *env)
{
jclass clazz;
@@ -260,6 +268,18 @@ if (!clazz) { \
return false;
}
+ jclass nodeInfoClass = env->FindClass("android/view/accessibility/AccessibilityNodeInfo");
+ GET_AND_CHECK_STATIC_METHOD(m_addActionMethodID, nodeInfoClass, "addAction", "(I)V");
+ GET_AND_CHECK_STATIC_METHOD(m_setCheckableMethodID, nodeInfoClass, "setCheckable", "(Z)V");
+ GET_AND_CHECK_STATIC_METHOD(m_setCheckedMethodID, nodeInfoClass, "setChecked", "(Z)V");
+ GET_AND_CHECK_STATIC_METHOD(m_setClickableMethodID, nodeInfoClass, "setClickable", "(Z)V");
+ GET_AND_CHECK_STATIC_METHOD(m_setContentDescriptionMethodID, nodeInfoClass, "setContentDescription", "(Ljava/lang/CharSequence;)V");
+ GET_AND_CHECK_STATIC_METHOD(m_setEnabledMethodID, nodeInfoClass, "setEnabled", "(Z)V");
+ GET_AND_CHECK_STATIC_METHOD(m_setFocusableMethodID, nodeInfoClass, "setFocusable", "(Z)V");
+ GET_AND_CHECK_STATIC_METHOD(m_setFocusedMethodID, nodeInfoClass, "setFocused", "(Z)V");
+ GET_AND_CHECK_STATIC_METHOD(m_setTextSelectionMethodID, nodeInfoClass, "setTextSelection", "(II)V");
+ GET_AND_CHECK_STATIC_METHOD(m_setVisibleToUserMethodID, nodeInfoClass, "setVisibleToUser", "(Z)V");
+
return true;
}
}
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index 7ca4db710b..d484a2faff 100644
--- a/src/plugins/platforms/android/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -573,8 +573,11 @@ static void updateWindow(JNIEnv */*env*/, jobject /*thiz*/)
return;
if (QGuiApplication::instance() != 0) {
- foreach (QWindow *w, QGuiApplication::topLevelWindows())
- QWindowSystemInterface::handleExposeEvent(w, QRegion(w->geometry()));
+ foreach (QWindow *w, QGuiApplication::topLevelWindows()) {
+ QRect availableGeometry = w->screen()->availableGeometry();
+ if (w->geometry().width() > 0 && w->geometry().height() > 0 && availableGeometry.width() > 0 && availableGeometry.height() > 0)
+ QWindowSystemInterface::handleExposeEvent(w, QRegion(w->geometry()));
+ }
}
QAndroidPlatformScreen *screen = static_cast<QAndroidPlatformScreen *>(m_androidPlatformIntegration->screen());
diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp
index c2e5f83639..5d47d2fda4 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.cpp
+++ b/src/plugins/platforms/android/qandroidinputcontext.cpp
@@ -472,12 +472,24 @@ void QAndroidInputContext::updateCursorPosition()
if (m_composingText.isEmpty() != (m_composingTextStart == -1))
qWarning() << "Input method out of sync" << m_composingText << m_composingTextStart;
-
- // Qt's idea of the cursor position is the start of the preedit area, so we have to maintain our own preedit cursor pos
int realCursorPosition = cursorPos;
+ int realAnchorPosition = cursorPos;
+
+ int cpos = query->value(Qt::ImCursorPosition).toInt();
+ int anchor = query->value(Qt::ImAnchorPosition).toInt();
+ if (cpos != anchor) {
+ if (!m_composingText.isEmpty()) {
+ qWarning("Selecting text while preediting may give unpredictable results.");
+ finishComposingText();
+ }
+ int blockPos = getBlockPosition(query);
+ realCursorPosition = blockPos + cpos;
+ realAnchorPosition = blockPos + anchor;
+ }
+ // Qt's idea of the cursor position is the start of the preedit area, so we maintain our own preedit cursor pos
if (!m_composingText.isEmpty())
- realCursorPosition = m_composingCursor;
- QtAndroidInput::updateSelection(realCursorPosition, realCursorPosition, //empty selection
+ realCursorPosition = realAnchorPosition = m_composingCursor;
+ QtAndroidInput::updateSelection(realCursorPosition, realAnchorPosition,
m_composingTextStart, m_composingTextStart + composeLength); // pre-edit text
}
}
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp
index 7f0f40be0f..213b1bb7e6 100644
--- a/src/plugins/platforms/android/qandroidplatformintegration.cpp
+++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp
@@ -45,11 +45,14 @@
#include <QGuiApplication>
#include <QOpenGLContext>
#include <QThread>
+#include <QOffscreenSurface>
#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
+#include <QtPlatformSupport/private/qeglpbuffer_p.h>
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatformwindow.h>
+#include <qpa/qplatformoffscreensurface.h>
#include "androidjnimain.h"
#include "qabstracteventdispatcher.h"
@@ -207,6 +210,17 @@ QPlatformOpenGLContext *QAndroidPlatformIntegration::createPlatformOpenGLContext
return new QAndroidPlatformOpenGLContext(format, context->shareHandle(), m_eglDisplay);
}
+QPlatformOffscreenSurface *QAndroidPlatformIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
+{
+ QSurfaceFormat format(surface->requestedFormat());
+ format.setAlphaBufferSize(8);
+ format.setRedBufferSize(8);
+ format.setGreenBufferSize(8);
+ format.setBlueBufferSize(8);
+
+ return new QEGLPbuffer(m_eglDisplay, format, surface);
+}
+
QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *window) const
{
if (window->type() == Qt::ForeignWindow)
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.h b/src/plugins/platforms/android/qandroidplatformintegration.h
index 4a3fe6c766..f8fa1a91dd 100644
--- a/src/plugins/platforms/android/qandroidplatformintegration.h
+++ b/src/plugins/platforms/android/qandroidplatformintegration.h
@@ -82,6 +82,7 @@ public:
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
QAbstractEventDispatcher *createEventDispatcher() const;
QAndroidPlatformScreen *screen() { return m_primaryScreen; }
+ QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const;
virtual void setDesktopSize(int width, int height);
virtual void setDisplayMetrics(int width, int height);
diff --git a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
index 152a06c99d..53047585cf 100644
--- a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
+++ b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
@@ -44,6 +44,8 @@
#include "qandroidplatformopenglwindow.h"
#include "qandroidplatformintegration.h"
+#include <QtPlatformSupport/private/qeglpbuffer_p.h>
+
#include <QSurface>
#include <QtGui/private/qopenglcontext_p.h>
@@ -98,7 +100,8 @@ EGLSurface QAndroidPlatformOpenGLContext::eglSurfaceForPlatformSurface(QPlatform
{
if (surface->surface()->surfaceClass() == QSurface::Window)
return static_cast<QAndroidPlatformOpenGLWindow *>(surface)->eglSurface(eglConfig());
- return EGL_NO_SURFACE;
+ else
+ return static_cast<QEGLPbuffer *>(surface)->pbuffer();
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp b/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp
index 34db729289..f0c4a1de2a 100644
--- a/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp
+++ b/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp
@@ -47,7 +47,8 @@
#include <QSurfaceFormat>
#include <qpa/qwindowsysteminterface.h>
-
+#include <qpa/qplatformscreen.h>
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <android/native_window.h>
#include <android/native_window_jni.h>
@@ -77,8 +78,20 @@ void QAndroidPlatformOpenGLWindow::setGeometry(const QRect &rect)
if (rect == geometry())
return;
+ QRect oldGeometry = geometry();
+
QAndroidPlatformWindow::setGeometry(rect);
QtAndroid::setSurfaceGeometry(m_nativeSurfaceId, rect);
+
+ QRect availableGeometry = screen()->availableGeometry();
+ if (oldGeometry.width() == 0
+ && oldGeometry.height() == 0
+ && rect.width() > 0
+ && rect.height() > 0
+ && availableGeometry.width() > 0
+ && availableGeometry.height() > 0) {
+ QWindowSystemInterface::handleExposeEvent(window(), QRegion(rect));
+ }
}
EGLSurface QAndroidPlatformOpenGLWindow::eglSurface(EGLConfig config)
@@ -100,8 +113,11 @@ void QAndroidPlatformOpenGLWindow::checkNativeSurface(EGLConfig config)
createEgl(config);
+
// we've create another surface, the window should be repainted
- QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry()));
+ QRect availableGeometry = screen()->availableGeometry();
+ if (geometry().width() > 0 && geometry().height() > 0 && availableGeometry.width() > 0 && availableGeometry.height() > 0)
+ QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry()));
}
void QAndroidPlatformOpenGLWindow::createEgl(EGLConfig config)
@@ -111,6 +127,7 @@ void QAndroidPlatformOpenGLWindow::createEgl(EGLConfig config)
m_nativeWindow = ANativeWindow_fromSurface(env, m_androidSurfaceObject.object());
m_androidSurfaceObject = QJNIObjectPrivate();
m_eglSurface = eglCreateWindowSurface(m_eglDisplay, config, m_nativeWindow, NULL);
+ m_format = q_glFormatFromConfig(m_eglDisplay, config, window()->requestedFormat());
if (m_eglSurface == EGL_NO_SURFACE) {
EGLint error = eglGetError();
eglTerminate(m_eglDisplay);
@@ -118,6 +135,14 @@ void QAndroidPlatformOpenGLWindow::createEgl(EGLConfig config)
}
}
+QSurfaceFormat QAndroidPlatformOpenGLWindow::format() const
+{
+ if (m_nativeWindow == 0)
+ return window()->requestedFormat();
+ else
+ return m_format;
+}
+
void QAndroidPlatformOpenGLWindow::clearEgl()
{
eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
@@ -143,7 +168,9 @@ void QAndroidPlatformOpenGLWindow::surfaceChanged(JNIEnv *jniEnv, jobject surfac
unlockSurface();
// repaint the window
- QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry()));
+ QRect availableGeometry = screen()->availableGeometry();
+ if (geometry().width() > 0 && geometry().height() > 0 && availableGeometry.width() > 0 && availableGeometry.height() > 0)
+ QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry()));
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformopenglwindow.h b/src/plugins/platforms/android/qandroidplatformopenglwindow.h
index 7af8b722aa..83df15a524 100644
--- a/src/plugins/platforms/android/qandroidplatformopenglwindow.h
+++ b/src/plugins/platforms/android/qandroidplatformopenglwindow.h
@@ -60,6 +60,7 @@ public:
void setGeometry(const QRect &rect);
EGLSurface eglSurface(EGLConfig config);
+ QSurfaceFormat format() const;
void checkNativeSurface(EGLConfig config);
@@ -76,6 +77,7 @@ private:
int m_nativeSurfaceId = -1;
QJNIObjectPrivate m_androidSurfaceObject;
QWaitCondition m_surfaceWaitCondition;
+ QSurfaceFormat m_format;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformrasterwindow.cpp b/src/plugins/platforms/android/qandroidplatformrasterwindow.cpp
index eb5a73c4a3..3fb236793b 100644
--- a/src/plugins/platforms/android/qandroidplatformrasterwindow.cpp
+++ b/src/plugins/platforms/android/qandroidplatformrasterwindow.cpp
@@ -76,6 +76,8 @@ void QAndroidPlatformRasterWindow::setGeometry(const QRect &rect)
{
m_oldGeometry = geometry();
QAndroidPlatformWindow::setGeometry(rect);
+ if (rect.topLeft() != m_oldGeometry.topLeft())
+ repaint(QRegion(rect));
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp
index f03f551d8a..e67a039ff4 100644
--- a/src/plugins/platforms/android/qandroidplatformscreen.cpp
+++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp
@@ -55,6 +55,9 @@
#include <android/bitmap.h>
#include <android/native_window_jni.h>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QWindow>
+
QT_BEGIN_NAMESPACE
#ifdef QANDROIDPLATFORMSCREEN_DEBUG
@@ -217,11 +220,23 @@ void QAndroidPlatformScreen::setGeometry(const QRect &rect)
if (m_geometry == rect)
return;
+ QRect oldGeometry = m_geometry;
+
m_geometry = rect;
QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry());
QWindowSystemInterface::handleScreenAvailableGeometryChange(QPlatformScreen::screen(), availableGeometry());
resizeMaximizedWindows();
+ if (oldGeometry.width() == 0 && oldGeometry.height() == 0 && rect.width() > 0 && rect.height() > 0) {
+ QList<QWindow *> windows = QGuiApplication::allWindows();
+ for (int i = 0; i < windows.size(); ++i) {
+ QWindow *w = windows.at(i);
+ QRect geometry = w->handle()->geometry();
+ if (geometry.width() > 0 && geometry.height() > 0)
+ QWindowSystemInterface::handleExposeEvent(w, QRegion(geometry));
+ }
+ }
+
if (m_id != -1) {
if (m_nativeSurface) {
ANativeWindow_release(m_nativeSurface);
diff --git a/src/plugins/platforms/android/qandroidplatformwindow.cpp b/src/plugins/platforms/android/qandroidplatformwindow.cpp
index b4231f0283..558525b78c 100644
--- a/src/plugins/platforms/android/qandroidplatformwindow.cpp
+++ b/src/plugins/platforms/android/qandroidplatformwindow.cpp
@@ -88,7 +88,9 @@ void QAndroidPlatformWindow::setVisible(bool visible)
setGeometry(platformScreen()->availableGeometry());
}
- QPlatformWindow::setVisible(visible);
+ QRect availableGeometry = screen()->availableGeometry();
+ if (geometry().width() > 0 && geometry().height() > 0 && availableGeometry.width() > 0 && availableGeometry.height() > 0)
+ QPlatformWindow::setVisible(visible);
if (visible)
platformScreen()->addWindow(this);