Fix the tray icon scaling on HiDPI screens
Needs RevisionPublic

Authored by pgkos on Sep 16 2017, 2:43 PM.

Details

Reviewers
ngraham
Group Reviewers
Plasma
Summary

This patch fixes the problem with tray icon scaling on HiDPI screens - the icons are too small.

The function Units::roundToIconSize returns an unscaled icon size, but we need a size scaled by the HiDPI factor (e.g. 2.0). Also, the arguments passed to this function must be in pixels (density-independent, for 96 dpi), but now they are multiplied by the HiDPI factor, so the function returns a wrong size.

Diff Detail

Repository
R242 Plasma Framework (Library)
Lint
Lint Skipped
Unit
Unit Tests Skipped
pgkos created this revision.Sep 16 2017, 2:43 PM
Restricted Application added a project: Plasma. · View Herald TranscriptSep 16 2017, 2:43 PM
Restricted Application added a subscriber: plasma-devel. · View Herald Transcript

So isn't it round to icon size which is wrong?

pgkos updated this revision to Diff 19592.Sep 16 2017, 5:31 PM
pgkos changed the repository for this revision from R120 Plasma Workspace to R242 Plasma Framework (Library).

Edited the function Units::roundToIconSize so it both accepts and outputs a dpi-scaled pixel value.

This might break some things, but on the other hand there are places (other than the system tray) which also have exactly the same problem with icon scaling on hidpi screens (see e.g. https://cgit.kde.org/plasma-desktop.git/tree/applets/taskmanager/package/contents/ui/Task.qml), this patch will also fix all these other cases.

Restricted Application added a project: Frameworks. · View Herald TranscriptSep 16 2017, 5:31 PM
Restricted Application added a subscriber: Frameworks. · View Herald Transcript
pgkos updated this revision to Diff 19612.Sep 17 2017, 2:32 PM

Fixed the previous diff.

I don't understand this. RoundToIconSize is supposed to round down and that's it. If I pass it 100 px because I'm on a high dpi screen, it will still return 100. Only if I pass it e.g. 34 it will change it to 32.

pgkos added a comment.Sep 17 2017, 3:04 PM

@broulik consider this case:

The tray icons' size is defined by default in org.kde.plasma.private.systemtray/contents/config/main.xml to smallMedium, which means 22 pixels on a 96-dpi screen. On a 192-dpi screen, the icons' real size is 44 pixels.
Now, in org.kde.plasma.private.systemtray/contents/ui/main.qml there is this line:

units.roundToIconSize(Math.min(Math.min(width, height), units.iconSizes[iconSizes[plasmoid.configuration.iconSize]]))

The height property is the height of the panel (assuming the panel is horizontal). On my hidpi screen the default panel height is around 72 pixels (32 px * 2).

So the above line evaluates to:
units.roundToIconSize(Math.min(72, units.iconSizes.smallMedium))
units.roundToIconSize(Math.min(72, 44))
units.roundToIconSize(44)

and that gets rounded to medium size, which is incorrect, because we want a smallMedium size multiplied by two (32 px != 22 px * 2).

So, on a hidpi screen the roundToIconSize function returns a wrong size, and additionally it (wrongly) does not multiply the size by the icon dpi scaling factor (e.g. 2.0).

So, Kai is right, it roundToIconSize only round size independent from dpi. Then when it used, it should be multiplyed by dpi.

pgkos added a comment.Sep 17 2017, 3:19 PM

@anthonyfieroni my first version of the diff changed only the tray icon QML file, but I think that it is better to fix it in the plasma framework, as that function is used in multiple other places and there is the same problem with wrongly sized icons on hidpi screens.

Any chance we can reach some kind of consensus here?

pgkos updated this revision to Diff 26878.Feb 10 2018, 4:25 PM

This is a simpler implementation - the diff changes roundToIconSize so it uses scaled units.

pgkos added a comment.Feb 10 2018, 4:34 PM

In my opinion, roundToIconSize should operate on scaled units - it is used multiple times in a few plasmoids - all calls from them to roundToIconSize assume it will operate on scaled units.

The method, as it is now, is useless, because QML code has no access to KIconLoader sizes and devicePixelIconSize() method, so it cannot operate on unscaled units or convert them on the fly.

ngraham requested changes to this revision.Oct 21 2018, 9:31 PM

This does not actually compile for me against current git master:

/home/dev/repos/plasma-framework/src/declarativeimports/core/units.cpp: In static member function ‘static int Units::roundToIconSize(int)’:
/home/dev/repos/plasma-framework/src/declarativeimports/core/units.cpp:160:65: error: cannot call member function ‘int Units::devicePixelIconSize(int) const’ without object
     } else if (size < devicePixelIconSize(KIconLoader::SizeSmall)) {
                                                                 ^
/home/dev/repos/plasma-framework/src/declarativeimports/core/units.cpp:161:58: error: cannot call member function ‘int Units::devicePixelIconSize(int) const’ without object
         return devicePixelIconSize(KIconLoader::SizeSmall) / 2;
                                                          ^
/home/dev/repos/plasma-framework/src/declarativeimports/core/units.cpp:162:71: error: cannot call member function ‘int Units::devicePixelIconSize(int) const’ without object
     } else if (size < devicePixelIconSize(KIconLoader::SizeSmallMedium)) {
                                                                       ^
/home/dev/repos/plasma-framework/src/declarativeimports/core/units.cpp:163:58: error: cannot call member function ‘int Units::devicePixelIconSize(int) const’ without object
         return devicePixelIconSize(KIconLoader::SizeSmall);
                                                          ^
/home/dev/repos/plasma-framework/src/declarativeimports/core/units.cpp:164:66: error: cannot call member function ‘int Units::devicePixelIconSize(int) const’ without object
     } else if (size < devicePixelIconSize(KIconLoader::SizeMedium)) {
                                                                  ^
/home/dev/repos/plasma-framework/src/declarativeimports/core/units.cpp:165:64: error: cannot call member function ‘int Units::devicePixelIconSize(int) const’ without object
         return devicePixelIconSize(KIconLoader::SizeSmallMedium);
                                                                ^
/home/dev/repos/plasma-framework/src/declarativeimports/core/units.cpp:166:65: error: cannot call member function ‘int Units::devicePixelIconSize(int) const’ without object
     } else if (size < devicePixelIconSize(KIconLoader::SizeLarge)) {
                                                                 ^
/home/dev/repos/plasma-framework/src/declarativeimports/core/units.cpp:167:59: error: cannot call member function ‘int Units::devicePixelIconSize(int) const’ without object
         return devicePixelIconSize(KIconLoader::SizeMedium);
                                                           ^
/home/dev/repos/plasma-framework/src/declarativeimports/core/units.cpp:168:64: error: cannot call member function ‘int Units::devicePixelIconSize(int) const’ without object
     } else if (size < devicePixelIconSize(KIconLoader::SizeHuge)) {
                                                                ^
/home/dev/repos/plasma-framework/src/declarativeimports/core/units.cpp:169:58: error: cannot call member function ‘int Units::devicePixelIconSize(int) const’ without object
         return devicePixelIconSize(KIconLoader::SizeLarge);
                                                          ^
src/plasmaquick/CMakeFiles/KF5PlasmaQuick.dir/build.make:374: recipe for target 'src/plasmaquick/CMakeFiles/KF5PlasmaQuick.dir/__/declarativeimports/core/units.cpp.o' failed
make[2]: *** [src/plasmaquick/CMakeFiles/KF5PlasmaQuick.dir/__/declarativeimports/core/units.cpp.o] Error 1
CMakeFiles/Makefile2:1782: recipe for target 'src/plasmaquick/CMakeFiles/KF5PlasmaQuick.dir/all' failed
make[1]: *** [src/plasmaquick/CMakeFiles/KF5PlasmaQuick.dir/all] Error 2
This revision now requires changes to proceed.Oct 21 2018, 9:31 PM
Restricted Application edited subscribers, added: kde-frameworks-devel; removed: Frameworks. · View Herald TranscriptOct 21 2018, 9:31 PM