Skip to content

Return appropriate value for Qt automatic legacy scaling

Ratchanan Srirattanamet requested to merge xenial_-_correct-qtquick-scaling into xenial

Created by: UniversalSuperBox

Previously, QtUbuntu did not return the appropriate values for QtQuick2 scaling. This meant that developers would need to add some boilerplate to their main.cpp or a shell script which set the QT_SCALE_FACTOR environment variable by dividing the GRID_UNIT_PIXELS value on the platform. This change makes QtUbuntu return QScreen::pixelDensity(), the value which Qt uses to determine the scale factor by itself. The constant of 96 was chosen since it appears to give amicable results with the apps I've tested and is in line with the X QPA's pixelDensity() equation.

Now, apps which specify sizes in pixels (by just putting an integer in their width or height of widgets) will receive an integer scale factor. For example, an item with a width of 100 pixels becomes 200 pixels wide when run.

Fixes https://github.com/ubports/ubuntu-touch/issues/841

Demonstration

Click any image to see a larger preview

Before

@timsueberkrueb's Switch Reloaded is a QtQuickControls2 app which was originally referenced in the bug this fixes. I've rebuilt the app to remove its Ubuntu Touch scaling hack.

And here's a quick app I made thanks to Clickable templates that places a 100px*100px rectangle on the page:

The second image demonstrates UITK scaling working while native Qt scaling does not.

After

With this change installed (sudo ubports-qa install xenial_-_correct-qtquick-scaling), Switch Reloaded looks way better.

And the test app shows that QtQuick scaling is working (at a scale of 3.0 on this display), the 100px*100px rectangle looks like it's 300px*300px now! Also, UITK scaling is completely unaffected due to some great foresight by the Canonical devs.

Danger, Will Robinson!

This fix is definitely not a magic bullet. Apps which mix UITK gridUnits or displayPixels with hard-coded pixels will have their layouts broken since UITK scaling is non-integer while Qt scaling is integer-only. This means that pixel values will only be multiplied by whole numbers (1, 2, 3) while the UITK can have any integer number of pixels in a GridUnit, therefore scale can be finely tuned. In simpler terms, you may find you have a scale of ~3.6 on UITK widgets but 3 on your pixel values. That would be all kinds of wonky.

The Qt docs mark this feature as "scaling for legacy applications", applications should choose a platform-independent unit (like the GridUnit on Ubuntu Touch) to use for scaling.

Merge request reports