theme cleanups and hidpi branch merged
Sebastian Kügler
sebas at kde.org
Tue Jan 28 02:10:05 UTC 2014
Hi all,
I've merged my sebas/hidpi branches into plasma-framework[master] and kde-
workspace[master]. It's quite a number of small patches, so let me summarize
some interesting bits. If you read all of this, there are screenshots looming
at the end of this email. :)
Theme Cleanup
We wanted to remove the proxy class in PlasmaCore. This meant two things:
- moving some convenience API up into Plasma::Theme, basically the color
accessors for QML. This is entirely source-compatible.
- move mSize into Plasma::Theme
- move icon size, spacing properties into Units. This is a SIC change, the
porting scripts have been updated with this, and all known occurrences have
been ported without apparent regressions (if you notice one, holler!).
- For all these new and changed API bits, api docs have been updated, and the
porting guide at has the necessary changes documented.
http://community.kde.org/Plasma/PortingQMLPlasmoids#Porting_QML_Plasmoids_to_Plasma_2
High DPI support
The iconSizes.*, smallSpacing and largeSpacing properties have moved from
Theme to Units. The point of Units is that it provides the API needed to scale
the UI taking DPI values into account. There are basically two ways to achieve
this, which are currently used:
- Coarsely stepped UIs. This means the UI is scaled in int steppings. So you
get either everything once, twice, or thrice the size. It's a trick that can
be used to "make things work" on high dpi screens, because scaling by full
pixels will give you good results. In does lose the sharpness, however.
- Finely-stepped scaling. This means that the scaling factor is used as a
qreal. This is basically a superset of the coarsely stepped UI, but it does
allow to achieve nicer results also on, for example 180 dpi screens.
This API implements the finely-stepped scaling. If you want coarsely stepped,
Math.floor() is your friend. ;)
An interesting thing is that Units applies the devicePixelRatio (the ratio
between "normalized" pixels at 96 and the actual DPI). For most screens on the
market, this value is around 1. In this case, nothing happens.
For screens above 150 DPI, we scale the icon sizes up according to the
devicePixelRatio. This happens automatically, so as long as you use
units.iconSizes.large for example, it will take DPI into account. This
devicePixelRatio is useful to make sure that the same graphical items have
large enough interaction areas, are well-spaced and proportional to their
neighbouring UI.
The finer devicePixelRatio is also very useful in combination with our SVG.
While on the one hand, it can produce spotty results for pixel-graphics, our
SVG-based themes can vastly benefit from this API.
units.gridUnit, units.smallSpacing and units.largeSpacing all take the
stepping into account, but in a different way. They are based on the rendered
height of the defaultFont. This means they take two things into account: the
DPI setting on the screen and the user-configured font size. This makes them
very useful for setting dimensions of items, dialogs, etc.
height: units.gridUnit * 40
for example. These properties are notifiable, so they'll get automatically
updated when these metrics change. In theory at least. In practice, X11 only
gives us one value, and we have to jump through some hoops currently (meaning
QApplication::desktop()->screen()->physicalDpiX()). I hope that we can make
this a bit smarter, but for now, this API is future proof. Once our underlying
target platform (Wayland, for example) supports DPI per output, we can fix
this in the underlying infrastructure.
What these patches don't do: I've not poked into PlasmaComponents yet. Well, I
have experimented with making the Slider devicePixelRatio-sized. It worked
well, but I'd like to do this in later iterations. Get the API nailed and
merged first, then we can start thinking of making our components more DPI
friendly. In some cases that will be easy, others, such as Svg and FrameSvg
need a bit more thinking and probably some engineering in the inkscape
department to make things such as bitmap shadows work well.
I've tested these things on a dual-head, 102 DPI screen, and on a 180 DPI
screen. The dual-head gives me one single DPI, no matter what monitor. That
seems to be a limitation of X. Alex says he has code to read the DPI of the
current screen, but this would bring us an X11 dependency at this point. Maybe
we can find a neater solution here.
The visual result is that I get a more proportionally correct UI on my 180 DPI
screen, spacing is more correct as well. Compare the following two
screenshots, especially the icons for batterys and brightness outputs. (These
screenshot comes from a 180 DPI display.)
before: http://vizzzion.org/stuff/plasma/battery-no-scaling.png
after: http://vizzzion.org/stuff/plasma/battery-scaling.png
An experiment that shows roughly what we can make happen automatically.
(Obviously, as this is all rendered onto the same screen, some limitations
apply, but you should get the idea nevertheless.) In this screenshot, I've
also hacked the slider to scale with the devicePixelRatio:
http://vizzzion.org/stuff/plasma/scaling-3.png
If you have a high DPI / retina display it would be cool if you could test the
changes. My main interest is in breakage, especially over-sized UI elements
that you suddenly see. On a 220DPI display, you should get double-sized icons
in many cases. With fonts configured correctly, this should give balanced
results, though. Screenshots of such screens are most welcome.
Thanks go to Marco and a few others for bouncing ideas and reviewing the code
and API.
Cheers,
--
sebas
http://www.kde.org | http://vizZzion.org | GPG Key ID: 9119 0EF9
More information about the Plasma-devel
mailing list