From 59bbfb17db563d7e62b9f3158dab3cc6e7e68acd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 22 Nov 2024 18:40:09 +0100 Subject: [PATCH] Windows: Return high-DPI pixmaps from QWindowsTheme::standardPixmap Most consumers feed the pixmaps into a QIcon, pulling out pixmaps of sizes 32, 64, 128, 256, 512, so consumers of that QIcon will not see low-resolution pixmaps for the common sizes like 64x64. However if someone uses standardPixmap directly, or request an icon with size 512x512, we won't have a high-DPI pixmap. Unlike QStyle::standardPixmap we don't have a QWidget/QWindow argument we can use to resolve the target DPR, so we have to assume the pixmap can be used anywhere, and use the highest DPR we've seen so far, via QGuiApplication::devicePixelRatio(). Pick-to: 6.9 Change-Id: Ib7fb08ab4932da1ca3f3325e25a7022c1cd17435 Reviewed-by: Volker Hilsheimer --- src/plugins/platforms/windows/qwindowstheme.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index 1379018793b..92b8478ee52 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -803,12 +803,12 @@ void QWindowsTheme::refreshIconPixmapSizes() // Defined in qpixmap_win.cpp Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon); -static QPixmap loadIconFromShell32(int resourceId, QSizeF size) +static QPixmap loadIconFromShell32(int resourceId, QSize size) { if (const HMODULE hmod = QSystemLibrary::load(L"shell32")) { auto iconHandle = static_cast(LoadImage(hmod, MAKEINTRESOURCE(resourceId), - IMAGE_ICON, int(size.width()), int(size.height()), 0)); + IMAGE_ICON, size.width(), size.height(), 0)); if (iconHandle) { QPixmap iconpixmap = qt_pixmapFromWinHICON(iconHandle); DestroyIcon(iconHandle); @@ -818,7 +818,7 @@ static QPixmap loadIconFromShell32(int resourceId, QSizeF size) return QPixmap(); } -QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &pixmapSize) const +QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const { int resourceId = -1; SHSTOCKICONID stockId = SIID_INVALID; @@ -907,16 +907,19 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &pixmapSiz break; } + const auto dpr = qGuiApp->devicePixelRatio(); // Highest in the system + if (stockId != SIID_INVALID) { SHSTOCKICONINFO iconInfo; memset(&iconInfo, 0, sizeof(iconInfo)); iconInfo.cbSize = sizeof(iconInfo); stockFlags |= SHGSI_ICONLOCATION; if (SHGetStockIconInfo(stockId, stockFlags, &iconInfo) == S_OK) { - const auto iconSize = pixmapSize.width(); + const auto iconSize = size.width() * dpr; HICON icon; if (SHDefExtractIcon(iconInfo.szPath, iconInfo.iIcon, 0, &icon, nullptr, iconSize) == S_OK) { QPixmap pixmap = qt_pixmapFromWinHICON(icon); + pixmap.setDevicePixelRatio(dpr); DestroyIcon(icon); return pixmap; } @@ -924,13 +927,15 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &pixmapSiz } if (resourceId != -1) { + const QSize pixmapSize(size.width() * dpr, size.height() * dpr); QPixmap pixmap = loadIconFromShell32(resourceId, pixmapSize); if (!pixmap.isNull()) { if (sp == FileLinkIcon || sp == DirLinkIcon || sp == DirLinkOpenIcon) { QPainter painter(&pixmap); QPixmap link = loadIconFromShell32(30, pixmapSize); - painter.drawPixmap(0, 0, int(pixmapSize.width()), int(pixmapSize.height()), link); + painter.drawPixmap(0, 0, pixmapSize.width(), pixmapSize.height(), link); } + pixmap.setDevicePixelRatio(dpr); return pixmap; } } @@ -943,7 +948,7 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &pixmapSiz return pixmap; } - return QPlatformTheme::standardPixmap(sp, pixmapSize); + return QPlatformTheme::standardPixmap(sp, size); } enum { // Shell image list ids