[Development] What to expect from QIcon/the icon engine on screen changes

Olivier Goffart olivier at woboq.com
Sun Apr 7 18:43:55 CEST 2019

On 06.04.19 10:40, Elvis Stansvik wrote:
> Hi all,
> I'm looking for someone who knows the inner workings of QIcon and the
> icon engines.
> In our application, we almost exclusively use SVG icons, and we use a
> single SVG file for each icon (no @2x versions) that we try to design
> to work reasonably well at all sizes, since we do not have the
> resources to make custom variations for each target size.
> We put these SVG icons into an XDG icon theme, that we ship inside the
> application resources (.qrc) in the expected XDG layout and with an
> icon theme index file. We can then use
> QIcon::fromTheme("our-app-some-icon") to reference an icon (either
> through the .ui file or in code).
> The problem we've run into is that when the application is launched in
> a mixed-DPI setup, for example a retina Mac laptop with an external
> lower-DPI monitor, the icons appear too large and get cropped. In
> effect, it seems to always use the DPI of the primary screen (the
> built-in retina screen) when calculating the size of the pixmaps it
> generates for the icons.

Not sure if this is your problem, but it seems that 
QSvgIconEngine::virtual_hook does not handle the QIconEngine::ScaledPixmapHook 
call, which is needed for the QIcon::pixmap(QWindow *window, ...) call.

> To work around this, we've had to put in special code in all of our
> widgets that use icons. The code reacts to screen change events (or
> changes to the underlying QWindow in some cases), and in that code, go
> through each and every one of our icons and do this monkey dance:
>          auto pixmap = someButton->icon().pixmap(someButton->iconSize());
>          pixmap.setDevicePixelRatio(window()->windowHandle()->screen()->devicePixelRatio());
>          someButton->setIcon(QIcon(pixmap));
> So essentially taking the pixmap out of the icon, set its DPR to that
> of the current screen, and then set that pixmap back on the icon.
> This "works", the icons now look correct on both the retina screen and
> the external one, and adjust themselves when the application is moved
> back and forth, or when the external monitor is activated/deactivated.
> But surely this kludge should not be necessary? We've provided Qt with
> an SVG, so it should be able to work out on its own that the screen
> has changed, and regenerate an appropriate pixmap in response to that?
> Some more details:
> - We are running with the Qt::AA_UseHighDpiPixmaps application
> attribute turned on. I'm not sure this is relevant for this issue
> though, because AFAIK that attribute is only about picking 2x versions
> of icons (we have a couple of those, where we have PNGs with 2x
> versions).
> - We are not running with Qt's built-in scaling activated, but relying
> on the Mac platform scaling (I'm not even sure Qt's built-in scaling
> is applicable on Mac). The application runs with
> NSHighResolutionCapable set to True in its Info.plist (which I also
> think is the default nowadays).
> - I have not investigated yet whether this problem also occurs on a
> mixed-DPI Linux setup, with Qt's high-dpi scaling activated. Nor have
> I checked if it happens on Windows using it's artificial "screen
> scaling" (we do not use Qt's built-in scaling on Windows either,
> trying to follow the advise in the docs to avoid that for new
> applications). So for now this is only about Mac retina + external
> monitor.
> Any advise on this would be highly appreciated, because the code
> required to re-trigger pixmap generation on screen changes is a real
> kludge all over our code base, and often it happens that we add
> buttons et.c. with icons, but forget to update this machinery.
> I'm not at the office at the moment, but can provide a little test
> program that mimics what we're doing on Monday.
> Thanks in advance,
> Elvis
> _______________________________________________
> Development mailing list
> Development at qt-project.org
> https://lists.qt-project.org/listinfo/development

More information about the Development mailing list