diff options
Diffstat (limited to 'src')
5 files changed, 77 insertions, 7 deletions
diff --git a/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java index 9a43f85e4d..c6ae62273e 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt/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/ ** @@ -693,13 +693,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); } @@ -831,6 +845,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/qt/android/QtLayout.java b/src/android/jar/src/org/qtproject/qt/android/QtLayout.java index 2e52770cc5..7cb694dacf 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtLayout.java +++ b/src/android/jar/src/org/qtproject/qt/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/ ** @@ -53,6 +53,26 @@ import android.view.WindowInsets; 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); @@ -80,6 +100,17 @@ public class QtLayout extends ViewGroup : ((Activity)getContext()).getDisplay(); display.getRealMetrics(realMetrics); + if ((realMetrics.widthPixels > realMetrics.heightPixels) != (w > h)) { + // This is an intermediate state during display rotation. + // The new size is still reported for old orientation, while + // realMetrics 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; + } + boolean isFullScreenView = h == realMetrics.heightPixels; int insetLeft = isFullScreenView ? insets.getSystemWindowInsetLeft() : 0; @@ -95,6 +126,17 @@ public class QtLayout extends ViewGroup usableAreaWidth, usableAreaHeight, realMetrics.xdpi, realMetrics.ydpi, realMetrics.scaledDensity, realMetrics.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 280cfa2c53..e584e7308f 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. @@ -541,6 +541,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")); @@ -757,9 +760,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 59c8f396af..0ba3c17f88 100644 --- a/src/plugins/platforms/android/qandroidplatformscreen.cpp +++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp @@ -291,6 +291,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 e0de85277a..0f3d02a183 100644 --- a/src/plugins/platforms/android/qandroidplatformscreen.h +++ b/src/plugins/platforms/android/qandroidplatformscreen.h @@ -94,6 +94,7 @@ public slots: void setAvailableGeometry(const QRect &rect); void setSize(const QSize &size); void setRefreshRate(qreal refreshRate); + void setOrientation(Qt::ScreenOrientation orientation); protected: bool event(QEvent *event) override; |