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