summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java19
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtLayout.java46
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp15
-rw-r--r--src/plugins/platforms/android/qandroidplatformscreen.cpp5
-rw-r--r--src/plugins/platforms/android/qandroidplatformscreen.h1
5 files changed, 79 insertions, 7 deletions
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
index f7e97930ae..9f7c040c17 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2017 BogDan Vatra <bogdan@kde.org>
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com>
** Contact: https://www.qt.io/licensing/
**
@@ -676,13 +676,27 @@ public class QtActivityDelegate
@Override
public void onDisplayAdded(int displayId) { }
+ private boolean isSimilarRotation(int r1, int r2)
+ {
+ return (r1 == r2)
+ || (r1 == Surface.ROTATION_0 && r2 == Surface.ROTATION_180)
+ || (r1 == Surface.ROTATION_180 && r2 == Surface.ROTATION_0)
+ || (r1 == Surface.ROTATION_90 && r2 == Surface.ROTATION_270)
+ || (r1 == Surface.ROTATION_270 && r2 == Surface.ROTATION_90);
+ }
+
@Override
public void onDisplayChanged(int displayId) {
Display display = (Build.VERSION.SDK_INT < Build.VERSION_CODES.R)
? m_activity.getWindowManager().getDefaultDisplay()
: m_activity.getDisplay();
m_currentRotation = display.getRotation();
- QtNative.handleOrientationChanged(m_currentRotation, m_nativeOrientation);
+ m_layout.setActivityDisplayRotation(m_currentRotation);
+ // Process orientation change only if it comes after the size
+ // change, or if the screen is rotated by 180 degrees.
+ // Otherwise it will be processed in QtLayout.
+ if (isSimilarRotation(m_currentRotation, m_layout.displayRotation()))
+ QtNative.handleOrientationChanged(m_currentRotation, m_nativeOrientation);
float refreshRate = display.getRefreshRate();
QtNative.handleRefreshRateChanged(refreshRate);
}
@@ -812,6 +826,7 @@ public class QtActivityDelegate
else
m_nativeOrientation = Configuration.ORIENTATION_PORTRAIT;
+ m_layout.setNativeOrientation(m_nativeOrientation);
QtNative.handleOrientationChanged(rotation, m_nativeOrientation);
m_currentRotation = rotation;
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtLayout.java b/src/android/jar/src/org/qtproject/qt5/android/QtLayout.java
index 0d370a51f1..123c5bc248 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtLayout.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtLayout.java
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
** Contact: https://www.qt.io/licensing/
**
@@ -52,6 +52,26 @@ import android.view.ViewGroup;
public class QtLayout extends ViewGroup
{
private Runnable m_startApplicationRunnable;
+
+ private int m_activityDisplayRotation = -1;
+ private int m_ownDisplayRotation = -1;
+ private int m_nativeOrientation = -1;
+
+ public void setActivityDisplayRotation(int rotation)
+ {
+ m_activityDisplayRotation = rotation;
+ }
+
+ public void setNativeOrientation(int orientation)
+ {
+ m_nativeOrientation = orientation;
+ }
+
+ public int displayRotation()
+ {
+ return m_ownDisplayRotation;
+ }
+
public QtLayout(Context context, Runnable startRunnable)
{
super(context);
@@ -76,9 +96,33 @@ public class QtLayout extends ViewGroup
? ((Activity)getContext()).getWindowManager().getDefaultDisplay()
: ((Activity)getContext()).getDisplay();
display.getMetrics(metrics);
+
+ if ((metrics.widthPixels > metrics.heightPixels) != (w > h)) {
+ // This is an intermediate state during display rotation.
+ // The new size is still reported for old orientation, while
+ // metrics contain sizes for new orientation. Setting
+ // such parameters will produce inconsistent results, so
+ // we just skip them.
+ // We will have another onSizeChanged() with normal values
+ // a bit later.
+ return;
+ }
+
QtNative.setApplicationDisplayMetrics(metrics.widthPixels, metrics.heightPixels, w, h,
metrics.xdpi, metrics.ydpi, metrics.scaledDensity,
metrics.density, display.getRefreshRate());
+
+ int newRotation = display.getRotation();
+ if (m_ownDisplayRotation != m_activityDisplayRotation
+ && newRotation == m_activityDisplayRotation) {
+ // If the saved rotation value does not match the one from the
+ // activity, it means that we got orientation change before size
+ // change, and the value was cached. So we need to notify about
+ // orientation change now.
+ QtNative.handleOrientationChanged(newRotation, m_nativeOrientation);
+ }
+ m_ownDisplayRotation = newRotation;
+
if (m_startApplicationRunnable != null) {
m_startApplicationRunnable.run();
m_startApplicationRunnable = null;
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index 2c0469d692..207f94bb58 100644
--- a/src/plugins/platforms/android/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
-** Copyright (C) 2021 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -567,6 +567,9 @@ static void startQtApplication(JNIEnv */*env*/, jclass /*clazz*/)
vm->AttachCurrentThread(&env, &args);
}
+ // Register type for invokeMethod() calls.
+ qRegisterMetaType<Qt::ScreenOrientation>("Qt::ScreenOrientation");
+
// Register resources if they are available
if (QFile{QStringLiteral("assets:/android_rcc_bundle.rcc")}.exists())
QResource::registerResource(QStringLiteral("assets:/android_rcc_bundle.rcc"));
@@ -793,9 +796,13 @@ static void handleOrientationChanged(JNIEnv */*env*/, jobject /*thiz*/, jint new
QAndroidPlatformIntegration::setScreenOrientation(screenOrientation, native);
QMutexLocker lock(&m_platformMutex);
if (m_androidPlatformIntegration) {
- QPlatformScreen *screen = m_androidPlatformIntegration->screen();
- QWindowSystemInterface::handleScreenOrientationChange(screen->screen(),
- screenOrientation);
+ QAndroidPlatformScreen *screen = m_androidPlatformIntegration->screen();
+ // Use invokeMethod to keep the certain order of the "geometry change"
+ // and "orientation change" event handling.
+ if (screen) {
+ QMetaObject::invokeMethod(screen, "setOrientation", Qt::AutoConnection,
+ Q_ARG(Qt::ScreenOrientation, screenOrientation));
+ }
}
}
diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp
index 985b0ea5f4..fd184e6757 100644
--- a/src/plugins/platforms/android/qandroidplatformscreen.cpp
+++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp
@@ -306,6 +306,11 @@ void QAndroidPlatformScreen::setRefreshRate(qreal refreshRate)
QWindowSystemInterface::handleScreenRefreshRateChange(QPlatformScreen::screen(), refreshRate);
}
+void QAndroidPlatformScreen::setOrientation(Qt::ScreenOrientation orientation)
+{
+ QWindowSystemInterface::handleScreenOrientationChange(QPlatformScreen::screen(), orientation);
+}
+
void QAndroidPlatformScreen::setAvailableGeometry(const QRect &rect)
{
QMutexLocker lock(&m_surfaceMutex);
diff --git a/src/plugins/platforms/android/qandroidplatformscreen.h b/src/plugins/platforms/android/qandroidplatformscreen.h
index 755b5f4e45..83d1dffeec 100644
--- a/src/plugins/platforms/android/qandroidplatformscreen.h
+++ b/src/plugins/platforms/android/qandroidplatformscreen.h
@@ -96,6 +96,7 @@ public slots:
void setSizeParameters(const QSize &physicalSize, const QSize &size,
const QRect &availableGeometry);
void setRefreshRate(qreal refreshRate);
+ void setOrientation(Qt::ScreenOrientation orientation);
protected:
bool event(QEvent *event) override;