Bugzilla – Bug 1123424
Qt5 application rendering broken with "odd" GNOME desktop scaling factors like 1.26 instead of 1.25 / 1.5 / 1.75 / 2.0 / ...
Last modified: 2020-06-16 09:29:16 UTC
Created attachment 795465 [details] YaST2 controlcenter with Gnome font scale 1,25 and 1,26 As also for previous Leap 15.0, the YaST2 controlcenter opens with half size icons and fonts after Tweaking the font scale from 1,25 to 1,26 on Gnome. This is on a XPS 13 with HiDPI display, On the attached screenshot the windows to the upper left is YaST2 controlcenter opened with the standard font scale 1,25, the window to the upper right show YaST2 controlcenter opened after extending the font scale one step to 1,26.
Not sure how much influence have on that; we are using theme icons now. It's probably the icon size that the theme gives us.
Stasiek, any idea?
I just installed and tested the same on Tumbleweed on the same machine, and this issue simply doesn't occure there. If possible, why not jump on the current Gnome 3.30 wagon for Leap 15.1 as Tumbleweed? https://bugzilla.suse.com/show_bug.cgi?id=1123214#c1
I suspect that's not just Gnome changes. YaST CC and modules around it were heavily updated over the last year, introducing fixes to hidpi, svg icons etc.
I am not an expert here, but I do not think that it is an icon issue only because the descriptions have also the half size. Anyway....added it to our board.
I just did a fresh Leap 15.0 installation in a QEMU VM to test this. AFAICS that release does not have SVG icons yet for the YaST modules; it is limited to a small set of pre-rendered PNG icons in those sizes below /usr/share/YaST2/theme/icons: 22x22/ 32x32/ 48x48/ 64x64/ 256x256/ I can confirm that strange things happen when trying to increase the desktop scaling factor from 1.25 to 1.26, but in my case the content (both the icons and the texts) completely disappear. The YaST control center doesn't do anything special here; it just uses Qt defaults for both font and icon sizes. I am pretty sure that other Qt programs must have the same kind of problem in that scenario; this must be somewhere deep within Qt, very likely in the layer that implements the desktop settings that Qt (starting with Qt 5.x) now takes from its desktop.
Experimenting with other values it looks like that scaling works well only for certain values: 1.25 works 1.26 does not work 1.27 does not work 1.30 does not work 1.40 does not work 1.50 works 1.60 does not work 1.70 does not work 2.00 works In my case, "does not work" means that all I see is a large window with a vertical grey bar on the left that I can drag to the right, but no content whatsoever - neither the "Search" box nor the categories nor any content on the right side where the modules should appear. But I do see a status line with "Ready" in a really tiny font. To me this sounds like that desktop scaling is completely broken for Qt applications.
Confirmed. I just checked with QDirStat, and it has the exact same problem: When choosing a "weird" scaling factor, I get only the menu in a really tiny font. I see icons in the menu, but all other window elements are gone - just flat grey. There is no tree, no treemap, nothing. When choosing another scaling factor like 1.5 or 2.0, the application scales nicely.
hellcp just gave me the hint that this is called "fractional scaling", and it only works for multiples of 0.25. I just confirmed that: 1.75 also works nicely. [15:43:08] <lcp> HuHa: that's called fractional scaling, it works for multiples of 0.25 [15:43:22] <lcp> should have tested 1.75 too :P [15:44:48] <lcp> it is a qt bug, obviously, gtk works in the exact same way though [15:45:20] <lcp> so rather than being a bug, it's an expected behaviour [15:46:18] <HuHa> lcp: ah, ok, thx for the hint [15:46:27] <HuHa> I had suspected something like that [15:46:38] <HuHa> so they *should* at least fall back to the next scaling factor that is supported [15:46:50] <HuHa> and not to "tiny and unreadable" and just break completely [15:47:27] <lcp> yes, that's true, more importantly gnome should not allow to set anything non-multiple of .25 in gui tools [15:48:05] <lcp> and considering they finally got it to work natively, instead of working with changing font sizes, that will be a thing in gnome 3.32
Created attachment 798758 [details] Screenshot: QDirStat in Leap 15.0 with desktop scaling factor 1.74
Notice that this "Clean Up" is a pop-up menu from the same menu bar where you can see "File", "Edit", "View", "Go To", "Treemap". The font is tiny (probably some last-ditch minimum size as a fallback when all else fails), but the icons are there since they are compiled into the application via Qt resources. The "Clean Up" menu title might actually be a window manager decoration (or whatever the Wayland counterpart of that is called); that might be why it is rendered correctly.
Changing the subject. Old subject: "YaST icons and fonts switch to half size when Tweaking font scale from 1,25 to 1,26 (HiDPI) "
BTW that "Clean Up" menu is the only one that is a "tear-off" menu that you can rip off the menu bar for repeated use, so it has a WM title. All the other menus don't; they only have the tiny menu content. It looks to me like the QMainWindow and its QMenuBar and its QStatusBar are the only widgets that at least give it an honest try to display something if the widget font is invalid (zero size?). Most other widgets appear to use font metrics for their size hint and obviously return a zero size.
I just checked: It's the exact same in a reasonably recent Tumbleweed (tested with openSUSE-Tumbleweed-DVD-x86_64-Snapshot20190224-Media.iso). Test procedure: - Install with a GNOME desktop - Install any pure Qt application (used QDirStat here) - In the GNOME desktop, open the "Tweaks" application - In "Tweaks", switch to the "Fonts" page and change the "Scaling Factor" - Start the Qt application (QDirStat or whatever) - Check if the UI is rendered normally or with that tiny font scaling factor multiple of 0.25 -> works any other number (1.26, 1.01) -> fail
IMHO this is a Qt problem. Reassigning to our Qt maintainers.
The problem might also be on the GNOME side, or, more likely, in that plug-in where Qt gets the desktop settings. That plug-in might choose to round to the next possible font size rather than allowing fonts that are just invalid.
What GNOME shows as "scale factor" is actually just the font size. YaST does not scale at all in those screenshot as you can tell by the tiny buttons in the dock. It's still unexpected behaviour though, as text should not get smaller if the font size increases... What's the output of "xrdb -query | grep Xft"?
Also, what's the output of QT_LOGGING_RULES=qt.qpa.screen.debug=true qdirstat (or yast)?
tux@g1:~> xrdb -query | grep Xft Xft.dpi: 120.9599609375 Xft.antialias: 1 Xft.hinting: 1 Xft.hintstyle: hintslight Xft.rgba: none tux@g1:~> QT_LOGGING_RULES=qt.qpa.screen.debug=true qdirstat . Logging to /tmp/qdirstat-tux/qdirstat.log tux@g1:~> fgrep '<Verbose>' /tmp/qdirstat-tux/qdirstat.log 2019-03-04 17:36:58.204 [2558] <Verbose> Failed to parse EDID data for output "XWAYLAND0" edid data: "" 2019-03-04 17:36:58.208 [2558] <Verbose> adding QXcbScreen(0x5596f81fc8b0, name="XWAYLAND0", geometry=1680x1050+0+0, availableGeometry=1680x1016+0+34, devicePixelRatio=1.0, logicalDpi=QPair(inf,inf), physicalSize=0.0x0.0mm, screenNumber=0, virtualSize=1680x1050 (1680.0x1050.0mm), orientation=Qt::LandscapeOrientation, depth=24, refreshRate=59.0, root=38c, windowManagerName="GNOME Shell") (Primary: true ) 2019-03-04 17:36:58.208 [2558] <Verbose> primary output is "XWAYLAND0"
Not sure if this is expected, but I still find it weird: When I use "ssh -X" to that machine to try to start qdirstat via remote X, it still appears on that Wayland display (i.e. in the VM, not on the remote X server), and it looks just fine (with unscaled fonts, but otherwise perfectly normal). It complains on that ssh command line: libGL error: failed to load driver: swrast So it might simply ignore the desktop settings now.
(In reply to Stefan Hundhammer from comment #19) > tux@g1:~> xrdb -query | grep Xft > Xft.dpi: 120.9599609375 This seems to be the culprit to me. Does it work after running "echo Xft.dpi: 120 | xrdb -nocpp -merge"? If that's not enough, does "QT_LOGGING_RULES=qt.qpa.screen.debug=true QT_FONT_DPI=120 qdirstat" work? > Xft.antialias: 1 > Xft.hinting: 1 > Xft.hintstyle: hintslight > Xft.rgba: none > > tux@g1:~> QT_LOGGING_RULES=qt.qpa.screen.debug=true qdirstat . > Logging to /tmp/qdirstat-tux/qdirstat.log > > tux@g1:~> fgrep '<Verbose>' /tmp/qdirstat-tux/qdirstat.log > 2019-03-04 17:36:58.204 [2558] <Verbose> Failed to parse EDID data for > output "XWAYLAND0" edid data: "" > > 2019-03-04 17:36:58.208 [2558] <Verbose> adding QXcbScreen(0x5596f81fc8b0, > name="XWAYLAND0", geometry=1680x1050+0+0, availableGeometry=1680x1016+0+34, > devicePixelRatio=1.0, logicalDpi=QPair(inf,inf), physicalSize=0.0x0.0mm, ^^^^^^^ That doesn't look right either, but it might be unrelated. It's caused by the invalid physicalSize value, so the safeguards there didn't work for some reason. I'll have a look at that tomorrow. What does xrandr show as geometry? > screenNumber=0, virtualSize=1680x1050 (1680.0x1050.0mm), > orientation=Qt::LandscapeOrientation, depth=24, refreshRate=59.0, root=38c, > windowManagerName="GNOME Shell") (Primary: true ) > > 2019-03-04 17:36:58.208 [2558] <Verbose> primary output is "XWAYLAND0"
(In reply to Stefan Hundhammer from comment #20) > Not sure if this is expected, but I still find it weird: > > When I use "ssh -X" to that machine to try to start qdirstat via remote X, > it still appears on that Wayland display (i.e. in the VM, not on the remote > X server), Do you ssh -X from inside the VM or from the outside? > and it looks just fine (with unscaled fonts, but otherwise > perfectly normal). It complains on that ssh command line: > > libGL error: failed to load driver: swrast > > So it might simply ignore the desktop settings now. Desktop settings should not have any effect on scaling at all - unless some third-party plugin uses the private API.
(In reply to Fabian Vogt from comment #21) > (In reply to Stefan Hundhammer from comment #19) > > tux@g1:~> xrdb -query | grep Xft > > Xft.dpi: 120.9599609375 > > This seems to be the culprit to me. > Does it work after running "echo Xft.dpi: 120 | xrdb -nocpp -merge"? Right; that fixes the problem indeed, both for QDirStat and for the YaST Qt control center. > If that's not enough, does > "QT_LOGGING_RULES=qt.qpa.screen.debug=true QT_FONT_DPI=120 qdirstat" work? I tried this first (to leave the X resources undisturbed before changing them for the running X server with the "xrdb" command) and I can confirm that this also works.
(In reply to Stefan Hundhammer from comment #23) > (In reply to Fabian Vogt from comment #21) > > (In reply to Stefan Hundhammer from comment #19) > > > tux@g1:~> xrdb -query | grep Xft > > > Xft.dpi: 120.9599609375 > > > > This seems to be the culprit to me. > > Does it work after running "echo Xft.dpi: 120 | xrdb -nocpp -merge"? > > Right; that fixes the problem indeed, both for QDirStat and for the YaST Qt > control center. Ok, that confirms that the root cause is GNOME not rounding Xft.dpi. > > If that's not enough, does > > "QT_LOGGING_RULES=qt.qpa.screen.debug=true QT_FONT_DPI=120 qdirstat" work? > > I tried this first (to leave the X resources undisturbed before changing > them for the running X server with the "xrdb" command) and I can confirm > that this also works. Regarding the "QDpi(inf, inf)" issue - does that still appear if "Xft.dpi" is set to a valid integer? If so, can you give me access to the VM you saw it on?
(In reply to Fabian Vogt from comment #22) > > When I use "ssh -X" to that machine to try to start qdirstat via remote X, > > it still appears on that Wayland display (i.e. in the VM, not on the remote > > X server), > > Do you ssh -X from inside the VM or from the outside? I did that from the outside. I tried again, and the result was a bit surprising: [shundhammer @ morgul] ~ % ssh -X tux@g1 tux@g1:~> echo $DISPLAY localhost:10.0 tux@g1:~> qdirstat . Logging to /tmp/qdirstat-tux/qdirstat.log libGL error: failed to load driver: swrast -> QDirStat runs on the Wayland display (??) [shundhammer @ morgul] % ssh -X root@g1 g1:~ # echo $DISPLAY localhost:10.0 g1:~ # qdirstat . Logging to /tmp/qdirstat-root/qdirstat.log libGL error: failed to load driver: swrast -> QDirStat runs on the remote X server as expected (with unscaled fonts etc. and perfectly normal rendering) > Desktop settings should not have any effect on scaling at all - unless some > third-party plugin uses the private API. I don't know what exactly that GNOME "Tweak" application does, but it does affect Qt programs. After using it I find that "Xft.dpi" X resource in the X server changed; maybe that's all that it does. tux@g1:~> xrdb -query | grep Xft.dpi Xft.dpi: 120.9599609375 tux@g1:~> echo Xft.dpi: 120 | xrdb -nocpp -merge tux@g1:~> xrdb -query | grep Xft.dpi Xft.dpi: 120 tux@g1:~> gnome-tweaks (change the font scaling in that program's "Fonts" page) tux@g1:~> xrdb -query | grep Xft.dpi Xft.dpi: 120.9599609375
When I round the Xft.dpi to an integer number, it also works fine. tux@g1:~> echo Xft.dpi: 121 | xrdb -nocpp -merge tux@g1:~> qdirstat .
Wild shot into the blue: QVariant conversion gone wrong? Expecting and int and getting a double, so the toInt() conversion fails?
(In reply to Stefan Hundhammer from comment #27) > Wild shot into the blue: QVariant conversion gone wrong? Expecting and int > and getting a double, so the toInt() conversion fails? No, Qt simply expects that Xft.dpi is an integer, but it's not, so Xft.dpi is ignored and it uses whatever is the next source for the logical DPI (in this case the physical screen DPI). This needs to be fixed in GNOME.
I completely agree that the GNOME people should fix that on their level. But Qt could also do this a lot more defensively; AFAICS it would be a really trivial patch to also check for a double if the int conversion fails: https://github.com/qt/qtbase/blob/5.12/src/plugins/platforms/xcb/qxcbscreen.cpp#L323 static bool parseXftInt(const QByteArray& stringValue, int *value) { Q_ASSERT(value != 0); bool ok; *value = stringValue.toInt(&ok); return ok; } Maybe something like (untested) static bool parseXftInt(const QByteArray& stringValue, int *value) { Q_ASSERT(value != 0); bool ok; *value = stringValue.toInt(&ok); if (!ok) *value = round(stringValue.toDouble(&ok) return ok; } (Even the rounding is already the de luxe version)
(In reply to Stefan Hundhammer from comment #29) > I completely agree that the GNOME people should fix that on their level. > > But Qt could also do this a lot more defensively; It could, but IMO it only makes sense if the majority of toolkits interpret it in the same way. I'm not aware of any valid use of non-integer Xft DPI values - it does not make much sense to me. > AFAICS it would be a > really trivial patch to also check for a double if the int conversion fails: > > https://github.com/qt/qtbase/blob/5.12/src/plugins/platforms/xcb/qxcbscreen. > cpp#L323 > > static bool parseXftInt(const QByteArray& stringValue, int *value) > { > Q_ASSERT(value != 0); > bool ok; > *value = stringValue.toInt(&ok); > return ok; > } > > > Maybe something like (untested) > > static bool parseXftInt(const QByteArray& stringValue, int *value) > { > Q_ASSERT(value != 0); > bool ok; > *value = stringValue.toInt(&ok); > if (!ok) > *value = round(stringValue.toDouble(&ok) > return ok; > } > > > (Even the rounding is already the de luxe version)
(In reply to Fabian Vogt from comment #24) > Regarding the "QDpi(inf, inf)" issue - does that still appear if "Xft.dpi" > is set to a valid integer? If so, can you give me access to the VM you saw > it on? It does and it's indeed simply because the physicalSize is invalid. Normally the X server takes care of not supplying invalid values there, but apparently it does anyway. So that's either a bug in Xwayland or gnome. In this case playing it safe in Qt and using 96 dpi for guessing the physical size (same what X normally does) might make sense, but unless we see any bugs directly caused by that it shouldn't be necessary.
Please be aware that the original bug was in a HiDPI scenario where falling back to 96 dpi might be counterproductive.
*** Bug 1167341 has been marked as a duplicate of this bug. ***