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 / ...
Qt5 application rendering broken with "odd" GNOME desktop scaling factors lik...
Status: NEW
Classification: openSUSE
Product: openSUSE Distribution
Classification: openSUSE
Component: GNOME
Leap 15.1
Other Other
: P5 - None : Normal (vote)
: ---
Assigned To: E-mail List
E-mail List
https://trello.com/c/uIp9v6Ku/2835-le...
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2019-01-28 23:07 UTC by Terje J. Hanssen
Modified: 2020-06-16 09:29 UTC (History)
10 users (show)

See Also:
Found By: ---
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments
YaST2 controlcenter with Gnome font scale 1,25 and 1,26 (1.03 MB, image/png)
2019-01-28 23:07 UTC, Terje J. Hanssen
Details
Screenshot: QDirStat in Leap 15.0 with desktop scaling factor 1.74 (451.62 KB, image/png)
2019-03-04 14:53 UTC, Stefan Hundhammer
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Terje J. Hanssen 2019-01-28 23:07:36 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.
Comment 1 Stefan Hundhammer 2019-01-29 10:13:28 UTC
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.
Comment 2 Stefan Hundhammer 2019-01-29 10:17:30 UTC
Stasiek, any idea?
Comment 3 Terje J. Hanssen 2019-01-29 15:17:48 UTC
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
Comment 4 Sasi Olin 2019-01-29 18:32:21 UTC
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.
Comment 5 Stefan Schubert 2019-02-04 14:48:42 UTC
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.
Comment 6 Stefan Hundhammer 2019-03-04 14:28:33 UTC
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.
Comment 7 Stefan Hundhammer 2019-03-04 14:41:40 UTC
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.
Comment 8 Stefan Hundhammer 2019-03-04 14:46:05 UTC
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.
Comment 9 Stefan Hundhammer 2019-03-04 14:48:31 UTC
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
Comment 10 Stefan Hundhammer 2019-03-04 14:53:21 UTC
Created attachment 798758 [details]
Screenshot: QDirStat in Leap 15.0 with desktop scaling factor 1.74
Comment 11 Stefan Hundhammer 2019-03-04 14:57:05 UTC
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.
Comment 12 Stefan Hundhammer 2019-03-04 15:03:16 UTC
Changing the subject. Old subject:

"YaST icons and fonts switch to half size when Tweaking font scale from 1,25 to 1,26 (HiDPI) "
Comment 13 Stefan Hundhammer 2019-03-04 15:07:39 UTC
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.
Comment 14 Stefan Hundhammer 2019-03-04 15:46:26 UTC
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
Comment 15 Stefan Hundhammer 2019-03-04 15:49:15 UTC
IMHO this is a Qt problem. Reassigning to our Qt maintainers.
Comment 16 Stefan Hundhammer 2019-03-04 16:05:15 UTC
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.
Comment 17 Fabian Vogt 2019-03-04 16:06:55 UTC
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"?
Comment 18 Fabian Vogt 2019-03-04 16:09:44 UTC
Also, what's the output of QT_LOGGING_RULES=qt.qpa.screen.debug=true qdirstat (or yast)?
Comment 19 Stefan Hundhammer 2019-03-04 16:39:52 UTC
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"
Comment 20 Stefan Hundhammer 2019-03-04 16:48:39 UTC
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.
Comment 21 Fabian Vogt 2019-03-04 18:03:42 UTC
(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"
Comment 22 Fabian Vogt 2019-03-04 18:18:28 UTC
(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.
Comment 23 Stefan Hundhammer 2019-03-05 10:22:47 UTC
(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.
Comment 24 Fabian Vogt 2019-03-05 10:28:01 UTC
(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?
Comment 25 Stefan Hundhammer 2019-03-05 10:39:04 UTC
(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
Comment 26 Stefan Hundhammer 2019-03-05 10:40:03 UTC
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 .
Comment 27 Stefan Hundhammer 2019-03-05 10:45:08 UTC
Wild shot into the blue: QVariant conversion gone wrong? Expecting and int and getting a double, so the toInt() conversion fails?
Comment 28 Fabian Vogt 2019-03-05 10:53:26 UTC
(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.
Comment 29 Stefan Hundhammer 2019-03-05 11:14:33 UTC
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)
Comment 30 Fabian Vogt 2019-03-05 11:58:17 UTC
(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)
Comment 31 Fabian Vogt 2019-03-05 13:24:33 UTC
(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.
Comment 32 Stefan Hundhammer 2019-03-05 15:10:47 UTC
Please be aware that the original bug was in a HiDPI scenario where falling back to 96 dpi might be counterproductive.
Comment 33 Stefan Hundhammer 2020-06-16 09:29:16 UTC
*** Bug 1167341 has been marked as a duplicate of this bug. ***