Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't Qt::AA_DisableHighDpiScaling disable high DPI scaling, and why does Qt::AA_EnableHighDpiScaling disable it?

I'm working on a Qt application (deploying to Qt 5.11, but I'm testing on Qt 5.14) that needs to run on a variety of projectors. At least one of these projectors reports a physical size of over one metre, which results in only 32.5 dpi reported to the Linux OS (compared to the default of 96 dpi). The effect of this setting on our Qt app is that all text becomes unreadably small:

Screenshot of problem

It can be reproduced on any system by running

xrandr --dpi 32.5

before starting the application.

We could configure the system dpi differently, but there are reasons not to: this dpi is actually in the right ballpark (it's even too high), we may want to use it in other applications, and customers may use their own projector which might break our manual configuration.

The safe approach for this particular use case is to pretend we're still living in the stone age: ignore the system dpi setting and just use a 1:1 mapping between device-independent pixels and device pixels. The High DPI displays documentation says:

The Qt::AA_DisableHighDpiScaling application attribute, introduced in Qt 5.6, turns off all scaling. This is intended for applications that require actual window system coordinates, regardless of environment variables. This attribute takes priority over Qt::AA_EnableHighDpiScaling.

So I added this as the first line in main (before the QApplication is created):

QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling);

However, it seems to have no effect; text is still unreadably small. I also tried this in various combinations with:

QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling, false);
QCoreApplication::setAttribute(Qt::AA_Use96Dpi);

Nothing has any visible effect effect.

What does work is setting QT_AUTO_SCREEN_SCALE_FACTOR=1 in the environment. If I understand correctly, this would enable scaling rather than disable it, but setting it to 0 does not work!

Similarly, if I enable Qt::AA_EnableHighDpiScaling in code like this, everything becomes readable:

QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

What also works to some extent is hardcoding the font size (found here):

QFont font = qApp->font();
font.setPixelSize(11);
qApp->setFont(font);

However, margins in the layout still seem to be scaled, so this results in a very cramped (albeit usable) layout.

What also works is setting QT_FONT_DPI=96 in the environment (this variable seems to be undocumented, but it works in Qt 5.11 and 5.14 at least).

Either there are bugs in Qt, or more likely, I'm misunderstanding something. How come that enabling the scaling seems to disable it and vice versa?


Edit: just tested on Qt 5.11 too, although it's on another system. There, neither QT_AUTO_SCREEN_SCALE_FACTOR=1 nor QT_AUTO_SCREEN_SCALE_FACTOR=0 works, so it seems we are dealing with Qt bugs to some extent after all. Maybe related:

  • High DPI scaling not working correctly - CLOSED Out of scope
  • HighDPi: Update scale factor setting for devicePixelRatio scaling (AA_EnableHighDpiScaling) - CLOSED Done in 5.14
  • Support of DPI Scaling Level for Displays in Windows 10 - REPORTED Unresolved
  • Qt uses wrong source for logical DPI on X - REPORTED Unresolved - This may be the root cause of the issue I'm seeing.
  • Uselessness of setAttribute(Qt::AA_EnableHighDpiScaling) - REPORTED Unresolved

So how can I make it work reliably in all cases?

like image 902
Thomas Avatar asked Jan 28 '20 10:01

Thomas


People also ask

How do I fix Disable display scaling on high DPI settings?

Select Display > Change the size of text, apps, and other items, and then adjust the slider for each monitor. Right-click the application, select Properties, select the Compatibility tab, and then select the Disable display scaling on high DPI settings check box.

Should I disable display scaling on high DPI?

But sometimes this feature for some specific apps can cause compatibility issues, unreadable texts, blurry signs, and ultimately app crashes. It is quite a headache if you are working on a 2160p resolution or higher. There are many ways to disable the default display scaling feature on High DPI settings.

What is Disable display scaling on high DPI?

This option was previously known as “Disable display scaling on high DPI settings”, and it does the same thing. System: Windows will use its normal behavior. Applications that don't respect system DPI settings will be “bitmap stretched” to appear larger so they're more easily readable, but will often appear blurry.

What does high DPI scaling override do?

High DPI scaling override Application: The application will be unaware of high DPI and will not be scaled; System: The application will again be unaware of high DPI and the system will scale it; System (Enhanced): This is only available in Windows 10 (1703)+.


1 Answers

Here's what I did in the end to forcibly disable any scaling on Qt 5.11:

    QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling);
    if (qgetenv("QT_FONT_DPI").isEmpty()) {
        qputenv("QT_FONT_DPI", "84");
    }
like image 137
Thomas Avatar answered Sep 27 '22 22:09

Thomas