10#include <QGuiApplication>
16#include <QLoggingCategory>
18#include <QStandardPaths>
20#if QT_CONFIG(mimetype)
21#include <QMimeDatabase>
23#if QT_CONFIG(settings)
26#include "qkdetheme_p.h"
30#include <qpa/qplatformfontdatabase.h>
31#include <qpa/qplatformintegration.h>
32#include <qpa/qplatformservices.h>
33#include <qpa/qplatformdialoghelper.h>
34#include <qpa/qplatformtheme_p.h>
37#include <QJsonDocument>
41#include <QJsonParseError>
42#include <private/qdbusmenubar_p.h>
44#if QT_CONFIG(dbus) && QT_CONFIG(systemtrayicon)
45#include <private/qdbustrayicon_p.h>
48#include <private/qguiapplication_p.h>
49#include <qpa/qplatformintegration.h>
50#include <QtCore/QStandardPaths>
52#include <QtDBus/QDBusConnectionInterface>
54#if QT_CONFIG(mimetype)
55#include <QtCore/QMimeDatabase>
56#include <QtCore/QMimeData>
62Q_DECLARE_LOGGING_CATEGORY(qLcTray)
63using namespace Qt::StringLiterals;
65const char *QGenericUnixTheme::name =
"generic";
74 fixedFont.setStyleHint(QFont::TypeWriter);
75 qCDebug(lcQpaFonts) <<
"default fonts: system" << systemFont <<
"fixed" << fixedFont;
78QGenericUnixTheme::QGenericUnixTheme(QGenericUnixThemePrivate *p)
82QGenericUnixTheme::QGenericUnixTheme()
83 : QPlatformTheme(
new QGenericUnixThemePrivate())
86const QFont *QGenericUnixTheme::font(Font type)
const
88 Q_D(
const QGenericUnixTheme);
90 case QPlatformTheme::SystemFont:
91 return &d->systemFont;
92 case QPlatformTheme::FixedFont:
100QPlatformMenuBar *QGenericUnixTheme::createPlatformMenuBar()
const
102 if (isDBusGlobalMenuAvailable())
103 return new QDBusMenuBar();
108#if QT_CONFIG(dbus) && QT_CONFIG(systemtrayicon)
109QPlatformSystemTrayIcon *QGenericUnixTheme::createPlatformSystemTrayIcon()
const
111 if (shouldUseDBusTray())
112 return new QDBusTrayIcon();
117QVariant QGenericUnixTheme::themeHint(ThemeHint hint)
const
120 case QPlatformTheme::SystemIconFallbackThemeName:
121 return QVariant(QString(QStringLiteral(
"hicolor")));
122 case QPlatformTheme::IconThemeSearchPaths:
123 return xdgIconThemePaths();
124 case QPlatformTheme::IconFallbackSearchPaths:
125 return iconFallbackPaths();
126 case QPlatformTheme::DialogButtonBoxButtonsHaveIcons:
127 return QVariant(
true);
128 case QPlatformTheme::StyleNames: {
129 QStringList styleNames;
130 styleNames << QStringLiteral(
"Fusion") << QStringLiteral(
"Windows");
131 return QVariant(styleNames);
133 case QPlatformTheme::KeyboardScheme:
134 return QVariant(
int(X11KeyboardScheme));
135 case QPlatformTheme::UiEffects:
136 return QVariant(
int(HoverEffect));
137 case QPlatformTheme::MouseCursorTheme:
138 return QVariant(mouseCursorTheme());
139 case QPlatformTheme::MouseCursorSize:
140 return QVariant(mouseCursorSize());
141 case QPlatformTheme::PreferFileIconFromTheme:
146 return QPlatformTheme::themeHint(hint);
149QStringList QGenericUnixTheme::themeNames()
152 if (QGuiApplication::desktopSettingsAware()) {
153 const QByteArray desktopEnvironment = QGuiApplicationPrivate::platformIntegration()->services()->desktopEnvironment();
154 QList<QByteArray> gtkBasedEnvironments;
155 gtkBasedEnvironments <<
"GNOME"
162 const QList<QByteArray> desktopNames = desktopEnvironment.split(
':');
163 for (
const QByteArray &desktopName : desktopNames) {
164#if QT_CONFIG(dbus) && QT_CONFIG(settings) && (QT_CONFIG(xcb) || QT_CONFIG(wayland))
165 if (desktopEnvironment ==
"KDE") {
166 result.push_back(QLatin1StringView(QKdeTheme::name));
169 if (gtkBasedEnvironments.contains(desktopName)) {
171 result.push_back(QStringLiteral(
"gtk3"));
173 result.push_back(QLatin1StringView(QGnomeTheme::name));
177 QString s = QString::fromLatin1(desktopName.toLower());
178 result.push_back(s.startsWith(
"x-"_L1) ? s.mid(2) : s);
182 result.append(QLatin1StringView(QGenericUnixTheme::name));
187
188
189
190QPlatformTheme *QGenericUnixTheme::createUnixTheme(
const QString &name)
192 if (name == QLatin1StringView(QGenericUnixTheme::name))
193 return new QGenericUnixTheme;
194#if QT_CONFIG(dbus) && QT_CONFIG(settings) && (QT_CONFIG(xcb) || QT_CONFIG(wayland))
195 if (name == QLatin1StringView(QKdeTheme::name))
196 return QKdeTheme::createKdeTheme();
198 if (name == QLatin1StringView(QGnomeTheme::name))
199 return new QGnomeTheme;
204QStringList QGenericUnixTheme::xdgIconThemePaths()
208 const QFileInfo homeIconDir(QDir::homePath() +
"/.icons"_L1);
209 if (homeIconDir.isDir())
210 paths.prepend(homeIconDir.absoluteFilePath());
212 paths.append(QStandardPaths::locateAll(QStandardPaths::GenericDataLocation,
213 QStringLiteral(
"icons"),
214 QStandardPaths::LocateDirectory));
219QStringList QGenericUnixTheme::iconFallbackPaths()
222 const QFileInfo pixmapsIconsDir(QStringLiteral(
"/usr/share/pixmaps"));
223 if (pixmapsIconsDir.isDir())
224 paths.append(pixmapsIconsDir.absoluteFilePath());
229QString QGenericUnixTheme::mouseCursorTheme()
231 static QString themeName = qEnvironmentVariable(
"XCURSOR_THEME");
235QSize QGenericUnixTheme::mouseCursorSize()
237 constexpr int defaultCursorSize = 24;
238 static const int xCursorSize = qEnvironmentVariableIntValue(
"XCURSOR_SIZE");
239 static const int s = xCursorSize > 0 ? xCursorSize : defaultCursorSize;
244static bool checkDBusGlobalMenuAvailable()
246 const QDBusConnection connection = QDBusConnection::sessionBus();
247 static const QString registrarService = QStringLiteral(
"com.canonical.AppMenu.Registrar");
248 if (
const auto iface = connection.interface())
249 return iface->isServiceRegistered(registrarService);
253bool QGenericUnixTheme::isDBusGlobalMenuAvailable()
255 static bool dbusGlobalMenuAvailable = checkDBusGlobalMenuAvailable();
256 return dbusGlobalMenuAvailable;
260#if QT_CONFIG(mimetype)
261QIcon QGenericUnixTheme::xdgFileIcon(
const QFileInfo &fileInfo)
263 QMimeDatabase mimeDatabase;
264 QMimeType mimeType = mimeDatabase.mimeTypeForFile(fileInfo);
265 if (!mimeType.isValid())
267 const QString &iconName = mimeType.iconName();
268 if (!iconName.isEmpty()) {
269 QIcon icon = QIcon::fromTheme(iconName);
273 const QString &genericIconName = mimeType.genericIconName();
274 return genericIconName.isEmpty() ? QIcon() : QIcon::fromTheme(genericIconName);
279#if QT_CONFIG(dbus) && QT_CONFIG(systemtrayicon)
280bool QGenericUnixTheme::shouldUseDBusTray()
284 if (QGuiApplication::platformName() !=
"xcb"_L1)
286 const bool result = QDBusMenuConnection().isWatcherRegistered();
287 qCDebug(qLcTray) <<
"D-Bus tray available:" << result;
293QList<QSize> QGenericUnixTheme::availableXdgFileIconSizes()
295 return QIcon::fromTheme(QStringLiteral(
"inode-directory")).availableSizes();
QGenericUnixThemePrivate()
Combined button and popup list for selecting options.