QWindowsTheme: honor dpr when requesting standard icons

The devicePixelRatio was not taken into account when a standard icon was
requested from the windows qpa which resulted in blurry icons for a
dpr != 1.
Therefore pass the dpr-corrected size to QWindowsTheme::standardPixmap()
and pass this size to SHDefExtractIcon() to get a correctly scaled icon.

Pick-to: 6.7 6.6
Fixes: QTBUG-52622
Change-Id: Ia771dd2f93fa133cf2c4429ef59a9c5cb05ad047
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
Christian Ehrlicher 2023-12-11 11:50:52 +01:00
parent afddb327bd
commit 20cdc663b4
2 changed files with 18 additions and 10 deletions

View File

@ -931,17 +931,20 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &pixmapSiz
} }
if (stockId != SIID_INVALID) { if (stockId != SIID_INVALID) {
QPixmap pixmap;
SHSTOCKICONINFO iconInfo; SHSTOCKICONINFO iconInfo;
memset(&iconInfo, 0, sizeof(iconInfo)); memset(&iconInfo, 0, sizeof(iconInfo));
iconInfo.cbSize = sizeof(iconInfo); iconInfo.cbSize = sizeof(iconInfo);
stockFlags |= (pixmapSize.width() > 16 ? SHGFI_LARGEICON : SHGFI_SMALLICON); stockFlags |= SHGSI_ICONLOCATION;
if (SHGetStockIconInfo(stockId, SHGFI_ICON | stockFlags, &iconInfo) == S_OK) { if (SHGetStockIconInfo(stockId, stockFlags, &iconInfo) == S_OK) {
pixmap = qt_pixmapFromWinHICON(iconInfo.hIcon); const auto iconSize = pixmapSize.width();
DestroyIcon(iconInfo.hIcon); HICON icon;
if (SHDefExtractIcon(iconInfo.szPath, iconInfo.iIcon, 0, &icon, nullptr, iconSize) == S_OK) {
QPixmap pixmap = qt_pixmapFromWinHICON(icon);
DestroyIcon(icon);
return pixmap; return pixmap;
} }
} }
}
if (resourceId != -1) { if (resourceId != -1) {
QPixmap pixmap = loadIconFromShell32(resourceId, pixmapSize); QPixmap pixmap = loadIconFromShell32(resourceId, pixmapSize);

View File

@ -5616,8 +5616,10 @@ QIcon QCommonStylePrivate::iconFromWindowsTheme(QCommonStyle::StandardPixmap sta
case QStyle::SP_MessageBoxQuestion: case QStyle::SP_MessageBoxQuestion:
if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
QPlatformTheme::StandardPixmap sp = static_cast<QPlatformTheme::StandardPixmap>(standardIcon); QPlatformTheme::StandardPixmap sp = static_cast<QPlatformTheme::StandardPixmap>(standardIcon);
for (int size = 16 ; size <= 32 ; size += 16) { const auto dpr = qt_getDevicePixelRatio(widget);
QPixmap pixmap = theme->standardPixmap(sp, QSizeF(size, size)); for (const int size : {16, 32}) {
QPixmap pixmap = theme->standardPixmap(sp, QSizeF(size, size) * dpr);
pixmap.setDevicePixelRatio(dpr);
icon.addPixmap(pixmap, QIcon::Normal); icon.addPixmap(pixmap, QIcon::Normal);
} }
} }
@ -5628,11 +5630,14 @@ QIcon QCommonStylePrivate::iconFromWindowsTheme(QCommonStyle::StandardPixmap sta
QPlatformTheme::StandardPixmap spOff = static_cast<QPlatformTheme::StandardPixmap>(standardIcon); QPlatformTheme::StandardPixmap spOff = static_cast<QPlatformTheme::StandardPixmap>(standardIcon);
QPlatformTheme::StandardPixmap spOn = standardIcon == QStyle::SP_DirIcon ? QPlatformTheme::DirOpenIcon QPlatformTheme::StandardPixmap spOn = standardIcon == QStyle::SP_DirIcon ? QPlatformTheme::DirOpenIcon
: QPlatformTheme::DirLinkOpenIcon; : QPlatformTheme::DirLinkOpenIcon;
for (int size = 16 ; size <= 32 ; size += 16) { const auto dpr = qt_getDevicePixelRatio(widget);
QSizeF pixSize(size, size); for (const int size : {16, 32}) {
const QSizeF pixSize = QSizeF(size, size) * dpr;
QPixmap pixmap = theme->standardPixmap(spOff, pixSize); QPixmap pixmap = theme->standardPixmap(spOff, pixSize);
pixmap.setDevicePixelRatio(dpr);
icon.addPixmap(pixmap, QIcon::Normal, QIcon::Off); icon.addPixmap(pixmap, QIcon::Normal, QIcon::Off);
pixmap = theme->standardPixmap(spOn, pixSize); pixmap = theme->standardPixmap(spOn, pixSize);
pixmap.setDevicePixelRatio(dpr);
icon.addPixmap(pixmap, QIcon::Normal, QIcon::On); icon.addPixmap(pixmap, QIcon::Normal, QIcon::On);
} }
} }