Before writing about my actual Summer of Code experiences, I wanted to briefly share what I worked on before the official coding start.

Plasma toolicons
Can you see these ridiculously small toolicons next to the Media frame plasmoid? I’m talking about the icons which allow you to Resize, Rotate and Remove the Plasmoid. Compared with other icons, these are clearly too small.
So, as preparation for GSoC, I wanted to know why this happens, and what would be required to make them bigger. Thus my journey into the (Plasma) rabbithole began…
Tracking down where the containment is defined was relatively easy, and shortly after i found the code responsible for the ActionButton:
PlasmaCore.ToolTipArea {
id: button
location: PlasmaCore.Types.LeftEdge
mainText: action !== undefined ? action.text : ""
mainItem: toolTipDelegate
//API
property QtObject svg
property alias elementId: icon.elementId
property QtObject action
property bool backgroundVisible: false
property int iconSize: 32
[...]
Huh, the iconSize
is 32px? Well, that was easy to fix, surely this should be set to units.iconSizes.small
and this problem is gone…
… or so I thought. No, this didn’t improve the situation, back to square one.
Is it overwritten by the look and feel theme? plasma-workspace/lookandfeel/contents/components/ActionButton.qml
at least doesn’t - and it also happens with the style set to Oxygen.
While looking at this, I also noticed that units.iconSizes.small
returned 16px on my system. This seemed odd, because the scale factor was set to 1.8x, so I would have expected bigger icons.
Where is this icon size calculated? Ah yes, in the file units.cpp, method Units::devicePixelIconSize
.
int Units::devicePixelIconSize(const int size) const
{
/* in kiconloader.h
enum StdSizes {
SizeSmall=16,
SizeSmallMedium=22,
SizeMedium=32,
[...]
};
*/
// Scale the icon sizes up using the devicePixelRatio
// This function returns the next stepping icon size
// and multiplies the global settings with the dpi ratio.
const qreal ratio = devicePixelRatio();
if (ratio < 1.5) {
return size;
} else if (ratio < 2.0) {
return size * 1.5;
} else if (ratio < 2.5) {
[...]
}
Ok, my devicePixelRatio
is 1.8 and therefore the icon size of a small pixmap gets multiplied by 1.5 and a request for a small (16px) pixmap should return a 24px pixmap.
But it doesn’t…
Debugging suggested that my devicePixelRatio
is NOT 1.8, but rather around 1.4. How did that happen, isn’t the scale factor from the KDE settings used?
Oh, the comment in updateDevicePixelRatio()
mentions that QGuiApplication::devicePixelRatio()
is really not used:
void Units::updateDevicePixelRatio()
{
// Using QGuiApplication::devicePixelRatio() gives too coarse values,
// i.e. it directly jumps from 1.0 to 2.0. We want tighter control on
// sizing, so we compute the exact ratio and use that.
// TODO: make it possible to adapt to the dpi for the current screen dpi
// instead of assuming that all of them use the same dpi which applies for
// X11 but not for other systems.
QScreen *primary = QGuiApplication::primaryScreen();
if (!primary) {
return;
}
const qreal dpi = primary->logicalDotsPerInchX();
// Usual "default" is 96 dpi
// that magic ratio follows the definition of "device independent pixel" by Microsoft
m_devicePixelRatio = (qreal)dpi / (qreal)96;
Hmm, yes, that was the case in earlier Qt versions when devicePixelRatio
still returned an integer - but nowadays the value is a real number.
So, instead of calculating dpi / 96
I just changed it to return primary->devicePixelRatio()
.
Which now, finally, should return a devicePixelRatio of 1.8 and therefore result in bigger pixmaps.
Compiled it, and confident of victory restarted plasmashell… only to notice, that it still didn’t work.
What could there still go wrong?
So I got back to debugging.. to notice that primary->devicePixelRatio()
returns a scale factor of 1.0. Huh? Isn’t this supposed to just use the QT_SCREEN_SCALE_FACTORS
environment variable, which gets set to the value of the “Scale Display” dialog in the Systemsettings? If you want to know, the code for setting the environment variable is located in plasma-workspace/startkde/startplasmacompositor.cmake
.
But why isn’t the problem gone, is there something in Plasma that overwrites this value?
Yes, of course there is!
The only way this value can be overwritten is due to the Qt attribute Qt::AA_DisableHighDpiScaling
.
Grep’ing for that one pointed me to plasma-workspace/shell/main.cpp
- the base file for plasmashell:
int main(int argc, char *argv[])
{
// Devive pixel ratio has some problems in plasmashell currently.
// - dialog continually expands (347951)
// - Text element text is screwed (QTBUG-42606)
// - Panel struts (350614)
// This variable should possibly be removed when all are fixed
qunsetenv("QT_DEVICE_PIXEL_RATIO");
QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling);
I looked into the mentioned bugs. What should I do now? Re-enabling the HighDpiScaling-flag so the real devicePixelRatio is returned in Qt, and therefore I can use this value to calculate the sizes icons should be and then have the bigger Plasma ToolIcons? At least QTBUG-42606 seems to be fixed…
Oh boy, what have I gotten into now…
It was time to talk to my mentor!
David Edmundson quickly noticed that there should be no mismatch with the dpi / 96
calculation.
Something fishy seems to be going on here…
What is this dpi value anyway? This is the one reported by xrdb -query |grep Xft.dpi
and managed in the file $HOME/.config/kcmfonts
.
And that value - as you probably can guess by now - did not make any sense. It didn’t match the expectation of being scaleFactor * 96
, the value it should have been set to.
On we go to the location where the scaling configuration is set - scalingconfig.cpp in the KScreen KConfig Module.
void ScalingConfig::accept()
{
[...]
fontConfigGroup.writeEntry("forceFontDPI", scaleDPI());
[...]
}
qreal ScalingConfig::scaleDPI() const
{
return scaleFactor() * 96.0;
}
This scaleDPI
is then applied with xrdb -quiet -merge -nocpp
on startup.
So Xft.dpi
is set to 1.8 * 96.0
, or 172.8
.
Have you spotted what is going wrong?
I did not, but David noticed…
The X server can only handle real values - and therefore 172.8
is simlpy discarded!
A few moments later this patch was ready…

… and I was finally able to enjoy my icons in all their scaled glory! And you can too, because this patch is already in Plasma 5.10.