POC: Wayland fractional scale support#30492
POC: Wayland fractional scale support#30492zvova7890 wants to merge 1 commit intotelegramdesktop:devfrom
Conversation
| if (Platform::IsMac()) { | ||
| // 110% for Retina screens by default. | ||
| cSetScreenScale((useRatio == 2) ? 110 : style::kScaleDefault); | ||
| cSetScreenScale((useRatio >= 1.99) ? 110 : style::kScaleDefault); |
There was a problem hiding this comment.
Why do you change this macOS-specific code?
|
If I understand right, style::DevicePixelRatio is still set from QGuiApplication::devicePixelRatio? But AFAIK it returns ceiled value on fractional scales, how does it work? |
Yes, but not exactly. It is updated later in RefreshDevicePixelRatioFromWindow when QWindow receives a new scale factor from the compositor. Because of that, Telegram should support dynamically changing the scale at runtime. There were several problems with that, which I found during testing -- all known ones were resolved. Actually, it should be connected to QWindow::screenChanged and update the scale factor every time it changes. In that case, if the scale factor changes due to a monitor settings update or the window moving to another screen with a different scale factor, the UI will stay crisp. In this diff it is not yet done, but on my local branch I've already tested -- it seems to be working fine. |
That's not really right since on Wayland fractional scale factor is per-window rather than per-screen. The right event is QEvent::DevicePixelRatioChange.
I don't see it in this PR 🤔 |
Yes, you're right. Despite Qt still sending screenChanged events on Wayland for per‑window fractional scale changes, probably because all other platforms do that and Qt wants to keep as much as possible the same behavior across platforms, DevicePixelRatioChange is a better choice.
BTW, AFAIK Telegram does not support dynamic scale change on all platforms, right? I was interested whether it was possible even theoretically, and it seems yes, I managed to make core UI functionality adapt dynamically to the scale changes (e.g. moving around monitors with different scales or changing the scale for one monitor). Oh, how many caches, so many caches... There is the cache even for rounded rects :) |
|
Oh, thanks
Yeah, the fact that the app has lots of cache for CPU-based animations is the main blocker to support runtime scale changes and implement #1121. I so far believed that it's an architectural choice that couldn't be fixed at that point in time and only new client written from scratch on some other toolkit could fix it (such as https://web.telegram.org/a/get). |
2d0d1f5 to
3b794c5
Compare
3b794c5 to
e9b1ed2
Compare
|
I've pushed an updated version, with initial dynamic DPR support. So far, what I'm using works +- fine. I think it pretty doable 🤔 |
It conflicts though... |
That's because I'm on v6.6.4, not a head |
|
Great thanks, you save my eyes |
Since Telegram moved to Qt6, it has broken fractional scaling support on both X11 and Wayland. With Qt5, fractional scaling works as usual on X11. So I rebuilt Telegram myself with patches that force XWayland and built it with Qt5, thus fixing recurring compilation issues with new code.
Lately, I was wondering if current AI capabilities would be enough to fix the infamous "unfixable" Telegram problem? Apparently, yes! Just throw in an idea and see the magic. If nobody wants to fix it, let AI do it, right?
Anyway, after a ~day of iterations and fixing crashes/glitches/etc., I ended up with a patch that allows Telegram to run with a crystal-clear picture under a KDE Wayland session with 1.5 and 2.5 scale factors. Even enabling experimental fractional scaling works as intended.
There are still crashes/glitches/hangs because many places are not obviously dependent on the DevicePixelRatio. All usages of DevicePixelRatio should be reviewed, but there is a lot of code, and this can be done gradually, as ideally these changes should not break integer scaling. For example, I spent an hour figuring out why the user profile image history was trying to load images infinitely with no success. It turned out there was a check like
if (target.size() == requested) cached = true;and computation just don't match because of fractional scale.So basically, I don’t think anyone would be interested in merging this. Moreover, I don’t think I want to make it production-ready. I’m just sharing this as a proof of concept that says "Hey, it’s possible".
About 98% of the refactoring/bug fixing was done by GPT 5.4. I’m familiar with Qt, but not with the Telegram codebase at all. AI just makes it 9999x faster. God bless RAM.
There are also parts in
lib_uiandlib_lottie; I’ve included the diff here if anyone wants to check it out.Feel free to close this PR at any time!
tg-fraction-scale.diff.tar.gz diff for v6.6.4