[Interest] Question about correct way to initialize HiDPI support

Elvis Stansvik elvstone at gmail.com
Mon Jan 13 12:56:33 CET 2020


Den mån 13 jan. 2020 kl 10:35 skrev Christoph Cullmann <christoph at cullmann.io>:
>
> Hi,
>
> after reading https://doc.qt.io/qt-5/highdpi.html it is still a bit
> unclear to me,
> what is the correct sequence of attribute setting to have proper HiDPI
> support on the
> X11/Windows/macOS platforms (including support for scales like 150%).
>
> At the moment, e.g. in Kate, we try (before we init the QApplication):
>
>      /**
>       * enable high dpi support
>       */
>      QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true);
>      QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true);
>
>      /**
>       * allow fractional scaling
>       */
> #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
>
> QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
> #endif
>
> Is that actually the right way to do it?
>
> Does one actually need the Qt::AA_EnableHighDpiScaling call?
> We got some reports that we behave strangely (weird sizes) since we
> added Qt::AA_EnableHighDpiScaling.
>
> If I miss some example snippet in the documentation, any pointer is
> welcome ;=)

I've always thought that page to be a bit unclear too.

The way I've understood it, and someone please correct me if I'm wrong is:

- "Legacy" applications, those who do not consider the screen DPI in
any custom painting they might do et.c., can use
QT_AUTO_SCREEN_SCALE_FACTOR=1 (or the equivalent
Qt::AA_EnableHighDpiScaling application attribute) to enable automatic
scaling.
- New applications, which are DPI aware and consider the DPI whenever
they do custom painting, should not need to set that attribute.

I'm basing this off of the last section on the page "Migrate Existing
Applications" (https://doc.qt.io/qt-5/highdpi.html#migrate-existing-applications),
which says:

"To get an application designed for low DPI values running on high
resolution monitors quickly, consider one of the following:

- let the application run as DPI Unaware on Windows
- set the QT_AUTO_SCREEN_SCALE_FACTOR environment variable to 1.

However, these options may result in some scaling or painting artifacts.

In the long term, the application should be adapted to run unmodified:

- Always use the qreal versions of the QPainter drawing API.
- Size windows and dialogs in relation to the corresponding screen size.
- Replace hard-coded sizes in layouts and drawing code with values
calculated from font metrics or screen size."

The impression I get here when it says "In the long term [...]" is
that newly written applications, which are themselves DPI aware,
should not need to turn on the auto-scaling.

This is what we do in our application. We set the
Qt::AA_UseHighDpiPixmaps attribute like you do, but we do not set the
Qt::AA_EnableHighDpiScaling attribute. Whenever we do custom painting
using e.g. QPainter, or we use other APIs than Qt to do painting (for
example VTK), we have to ensure we take the DPI into account.

For the painting that Qt does itself, e.g. painting menus, buttons,
text on buttons et.c., I believe Qt should (modulo bugs of course)
take DPI into account, and work without the
Qt::AA_EnableHighDpiScaling attribute set.

Again, please correct me if I'm wrong here. The
Qt::AA_EnableHighDpiScaling attribute is for applications which were
written "DPI oblivious", to transparently scale drawn stuff for them?

As a side note, the cross-platform story is that in macOS, there's a
true pixel scaling going on at a lower level, and the devicePixelRatio
reported by Qt will reflect this scaling.

On Windows, the OS "scaling" mechnism is different - the OS reports
different sizes/metrics to Qt, which Qt will respect when sizing
buttons et.c. The devicePixelRatio reported by Qt to applications will
always be 1.0 (unless Qt's own auto-scaling is turned on). This means
in DPI aware applications on Windows, to figure out the factor you
should scale your painting with, you need to use something else than
Qt's devicePixelRatio. What we've done is something like logicalDpiX()
/ 96.0 to figure out the factor. This is motivated by
https://docs.microsoft.com/sv-se/windows/win32/learnwin32/dpi-and-device-independent-pixels
which says that 100% in Windows's screen scaling corresponds to a
logical DPI of 96.

Elvis

>
> Greetings
> Christoph
>
> --
> Ignorance is bliss...
> https://cullmann.io | https://kate-editor.org
> _______________________________________________
> Interest mailing list
> Interest at qt-project.org
> https://lists.qt-project.org/listinfo/interest


More information about the Interest mailing list