WindowsTheme: Draw icon overlay manually instead of relying on the api

Fix drawing the link overlay icon - we must not set the device pixel
ratio here as we don't know the exact value.
Also fix some styling issues introduced with the previous commit.

This amends fd7bc16e9fbdc63bd22ba90d0c20b36ccffd2bae.

Pick-to: 6.9 6.8
Task-number: QTBUG-131843
Change-Id: I382527d17e8187bfae7cf40f352e6f87965671a1
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
Christian Ehrlicher 2025-01-06 19:44:36 +01:00
parent 185cba6e95
commit f4b64f9c12

View File

@ -903,20 +903,19 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &pixmapSiz
break;
}
// Even with SHGSI_LINKOVERLAY flag set, loaded Icon with SHDefExtractIcon doesn't have
// any overlay, so we avoid SHGSI_LINKOVERLAY flag and draw it manually (QTBUG-131843)
const auto drawLinkOverlayIcon = [](StandardPixmap sp, QPixmap &pixmap, QSizeF pixmapSize) {
// Even with SHGSI_LINKOVERLAY flag set, loaded Icon with SHDefExtractIcon doesn't have
// any overlay, so we avoid SHGSI_LINKOVERLAY flag and draw it manually (QTBUG-131843)
const auto drawLinkOverlayIconIfNeeded = [](StandardPixmap sp, QPixmap &pixmap, QSizeF pixmapSize) {
if (sp == FileLinkIcon || sp == DirLinkIcon || sp == DirLinkOpenIcon) {
QPainter painter(&pixmap);
const QSizeF linkSize = pixmapSize / (pixmapSize.height() >= 48 ? 3 : 2);
const QPixmap link = loadIconFromShell32(16769, linkSize.toSize()); // 16769 = LinkOverlayIcon
static constexpr auto LinkOverlayIconId = 16769;
const QPixmap link = loadIconFromShell32(LinkOverlayIconId, linkSize.toSize());
const int yPos = pixmap.height() - link.size().height();
painter.drawPixmap(0, yPos, int(linkSize.width()), int(linkSize.height()), link);
}
};
const auto dpr = qGuiApp->devicePixelRatio(); // Highest in the system
if (stockId != SIID_INVALID) {
SHSTOCKICONINFO iconInfo;
memset(&iconInfo, 0, sizeof(iconInfo));
@ -927,12 +926,11 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &pixmapSiz
HICON icon;
if (SHDefExtractIcon(iconInfo.szPath, iconInfo.iIcon, 0, &icon, nullptr, iconSize) == S_OK) {
QPixmap pixmap = qt_pixmapFromWinHICON(icon);
if (!pixmap.isNull()) {
drawLinkOverlayIcon(sp, pixmap, pixmap.size());
pixmap.setDevicePixelRatio(dpr);
}
DestroyIcon(icon);
return pixmap;
if (!pixmap.isNull()) {
drawLinkOverlayIconIfNeeded(sp, pixmap, pixmap.size());
return pixmap;
}
}
}
}
@ -940,8 +938,7 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &pixmapSiz
if (resourceId != -1) {
QPixmap pixmap = loadIconFromShell32(resourceId, pixmapSize);
if (!pixmap.isNull()) {
drawLinkOverlayIcon(sp, pixmap, pixmapSize);
pixmap.setDevicePixelRatio(dpr);
drawLinkOverlayIconIfNeeded(sp, pixmap, pixmapSize);
return pixmap;
}
}