qgis / QGIS

QGIS is a free, open source, cross platform (lin/win/mac) geographical information system (GIS)
https://qgis.org
GNU General Public License v2.0
10.34k stars 2.97k forks source link

High DPI UI scaling issues in 3.32 (Windows) #53898

Open Houska1 opened 1 year ago

Houska1 commented 1 year ago

What is the bug or the crash?

UI icon spacing and UI text (e.g. newsfeed) sizes have changed in an undesirable way on my Windows laptop in shifting from 3.30 (and earlier) to 3.32. Seems to be related to an underlying change in how iface.mainWindow().logicalDpiX() and iface.mainWindow().physicalDpiX() are reported.

Steps to reproduce the issue

As baseline, here is what was prior behaviour on my Lenovo T490s laptop, using 3.30 or 3.28.8 LTR. For reference, my screen is 1920x1080, actual 158 dpi, and I use cross-application Windows display scaling of 125% which makes UI fine for all other applications.

LTR

Menu text and icons (set to 16px) are small but legible. The newsfeed text is crisp.

In contrast, here is the display with the new 3.32: 332

Icons are spread too widely (toolbar realestate is wasted), and the newsfeed text is blurred from artifical stretching.

Interestingly, .logicalDpiX() and .physicalDpiX() are 120, 158 in LTR/3.30 versus 96, 126 in 3.32, which I suspect is causing the problem. I think the LTR/3.30 numbers are right, but the 3.32 numbers are wrong (applying the Windows 125% scaling factor to physicalDpi instead of logicalDpi.

I have played around with:

Versions

3.32.0-3 (current OSGeo4W install), compared to previous 3.30 and current 3.28.8 LTR (OSGeo4W)

Supported QGIS version

New profile

Additional context

As expected, canvas (as opposed to UI) display reflects the .physicalDpi value as well as the Options / Canvas / DPI setting.

phidrho commented 1 year ago

Hi @Houska1,

just wanted to share my opinion on Windows scaling - in my experience, Windows scaling option only makes things much worse, not only in QGIS but in all applications. Unfortunately, there is no quick fix, we shall wait a long time until all software fixes their UI and become HiDPI friendly. I don't think that currently (in 2023) Windows can know which application needs custom scaling and which doesn't, so it applies "25% zoom" to everything, ending up in blurry texts and images in many applications including QGIS.

@nyalldawson did a recent update on this topic (see: mailing list topic) but I believe this presumes that you use a 100% scaling in Windows.

I would suggest that you enlarge UI elements through QGIS built-in settings and set Windows scaling to 100% - this should make everything nice and sharp. image

Houska1 commented 1 year ago

Thanks for the comment @phidrho. I think you are right that I could achieve a better outcome in QGIS currently by setting Windows scaling to 100% and adjusting QGIS display settings. However, Windows scaling is an unavoidable part of the Windows platform (on all high DPI laptops it is set >100% by default, and setting it to 100% makes many standard applications unusable with them). So it is not an esoteric edge case but something we need to get right.

I believe this is something that Qt's physicalDpi vs logicalDpi distinction is meant to address, and it seems whatever improvements done recently for highDPI displays have introduced a regression. If https://stackoverflow.com/questions/16561879/what-is-the-difference-between-logicaldpix-and-physicaldpix-in-qt is accurate, the behaviour through 3.30 of physicalDpi representing the true DPI of the display, regardless of Windows scaling; and logicalDPI being 96*WindowsScaling, was correct. On my machine, in 3.32.0 this has changed, and now logical DPI is unchanged and physical DPI is affected by the windows scaling factor. I suspect the is the root cause of the problem that has now bubbled up.

I will try with 3.32.1 and dev nightlies on Monday.

nyalldawson commented 1 year ago

Does setting the environment variable

QT_SCALE_FACTOR_ROUNDING_POLICY=PassThrough

Help at all?

Houska1 commented 1 year ago

@nyalldawson , this is really weird. I played around with QT_SCALE_FACTOR_ROUNDING_POLICY (putting it in qgis-bin.env)

When that variable is absent, or set to PassThrough, then the undersirable behaviour as above occurs (visual and dpi values).

When I set it to Round, RoundPreferFloor, or Floor, I have good display and correct dpi values (logical 120, physical 158), as in <=3.30. Yay, solves my problem. There are minute differences in borders, etc, between the settings as one would expect.

When I set it to Ceil, I get completely awful oversized UI elements, and logical dpi 96 and physical dpi 79.

I find this quite perplexing, as my understanding of the underlying logic (from helping Matthias with screen canvas scaling issues a while back) is that the physical DPI should always be unchanged based on scaling, while logical dpi should scale up based on the windows scaling factor (125% in my case). The setting above, per https://doc.qt.io/qt-5/highdpi.html, should affect small-pixel calculations of borders and font spacing but not the macro-level dpi calculation at all. An upstream Qt issue rearing its head in QGIS now, for some reason?

Houska1 commented 1 year ago

Likely related to https://github.com/qgis/QGIS/pull/52972 ?

jbp35 commented 1 year ago

@nyalldawson , this is really weird. I played around with QT_SCALE_FACTOR_ROUNDING_POLICY (putting it in qgis-bin.env)

When that variable is absent, or set to PassThrough, then the undersirable behaviour as above occurs (visual and dpi values).

When I set it to Round, RoundPreferFloor, or Floor, I have good display and correct dpi values (logical 120, physical 158), as in <=3.30. Yay, solves my problem. There are minute differences in borders, etc, between the settings as one would expect.

When I set it to Ceil, I get completely awful oversized UI elements, and logical dpi 96 and physical dpi 79.

I find this quite perplexing, as my understanding of the underlying logic (from helping Matthias with screen canvas scaling issues a while back) is that the physical DPI should always be unchanged based on scaling, while logical dpi should scale up based on the windows scaling factor (125% in my case). The setting above, per https://doc.qt.io/qt-5/highdpi.html, should affect small-pixel calculations of borders and font spacing but not the macro-level dpi calculation at all. An upstream Qt issue rearing its head in QGIS now, for some reason?

What is your font size in QGIS option ? Does it looks better if you set the font size to 9pt and restart qgis?

Setting QT_SCALE_FACTOR_ROUNDING_POLICY=Round is the same as setting windows DPI scaling to 100% in your case. Round policy means that QT rounds the Device Pixel Ratio (1.25 in your case) to the nearest integer. I don't think that this is really a solution, as it is just basically disabling DPI scaling in QGIS.

Houska1 commented 1 year ago

@jbp35 I do achieve better font appearance by adjusting font size, but icon spacing is still off, and the incorrect physicalDPI (using PassThrough or no setting) turns out to affect canvas appearance as well. Is it correct that the rounding policy affects the device pixel ratio (eg 1.25 -> 1) or does it affect pixel dimensions after scaling, eg 3 pixels with 125% becomes 4 vs 3 or 3.75?

jbp35 commented 1 year ago

@jbp35 I do achieve better font appearance by adjusting font size, but icon spacing is still off, and the incorrect physicalDPI (using PassThrough or no setting) turns out to affect canvas appearance as well. Is it correct that the rounding policy affects the device pixel ratio (eg 1.25 -> 1) or does it affect pixel dimensions after scaling, eg 3 pixels with 125% becomes 4 vs 3 or 3.75?

Regarding the font size, this is most likely a qt bug or undocumented behaviour. The default font size is incorrectly detected on some devices. I have already opened an issue for this #53419. This has been fixed with QT6. Replacing manually the font size to 9pt in qgis is a good solution in the meantime.

For the toolbar icon spacing, do you achieve a similar result as in qgis 3.30 by setting the toolbar icon size to 13px? I don't think this is a bug, it is just that qgis 3.30 was not scaling icons at 125% in your setup so it is normal that they look a bit bigger now.

nyalldawson commented 1 year ago

@jbp35

We currently aren't setting the rounding policy anywhere, which would mean we get the default qt 5 setting of "ROUND" (for qt 6 the default is passthrough)

I think we could further improve the qt 5 situation by forcibly setting the mode to passthrough too. Do you have any thoughts here?

jbp35 commented 1 year ago

@jbp35

We currently aren't setting the rounding policy anywhere, which would mean we get the default qt 5 setting of "ROUND" (for qt 6 the default is passthrough)

I think we could further improve the qt 5 situation by forcibly setting the mode to passthrough too. Do you have any thoughts here?

Actually, this is already done here:

https://github.com/qgis/QGIS/blob/fbb9e08687534f74797b93ea3760c5a781fdfe67/src/app/main.cpp#L927C98-L927C98

nyalldawson commented 1 year ago

Oh, i missed that somehow!

NormanRK commented 6 months ago

Hi.

I have the same issue that has been mentioned in this thread not only in QGIS 3.32, but it still continued in QGIS 3.34 and the latest QGIS v3.36 release candidate. The same solution are also works in the last 3 version of QGIS to this issue are to set QT_SCALE_FACTOR_ROUNDING_POLICY = Round in qgis-bin.env

tijan49 commented 6 months ago

Hi, I have the same issue from the 3.32 version, although I tried all possibilities for the variable : QT_SCALE_FACTOR_ROUNDING_POLICY = Round / Floor / PassThrough ... The appearence is still ugly. I have to continue to work with the 3.28 version, witch appearence is fine, but it's a pity not to be able to use last versions ... Any idea ? Thanks

NormanRK commented 6 months ago

Hi @tijan49 ,

Have you ever tried QT_SCALE_FACTOR_ROUNDING_POLICY=Round (note : without space between "=")?

Sorry because in my comment above i wrote QT_SCALE_FACTOR_ROUNDING_POLICY = Round (with space before and after "=")

tijan49 commented 6 months ago

Hi, I finally managed to solve the problem, but it's nothing but simple.

The way it works on my computer (W10 / 1920x1082 / 150% scaling) : 1°) changed the file qgis-bin.env with the new line : QT_SCALE_FACTOR_ROUNDING_POLICY=Floor (without any space, your are true NormanRK ...). 2°) changed the application compatibity settings to "application" (cf. image below, sorry in french).
Image5

I fear that this will be prohibitive for novice users ...

Thanks for your help. Jean

jbp35 commented 6 months ago

Hi, I finally managed to solve the problem, but it's nothing but simple.

The way it works on my computer (W10 / 1920x1082 / 150% scaling) : 1°) changed the file qgis-bin.env with the new line : QT_SCALE_FACTOR_ROUNDING_POLICY=Floor (without any space, your are true NormanRK ...). 2°) changed the application compatibity settings to "application" (cf. image below, sorry in french).
Image5

I fear that this will be prohibitive for novice users ...

Thanks for your help. Jean

Hi, just wondering what is your default qgis application font size? Did you try to set it to 9pt and restart qgis?

tijan49 commented 6 months ago

Hi, To answer you, my default font size is 8pt. But the ugly appearence of the UI is not only a matter of font size, but as well of icon size, icon spacement, windows size ... With the parameters I changed, it's now all perfect, and that means that I will have to change those paramaters for every new version of QGIS. As I mentioned, I fear that it will prevent many newbies to use QGIS ... Thanks

Martin-Jung commented 6 months ago

Hi, I finally managed to solve the problem, but it's nothing but simple.

The way it works on my computer (W10 / 1920x1082 / 150% scaling) : 1°) changed the file qgis-bin.env with the new line : QT_SCALE_FACTOR_ROUNDING_POLICY=Floor (without any space, your are true NormanRK ...). 2°) changed the application compatibity settings to "application" (cf. image below, sorry in french). Image5 Image5

I fear that this will be prohibitive for novice users ...

Thanks for your help. Jean

Thank you so much for this solution which worked like a charm (opposed to increasing the font size in the QGIS settings, which was essentially ignored). Without it QGIS was pretty much unreadable on my laptop (Win 11). I am wondering if this can't be implemented as a simple UI scaling flag in the options. Since UI scaling is a parameter in Windows 11 too (Settings - Display) this could even be read out from system configuration files.

jbp35 commented 6 months ago

With the parameters I changed, it's now all perfect, and that means that I will have to change those paramaters for every new version of QGIS.

Hi, To answer you, my default font size is 8pt. But the ugly appearence of the UI is not only a matter of font size, but as well of icon size, icon spacement, windows size ... With the parameters I changed, it's now all perfect, and that means that I will have to change those paramaters for every new version of QGIS. As I mentioned, I fear that it will prevent many newbies to use QGIS ... Thanks

A lot of UI elements depend on the font size to scale so it's not just a matter of text appearance. On windows the default QT font size should be 9px.

If you get a chance, could just confirm that the following actions are not working:

Thanks.

tijan49 commented 6 months ago

I jpb35, I did what you suggested, and here is the result :

screenshot

I specify that I made the following settings for my OS (W10), wich is not the recommanded one, but I can't tune it to 125% because of another applications ... image

Hope it helps Jean

jbp35 commented 6 months ago

I jpb35, I did what you suggested, and here is the result : screenshot

I specify that I made the following settings for my OS (W10), wich is not the recommanded one, but I can't tune it to 125% because of another applications ... image

Hope it helps Jean

Thanks. Indeed your toolbar icons are too big. The pixelated close button is a known issue which will be addressed with QT6.

Could you try running the following script in the python console to print screen information:

from qgis.PyQt import QtGui
from PyQt5.QtGui import QFont

app = QGuiApplication.instance()
all_screens = app.screens()

print('primary screen:', app.primaryScreen().name())

for s in all_screens:
    print()
    print('name: ' + str(s.name()))
    print('size: ' + str(s.size()))
    print('physicalSize: ' +str(s.physicalSize()))
    print('physicalDotsPerInch: ' + str(s.physicalDotsPerInch()))
    print('logicalDotsPerInch: ' + str(s.logicalDotsPerInch()))
    print('devicePixelRatio: '+ str(s.devicePixelRatio()))

print('\n')
print(f'Font size: ' + str(app.font().pointSizeF()))
tijan49 commented 6 months ago

Sure ... Here is the result 👍

primary screen: \.\DISPLAY1

name: \.\DISPLAY1 size: PyQt5.QtCore.QSize(1920, 1080) physicalSize: PyQt5.QtCore.QSizeF(344.0, 194.0) physicalDotsPerInch: 141.58475185806762 logicalDotsPerInch: 144.0 devicePixelRatio: 1.0

Font size: 8.0

jbp35 commented 6 months ago

Sure ... Here is the result 👍

primary screen: .\DISPLAY1

name: .\DISPLAY1 size: PyQt5.QtCore.QSize(1920, 1080) physicalSize: PyQt5.QtCore.QSizeF(344.0, 194.0) physicalDotsPerInch: 141.58475185806762 logicalDotsPerInch: 144.0 devicePixelRatio: 1.0

Font size: 8.0

Thanks. Could you do the same thing after stting the default font size to 9px and icon size to 24 and restarting qgis (without setting any flag and leaving HDI scaling override off in windows settings) to compare?

tijan49 commented 6 months ago

Sure, here it is ...

primary screen: \\.\DISPLAY1

name: \\.\DISPLAY1
size: PyQt5.QtCore.QSize(1280, 720)
physicalSize: PyQt5.QtCore.QSizeF(344.0, 194.0)
physicalDotsPerInch: 94.38983457204507
logicalDotsPerInch: 96.0
devicePixelRatio: 1.5

Font size: 9.0
jbp35 commented 6 months ago

Sure, here it is ...

primary screen: \\.\DISPLAY1

name: \\.\DISPLAY1
size: PyQt5.QtCore.QSize(1280, 720)
physicalSize: PyQt5.QtCore.QSizeF(344.0, 194.0)
physicalDotsPerInch: 94.38983457204507
logicalDotsPerInch: 96.0
devicePixelRatio: 1.5

Font size: 9.0

From my understanding, the sizing of your toolbar icons is correct when you set the font size to 9px. If you measure the pixel size of the icons on your screenshot it is 36px wide wich is equal to 24px multiplied by 1.5 (which is your DPR).

I feel the issue is that with laptop screens with limited real estate, 24px icons feel too big. In your case, I think the best options would be to reduce the icon size to 16px.

The spacing of the icons can be adjusted by setting the "toolbarSpacing" option variable to 0 in : settings/options/advanced/toolbarSpacing

@nyalldawson a few questions:

Houska1 commented 6 months ago

Appreciate the continued attention here. I've come to terms with the kluged QT_SCALE_FACTOR_ROUNDING_POLICY solution on my laptop, together with tweaking the font size and reducing icon size to 16. That said, more granularity on icon size than 16,24,32 would reduce user complexity considerably. It's the interplay of this, font size, and the Windows app scaling settings that create the challenge here, and if users had ability to adjust icon size more granularly (alongside font size), then the arcane QT_SCALE workarounds might not be necessary.

Thanks for the hint above regarding changing Settings/Options/Advanced:QGIS/stylesheet/toolbarSpacing to 0 (that's the full path, with a bit of digging). I just did this and it restored more toolbar real estate, the way I remember it used to be about a year ago.

nyalldawson commented 6 months ago

@jbp35

is there any reasons we limit the icon size to 16-24-32 ( I often feel 16 is too small for the toolbar and 24 too big).

Historic reasons only (from prior to use of svg based icons). Feel free to add additional sizes as you see fit!

would it make sense to use the toolbar icon size to determine other icon sizes in qgis? for instance the layer palette icons size could be 60% the size of the toolbar icon size?

This should already be the case (but possibly there's some missing places).

should the default font size be hardcoded to 9 on windows and QT5? It looks like it is incorretly detected on a lot of devices.

Hm, we actually don't have any default font size logic anymore (unless the user specifically opts in, that is). We just take what Qt gives us as the default font and don't have any special logic at all.

I'd be interested to see if the issue is reproducible in a non-QGIS qt app on these systems. (eg a little PyQt application which just shows a dialog with some widgets).

jbp35 commented 6 months ago

@nyalldawson OK, I will try to add a few sizes when ever I get some time.

Here is a script to highlight the issue with the font size:

import sys
from PyQt5.QtWidgets import QApplication as QApplication_qt5
from PyQt6.QtWidgets import QApplication as QApplication_qt6

if __name__ == "__main__":

    app_qt5 = QApplication_qt5(sys.argv)
    app_qt6 = QApplication_qt6(sys.argv)

    print(f"QT5: {app_qt5.font().pointSizeF()}")
    print(f"QT6: {app_qt6.font().pointSizeF()}")

When my primary display is set to DISPLAY1 the output is:

QT5: 8.1
QT6: 9.0

If I set DISPLAY2 to be the primary display I get:

QT5: 20.25
QT6: 9.0

I don't understand how the default font size is calculated in qt5.

tannenfreund87 commented 3 months ago

@jbp35

I don't understand how the default font size is calculated in qt5.

A lot of UI elements depend on the font size to scale so it's not just a matter of text appearance. On windows the default QT font size should be 9px.

Up to qt5, qt is using "MS Shell Dlg2" as standard font on Windows, only with qt6 the standard font is finally Segoe UI. "MS Shell Dlg2" is mostly an alias for "Tahoma, 8pt", only qt6 defaults to 9pt. The 8.1 value is some workaround they introduced in qt4 (?, if I remember correctly), to prevent some display issues. There is this post on stack overflow, if you're a bit more interested in fonts and scaling on windows. As usual, it's a mess: https://stackoverflow.com/a/6057761/2333821

Then, with qt5, scaling for multiple screens with different dpi is also a mess and often doesn't work. With qt6, a lot of the high dpi issues are solved, so I would suggest to only look for problems with qt6 from now on and leave qt5 as it is.

jbp35 commented 3 months ago

@jbp35

I don't understand how the default font size is calculated in qt5.

A lot of UI elements depend on the font size to scale so it's not just a matter of text appearance. On windows the default QT font size should be 9px.

Up to qt5, qt is using "MS Shell Dlg2" as standard font on Windows, only with qt6 the standard font is finally Segoe UI. "MS Shell Dlg2" is mostly an alias for "Tahoma, 8pt", only qt6 defaults to 9pt. The 8.1 value is some workaround they introduced in qt4 (?, if I remember correctly), to prevent some display issues. There is this post on stack overflow, if you're a bit more interested in fonts and scaling on windows. As usual, it's a mess: https://stackoverflow.com/a/6057761/2333821

Then, with qt5, scaling for multiple screens with different dpi is also a mess and often doesn't work. With qt6, a lot of the high dpi issues are solved, so I would suggest to only look for problems with qt6 from now on and leave qt5 as it is.

Thanks for the precisions! I came to the same conclusion to give up trying to fix this in qt5.