diff --git a/src/android/jar/src/org/qtproject/qt/android/QtDisplayManager.java b/src/android/jar/src/org/qtproject/qt/android/QtDisplayManager.java index 17678a7c758..551385653c7 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtDisplayManager.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtDisplayManager.java @@ -32,8 +32,7 @@ import android.content.res.Resources.Theme; class QtDisplayManager { // screen methods - static native void setDisplayMetrics(int screenWidthPixels, int screenHeightPixels, - int availableWidthPixels, int availableHeightPixels); + static native void handleLayoutSizeChanged(int availableWidth, int availableHeight); static native void handleOrientationChanged(int newRotation, int nativeOrientation); static native void handleRefreshRateChanged(float refreshRate); static native void handleUiDarkModeChanged(int newUiMode); @@ -290,15 +289,6 @@ class QtDisplayManager { } } - static void setApplicationDisplayMetrics(Activity activity, int width, int height) - { - if (activity == null) - return; - - Size displaySize = getDisplaySize(activity, QtDisplayManager.getDisplay(activity)); - setDisplayMetrics(displaySize.getWidth(), displaySize.getHeight(), width, height); - } - @UsedFromNativeCode static float getXDpi(final DisplayMetrics metrics) { if (metrics.xdpi < android.util.DisplayMetrics.DENSITY_LOW) diff --git a/src/android/jar/src/org/qtproject/qt/android/QtEmbeddedDelegate.java b/src/android/jar/src/org/qtproject/qt/android/QtEmbeddedDelegate.java index fbd3162264b..6b48cf5b44b 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtEmbeddedDelegate.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtEmbeddedDelegate.java @@ -113,8 +113,7 @@ class QtEmbeddedDelegate extends QtActivityDelegateBase if (ready) { QtNative.runAction(() -> { DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics(); - QtDisplayManager.setApplicationDisplayMetrics(m_activity, metrics.widthPixels, - metrics.heightPixels); + QtDisplayManager.handleLayoutSizeChanged(metrics.widthPixels, metrics.heightPixels); }); } } diff --git a/src/android/jar/src/org/qtproject/qt/android/QtRootLayout.java b/src/android/jar/src/org/qtproject/qt/android/QtRootLayout.java index 71fb750b9e9..761c5fbea20 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtRootLayout.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtRootLayout.java @@ -23,10 +23,10 @@ class QtRootLayout extends QtLayout protected void onSizeChanged(int w, int h, int oldw, int oldh) { Activity activity = (Activity) getContext(); - if (activity == null) + if (activity == null || (w == oldw && h == oldh)) return; - QtDisplayManager.setApplicationDisplayMetrics(activity, w, h); + QtDisplayManager.handleLayoutSizeChanged(w, h); } @Override diff --git a/src/android/jar/src/org/qtproject/qt/android/QtServiceEmbeddedDelegate.java b/src/android/jar/src/org/qtproject/qt/android/QtServiceEmbeddedDelegate.java index 08e098c6188..52ca1d92709 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtServiceEmbeddedDelegate.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtServiceEmbeddedDelegate.java @@ -40,7 +40,7 @@ class QtServiceEmbeddedDelegate implements QtEmbeddedViewInterface, QtNative.App final int maxWidth = metrics.widthPixels; final int maxHeight = metrics.heightPixels; - QtDisplayManager.setDisplayMetrics(maxWidth, maxHeight, maxWidth, maxHeight); + QtDisplayManager.handleLayoutSizeChanged(maxWidth, maxHeight); QtDisplayManager.updateRefreshRate(m_service); QtDisplayManager.handleScreenDensityChanged(metrics.density); diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index f2c317ad1bf..ab42b62d04f 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -565,24 +565,24 @@ static void terminateQt(JNIEnv *env, jclass /*clazz*/) sem_post(&m_exitSemaphore); } -static void setDisplayMetrics(JNIEnv * /*env*/, jclass /*clazz*/, - jint screenWidthPixels, jint screenHeightPixels, - jint availableWidthPixels, jint availableHeightPixels) +static void handleLayoutSizeChanged(JNIEnv * /*env*/, jclass /*clazz*/, + jint availableWidth, jint availableHeight) { - m_availableWidthPixels = availableWidthPixels; - m_availableHeightPixels = availableHeightPixels; + if (m_availableWidthPixels == availableWidth && m_availableHeightPixels == availableHeight) + return; - const QSize screenSize(screenWidthPixels, screenHeightPixels); - // available geometry always starts from top left - const QRect availableGeometry(0, 0, availableWidthPixels, availableHeightPixels); + m_availableWidthPixels = availableWidth; + m_availableHeightPixels = availableHeight; QMutexLocker lock(&m_platformMutex); + // available geometry always starts from top left + const QRect availableGeometry(0, 0, availableWidth, availableHeight); if (m_androidPlatformIntegration) - m_androidPlatformIntegration->setScreenSizeParameters(screenSize, availableGeometry); + m_androidPlatformIntegration->setAvailableGeometry(availableGeometry); else if (QAndroidPlatformScreen::defaultAvailableGeometry().isNull()) QAndroidPlatformScreen::defaultAvailableGeometry() = availableGeometry; } -Q_DECLARE_JNI_NATIVE_METHOD(setDisplayMetrics) +Q_DECLARE_JNI_NATIVE_METHOD(handleLayoutSizeChanged) static void updateApplicationState(JNIEnv */*env*/, jobject /*thiz*/, jint state) { @@ -785,7 +785,7 @@ static bool registerNatives(QJniEnvironment &env) success &= env.registerNativeMethods( QtJniTypes::Traits::className(), { - Q_JNI_NATIVE_METHOD(setDisplayMetrics), + Q_JNI_NATIVE_METHOD(handleLayoutSizeChanged), Q_JNI_NATIVE_METHOD(handleOrientationChanged), Q_JNI_NATIVE_METHOD(handleRefreshRateChanged), Q_JNI_NATIVE_METHOD(handleScreenAdded), diff --git a/src/plugins/platforms/android/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp index 8cd67b27b51..7c9e5193a92 100644 --- a/src/plugins/platforms/android/qandroidplatformintegration.cpp +++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp @@ -499,10 +499,8 @@ void QAndroidPlatformIntegration::setScreenOrientation(Qt::ScreenOrientation cur void QAndroidPlatformIntegration::flushPendingUpdates() { - if (m_primaryScreen) { - m_primaryScreen->setSizeParameters( - m_primaryScreen->geometry().size(), m_primaryScreen->availableGeometry()); - } + if (m_primaryScreen) + m_primaryScreen->setAvailableGeometry(m_primaryScreen->availableGeometry()); } #if QT_CONFIG(accessibility) @@ -542,15 +540,6 @@ void QAndroidPlatformIntegration::updateColorScheme(Qt::ColorScheme colorScheme) [] () { QAndroidPlatformTheme::instance()->updateColorScheme();}); } -void QAndroidPlatformIntegration::setScreenSizeParameters(const QSize &screenSize, - const QRect &availableGeometry) -{ - if (m_primaryScreen) { - QMetaObject::invokeMethod(m_primaryScreen, "setSizeParameters", Qt::AutoConnection, - Q_ARG(QSize, screenSize), Q_ARG(QRect, availableGeometry)); - } -} - void QAndroidPlatformIntegration::setRefreshRate(qreal refreshRate) { if (m_primaryScreen) @@ -581,10 +570,17 @@ void QAndroidPlatformIntegration::handleScreenChanged(int displayId) if (it == m_screens.end() || it->second == nullptr) { handleScreenAdded(displayId); } - // We do not do anything more here as handling of change of - // rotation and refresh rate is done in QtActivityDelegate java class - // which calls QAndroidPlatformIntegration::setOrientation, and - // QAndroidPlatformIntegration::setRefreshRate accordingly. + + if (QAndroidPlatformScreen *screen = it->second) { + QSize size = QAndroidPlatformScreen::sizeForDisplayId(displayId); + if (screen->geometry().size() != size) { + screen->setPhysicalSizeFromPixels(size); + screen->setSize(size); + } + } + + // We do not do handle changes in rotation, refresh rate and density + // as they are done under QtDisplayManager. } void QAndroidPlatformIntegration::handleScreenRemoved(int displayId) diff --git a/src/plugins/platforms/android/qandroidplatformintegration.h b/src/plugins/platforms/android/qandroidplatformintegration.h index b42727cd699..22f2a6e672b 100644 --- a/src/plugins/platforms/android/qandroidplatformintegration.h +++ b/src/plugins/platforms/android/qandroidplatformintegration.h @@ -66,11 +66,6 @@ public: void setAvailableGeometry(const QRect &availableGeometry); void setPhysicalSize(int width, int height); void setScreenSize(int width, int height); - // The 3 methods above were replaced by a new one, so that we could have - // a better control over "geometry changed" event handling. Technically - // they are no longer used and can be removed. Not doing it now, because - // I'm not sure if it might be helpful to have them or not. - void setScreenSizeParameters(const QSize &screenSize, const QRect &availableGeometry); void setRefreshRate(qreal refreshRate); bool isVirtualDesktop() { return true; } diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp index 65c50103623..b1037b9544b 100644 --- a/src/plugins/platforms/android/qandroidplatformscreen.cpp +++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp @@ -82,14 +82,10 @@ QAndroidPlatformScreen::QAndroidPlatformScreen(const QJniObject &displayObject) m_name = displayObject.callObjectMethod("getName").toString(); m_refreshRate = displayObject.callMethod("getRefreshRate"); m_displayId = displayObject.callMethod("getDisplayId"); - - const auto context = QNativeInterface::QAndroidApplication::context(); - const auto sizeObj = QtJniTypes::QtDisplayManager::callStaticMethod( - "getDisplaySize", context, - displayObject.object()); - m_size = QSize(sizeObj.callMethod("getWidth"), sizeObj.callMethod("getHeight")); + m_size = sizeForDisplayId(m_displayId); m_availableGeometry = defaultAvailableGeometry(); + const auto context = QNativeInterface::QAndroidApplication::context(); const auto resources = context.callMethod("getResources"); const auto metrics = resources.callMethod("getDisplayMetrics"); m_xdpi = QtJniTypes::QtDisplayManager::callStaticMethod("getXDpi", metrics); @@ -98,8 +94,7 @@ QAndroidPlatformScreen::QAndroidPlatformScreen(const QJniObject &displayObject) // Potentially densityDpi could be used instead of xpdi/ydpi to do the calculation, // but the results are not consistent with devices specs. // (https://issuetracker.google.com/issues/194120500) - m_physicalSize.setWidth(qRound(m_size.width() / m_xdpi * 25.4)); - m_physicalSize.setHeight(qRound(m_size.height() / m_ydpi * 25.4)); + setPhysicalSizeFromPixels(m_size); if (QNativeInterface::QAndroidApplication::sdkVersion() >= 23) { const QJniObject currentMode = displayObject.callObjectMethod("getMode"); @@ -126,6 +121,19 @@ QAndroidPlatformScreen::~QAndroidPlatformScreen() { } +QSize QAndroidPlatformScreen::sizeForDisplayId(int displayId) +{ + using namespace QtJniTypes; + const auto context = QNativeInterface::QAndroidApplication::context(); + const auto display = QtDisplayManager::callStaticMethod( + "getDisplay", context, displayId); + const auto sizeObj = QtDisplayManager::callStaticMethod( + "getDisplaySize", context, display); + + return QSize(sizeObj.callMethod("getWidth"), sizeObj.callMethod("getHeight")); + +} + QWindow *QAndroidPlatformScreen::topVisibleWindow() const { for (QAndroidPlatformWindow *w : m_windowStack) { @@ -213,28 +221,18 @@ void QAndroidPlatformScreen::setPhysicalSize(const QSize &size) m_physicalSize = size; } +void QAndroidPlatformScreen::setPhysicalSizeFromPixels(const QSize &size) +{ + m_physicalSize = QSize( + qRound(double(size.width()) / m_xdpi * 25.4), + qRound(double(size.height()) / m_ydpi * 25.4)); +} + void QAndroidPlatformScreen::setSize(const QSize &size) { m_size = size; - QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry(), availableGeometry()); -} - -void QAndroidPlatformScreen::setSizeParameters(const QSize &size, const QRect &availableGeometry) -{ - // The goal of this method is to set all geometry-related parameters - // at the same time and generate only one screen geometry change event. - m_size = size; - m_physicalSize = QSize(qRound(double(size.width()) / m_xdpi * 25.4), - qRound(double(size.height()) / m_ydpi * 25.4)); - // If available geometry has changed, the event will be handled in - // setAvailableGeometry. Otherwise we need to explicitly handle it to - // retain the behavior, because setSize() does the handling unconditionally. - if (m_availableGeometry != availableGeometry) { - setAvailableGeometry(availableGeometry); - } else { - QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry(), - this->availableGeometry()); - } + QWindowSystemInterface::handleScreenGeometryChange( + QPlatformScreen::screen(), geometry(), availableGeometry()); } int QAndroidPlatformScreen::displayId() const diff --git a/src/plugins/platforms/android/qandroidplatformscreen.h b/src/plugins/platforms/android/qandroidplatformscreen.h index d77d53ede5d..51fd3c66201 100644 --- a/src/plugins/platforms/android/qandroidplatformscreen.h +++ b/src/plugins/platforms/android/qandroidplatformscreen.h @@ -17,7 +17,6 @@ QT_BEGIN_NAMESPACE class QAndroidPlatformWindow; - class QAndroidPlatformScreen : public QObject, public QPlatformScreen, public QNativeInterface::QAndroidScreen @@ -49,12 +48,13 @@ public: int displayId() const override; static QRect &defaultAvailableGeometry(); + static QSize sizeForDisplayId(int displayId); public slots: void setPhysicalSize(const QSize &size); + void setPhysicalSizeFromPixels(const QSize &size); void setAvailableGeometry(const QRect &rect); void setSize(const QSize &size); - void setSizeParameters(const QSize &size, const QRect &availableGeometry); void setRefreshRate(qreal refreshRate); void setOrientation(Qt::ScreenOrientation orientation);