summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/android/src
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2013-11-26 22:30:27 +0100
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2013-11-26 22:35:48 +0100
commit4a8273a6fc2e741e811cf5dabc9a3c240306cf7f (patch)
tree2148abc88f8543eecdc0b97b2dd92594836af9b2 /src/plugins/platforms/android/src
parent036c5db468164297d213764c59a4b59daa76d90a (diff)
parent1c2be58fecaff1de5f2849192eb712984ebd59bd (diff)
Merge remote-tracking branch 'origin/stable' into dev
For the conflicts in msvc_nmake.cpp the ifdefs are extended since we need to support windows phone in the target branch while it is not there in the current stable branch (as of Qt 5.2). Conflicts: configure qmake/generators/win32/msvc_nmake.cpp src/3rdparty/angle/src/libEGL/Surface.cpp src/angle/src/common/common.pri src/corelib/global/qglobal.h src/corelib/io/qstandardpaths.cpp src/plugins/platforms/qnx/qqnxintegration.cpp src/plugins/platforms/qnx/qqnxscreeneventhandler.h src/plugins/platforms/xcb/qglxintegration.h src/widgets/kernel/win.pri tests/auto/corelib/thread/qreadwritelock/tst_qreadwritelock.cpp tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp tools/configure/configureapp.cpp Change-Id: I00b579eefebaf61d26ab9b00046d2b5bd5958812
Diffstat (limited to 'src/plugins/platforms/android/src')
-rw-r--r--src/plugins/platforms/android/src/androidjniaccessibility.cpp2
-rw-r--r--src/plugins/platforms/android/src/androidjniinput.cpp51
-rw-r--r--src/plugins/platforms/android/src/androidjnimain.cpp84
-rw-r--r--src/plugins/platforms/android/src/androidjnimain.h6
-rw-r--r--src/plugins/platforms/android/src/androidjnimenu.cpp36
-rw-r--r--src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp2
-rw-r--r--src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.cpp61
-rw-r--r--src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.h60
-rw-r--r--src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp32
-rw-r--r--src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h3
-rw-r--r--src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp5
-rw-r--r--src/plugins/platforms/android/src/qandroidassetsfileenginehandler.cpp73
-rw-r--r--src/plugins/platforms/android/src/qandroidassetsfileenginehandler.h8
-rw-r--r--src/plugins/platforms/android/src/qandroidinputcontext.cpp5
-rw-r--r--src/plugins/platforms/android/src/qandroidinputcontext.h1
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformdialoghelpers.cpp204
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformdialoghelpers.h77
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformintegration.cpp24
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformintegration.h5
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformmenu.cpp10
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformmenu.h1
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformmenubar.cpp2
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformtheme.cpp20
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformtheme.h3
-rw-r--r--src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp7
-rw-r--r--src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp35
-rw-r--r--src/plugins/platforms/android/src/raster/qandroidplatformwindow.h4
-rw-r--r--src/plugins/platforms/android/src/src.pri2
28 files changed, 741 insertions, 82 deletions
diff --git a/src/plugins/platforms/android/src/androidjniaccessibility.cpp b/src/plugins/platforms/android/src/androidjniaccessibility.cpp
index a27d9f5aed..b987c49c9c 100644
--- a/src/plugins/platforms/android/src/androidjniaccessibility.cpp
+++ b/src/plugins/platforms/android/src/androidjniaccessibility.cpp
@@ -46,7 +46,7 @@
#include "qguiapplication.h"
#include "qwindow.h"
#include "qrect.h"
-#include "private/qaccessible2_p.h"
+#include "QtGui/qaccessible.h"
#include "qdebug.h"
diff --git a/src/plugins/platforms/android/src/androidjniinput.cpp b/src/plugins/platforms/android/src/androidjniinput.cpp
index 30d4e69afe..8ce95532d3 100644
--- a/src/plugins/platforms/android/src/androidjniinput.cpp
+++ b/src/plugins/platforms/android/src/androidjniinput.cpp
@@ -47,6 +47,10 @@
#include <QTouchEvent>
#include <QPointer>
+#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
+# include <QDebug>
+#endif
+
using namespace QtAndroid;
namespace QtAndroidInput
@@ -63,12 +67,32 @@ namespace QtAndroidInput
static QPointer<QWindow> m_mouseGrabber;
+ static int m_lastCursorPos = -1;
+
void updateSelection(int selStart, int selEnd, int candidatesStart, int candidatesEnd)
{
AttachedJNIEnv env;
if (!env.jniEnv)
return;
+#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
+ qDebug() << ">>> UPDATESELECTION" << selStart << selEnd << candidatesStart << candidatesEnd;
+#endif
+ if (candidatesStart == -1 && candidatesEnd == -1 && selStart == selEnd) {
+ // Qt only gives us position inside the block, so if we move to the
+ // same position in another block, the Android keyboard will believe
+ // we have not changed position, and be terribly confused.
+ if (selStart == m_lastCursorPos) {
+#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
+ qDebug() << ">>> FAKEUPDATESELECTION" << selStart+1;
+#endif
+ env.jniEnv->CallStaticVoidMethod(applicationClass(), m_updateSelectionMethodID,
+ selStart+1, selEnd+1, candidatesStart, candidatesEnd);
+ }
+ m_lastCursorPos = selStart;
+ } else {
+ m_lastCursorPos = -1;
+ }
env.jniEnv->CallStaticVoidMethod(applicationClass(), m_updateSelectionMethodID,
selStart, selEnd, candidatesStart, candidatesEnd);
}
@@ -86,6 +110,9 @@ namespace QtAndroidInput
width,
height,
inputHints);
+#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
+ qDebug() << "@@@ SHOWSOFTWAREKEYBOARD" << left << top << width << height << inputHints;
+#endif
}
void resetSoftwareKeyboard()
@@ -95,6 +122,9 @@ namespace QtAndroidInput
return;
env.jniEnv->CallStaticVoidMethod(applicationClass(), m_resetSoftwareKeyboardMethodID);
+#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
+ qDebug() << "@@@ RESETSOFTWAREKEYBOARD";
+#endif
}
void hideSoftwareKeyboard()
@@ -104,6 +134,9 @@ namespace QtAndroidInput
return;
env.jniEnv->CallStaticVoidMethod(applicationClass(), m_hideSoftwareKeyboardMethodID);
+#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
+ qDebug() << "@@@ HIDESOFTWAREKEYBOARD";
+#endif
}
bool isSoftwareKeyboardVisible()
@@ -112,7 +145,11 @@ namespace QtAndroidInput
if (!env.jniEnv)
return false;
- return env.jniEnv->CallStaticBooleanMethod(applicationClass(), m_isSoftwareKeyboardVisibleMethodID);
+ bool visibility = env.jniEnv->CallStaticBooleanMethod(applicationClass(), m_isSoftwareKeyboardVisibleMethodID);
+#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
+ qDebug() << "@@@ ISSOFTWAREKEYBOARDVISIBLE" << visibility;
+#endif
+ return visibility;
}
@@ -511,6 +548,15 @@ namespace QtAndroidInput
false);
}
+ static void keyboardVisibilityChanged(JNIEnv */*env*/, jobject /*thiz*/, jboolean /*visibility*/)
+ {
+ QAndroidInputContext *inputContext = QAndroidInputContext::androidInputContext();
+ if (inputContext)
+ inputContext->emitInputPanelVisibleChanged();
+#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
+ qDebug() << "@@@ KEYBOARDVISIBILITYCHANGED" << inputContext;
+#endif
+ }
static JNINativeMethod methods[] = {
{"touchBegin","(I)V",(void*)touchBegin},
@@ -521,7 +567,8 @@ namespace QtAndroidInput
{"mouseMove", "(III)V", (void *)mouseMove},
{"longPress", "(III)V", (void *)longPress},
{"keyDown", "(III)V", (void *)keyDown},
- {"keyUp", "(III)V", (void *)keyUp}
+ {"keyUp", "(III)V", (void *)keyUp},
+ {"keyboardVisibilityChanged", "(Z)V", (void *)keyboardVisibilityChanged}
};
#define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \
diff --git a/src/plugins/platforms/android/src/androidjnimain.cpp b/src/plugins/platforms/android/src/androidjnimain.cpp
index 5c9ca798a8..3064e5d4e2 100644
--- a/src/plugins/platforms/android/src/androidjnimain.cpp
+++ b/src/plugins/platforms/android/src/androidjnimain.cpp
@@ -40,6 +40,7 @@
**
****************************************************************************/
+#include <QtGui/private/qguiapplication_p.h>
#include <dlfcn.h>
#include <pthread.h>
@@ -59,6 +60,7 @@
#include "androidjniinput.h"
#include "androidjniclipboard.h"
#include "androidjnimenu.h"
+#include "qandroidplatformdialoghelpers.h"
#include "qandroidplatformintegration.h"
#include <QtWidgets/QApplication>
@@ -97,6 +99,9 @@ static jmethodID m_createBitmapMethodID = 0;
static jobject m_ARGB_8888_BitmapConfigValue = 0;
static jobject m_RGB_565_BitmapConfigValue = 0;
+jmethodID m_setFullScreenMethodID = 0;
+static bool m_statusBarShowing = true;
+
static jclass m_bitmapDrawableClass = 0;
static jmethodID m_bitmapDrawableConstructorMethodID = 0;
@@ -111,8 +116,6 @@ static jobject m_surface = NULL;
static EGLNativeWindowType m_nativeWindow = 0;
static QSemaphore m_waitForWindowSemaphore;
static bool m_waitForWindow = false;
-
-static jfieldID m_surfaceFieldID = 0;
#endif
@@ -247,17 +250,6 @@ namespace QtAndroid
m_surfaceMutex.unlock();
return m_nativeWindow;
}
-
- QSize nativeWindowSize()
- {
- if (m_nativeWindow == 0)
- return QAndroidPlatformIntegration::defaultDesktopSize();
-
- int width = ANativeWindow_getWidth(m_nativeWindow);
- int height = ANativeWindow_getHeight(m_nativeWindow);
-
- return QSize(width, height);
- }
#endif
void setAndroidPlatformIntegration(QAndroidPlatformIntegration *androidPlatformIntegration)
@@ -323,6 +315,36 @@ namespace QtAndroid
return m_activityObject;
}
+ void showStatusBar()
+ {
+ if (m_statusBarShowing)
+ return;
+
+ QtAndroid::AttachedJNIEnv env;
+ if (env.jniEnv == 0) {
+ qWarning("Failed to get JNI Environment.");
+ return;
+ }
+
+ env.jniEnv->CallStaticVoidMethod(m_applicationClass, m_setFullScreenMethodID, false);
+ m_statusBarShowing = true;
+ }
+
+ void hideStatusBar()
+ {
+ if (!m_statusBarShowing)
+ return;
+
+ QtAndroid::AttachedJNIEnv env;
+ if (env.jniEnv == 0) {
+ qWarning("Failed to get JNI Environment.");
+ return;
+ }
+
+ env.jniEnv->CallStaticVoidMethod(m_applicationClass, m_setFullScreenMethodID, true);
+ m_statusBarShowing = false;
+ }
+
void setApplicationActive()
{
if (m_activityActive)
@@ -564,12 +586,16 @@ static void setSurface(JNIEnv *env, jobject /*thiz*/, jobject jSurface)
m_waitForWindowSemaphore.release();
if (m_androidPlatformIntegration) {
- QSize size = QtAndroid::nativeWindowSize();
+ // Use the desktop size.
+ // On some devices, the getters for the native window size gives wrong values
+ QSize size = QAndroidPlatformIntegration::defaultDesktopSize();
QPlatformScreen *screen = m_androidPlatformIntegration->screen();
QRect geometry(QPoint(0, 0), size);
- QWindowSystemInterface::handleScreenAvailableGeometryChange(screen->screen(), geometry);
- QWindowSystemInterface::handleScreenGeometryChange(screen->screen(), geometry);
+ if (screen) {
+ QWindowSystemInterface::handleScreenAvailableGeometryChange(screen->screen(), geometry);
+ QWindowSystemInterface::handleScreenGeometryChange(screen->screen(), geometry);
+ }
if (!sameNativeWindow) {
m_surfaceMutex.unlock();
@@ -666,7 +692,7 @@ static void updateApplicationState(JNIEnv */*env*/, jobject /*thiz*/, jint state
{
m_activityActive = (state == Qt::ApplicationActive);
- if (!m_androidPlatformIntegration)
+ if (!m_androidPlatformIntegration || !QGuiApplicationPrivate::platformIntegration())
return;
QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState(state));
@@ -762,6 +788,7 @@ static int registerNatives(JNIEnv *env)
jclass clazz;
FIND_AND_CHECK_CLASS("org/qtproject/qt5/android/QtNative");
m_applicationClass = static_cast<jclass>(env->NewGlobalRef(clazz));
+ GET_AND_CHECK_STATIC_METHOD(m_setFullScreenMethodID, m_applicationClass, "setFullScreen", "(Z)V");
if (env->RegisterNatives(m_applicationClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
__android_log_print(ANDROID_LOG_FATAL,"Qt", "RegisterNatives failed");
@@ -770,11 +797,6 @@ static int registerNatives(JNIEnv *env)
GET_AND_CHECK_STATIC_METHOD(m_redrawSurfaceMethodID, m_applicationClass, "redrawSurface", "(IIII)V");
-#ifdef ANDROID_PLUGIN_OPENGL
- FIND_AND_CHECK_CLASS("android/view/Surface");
- GET_AND_CHECK_FIELD(m_surfaceFieldID, clazz, "mNativeSurface", "I");
-#endif
-
jmethodID methodID;
GET_AND_CHECK_STATIC_METHOD(methodID, m_applicationClass, "activity", "()Landroid/app/Activity;");
jobject activityObject = env->CallStaticObjectMethod(m_applicationClass, methodID);
@@ -814,6 +836,15 @@ static int registerNatives(JNIEnv *env)
return JNI_TRUE;
}
+jint androidApiLevel(JNIEnv *env)
+{
+ jclass clazz;
+ FIND_AND_CHECK_CLASS("android/os/Build$VERSION");
+ jfieldID fieldId;
+ GET_AND_CHECK_STATIC_FIELD(fieldId, clazz, "SDK_INT", "I");
+ return env->GetStaticIntField(clazz, fieldId);
+}
+
Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/)
{
typedef union {
@@ -836,11 +867,18 @@ Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/)
|| !QtAndroidInput::registerNatives(env)
|| !QtAndroidClipboard::registerNatives(env)
|| !QtAndroidMenu::registerNatives(env)
- || !QtAndroidAccessibility::registerNatives(env)) {
+ || !QtAndroidAccessibility::registerNatives(env)
+ || !QtAndroidDialogHelpers::registerNatives(env)) {
__android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed");
return -1;
}
+ jint apiLevel = androidApiLevel(env);
+ if (apiLevel >= 16 && !QtAndroidAccessibility::registerNatives(env)) {
+ __android_log_print(ANDROID_LOG_FATAL, "Qt A11y", "registerNatives failed");
+ return -1;
+ }
+
m_javaVM = vm;
return JNI_VERSION_1_4;
}
diff --git a/src/plugins/platforms/android/src/androidjnimain.h b/src/plugins/platforms/android/src/androidjnimain.h
index 9a3d8a9607..11d3573404 100644
--- a/src/plugins/platforms/android/src/androidjnimain.h
+++ b/src/plugins/platforms/android/src/androidjnimain.h
@@ -69,13 +69,10 @@ namespace QtAndroid
void setAndroidPlatformIntegration(QAndroidPlatformIntegration *androidPlatformIntegration);
void setQtThread(QThread *thread);
- void setFullScreen(QWidget *widget);
-
#ifndef ANDROID_PLUGIN_OPENGL
void flushImage(const QPoint &pos, const QImage &image, const QRect &rect);
#else
EGLNativeWindowType nativeWindow(bool waitToCreate = true);
- QSize nativeWindowSize();
#endif
QWindow *topLevelWindowAt(const QPoint &globalPos);
@@ -90,6 +87,9 @@ namespace QtAndroid
void setApplicationActive();
+ void showStatusBar();
+ void hideStatusBar();
+
jobject createBitmap(QImage img, JNIEnv *env = 0);
jobject createBitmapDrawable(jobject bitmap, JNIEnv *env = 0);
diff --git a/src/plugins/platforms/android/src/androidjnimenu.cpp b/src/plugins/platforms/android/src/androidjnimenu.cpp
index bb180347c1..293af2b9cd 100644
--- a/src/plugins/platforms/android/src/androidjnimenu.cpp
+++ b/src/plugins/platforms/android/src/androidjnimenu.cpp
@@ -41,13 +41,14 @@
#include "androidjnimenu.h"
#include "androidjnimain.h"
-#include <qmutex.h>
-#include <qset.h>
-#include <qqueue.h>
-#include <android/log.h>
#include "qandroidplatformmenubar.h"
#include "qandroidplatformmenu.h"
-#include <qandroidplatformmenuitem.h>
+#include "qandroidplatformmenuitem.h"
+
+#include <QMutex>
+#include <QSet>
+#include <QQueue>
+#include <QWindow>
using namespace QtAndroid;
@@ -141,18 +142,17 @@ namespace QtAndroidMenu
void setActiveTopLevelWindow(QWindow *window)
{
+ Qt::WindowFlags flags = window ? window->flags() : Qt::WindowFlags();
+ bool isNonRegularWindow = flags & (Qt::Desktop | Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window;
+ if (isNonRegularWindow)
+ return;
+
QMutexLocker lock(&menuBarMutex);
if (activeTopLevelWindow == window)
return;
visibleMenuBar = 0;
activeTopLevelWindow = window;
-#ifdef ANDROID_PLUGIN_OPENGL
- //only one toplevel window, so the menu bar always belongs to us
- if (menuBars.size() == 1) {
- visibleMenuBar = *menuBars.constBegin(); //since QSet doesn't have first()
- } else
-#endif
foreach (QAndroidPlatformMenuBar *menuBar, menuBars) {
if (menuBar->parentWindow() == window) {
visibleMenuBar = menuBar;
@@ -173,8 +173,10 @@ namespace QtAndroidMenu
{
QMutexLocker lock(&menuBarMutex);
menuBars.remove(menuBar);
- if (visibleMenuBar == menuBar)
+ if (visibleMenuBar == menuBar) {
+ visibleMenuBar = 0;
resetMenuBar();
+ }
}
static QString removeAmpersandEscapes(QString s)
@@ -197,16 +199,18 @@ namespace QtAndroidMenu
env->CallObjectMethod(menuItem, setCheckedMenuItemMethodID, checked);
env->CallObjectMethod(menuItem, setEnabledMenuItemMethodID, enabled);
- if (!icon.isNull()) {
+ if (!icon.isNull()) { // isNull() only checks the d pointer, not the actual image data.
int sz = qMax(36, qgetenv("QT_ANDROID_APP_ICON_SIZE").toInt());
QImage img = icon.pixmap(QSize(sz,sz),
enabled
? QIcon::Normal
: QIcon::Disabled,
QIcon::On).toImage();
- env->CallObjectMethod(menuItem,
- setIconMenuItemMethodID,
- createBitmapDrawable(createBitmap(img, env), env));
+ if (!img.isNull()) { // Make sure we have a valid image.
+ env->CallObjectMethod(menuItem,
+ setIconMenuItemMethodID,
+ createBitmapDrawable(createBitmap(img, env), env));
+ }
}
env->CallObjectMethod(menuItem, setVisibleMenuItemMethodID, visible);
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp b/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp
index 9d6d4003f7..6431914812 100644
--- a/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp
+++ b/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp
@@ -71,6 +71,8 @@ void QAndroidOpenGLContext::swapBuffers(QPlatformSurface *surface)
if (size.isValid()) {
QRect geometry(QPoint(0, 0), size);
window->setGeometry(geometry);
+ QWindowSystemInterface::handleGeometryChange(window->window(), geometry);
+ QWindowSystemInterface::handleExposeEvent(window->window(), QRegion(geometry));
window->scheduleResize(QSize());
}
window->unlock();
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.cpp b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.cpp
new file mode 100644
index 0000000000..de4075feff
--- /dev/null
+++ b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidopenglplatformscreen.h"
+#include "qandroidopenglplatformwindow.h"
+#include "androidjnimenu.h"
+
+QT_BEGIN_NAMESPACE
+
+QAndroidOpenGLPlatformScreen::QAndroidOpenGLPlatformScreen(EGLDisplay display)
+ : QEglFSScreen(display)
+{
+}
+
+void QAndroidOpenGLPlatformScreen::topWindowChanged(QPlatformWindow *window)
+{
+ QtAndroidMenu::setActiveTopLevelWindow(window->window());
+ QAndroidOpenGLPlatformWindow *platformWindow = static_cast<QAndroidOpenGLPlatformWindow *>(window);
+ if (platformWindow != 0)
+ platformWindow->updateStatusBarVisibility();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.h b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.h
new file mode 100644
index 0000000000..e9251592aa
--- /dev/null
+++ b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDOPENGLPLATFORMSCREEN_H
+#define QANDROIDOPENGLPLATFORMSCREEN_H
+
+#include "qeglfsscreen.h"
+
+QT_BEGIN_NAMESPACE
+
+class QAndroidOpenGLPlatformScreen : public QEglFSScreen
+{
+public:
+ QAndroidOpenGLPlatformScreen(EGLDisplay display);
+
+protected:
+ void topWindowChanged(QPlatformWindow *window);
+};
+
+QT_END_NAMESPACE
+
+#endif // QANDROIDOPENGLPLATFORMSCREEN_H
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp
index 4934047af9..6ed805174b 100644
--- a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp
+++ b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp
@@ -41,6 +41,7 @@
#include "qandroidopenglplatformwindow.h"
#include "androidjnimain.h"
+#include "qandroidplatformintegration.h"
#include <qpa/qwindowsysteminterface.h>
QT_BEGIN_NAMESPACE
@@ -52,6 +53,7 @@ QBasicAtomicInt QAndroidOpenGLPlatformWindow::m_referenceCount = Q_BASIC_ATOMIC_
QAndroidOpenGLPlatformWindow::QAndroidOpenGLPlatformWindow(QWindow *window)
: QEglFSWindow(window)
+ , m_state(Qt::WindowNoState)
{
}
@@ -110,7 +112,9 @@ void QAndroidOpenGLPlatformWindow::resetSurface()
{
lock();
- scheduleResize(QtAndroid::nativeWindowSize());
+ // Use the desktop size.
+ // On some devices, the getters for the native window size gives wrong values
+ scheduleResize(QAndroidPlatformIntegration::defaultDesktopSize());
QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); // Expose event
unlock();
}
@@ -128,12 +132,38 @@ void QAndroidOpenGLPlatformWindow::destroy()
}
}
+void QAndroidOpenGLPlatformWindow::updateStatusBarVisibility()
+{
+ Qt::WindowFlags flags = window()->flags();
+ bool isNonRegularWindow = flags & (Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window;
+ if (!isNonRegularWindow) {
+ if (m_state & Qt::WindowFullScreen)
+ QtAndroid::hideStatusBar();
+ else if (m_state & Qt::WindowMaximized)
+ QtAndroid::showStatusBar();
+ }
+}
+
void QAndroidOpenGLPlatformWindow::raise()
{
+ updateStatusBarVisibility();
+}
+
+void QAndroidOpenGLPlatformWindow::setWindowState(Qt::WindowState state)
+{
+ if (m_state == state)
+ return;
+
+ m_state = state;
+ if (window()->isVisible())
+ updateStatusBarVisibility();
}
void QAndroidOpenGLPlatformWindow::setVisible(bool visible)
{
+ if (visible)
+ updateStatusBarVisibility();
+
QEglFSWindow::setVisible(visible);
// The Android Activity is activated before Qt is initialized, causing the application state to
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h
index 9a25957ccd..e4ff0444d4 100644
--- a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h
+++ b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h
@@ -66,16 +66,19 @@ public:
void invalidateSurface();
void resetSurface();
+ void setWindowState(Qt::WindowState state);
void setVisible(bool visible);
void destroy();
static void updateStaticNativeWindow();
+ void updateStatusBarVisibility();
private:
QSize m_scheduledResize;
QMutex m_lock;
+ Qt::WindowState m_state;
static QReadWriteLock m_staticSurfaceLock;
static EGLSurface m_staticSurface;
diff --git a/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp b/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp
index 338966eb40..278cd553f4 100644
--- a/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp
+++ b/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp
@@ -82,7 +82,7 @@ EGLNativeDisplayType QEglFSAndroidHooks::platformDisplay() const
QSize QEglFSAndroidHooks::screenSize() const
{
- return QtAndroid::nativeWindowSize();
+ return QAndroidPlatformIntegration::defaultDesktopSize();
}
QSizeF QEglFSAndroidHooks::physicalScreenSize() const
@@ -120,7 +120,8 @@ EGLNativeWindowType QEglFSAndroidHooks::createNativeWindow(QPlatformWindow *plat
void QEglFSAndroidHooks::destroyNativeWindow(EGLNativeWindowType window)
{
- ANativeWindow_release(window);
+ if (window != 0)
+ ANativeWindow_release(window);
}
bool QEglFSAndroidHooks::hasCapability(QPlatformIntegration::Capability capability) const
diff --git a/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.cpp b/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.cpp
index f3cb2586cc..95844fc649 100644
--- a/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.cpp
+++ b/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.cpp
@@ -43,20 +43,32 @@
#include "androidjnimain.h"
#include <QCoreApplication>
+#include <QVector>
+
+typedef QVector<QString> FilesList;
+
+struct AndroidAssetDir
+{
+ AndroidAssetDir(AAssetDir* ad)
+ {
+ const char *fileName;
+ while ((fileName = AAssetDir_getNextFileName(ad)))
+ m_items.push_back(QString::fromUtf8(fileName));
+ AAssetDir_close(ad);
+ }
+ FilesList m_items;
+};
class AndroidAbstractFileEngineIterator: public QAbstractFileEngineIterator
{
public:
AndroidAbstractFileEngineIterator(QDir::Filters filters,
const QStringList &nameFilters,
- AAssetDir *asset,
+ QSharedPointer<AndroidAssetDir> asset,
const QString &path)
: QAbstractFileEngineIterator(filters, nameFilters)
{
- AAssetDir_rewind(asset);
- const char *fileName;
- while ((fileName = AAssetDir_getNextFileName(asset)))
- m_items << fileName;
+ m_items = asset->m_items;
m_index = -1;
m_path = path;
}
@@ -93,7 +105,7 @@ public:
private:
QString m_path;
- QStringList m_items;
+ FilesList m_items;
int m_index;
};
@@ -102,12 +114,11 @@ class AndroidAbstractFileEngine: public QAbstractFileEngine
public:
explicit AndroidAbstractFileEngine(AAsset *asset, const QString &fileName)
{
- m_assetDir = 0;
m_assetFile = asset;
m_fileName = fileName;
}
- explicit AndroidAbstractFileEngine(AAssetDir *asset, const QString &fileName)
+ explicit AndroidAbstractFileEngine(QSharedPointer<AndroidAssetDir> asset, const QString &fileName)
{
m_assetFile = 0;
m_assetDir = asset;
@@ -119,8 +130,6 @@ public:
~AndroidAbstractFileEngine()
{
close();
- if (m_assetDir)
- AAssetDir_close(m_assetDir);
}
virtual bool open(QIODevice::OpenMode openMode)
@@ -188,7 +197,7 @@ public:
FileFlags flags(ReadOwnerPerm|ReadUserPerm|ReadGroupPerm|ReadOtherPerm|ExistsFlag);
if (m_assetFile)
flags |= FileType;
- if (m_assetDir)
+ if (!m_assetDir.isNull())
flags |= DirectoryType;
return type & flags;
@@ -233,19 +242,19 @@ public:
virtual Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames)
{
- if (m_assetDir)
+ if (!m_assetDir.isNull())
return new AndroidAbstractFileEngineIterator(filters, filterNames, m_assetDir, m_fileName);
return 0;
}
private:
AAsset *m_assetFile;
- AAssetDir *m_assetDir;
+ QSharedPointer<AndroidAssetDir> m_assetDir;
QString m_fileName;
};
-AndroidAssetsFileEngineHandler::AndroidAssetsFileEngineHandler()
+AndroidAssetsFileEngineHandler::AndroidAssetsFileEngineHandler():m_assetsCache(std::max(5, qgetenv("QT_ANDROID_MAX_ASSETS_CACHE_SIZE").toInt()))
{
m_assetManager = QtAndroid::assetManager();
}
@@ -264,25 +273,37 @@ QAbstractFileEngine * AndroidAssetsFileEngineHandler::create(const QString &file
int prefixSize=8;
- m_path.clear();
+ QByteArray path;
if (!fileName.endsWith(QLatin1Char('/'))) {
- m_path = fileName.toUtf8();
+ path = fileName.toUtf8();
AAsset *asset = AAssetManager_open(m_assetManager,
- m_path.constData() + prefixSize,
+ path.constData() + prefixSize,
AASSET_MODE_BUFFER);
if (asset)
return new AndroidAbstractFileEngine(asset, fileName);
}
- if (!m_path.size())
- m_path = fileName.left(fileName.length() - 1).toUtf8();
-
- AAssetDir *assetDir = AAssetManager_openDir(m_assetManager, m_path.constData() + prefixSize);
- if (assetDir) {
- if (AAssetDir_getNextFileName(assetDir))
- return new AndroidAbstractFileEngine(assetDir, fileName);
- else
- AAssetDir_close(assetDir);
+ if (!path.size())
+ path = fileName.left(fileName.length() - 1).toUtf8();
+
+ m_assetsCacheMutext.lock();
+ QSharedPointer<AndroidAssetDir> *aad = m_assetsCache.object(path);
+ m_assetsCacheMutext.unlock();
+ if (!aad) {
+ AAssetDir *assetDir = AAssetManager_openDir(m_assetManager, path.constData() + prefixSize);
+ if (assetDir) {
+ if (AAssetDir_getNextFileName(assetDir)) {
+ aad = new QSharedPointer<AndroidAssetDir>(new AndroidAssetDir(assetDir));
+ m_assetsCacheMutext.lock();
+ m_assetsCache.insert(path, aad);
+ m_assetsCacheMutext.unlock();
+ return new AndroidAbstractFileEngine(*aad, fileName);
+ } else {
+ AAssetDir_close(assetDir);
+ }
+ }
+ } else {
+ return new AndroidAbstractFileEngine(*aad, fileName);
}
return 0;
}
diff --git a/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.h b/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.h
index 9bff6a012e..7bd560886c 100644
--- a/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.h
+++ b/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.h
@@ -43,8 +43,13 @@
#define QANDROIDASSETSFILEENGINEHANDLER_H
#include <QtCore/private/qabstractfileengine_p.h>
+#include <QCache>
+#include <QMutex>
+#include <QSharedPointer>
+
#include <android/asset_manager.h>
+struct AndroidAssetDir;
class AndroidAssetsFileEngineHandler: public QAbstractFileEngineHandler
{
public:
@@ -54,7 +59,8 @@ public:
private:
AAssetManager *m_assetManager;
- mutable QByteArray m_path;
+ mutable QCache<QByteArray, QSharedPointer<AndroidAssetDir>> m_assetsCache;
+ mutable QMutex m_assetsCacheMutext;
};
#endif // QANDROIDASSETSFILEENGINEHANDLER_H
diff --git a/src/plugins/platforms/android/src/qandroidinputcontext.cpp b/src/plugins/platforms/android/src/qandroidinputcontext.cpp
index 386c8e006a..8556e8ebf1 100644
--- a/src/plugins/platforms/android/src/qandroidinputcontext.cpp
+++ b/src/plugins/platforms/android/src/qandroidinputcontext.cpp
@@ -381,6 +381,11 @@ QAndroidInputContext::~QAndroidInputContext()
m_textFieldID = 0;
}
+QAndroidInputContext *QAndroidInputContext::androidInputContext()
+{
+ return m_androidInputContext;
+}
+
void QAndroidInputContext::reset()
{
clear();
diff --git a/src/plugins/platforms/android/src/qandroidinputcontext.h b/src/plugins/platforms/android/src/qandroidinputcontext.h
index d19dcc384b..041bd0dc49 100644
--- a/src/plugins/platforms/android/src/qandroidinputcontext.h
+++ b/src/plugins/platforms/android/src/qandroidinputcontext.h
@@ -80,6 +80,7 @@ public:
public:
QAndroidInputContext();
~QAndroidInputContext();
+ static QAndroidInputContext * androidInputContext();
bool isValid() const { return true; }
void reset();
diff --git a/src/plugins/platforms/android/src/qandroidplatformdialoghelpers.cpp b/src/plugins/platforms/android/src/qandroidplatformdialoghelpers.cpp
new file mode 100644
index 0000000000..f379402e18
--- /dev/null
+++ b/src/plugins/platforms/android/src/qandroidplatformdialoghelpers.cpp
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtWidgets/QApplication>
+#include <QtWidgets/QStyle>
+#include "qandroidplatformdialoghelpers.h"
+#include "androidjnimain.h"
+
+namespace QtAndroidDialogHelpers {
+static jclass g_messageDialogHelperClass = 0;
+
+QAndroidPlatformMessageDialogHelper::QAndroidPlatformMessageDialogHelper()
+ :m_buttonId(-1)
+ ,m_javaMessageDialog(g_messageDialogHelperClass, "(Landroid/app/Activity;)V", QtAndroid::activity())
+ ,m_shown(false)
+{
+}
+
+void QAndroidPlatformMessageDialogHelper::exec()
+{
+ if (!m_shown)
+ show(Qt::Dialog, Qt::ApplicationModal, 0);
+ m_loop.exec();
+}
+
+static QString standardButtonText(int sbutton)
+{
+ switch (sbutton) {
+ case QMessageDialogOptions::Ok:
+ return QAndroidPlatformMessageDialogHelper::tr("OK");
+ case QMessageDialogOptions::Save:
+ return QAndroidPlatformMessageDialogHelper::tr("Save");
+ case QMessageDialogOptions::Open:
+ return QAndroidPlatformMessageDialogHelper::tr("Open");
+ case QMessageDialogOptions::Cancel:
+ return QAndroidPlatformMessageDialogHelper::tr("Cancel");
+ case QMessageDialogOptions::Close:
+ return QAndroidPlatformMessageDialogHelper::tr("Close");
+ case QMessageDialogOptions::Apply:
+ return QAndroidPlatformMessageDialogHelper::tr("Apply");
+ case QMessageDialogOptions::Reset:
+ return QAndroidPlatformMessageDialogHelper::tr("Reset");
+ case QMessageDialogOptions::Help:
+ return QAndroidPlatformMessageDialogHelper::tr("Help");
+ case QMessageDialogOptions::Discard:
+ return QAndroidPlatformMessageDialogHelper::tr("Discard");
+ case QMessageDialogOptions::Yes:
+ return QAndroidPlatformMessageDialogHelper::tr("Yes");
+ case QMessageDialogOptions::YesToAll:
+ return QAndroidPlatformMessageDialogHelper::tr("Yes to All");
+ case QMessageDialogOptions::No:
+ return QAndroidPlatformMessageDialogHelper::tr("No");
+ case QMessageDialogOptions::NoToAll:
+ return QAndroidPlatformMessageDialogHelper::tr("No to All");
+ case QMessageDialogOptions::SaveAll:
+ return QAndroidPlatformMessageDialogHelper::tr("Save All");
+ case QMessageDialogOptions::Abort:
+ return QAndroidPlatformMessageDialogHelper::tr("Abort");
+ case QMessageDialogOptions::Retry:
+ return QAndroidPlatformMessageDialogHelper::tr("Retry");
+ case QMessageDialogOptions::Ignore:
+ return QAndroidPlatformMessageDialogHelper::tr("Ignore");
+ case QMessageDialogOptions::RestoreDefaults:
+ return QAndroidPlatformMessageDialogHelper::tr("Restore Defaults");
+ } // switch
+ return QString();
+}
+
+bool QAndroidPlatformMessageDialogHelper::show(Qt::WindowFlags windowFlags
+ , Qt::WindowModality windowModality
+ , QWindow *parent)
+{
+ Q_UNUSED(windowFlags)
+ Q_UNUSED(windowModality)
+ Q_UNUSED(parent)
+ QSharedPointer<QMessageDialogOptions> opt = options();
+ if (!opt.data())
+ return false;
+
+ m_javaMessageDialog.callMethod<void>("setIcon", "(I)V", opt->icon());
+
+ QString str = opt->windowTitle();
+ if (!str.isEmpty())
+ m_javaMessageDialog.callMethod<void>("setTile", "(Ljava/lang/String;)V", QJNIObjectPrivate::fromString(str).object());
+
+ str = opt->text();
+ if (!str.isEmpty())
+ m_javaMessageDialog.callMethod<void>("setText", "(Ljava/lang/String;)V", QJNIObjectPrivate::fromString(str).object());
+
+ str = opt->informativeText();
+ if (!str.isEmpty())
+ m_javaMessageDialog.callMethod<void>("setInformativeText", "(Ljava/lang/String;)V", QJNIObjectPrivate::fromString(str).object());
+
+ str = opt->detailedText();
+ if (!str.isEmpty())
+ m_javaMessageDialog.callMethod<void>("setDetailedText", "(Ljava/lang/String;)V", QJNIObjectPrivate::fromString(str).object());
+
+ for (int i = QMessageDialogOptions::FirstButton; i < QMessageDialogOptions::LastButton; i<<=1) {
+ if ( opt->standardButtons() & i )
+ m_javaMessageDialog.callMethod<void>("addButton", "(ILjava/lang/String;)V", i, QJNIObjectPrivate::fromString(standardButtonText(i)).object());
+ }
+
+ m_javaMessageDialog.callMethod<void>("show", "(J)V", jlong(static_cast<QObject*>(this)));
+ m_shown = true;
+ return true;
+}
+
+void QAndroidPlatformMessageDialogHelper::hide()
+{
+ m_javaMessageDialog.callMethod<void>("hide", "()V");
+ m_shown = false;
+}
+
+void QAndroidPlatformMessageDialogHelper::dialogResult(int buttonID)
+{
+ m_buttonId = buttonID;
+ if (m_loop.isRunning())
+ m_loop.exit();
+ if (m_buttonId < 0) {
+ emit reject();
+ return;
+ }
+
+ QMessageDialogOptions::StandardButton standardButton = static_cast<QMessageDialogOptions::StandardButton>(buttonID);
+ QMessageDialogOptions::ButtonRole role = QMessageDialogOptions::buttonRole(standardButton);
+ emit clicked(standardButton, role);
+}
+
+static void dialogResult(JNIEnv * /*env*/, jobject /*thiz*/, jlong handler, int buttonID)
+{
+ QObject *object = reinterpret_cast<QObject *>(handler);
+ QMetaObject::invokeMethod(object, "dialogResult", Qt::QueuedConnection, Q_ARG(int, buttonID));
+}
+
+static JNINativeMethod methods[] = {
+ {"dialogResult", "(JI)V", (void *)dialogResult}
+};
+
+
+#define FIND_AND_CHECK_CLASS(CLASS_NAME) \
+ clazz = env->FindClass(CLASS_NAME); \
+ if (!clazz) { \
+ __android_log_print(ANDROID_LOG_FATAL, QtAndroid::qtTagText(), QtAndroid::classErrorMsgFmt(), CLASS_NAME); \
+ return false; \
+ }
+
+bool registerNatives(JNIEnv *env)
+{
+ jclass clazz = QtAndroid::findClass("org/qtproject/qt5/android/QtMessageDialogHelper", env);
+ if (!clazz) {
+ __android_log_print(ANDROID_LOG_FATAL, QtAndroid::qtTagText(), QtAndroid::classErrorMsgFmt()
+ , "org/qtproject/qt5/android/QtMessageDialogHelper");
+ return false;
+ }
+ g_messageDialogHelperClass = static_cast<jclass>(env->NewGlobalRef(clazz));
+ FIND_AND_CHECK_CLASS("org/qtproject/qt5/android/QtNativeDialogHelper");
+ jclass appClass = static_cast<jclass>(env->NewGlobalRef(clazz));
+
+ if (env->RegisterNatives(appClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
+ __android_log_print(ANDROID_LOG_FATAL, "Qt", "RegisterNatives failed");
+ return false;
+ }
+
+ return true;
+}
+}
diff --git a/src/plugins/platforms/android/src/qandroidplatformdialoghelpers.h b/src/plugins/platforms/android/src/qandroidplatformdialoghelpers.h
new file mode 100644
index 0000000000..88ec91d936
--- /dev/null
+++ b/src/plugins/platforms/android/src/qandroidplatformdialoghelpers.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDPLATFORMDIALOGHELPERS_H
+#define QANDROIDPLATFORMDIALOGHELPERS_H
+#include <jni.h>
+#include <qpa/qplatformdialoghelper.h>
+#include <QEventLoop>
+#include <private/qjni_p.h>
+
+namespace QtAndroidDialogHelpers {
+
+class QAndroidPlatformMessageDialogHelper: public QPlatformMessageDialogHelper
+{
+ Q_OBJECT
+public:
+ QAndroidPlatformMessageDialogHelper();
+ void exec();
+ bool show(Qt::WindowFlags windowFlags,
+ Qt::WindowModality windowModality,
+ QWindow *parent);
+ void hide();
+
+public slots:
+ void dialogResult(int buttonID);
+
+private:
+ int m_buttonId;
+ QEventLoop m_loop;
+ QJNIObjectPrivate m_javaMessageDialog;
+ bool m_shown;
+};
+
+
+bool registerNatives(JNIEnv *env);
+
+}
+
+#endif // QANDROIDPLATFORMDIALOGHELPERS_H
diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp
index a3db421de9..ae3e257d3c 100644
--- a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp
+++ b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp
@@ -61,6 +61,7 @@
# include "androidjnimenu.h"
# include "qandroidopenglcontext.h"
# include "qandroidopenglplatformwindow.h"
+# include "qandroidopenglplatformscreen.h"
# include "qeglfshooks.h"
# include <QtGui/qopenglcontext.h>
#endif
@@ -123,7 +124,6 @@ bool QAndroidPlatformIntegration::hasCapability(Capability cap) const
switch (cap) {
case ThreadedPixmaps: return true;
case ApplicationState: return true;
- case NonFullScreenWindows: return false;
case NativeWidgets: return false;
default:
#ifndef ANDROID_PLUGIN_OPENGL
@@ -142,7 +142,10 @@ QPlatformBackingStore *QAndroidPlatformIntegration::createPlatformBackingStore(Q
QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *window) const
{
- return new QAndroidPlatformWindow(window);
+ QAndroidPlatformWindow *platformWindow = new QAndroidPlatformWindow(window);
+ platformWindow->setWindowState(window->windowState());
+
+ return platformWindow;
}
QAbstractEventDispatcher *QAndroidPlatformIntegration::createEventDispatcher() const
@@ -155,6 +158,7 @@ QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *wind
QAndroidOpenGLPlatformWindow *platformWindow = new QAndroidOpenGLPlatformWindow(window);
platformWindow->create();
platformWindow->requestActivateWindow();
+ platformWindow->setWindowState(window->windowState());
QtAndroidMenu::setActiveTopLevelWindow(window);
return platformWindow;
@@ -231,13 +235,22 @@ QPlatformServices *QAndroidPlatformIntegration::services() const
QVariant QAndroidPlatformIntegration::styleHint(StyleHint hint) const
{
switch (hint) {
- case ShowIsFullScreen:
+ case ShowIsMaximized:
return true;
default:
return QPlatformIntegration::styleHint(hint);
}
}
+Qt::WindowState QAndroidPlatformIntegration::defaultWindowState(Qt::WindowFlags flags) const
+{
+ // Don't maximize dialogs on Android
+ if (flags & Qt::Dialog & ~Qt::Window)
+ return Qt::WindowNoState;
+
+ return QPlatformIntegration::defaultWindowState(flags);
+}
+
static const QLatin1String androidThemeName("android");
QStringList QAndroidPlatformIntegration::themeNames() const
{
@@ -308,6 +321,11 @@ void QAndroidPlatformIntegration::setDisplayMetrics(int width, int height)
m_defaultPhysicalSizeHeight = height;
}
+QEglFSScreen *QAndroidPlatformIntegration::createScreen() const
+{
+ return new QAndroidOpenGLPlatformScreen(display());
+}
+
#endif
void QAndroidPlatformIntegration::pauseApp()
diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.h b/src/plugins/platforms/android/src/qandroidplatformintegration.h
index 5ebdf9e65c..bd08ad694c 100644
--- a/src/plugins/platforms/android/src/qandroidplatformintegration.h
+++ b/src/plugins/platforms/android/src/qandroidplatformintegration.h
@@ -121,6 +121,7 @@ public:
#endif
QVariant styleHint(StyleHint hint) const;
+ Qt::WindowState defaultWindowState(Qt::WindowFlags flags) const Q_DECL_OVERRIDE;
QStringList themeNames() const;
QPlatformTheme *createPlatformTheme(const QString &name) const;
@@ -140,6 +141,10 @@ public:
QTouchDevice *touchDevice() const { return m_touchDevice; }
void setTouchDevice(QTouchDevice *touchDevice) { m_touchDevice = touchDevice; }
+#ifdef ANDROID_PLUGIN_OPENGL
+ QEglFSScreen *createScreen() const;
+#endif
+
private:
friend class QEglFSAndroidHooks;
diff --git a/src/plugins/platforms/android/src/qandroidplatformmenu.cpp b/src/plugins/platforms/android/src/qandroidplatformmenu.cpp
index 253c22a12f..1ecabb25e2 100644
--- a/src/plugins/platforms/android/src/qandroidplatformmenu.cpp
+++ b/src/plugins/platforms/android/src/qandroidplatformmenu.cpp
@@ -141,6 +141,15 @@ bool QAndroidPlatformMenu::isVisible() const
return m_isVisible;
}
+void QAndroidPlatformMenu::showPopup(const QWindow *parentWindow, QPoint pos, const QPlatformMenuItem *item)
+{
+ Q_UNUSED(parentWindow);
+ Q_UNUSED(pos);
+ Q_UNUSED(item);
+ setVisible(true);
+ QtAndroidMenu::showContextMenu(this);
+}
+
QPlatformMenuItem *QAndroidPlatformMenu::menuItemAt(int position) const
{
if (position < m_menuItems.size())
@@ -154,7 +163,6 @@ QPlatformMenuItem *QAndroidPlatformMenu::menuItemForTag(quintptr tag) const
if (menuItem->tag() == tag)
return menuItem;
}
-
return 0;
}
diff --git a/src/plugins/platforms/android/src/qandroidplatformmenu.h b/src/plugins/platforms/android/src/qandroidplatformmenu.h
index 20236cb636..305b64168a 100644
--- a/src/plugins/platforms/android/src/qandroidplatformmenu.h
+++ b/src/plugins/platforms/android/src/qandroidplatformmenu.h
@@ -71,6 +71,7 @@ public:
bool isEnabled() const;
void setVisible(bool visible);
bool isVisible() const;
+ void showPopup(const QWindow *parentWindow, QPoint pos, const QPlatformMenuItem *item);
QPlatformMenuItem *menuItemAt(int position) const;
QPlatformMenuItem *menuItemForTag(quintptr tag) const;
diff --git a/src/plugins/platforms/android/src/qandroidplatformmenubar.cpp b/src/plugins/platforms/android/src/qandroidplatformmenubar.cpp
index ef1ac61356..134062fb32 100644
--- a/src/plugins/platforms/android/src/qandroidplatformmenubar.cpp
+++ b/src/plugins/platforms/android/src/qandroidplatformmenubar.cpp
@@ -79,6 +79,8 @@ void QAndroidPlatformMenuBar::syncMenu(QPlatformMenu *menu)
void QAndroidPlatformMenuBar::handleReparent(QWindow *newParentWindow)
{
+ if (m_parentWindow == newParentWindow)
+ return;
m_parentWindow = newParentWindow;
QtAndroidMenu::setMenuBar(this, newParentWindow);
}
diff --git a/src/plugins/platforms/android/src/qandroidplatformtheme.cpp b/src/plugins/platforms/android/src/qandroidplatformtheme.cpp
index 79fbc440fc..308bb70faf 100644
--- a/src/plugins/platforms/android/src/qandroidplatformtheme.cpp
+++ b/src/plugins/platforms/android/src/qandroidplatformtheme.cpp
@@ -43,6 +43,7 @@
#include "qandroidplatformmenubar.h"
#include "qandroidplatformmenu.h"
#include "qandroidplatformmenuitem.h"
+#include "qandroidplatformdialoghelpers.h"
#include <QVariant>
#include <QFileInfo>
#include <qandroidplatformintegration.h>
@@ -124,7 +125,7 @@ const QFont *QAndroidPlatformTheme::font(Font type) const
return &(it.value());
// default in case the style has not set a font
- static QFont systemFont("Roboto", 12.0 * 100 / 72); // keep default size the same after changing from 100 dpi to 72 dpi
+ static QFont systemFont("Roboto", 14.0 * 100 / 72); // keep default size the same after changing from 100 dpi to 72 dpi
if (type == QPlatformTheme::SystemFont)
return &systemFont;
return 0;
@@ -150,3 +151,20 @@ QVariant QAndroidPlatformTheme::themeHint(ThemeHint hint) const
return QPlatformTheme::themeHint(hint);
}
}
+
+bool QAndroidPlatformTheme::usePlatformNativeDialog(QPlatformTheme::DialogType type) const
+{
+ if (type == MessageDialog)
+ return qgetenv("QT_USE_ANDROID_NATIVE_DIALOGS").toInt() == 1;
+ return false;
+}
+
+QPlatformDialogHelper *QAndroidPlatformTheme::createPlatformDialogHelper(QPlatformTheme::DialogType type) const
+{
+ switch (type) {
+ case MessageDialog:
+ return new QtAndroidDialogHelpers::QAndroidPlatformMessageDialogHelper;
+ default:
+ return 0;
+ }
+}
diff --git a/src/plugins/platforms/android/src/qandroidplatformtheme.h b/src/plugins/platforms/android/src/qandroidplatformtheme.h
index 15d2cb2000..ec259a9b0a 100644
--- a/src/plugins/platforms/android/src/qandroidplatformtheme.h
+++ b/src/plugins/platforms/android/src/qandroidplatformtheme.h
@@ -54,6 +54,9 @@ public:
virtual const QPalette *palette(Palette type = SystemPalette) const;
virtual const QFont *font(Font type = SystemFont) const;
virtual QVariant themeHint(ThemeHint hint) const;
+ virtual bool usePlatformNativeDialog(DialogType type) const;
+ virtual QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const;
+
private:
QAndroidPlatformNativeInterface * m_androidPlatformNativeInterface;
diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp b/src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp
index 0250a6122c..2e59c307c3 100644
--- a/src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp
+++ b/src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp
@@ -43,6 +43,7 @@
#include "qandroidplatformintegration.h"
#include "androidjnimain.h"
#include "androidjnimenu.h"
+#include "qandroidplatformwindow.h"
QAndroidPlatformScreen::QAndroidPlatformScreen():QFbScreen()
{
@@ -57,6 +58,12 @@ QAndroidPlatformScreen::QAndroidPlatformScreen():QFbScreen()
void QAndroidPlatformScreen::topWindowChanged(QWindow *w)
{
QtAndroidMenu::setActiveTopLevelWindow(w);
+
+ if (w != 0) {
+ QAndroidPlatformWindow *platformWindow = static_cast<QAndroidPlatformWindow *>(w->handle());
+ if (platformWindow != 0)
+ platformWindow->updateStatusBarVisibility();
+ }
}
QRegion QAndroidPlatformScreen::doRedraw()
diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp
index f5fce0ae34..7ff18526d9 100644
--- a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp
+++ b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp
@@ -44,7 +44,8 @@
#include "androidjnimain.h"
#include <qpa/qwindowsysteminterface.h>
-QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window) : QFbWindow(window)
+QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window)
+ : QFbWindow(window)
{
}
@@ -58,8 +59,40 @@ void QAndroidPlatformWindow::propagateSizeHints()
//shut up warning from default implementation
}
+void QAndroidPlatformWindow::updateStatusBarVisibility()
+{
+ Qt::WindowFlags flags = window()->flags();
+ bool isNonRegularWindow = flags & (Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window;
+ if (!isNonRegularWindow) {
+ if (mWindowState & Qt::WindowFullScreen)
+ QtAndroid::hideStatusBar();
+ else if (mWindowState & Qt::WindowMaximized)
+ QtAndroid::showStatusBar();
+ }
+}
+
+void QAndroidPlatformWindow::raise()
+{
+ updateStatusBarVisibility();
+ QFbWindow::raise();
+}
+
+void QAndroidPlatformWindow::setWindowState(Qt::WindowState state)
+{
+ if (mWindowState == state)
+ return;
+
+ if (window()->isVisible())
+ updateStatusBarVisibility();
+
+ QFbWindow::setWindowState(state);
+}
+
void QAndroidPlatformWindow::setVisible(bool visible)
{
+ if (visible)
+ updateStatusBarVisibility();
+
QFbWindow::setVisible(visible);
// The Android Activity is activated before Qt is initialized, causing the application state to
diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h
index 58e6451ea1..9e3f203201 100644
--- a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h
+++ b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h
@@ -52,11 +52,13 @@ public:
void propagateSizeHints();
+ void raise();
+ void setWindowState(Qt::WindowState state);
void setVisible(bool visible);
+ void updateStatusBarVisibility();
public slots:
void setGeometry(const QRect &rect);
-
};
#endif // ANDROIDPLATFORMWINDOW_H
diff --git a/src/plugins/platforms/android/src/src.pri b/src/plugins/platforms/android/src/src.pri
index 6cc41c3e68..9b64e846f7 100644
--- a/src/plugins/platforms/android/src/src.pri
+++ b/src/plugins/platforms/android/src/src.pri
@@ -21,6 +21,7 @@ SOURCES += $$PWD/androidplatformplugin.cpp \
$$PWD/qandroidinputcontext.cpp \
$$PWD/qandroidplatformaccessibility.cpp \
$$PWD/qandroidplatformfontdatabase.cpp \
+ $$PWD/qandroidplatformdialoghelpers.cpp \
$$PWD/qandroidplatformclipboard.cpp \
$$PWD/qandroidplatformtheme.cpp \
$$PWD/qandroidplatformmenubar.cpp \
@@ -41,6 +42,7 @@ HEADERS += $$PWD/qandroidplatformintegration.h \
$$PWD/qandroidplatformaccessibility.h \
$$PWD/qandroidplatformfontdatabase.h \
$$PWD/qandroidplatformclipboard.h \
+ $$PWD/qandroidplatformdialoghelpers.h \
$$PWD/qandroidplatformtheme.h \
$$PWD/qandroidplatformmenubar.h \
$$PWD/qandroidplatformmenu.h \