Skip to content

Commit

Permalink
Document that QPlatformTheme::standardPixmap should always be a 1x pi…
Browse files Browse the repository at this point in the history
…xmap

This reverts 59bbfb1 and
c853054, as that approach
was causing issues for QCommonStyle::iconFromWindowsTheme,
for example in situations where the system has a 1x and 2.5x
screen, and the user requests a 16x16 pixmap or icon via
QStyle::standardPixmap or QStyle::standardIcon. In that
situation our smallest pixmap is 40x40, and we need to
downscale, causing blurred results on a 1x screen.

Pick-to: 6.9
Change-Id: Ifa6e15d37d15954df689253c32eaa779885c567b
Reviewed-by: Volker Hilsheimer <[email protected]>
  • Loading branch information
torarnv committed Dec 16, 2024
1 parent 66d42b6 commit d884aba
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 17 deletions.
11 changes: 9 additions & 2 deletions src/gui/kernel/qplatformtheme.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -470,9 +470,16 @@ const QFont *QPlatformTheme::font(Font type) const
return nullptr;
}

QPixmap QPlatformTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const
/*!
\brief Return a pixmap for \a standardPixmap, at the given \a size.
The implementation should not take system DPR into account, and
always return a pixmap with a DPR of 1. It's up to the consumer
to account for DPR and request a pixmap of the right size.
*/
QPixmap QPlatformTheme::standardPixmap(StandardPixmap standardPixmap, const QSizeF &size) const
{
Q_UNUSED(sp);
Q_UNUSED(standardPixmap);
Q_UNUSED(size);
// TODO Should return QCommonStyle pixmaps?
return QPixmap();
Expand Down
4 changes: 1 addition & 3 deletions src/plugins/platforms/cocoa/qcocoatheme.mm
Original file line number Diff line number Diff line change
Expand Up @@ -390,9 +390,7 @@ QPixmap qt_mac_convert_iconref(const IconRef icon, int width, int height)
QT_IGNORE_DEPRECATIONS(GetIconRef(kOnSystemDisk, kSystemIconsCreator, iconType, &icon));

if (icon) {
const auto dpr = qGuiApp->devicePixelRatio(); // Highest in the system
pixmap = qt_mac_convert_iconref(icon, size.width() * dpr, size.height() * dpr);
pixmap.setDevicePixelRatio(dpr);
pixmap = qt_mac_convert_iconref(icon, size.width(), size.height());
QT_IGNORE_DEPRECATIONS(ReleaseIconRef(icon));
}

Expand Down
17 changes: 6 additions & 11 deletions src/plugins/platforms/windows/qwindowstheme.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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, QSize size)
static QPixmap loadIconFromShell32(int resourceId, QSizeF size)
{
if (const HMODULE hmod = QSystemLibrary::load(L"shell32")) {
auto iconHandle =
static_cast<HICON>(LoadImage(hmod, MAKEINTRESOURCE(resourceId),
IMAGE_ICON, size.width(), size.height(), 0));
IMAGE_ICON, int(size.width()), int(size.height()), 0));
if (iconHandle) {
QPixmap iconpixmap = qt_pixmapFromWinHICON(iconHandle);
DestroyIcon(iconHandle);
Expand All @@ -818,7 +818,7 @@ static QPixmap loadIconFromShell32(int resourceId, QSize size)
return QPixmap();
}

QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const
QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &pixmapSize) const
{
int resourceId = -1;
SHSTOCKICONID stockId = SIID_INVALID;
Expand Down Expand Up @@ -907,35 +907,30 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) con
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 = size.width() * dpr;
const auto iconSize = pixmapSize.width();
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;
}
}
}

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, pixmapSize.width(), pixmapSize.height(), link);
painter.drawPixmap(0, 0, int(pixmapSize.width()), int(pixmapSize.height()), link);
}
pixmap.setDevicePixelRatio(dpr);
return pixmap;
}
}
Expand All @@ -948,7 +943,7 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) con
return pixmap;
}

return QPlatformTheme::standardPixmap(sp, size);
return QPlatformTheme::standardPixmap(sp, pixmapSize);
}

enum { // Shell image list ids
Expand Down
3 changes: 2 additions & 1 deletion tests/manual/iconbrowser/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,8 @@ class IconModel : public QAbstractItemModel
case Theme:
if (row >= themedIcons.size())
break;
return QIcon(QApplicationPrivate::platformTheme()->standardPixmap(QPlatformTheme::StandardPixmap(row), {64, 64}));
return QIcon(QApplicationPrivate::platformTheme()->standardPixmap(
QPlatformTheme::StandardPixmap(row), QSize(64, 64) * qGuiApp->devicePixelRatio()));
case Icon:
if (row < themedIcons.size())
return QIcon::fromTheme(themedIcons.at(row));
Expand Down

0 comments on commit d884aba

Please sign in to comment.