Android: don't pass x/y dpi values to setDisplayMetrics()

Those values are only used to calculate the final value for the screen
size, which means we can simply do the calculation first and pass the
final values anyway and avoid carrying those params and making things
harder to read, and since those values are tied to the screen, we can
deffer calculating the physical size to the screen itself.

Dpi values are at least DisplayMetrics.DENSITY_LOW, if the xdpi/ydpi
returned metrics values are below that.

Task-number: QTBUG-132720
Change-Id: Idd6a4db24a460aeb66e626cd93d52b87566ce69c
Reviewed-by: Petri Virkkunen <petri.virkkunen@qt.io>
This commit is contained in:
Assam Boudjelthia 2025-01-06 17:15:23 +02:00
parent 65c41c6be6
commit d25064b04d
7 changed files with 24 additions and 36 deletions

View File

@ -34,8 +34,7 @@ class QtDisplayManager {
// screen methods
static native void setDisplayMetrics(int screenWidthPixels, int screenHeightPixels,
int availableWidthPixels, int availableHeightPixels,
double XDpi, double YDpi);
int availableWidthPixels, int availableHeightPixels);
static native void handleOrientationChanged(int newRotation, int nativeOrientation);
static native void handleRefreshRateChanged(float refreshRate);
static native void handleUiDarkModeChanged(int newUiMode);
@ -285,20 +284,18 @@ class QtDisplayManager {
if (activity == null)
return;
final DisplayMetrics displayMetrics = activity.getResources().getDisplayMetrics();
Size displaySize = getDisplaySize(activity, QtDisplayManager.getDisplay(activity));
setDisplayMetrics(displaySize.getWidth(), displaySize.getHeight(),
width, height,
getXDpi(displayMetrics), getYDpi(displayMetrics));
setDisplayMetrics(displaySize.getWidth(), displaySize.getHeight(), width, height);
}
@UsedFromNativeCode
static float getXDpi(final DisplayMetrics metrics) {
if (metrics.xdpi < android.util.DisplayMetrics.DENSITY_LOW)
return android.util.DisplayMetrics.DENSITY_LOW;
return metrics.xdpi;
}
@UsedFromNativeCode
static float getYDpi(final DisplayMetrics metrics) {
if (metrics.ydpi < android.util.DisplayMetrics.DENSITY_LOW)
return android.util.DisplayMetrics.DENSITY_LOW;

View File

@ -42,9 +42,7 @@ class QtServiceEmbeddedDelegate implements QtEmbeddedViewInterface, QtNative.App
final int maxWidth = metrics.widthPixels;
final int maxHeight = metrics.heightPixels;
QtDisplayManager.setDisplayMetrics(
maxWidth, maxHeight, maxWidth, maxHeight,
QtDisplayManager.getXDpi(metrics), QtDisplayManager.getYDpi(metrics));
QtDisplayManager.setDisplayMetrics(maxWidth, maxHeight, maxWidth, maxHeight);
QtDisplayManager.updateRefreshRate(m_service);
QtDisplayManager.handleScreenDensityChanged(metrics.density);

View File

@ -567,8 +567,7 @@ static void terminateQt(JNIEnv *env, jclass /*clazz*/)
static void setDisplayMetrics(JNIEnv * /*env*/, jclass /*clazz*/,
jint screenWidthPixels, jint screenHeightPixels,
jint availableWidthPixels, jint availableHeightPixels,
jdouble xdpi, jdouble ydpi)
jint availableWidthPixels, jint availableHeightPixels)
{
m_availableWidthPixels = availableWidthPixels;
m_availableHeightPixels = availableHeightPixels;
@ -576,16 +575,12 @@ static void setDisplayMetrics(JNIEnv * /*env*/, jclass /*clazz*/,
const QSize screenSize(screenWidthPixels, screenHeightPixels);
// available geometry always starts from top left
const QRect availableGeometry(0, 0, availableWidthPixels, availableHeightPixels);
const QSize physicalSize(qRound(double(screenWidthPixels) / xdpi * 25.4),
qRound(double(screenHeightPixels) / ydpi * 25.4));
QMutexLocker lock(&m_platformMutex);
if (m_androidPlatformIntegration) {
m_androidPlatformIntegration->setScreenSizeParameters(
physicalSize, screenSize, availableGeometry);
} else if (QAndroidPlatformScreen::defaultAvailableGeometry().isNull()) {
if (m_androidPlatformIntegration)
m_androidPlatformIntegration->setScreenSizeParameters(screenSize, availableGeometry);
else if (QAndroidPlatformScreen::defaultAvailableGeometry().isNull())
QAndroidPlatformScreen::defaultAvailableGeometry() = availableGeometry;
}
}
Q_DECLARE_JNI_NATIVE_METHOD(setDisplayMetrics)

View File

@ -500,8 +500,8 @@ void QAndroidPlatformIntegration::setScreenOrientation(Qt::ScreenOrientation cur
void QAndroidPlatformIntegration::flushPendingUpdates()
{
if (m_primaryScreen) {
m_primaryScreen->setSizeParameters(m_primaryScreen->physicalSize().toSize(),
m_primaryScreen->geometry().size(), m_primaryScreen->availableGeometry());
m_primaryScreen->setSizeParameters(
m_primaryScreen->geometry().size(), m_primaryScreen->availableGeometry());
}
}
@ -542,14 +542,12 @@ void QAndroidPlatformIntegration::updateColorScheme(Qt::ColorScheme colorScheme)
[] () { QAndroidPlatformTheme::instance()->updateColorScheme();});
}
void QAndroidPlatformIntegration::setScreenSizeParameters(const QSize &physicalSize,
const QSize &screenSize,
void QAndroidPlatformIntegration::setScreenSizeParameters(const QSize &screenSize,
const QRect &availableGeometry)
{
if (m_primaryScreen) {
QMetaObject::invokeMethod(m_primaryScreen, "setSizeParameters", Qt::AutoConnection,
Q_ARG(QSize, physicalSize), Q_ARG(QSize, screenSize),
Q_ARG(QRect, availableGeometry));
Q_ARG(QSize, screenSize), Q_ARG(QRect, availableGeometry));
}
}

View File

@ -70,8 +70,7 @@ public:
// 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 &physicalSize, const QSize &screenSize,
const QRect &availableGeometry);
void setScreenSizeParameters(const QSize &screenSize, const QRect &availableGeometry);
void setRefreshRate(qreal refreshRate);
bool isVirtualDesktop() { return true; }

View File

@ -92,14 +92,14 @@ QAndroidPlatformScreen::QAndroidPlatformScreen(const QJniObject &displayObject)
const auto resources = context.callMethod<QtJniTypes::Resources>("getResources");
const auto metrics = resources.callMethod<QtJniTypes::DisplayMetrics>("getDisplayMetrics");
const float xdpi = metrics.getField<float>("xdpi");
const float ydpi = metrics.getField<float>("ydpi");
m_xdpi = QtJniTypes::QtDisplayManager::callStaticMethod<jfloat>("getXDpi", metrics);
m_ydpi = QtJniTypes::QtDisplayManager::callStaticMethod<jfloat>("getYDpi", metrics);
// 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() / xdpi * 25.4));
m_physicalSize.setHeight(qRound(m_size.height() / ydpi * 25.4));
m_physicalSize.setWidth(qRound(m_size.width() / m_xdpi * 25.4));
m_physicalSize.setHeight(qRound(m_size.height() / m_ydpi * 25.4));
if (QNativeInterface::QAndroidApplication::sdkVersion() >= 23) {
const QJniObject currentMode = displayObject.callObjectMethod<QtJniTypes::DisplayMode>("getMode");
@ -219,13 +219,13 @@ void QAndroidPlatformScreen::setSize(const QSize &size)
QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry(), availableGeometry());
}
void QAndroidPlatformScreen::setSizeParameters(const QSize &physicalSize, const QSize &size,
const QRect &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_physicalSize = physicalSize;
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.

View File

@ -54,8 +54,7 @@ public slots:
void setPhysicalSize(const QSize &size);
void setAvailableGeometry(const QRect &rect);
void setSize(const QSize &size);
void setSizeParameters(const QSize &physicalSize, const QSize &size,
const QRect &availableGeometry);
void setSizeParameters(const QSize &size, const QRect &availableGeometry);
void setRefreshRate(qreal refreshRate);
void setOrientation(Qt::ScreenOrientation orientation);
@ -71,6 +70,8 @@ protected:
QList<Mode> m_modes;
int m_currentMode = 0;
int m_displayId = -1;
int m_xdpi;
int m_ydpi;
private:
QDpi logicalDpi() const override;