// Copyright (C) 2020 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include #include #include #include #include #include /* DprGadget: The focused High-DPI settings debug utility DprGadget displays the device pixel ratio ("DPR") for the screen it's on in a large font, as well as the inputs (from the platform plugin or environment) currently in use for determinging the DPR. Non-relevant inputs are not displayed. See qttools/src/qtdiag for an utility which displays all inputs. */ bool g_qtScaleFactor = false; bool g_qtUsePhysicalDpi = false; bool g_qtFontDpi = false; bool g_qtScaleFactorRoundingPolicy = false; bool g_qtHighDpiDownscale = false; bool g_displayEvents = false; class DprGadget : public QWidget { public: std::function m_clearFn; std::function m_updateFn; qreal m_currentDpr = -1; QString m_eventsText; DprGadget() { setWindowTitle(QString("DprGadget - Qt %1").arg(qVersion())); QFont tinyFont; tinyFont.setPointSize(8); QFont smallFont; smallFont.setPointSize(12); QFont bigFont; bigFont.setPointSize(42); QFont biggerFont; biggerFont.setPointSize(80); QLabel *dprLabel = new QLabel("Device Pixel Ratio"); dprLabel->setFont(bigFont); dprLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); QLabel *dprValue = new QLabel(); dprValue->setFont(biggerFont); dprValue->setTextInteractionFlags(Qt::TextSelectableByMouse); QLabel *screenLabel = new QLabel("Current Screen:"); screenLabel->setFont(smallFont); QLabel *sizeLabel = new QLabel("Window size:"); sizeLabel->setFont(smallFont); sizeLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); QLabel *nativeSizeLabel = new QLabel("Native:"); nativeSizeLabel->setFont(smallFont); nativeSizeLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); QLabel *dpiLabel = new QLabel("Logical DPI:"); dpiLabel->setFont(smallFont); dpiLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); QLabel *windowDpiLabel = new QLabel("Window DPI:"); windowDpiLabel->setFont(smallFont); windowDpiLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); QLabel *platformDpiLabel = new QLabel("Native Device Pixel Ratio:"); platformDpiLabel->setFont(smallFont); platformDpiLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); QLabel *windowDprLabel = new QLabel("Window DPR:"); windowDprLabel->setFont(smallFont); windowDprLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); QLabel *plarformDprLabel = new QLabel("Native DPI:"); plarformDprLabel->setFont(smallFont); plarformDprLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); QLabel *qtScaleFactorLabel = new QLabel("Qt Internal Scale Factor:"); qtScaleFactorLabel->setFont(smallFont); QLabel *eventsLabel = new QLabel(m_eventsText); eventsLabel->setFont(tinyFont); eventsLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); QVBoxLayout *layout = new QVBoxLayout(); layout->addWidget(dprLabel); layout->setAlignment(dprLabel, Qt::AlignHCenter); layout->addWidget(dprValue); layout->setAlignment(dprValue, Qt::AlignHCenter); bool displayLogicalDpi = false; if (displayLogicalDpi) layout->addWidget(dpiLabel); layout->addStretch(); QHBoxLayout *screenLabelLayout = new QHBoxLayout(); screenLabelLayout->addStretch(); screenLabelLayout->addWidget(screenLabel); screenLabelLayout->addStretch(); layout->addLayout(screenLabelLayout); QHBoxLayout *windowSizeLayout = new QHBoxLayout(); windowSizeLayout->addWidget(sizeLabel); windowSizeLayout->addStretch(); windowSizeLayout->addWidget(nativeSizeLabel); layout->addLayout(windowSizeLayout); QHBoxLayout *dpiLayout = new QHBoxLayout(); dpiLayout->addWidget(windowDpiLabel); dpiLayout->addStretch(); dpiLayout->addWidget(platformDpiLabel); layout->addLayout(dpiLayout); QHBoxLayout *dprLayout = new QHBoxLayout(); dprLayout->addWidget(windowDprLabel); dprLayout->addStretch(); dprLayout->addWidget(plarformDprLabel); layout->addLayout(dprLayout); QHBoxLayout *qtScaleFactorLabelLayout = new QHBoxLayout(); qtScaleFactorLabelLayout->addStretch(); qtScaleFactorLabelLayout->addWidget(qtScaleFactorLabel); qtScaleFactorLabelLayout->addStretch(); layout->addLayout(qtScaleFactorLabelLayout); if (g_displayEvents) layout->addWidget(eventsLabel); bool activeEnvironment = g_qtScaleFactor || g_qtUsePhysicalDpi || g_qtFontDpi || g_qtScaleFactorRoundingPolicy || g_qtHighDpiDownscale; if (activeEnvironment) { layout->addWidget(new QLabel("Active Environment:")); if (g_qtScaleFactor) { QString text = QString("QT_SCALE_FACTOR=") + qgetenv("QT_SCALE_FACTOR"); layout->addWidget(new QLabel(text)); } if (g_qtUsePhysicalDpi) { QString text = QString("QT_USE_PHYSICAL_DPI=") + qgetenv("QT_USE_PHYSICAL_DPI"); layout->addWidget(new QLabel(text)); } if (g_qtFontDpi) { QString text = QString("QT_FONT_DPI=") + qgetenv("QT_FONT_DPI"); layout->addWidget(new QLabel(text)); } if (g_qtScaleFactorRoundingPolicy) { QString text = QString("QT_SCALE_FACTOR_ROUNDING_POLICY=") + qgetenv("QT_SCALE_FACTOR_ROUNDING_POLICY"); layout->addWidget(new QLabel(text)); } if (g_qtHighDpiDownscale) { QString text = QString("QT_WIDGETS_HIGHDPI_DOWNSCALE=") + qgetenv("QT_WIDGETS_HIGHDPI_DOWNSCALE"); layout->addWidget(new QLabel(text)); } } auto updateValues = [=]() { dprValue->setText(QString("%1").arg(devicePixelRatioF())); windowDpiLabel->setText(QString("QWindow DPI: %1").arg(logicalDpiX())); dpiLabel->setText(QString("Logical DPI: %1").arg(logicalDpiX())); sizeLabel->setText(QString("QWindow size: %1 %2").arg(width()).arg(height())); QPlatformWindow *platformWindow = windowHandle()->handle(); nativeSizeLabel->setText(QString("native size %1 %2").arg(platformWindow->geometry().width()) .arg(platformWindow->geometry().height())); QPlatformScreen *pscreen = screen()->handle(); if (g_qtUsePhysicalDpi) { int physicalDpi = qRound(pscreen->geometry().width() / pscreen->physicalSize().width() * qreal(25.4)); platformDpiLabel->setText(QString("Native Physical DPI: %1").arg(physicalDpi)); } else { platformDpiLabel->setText(QString("native logical DPI: %1").arg(pscreen->logicalDpi().first)); } windowDprLabel->setText(QString("QWindow DPR: %1").arg(windowHandle()->devicePixelRatio())); plarformDprLabel->setText(QString("native DPR: %1").arg(pscreen->devicePixelRatio())); screenLabel->setText(QString("Current Screen: %1").arg(screen()->name())); qtScaleFactorLabel->setText(QString("Qt Internal Scale Factor: %1").arg(QHighDpiScaling::factor(windowHandle()))); eventsLabel->setText(QString(m_eventsText)); }; m_updateFn = updateValues; m_clearFn = [=]() { dprValue->setText(QString("")); m_eventsText.clear(); }; create(); QObject::connect(this->windowHandle(), &QWindow::screenChanged, [updateValues, this](QScreen *screen){ Q_UNUSED(screen); this->m_eventsText.prepend(QString("ScreenChange ")); this->m_eventsText.truncate(80); updateValues(); }); setLayout(layout); updateValues(); } void paintEvent(QPaintEvent *) override { // Update the UI in the paint event - normally not good // practice but it looks like we can get away with it here this->m_eventsText.prepend(QString("Paint ")); this->m_eventsText.truncate(80); // Dpr change should trigger a repaint, update display values here if (m_currentDpr == devicePixelRatioF()) return; m_currentDpr = devicePixelRatioF(); m_updateFn(); } void resizeEvent(QResizeEvent *event) override { QSize size = event->size(); m_eventsText.prepend(QString("Resize(%1 %2) ").arg(size.width()).arg(size.height())); m_eventsText.truncate(80); m_updateFn(); } void mousePressEvent(QMouseEvent *) override { m_clearFn(); QTimer::singleShot(500, this, [this](){ m_updateFn(); }); } }; int main(int argc, char **argv) { // Set sensible defaults QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); // Display any set high-dpi eviornment variable. g_qtScaleFactor = qEnvironmentVariableIsSet("QT_SCALE_FACTOR"); g_qtUsePhysicalDpi = qgetenv("QT_USE_PHYSICAL_DPI") == QByteArray("1"); g_qtFontDpi = qEnvironmentVariableIsSet("QT_FONT_DPI"); g_qtScaleFactorRoundingPolicy = qEnvironmentVariableIsSet("QT_SCALE_FACTOR_ROUNDING_POLICY"); g_qtHighDpiDownscale = qEnvironmentVariableIsSet("QT_WIDGETS_HIGHDPI_DOWNSCALE"); QApplication app(argc, argv); DprGadget dprGadget; dprGadget.show(); return app.exec(); }