Bug 471443 - Low-res Images in Qt Apps when using fractional scaling
Summary: Low-res Images in Qt Apps when using fractional scaling
Status: RESOLVED INTENTIONAL
Alias: None
Product: plasmashell
Classification: Plasma
Component: Startup process (show other bugs)
Version: 5.27.6
Platform: NixOS Linux
: NOR normal
Target Milestone: 1.0
Assignee: Plasma Bugs List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-06-25 17:28 UTC by Max Staff
Modified: 2023-09-20 17:42 UTC (History)
4 users (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments
Current pixelated scaling (13.19 KB, image/png)
2023-06-25 17:28 UTC, Max Staff
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Max Staff 2023-06-25 17:28:37 UTC
Created attachment 159897 [details]
Current pixelated scaling

SUMMARY
***
Icons in the Telegram Desktop App are blurry or pixelated when setting the global scaling to e.g. 150% in the display settings.
***


STEPS TO REPRODUCE
1. Set global scaling to 150% in display settings
2. reboot
3. open Telegram and closely look at any icon

OBSERVED RESULT

* rounded corners of profile pictures look pixelated
* icons and emojis look pixelated

EXPECTED RESULT
* rounded corners actually round
* high-res version of icons and emojis used

SOFTWARE/OS VERSIONS
NixOS: 23.11
KDE Plasma Version: 5.27.6
KDE Frameworks Version: 5.107.0
Qt Version: 5.15.9
Kernel-Version: 6.3.6 (64-bit)
Graphics: X11

ADDITIONAL INFORMATION
* Telegram also had display scaling set to 225% by default (in the in-app-settings) after switching to global scaling of 150%
* Other users have also reported this to the Telegram Desktop Github issue tracker as well as the Qt issue tracker with both saying that the issue lies with KDE
  * some users have reported that this happens only on the official version of Telegram for their respective distro, not on snaps
  * quote from Telegram Desktop issue tracker: "According to https://doc.qt.io/qt-6/highdpi.html, QT_SCREEN_SCALE_FACTORS is in line with debug-only environment variables KDE shouldn't set."
Comment 1 Max Staff 2023-06-25 17:36:54 UTC
Telegram Desktop issues:
https://github.com/telegramdesktop/tdesktop/issues/26155
https://github.com/telegramdesktop/tdesktop/issues/17173
https://github.com/telegramdesktop/tdesktop/issues/25961

Explanation of the problem (see block below screenshot, item no 4):
https://github.com/telegramdesktop/tdesktop/issues/25126
That one also contains links to the respective Qt bugreports, in case they change the text after this bugreport here's a copy:

> Icons and emojis are blurry #17173 - exists only in third-party builds, was reported as https://bugreports.qt.io/browse/QTBUG-95930, https://bugreports.qt.io/browse/QTBUG-99546 and https://bugreports.qt.io/browse/QTBUG-110626, Qt tried to fix this, but then reverted, so apparently they think there's no bug on their side and this needs a report to KDE as they probably use the wrong API to tell scale factor to Qt. According to https://doc.qt.io/qt-6/highdpi.html, QT_SCREEN_SCALE_FACTORS is in line with debug-only environment variables KDE shouldn't set.
Comment 2 Ilya Fedin 2023-07-04 23:40:10 UTC
Hope plasmashell is the correct component, the bug is in startkde which is a part of plasma-workspace. The underlying problem is Plasma uses debug environment variables Qt provides instead of the proper API[1] such as Xft.dpi in xrdb and Xft/DPI in xsettings. The second one could be changed without re-login.

Since the way Plasma sets up the scaling[3][4] is a debug one[2], it completely disregards the hints set by applications, such as no fractional scaling support[5] so Qt applies fractional scaling forcefully what leads to UI corruption. I'd say this is even worse than the effect of setting GTK debug environment variables which Plasma was doing in the past.

Moreover, during the evolution of the codebase it has happened that a part of this logic has ended up being in startplasma-x11.cpp[3] and a part resides now in startplasma.cpp[4]. This leads to Xwayland Qt 5 applications being forbidden to scale.

QT_AUTO_SCREEN_SCALE_FACTOR[4] is also a deprecated variable that was replaced by QT_ENABLE_HIGHDPI_SCALING during Qt 5 lifetime (seem to be undocumented) and is not being read by Qt 6 so Qt 6 applications end up being double-scaled.

What Plasma should is to stop using Qt's debug environment variables, at all. This never makes any good, just like with gtk and likely any other library. If it needs its apps to be fractionally scaled then it should do that properly: by opting in every application, as that's the way upstream in the face of Qt has provided. Every other way screws up third-party applications which may not have support for fractional scaling.

[1] https://doc.qt.io/qt-6/highdpi.html#configuring-x11 (undocumented in Qt 5 but mostly the same)
[2] https://doc.qt.io/qt-6/highdpi.html#environment-variable-reference (poorly documented in Qt 5)
[3] https://invent.kde.org/plasma/plasma-workspace/-/blob/master/startkde/startplasma-x11.cpp#L46-54
[4] https://invent.kde.org/plasma/plasma-workspace/-/blob/master/startkde/startplasma.cpp#L328-330
[5] https://doc.qt.io/qt-5/qguiapplication.html#highDpiScaleFactorRoundingPolicy
Comment 3 David Edmundson 2023-09-18 09:30:08 UTC
Font DPI and scaling are separate concepts. We *do* use Xft.dpi in xrdb.
We still need something for the applications to scale instead of just adjusting their font. 

It was not dubbed a debug environment variable at the time [1]. 
"This allows applications written for low DPI screens to run unchanged on high DPI devices. This feature is opt-in, and can be enabled using the following environment variables"

Unchanged meaning everything will be the right size, but some images mnight be upscaled internally. This was dubbed better than things being too small. Retrofitting is always hard, there's no magic solution.

Whilst the situation could have been handled differently if we had done things differently in the past, the proposals given in #4 will break a tonne of software and are simply not viable.
Over time Wayland is more explicit and applications will gain Qt scaling support and this will be moot.

[1] https://doc.qt.io/qt-5/highdpi.html#configuring-x11
Comment 4 Ilya Fedin 2023-09-18 10:02:52 UTC
David, I had a conversation on Qt mailing list and Qt developers said they were always treating the variables as a way for the user to override application behavior, not as a way for environment to tell the settings, even if this was not documented. The intended way was always Xft.dpi. You're mis-using the APIs what breaks third-party applications, closing as intentional is not really nice.
Comment 5 Nate Graham 2023-09-19 16:54:33 UTC
Can you point me to an archive of that thread?
Comment 7 Nate Graham 2023-09-19 17:40:05 UTC
Thanks.

From what I can see of that thread, there's no consensus that we're doing anything wrong. Some quotations from the thread:

> if I recall correctly the current consensus there is “keep it working exactly
> as-is” so the subject of changing its behavior is a good candidate for
> discussion on this list.

And the ensuing discussion resulted in statements like these:

> It it's a system setting, then one should assume it's been set to the exact 
> value that the system wanted it to be. So if they'd wanted it rounded, they'd 
> have rounded it.

> Looks inconclusive to me - no clear consensus either way. (I’m also not sure
> if it's a bug - it’s just "the current behavior")

> It it's a system setting, then one should assume it's been set to the exact 
> value that the system wanted it to be. So if they'd wanted it rounded, they'd 
> have rounded it.

> The QT_ environment variables are often sharp tools, and do make it possible
> to configure Qt in such a way that it appears broken.
> 
> I’m not sure I see what KDE could realistically change here  - given that they
> want to continue to set QT_SCREEN_SCALE_FACTORS, also with fractional
> factors since that works for most/many apps

I don't see indications that the Qt developers view what we're doing as a misuse of the feature or a bug. I understand that you see it that way, and that's fine, but the Qt developers don't appear to share that viewpoint.
Comment 8 Ilya Fedin 2023-09-19 17:44:42 UTC
The problem is QGuiApplication::setHighDpiScaleFactorRoundingPolicy is broken on Plasma X11 what makes applications broken and no one wants to take the responsibility... Does this mean we have to block applications to work on KDE X11 if HiDPI is active?
Comment 9 Nate Graham 2023-09-20 17:09:22 UTC
Can you explain exactly how it's broken and what the effects are for the user? i.e. where can I test it out to see the brokenness?
Comment 10 Ilya Fedin 2023-09-20 17:19:55 UTC
Try any distro build of Telegram Desktop (official builds patch Qt to work around the bug) on a KDE X11 session with fractional scaling factor (e.g. 1.25). The app is full of 10 year old code, written before Qt got HiDPI support, it has integer devicePixelRatio support thanks to macOS but no fractional devicePixelRatio support. Application uses QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::RoundPreferFloor) to tell Qt about that but given that KDE uses this user-override environment variable (instead of the proper way) to tell the scale factor, this setting gets ignored by Qt and application UI is broken.
Comment 11 Ilya Fedin 2023-09-20 17:42:39 UTC
> Font DPI and scaling are separate concepts. We *do* use Xft.dpi in xrdb.
> We still need something for the applications to scale instead of just adjusting their font. 

David, Qt uses DPI to do scaling on both Windows and X11. It's the intended behavior to do scaling on those systems. The problem is just some Qt applications don't enable HiDPI scaling, it's opt-in in Qt 5. Application should do this in Qt 5 to achieve HiDPI scaling:

QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true);
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);

With Qt 6, it works out-of-the-box. QT_SCREEN_SCALE_FACTORS being a user-override variable discards all this so Qt 5 applications being scaled even without these lines. For some applciations this hide the problem that they didn't enabled HiDPI scaling so it won't be scaled on other systems (non-KDE Linux or Windows). That's probably why most Qt 5 applications don't being scaled automatically outside of KDE on Linux: KDE hides that. For other applications like Telegram, this breaks entire application UI on KDE despite application developers did everything right (the right HighDpiScaleFactorRoundingPolicy is set).

The reality is that Xft.dpi is for UI scaling. But KDE interprets it incorrectly as font DPI setting and tinkers with sets of these debug variables instead (what is likely to always produce various bugs, just like it was when KDE was setting debug GTK variables).