QFileSystemModel: only use theme icons if a theme is set

The old code checked themes first, and only went through the platform's
file-based icon resolving code if the theme didn't provide an icon. With
the added support for theme icons on macOS and Windows, this broke
standard file icons on macOS and Windows: the icon theme provides the
font-based icons, but they are significantly different from what users
expect a folder, drive, or generic file icon to look like in a file
explorer-like UI.

To fix this, we cannot simply turn the priorities around, as we get a
standard, default file icon for any file that doesn't have a specific
icon configured. The behavior needs to be different on each platform:
on Linux desktop we respect the icon theme, on other platforms we prefer
the file-type based icon.

Add a theme hint that tells the icon provider which one to prefer.
Implemented in on Linux desktop to return true, otherwise returns false.
Adapt the logic in QAbstractFileIconProvider accordingly.

Pick-to: 6.7
Fixes: QTBUG-124829
Change-Id: I9ff3f543c000aec8238bdf36b18be5c7a2349098
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
(cherry picked from commit e10308769592222b97153956feeb9531863bef35)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Volker Hilsheimer 2024-06-17 13:57:25 +02:00 committed by Qt Cherry-pick Bot
parent 92228ed7f2
commit d2637d2323
4 changed files with 24 additions and 5 deletions

View File

@ -39,6 +39,12 @@ QIcon QAbstractFileIconProviderPrivate::getPlatformThemeIcon(QAbstractFileIconPr
if (theme == nullptr)
return {};
if (theme->themeHint(QPlatformTheme::PreferFileIconFromTheme).toBool()) {
const QIcon result = getIconThemeIcon(type);
if (!result.isNull())
return result;
}
auto &cache = *iconTypeCache();
auto it = cache.find(type);
if (it == cache.end()) {
@ -108,8 +114,14 @@ static inline QPlatformTheme::IconOptions toThemeIconOptions(QAbstractFileIconPr
QIcon QAbstractFileIconProviderPrivate::getPlatformThemeIcon(const QFileInfo &info) const
{
if (auto theme = QGuiApplicationPrivate::platformTheme())
if (auto theme = QGuiApplicationPrivate::platformTheme()) {
if (theme->themeHint(QPlatformTheme::PreferFileIconFromTheme).toBool()) {
const QIcon result = getIconThemeIcon(info);
if (!result.isNull())
return result;
}
return theme->fileIcon(info, toThemeIconOptions(options));
}
return {};
}
@ -211,8 +223,7 @@ QAbstractFileIconProvider::Options QAbstractFileIconProvider::options() const
QIcon QAbstractFileIconProvider::icon(IconType type) const
{
Q_D(const QAbstractFileIconProvider);
const QIcon result = d->getIconThemeIcon(type);
return result.isNull() ? d->getPlatformThemeIcon(type) : result;
return d->getPlatformThemeIcon(type);
}
/*!
@ -225,8 +236,7 @@ QIcon QAbstractFileIconProvider::icon(IconType type) const
QIcon QAbstractFileIconProvider::icon(const QFileInfo &info) const
{
Q_D(const QAbstractFileIconProvider);
const QIcon result = d->getIconThemeIcon(info);
return result.isNull() ? d->getPlatformThemeIcon(info) : result;
return d->getPlatformThemeIcon(info);
}

View File

@ -654,6 +654,8 @@ QVariant QPlatformTheme::defaultThemeHint(ThemeHint hint)
return true;
case ShowIconsInMenus:
return true;
case PreferFileIconFromTheme:
return false;
}
return QVariant();

View File

@ -98,6 +98,7 @@ public:
MouseCursorSize,
UnderlineShortcut,
ShowIconsInMenus,
PreferFileIconFromTheme,
};
Q_ENUM(ThemeHint)

View File

@ -503,6 +503,8 @@ QVariant QGenericUnixTheme::themeHint(ThemeHint hint) const
return QVariant(mouseCursorTheme());
case QPlatformTheme::MouseCursorSize:
return QVariant(mouseCursorSize());
case QPlatformTheme::PreferFileIconFromTheme:
return true;
default:
break;
}
@ -1108,6 +1110,8 @@ QVariant QKdeTheme::themeHint(QPlatformTheme::ThemeHint hint) const
return QVariant(mouseCursorTheme());
case QPlatformTheme::MouseCursorSize:
return QVariant(mouseCursorSize());
case QPlatformTheme::PreferFileIconFromTheme:
return true;
default:
break;
}
@ -1385,6 +1389,8 @@ QVariant QGnomeTheme::themeHint(QPlatformTheme::ThemeHint hint) const
return QVariant(mouseCursorTheme());
case QPlatformTheme::MouseCursorSize:
return QVariant(mouseCursorSize());
case QPlatformTheme::PreferFileIconFromTheme:
return true;
default:
break;
}