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#ifndef QT_NO_SYSTEMTRAYICON
43#include <private/qdbustrayicon_p.h>
44#include <private/qdbusmenubar_p.h>
48#include <private/qguiapplication_p.h>
49#include <qpa/qplatformintegration.h>
50#include <QtCore/QStandardPaths>
52#include <QtDBus/QDBusConnectionInterface>
53#include <private/qdbustrayicon_p.h>
55#if QT_CONFIG(mimetype)
56#include <QtCore/QMimeDatabase>
57#include <QtCore/QMimeData>
63Q_DECLARE_LOGGING_CATEGORY(qLcTray)
64using namespace Qt::StringLiterals;
66const char *QGenericUnixTheme::name =
"generic";
75 fixedFont.setStyleHint(QFont::TypeWriter);
76 qCDebug(lcQpaFonts) <<
"default fonts: system" << systemFont <<
"fixed" << fixedFont;
79QGenericUnixTheme::QGenericUnixTheme(QGenericUnixThemePrivate *p)
83QGenericUnixTheme::QGenericUnixTheme()
84 : QPlatformTheme(
new QGenericUnixThemePrivate())
87const QFont *QGenericUnixTheme::font(Font type)
const
89 Q_D(
const QGenericUnixTheme);
91 case QPlatformTheme::SystemFont:
92 return &d->systemFont;
93 case QPlatformTheme::FixedFont:
101QPlatformMenuBar *QGenericUnixTheme::createPlatformMenuBar()
const
103 if (isDBusGlobalMenuAvailable())
104 return new QDBusMenuBar();
109#if QT_CONFIG(dbus) && QT_CONFIG(systemtrayicon)
110QPlatformSystemTrayIcon *QGenericUnixTheme::createPlatformSystemTrayIcon()
const
112 if (shouldUseDBusTray())
113 return new QDBusTrayIcon();
118QVariant QGenericUnixTheme::themeHint(ThemeHint hint)
const
121 case QPlatformTheme::SystemIconFallbackThemeName:
122 return QVariant(QString(QStringLiteral(
"hicolor")));
123 case QPlatformTheme::IconThemeSearchPaths:
124 return xdgIconThemePaths();
125 case QPlatformTheme::IconFallbackSearchPaths:
126 return iconFallbackPaths();
127 case QPlatformTheme::DialogButtonBoxButtonsHaveIcons:
128 return QVariant(
true);
129 case QPlatformTheme::StyleNames: {
130 QStringList styleNames;
131 styleNames << QStringLiteral(
"Fusion") << QStringLiteral(
"Windows");
132 return QVariant(styleNames);
134 case QPlatformTheme::KeyboardScheme:
135 return QVariant(
int(X11KeyboardScheme));
136 case QPlatformTheme::UiEffects:
137 return QVariant(
int(HoverEffect));
138 case QPlatformTheme::MouseCursorTheme:
139 return QVariant(mouseCursorTheme());
140 case QPlatformTheme::MouseCursorSize:
141 return QVariant(mouseCursorSize());
142 case QPlatformTheme::PreferFileIconFromTheme:
147 return QPlatformTheme::themeHint(hint);
150QStringList QGenericUnixTheme::themeNames()
153 if (QGuiApplication::desktopSettingsAware()) {
154 const QByteArray desktopEnvironment = QGuiApplicationPrivate::platformIntegration()->services()->desktopEnvironment();
155 QList<QByteArray> gtkBasedEnvironments;
156 gtkBasedEnvironments <<
"GNOME"
163 const QList<QByteArray> desktopNames = desktopEnvironment.split(
':');
164 for (
const QByteArray &desktopName : desktopNames) {
165#if QT_CONFIG(dbus) && QT_CONFIG(settings) && (QT_CONFIG(xcb) || QT_CONFIG(wayland))
166 if (desktopEnvironment ==
"KDE") {
167 result.push_back(QLatin1StringView(QKdeTheme::name));
170 if (gtkBasedEnvironments.contains(desktopName)) {
172 result.push_back(QStringLiteral(
"gtk3"));
174 result.push_back(QLatin1StringView(QGnomeTheme::name));
178 QString s = QString::fromLatin1(desktopName.toLower());
179 result.push_back(s.startsWith(
"x-"_L1) ? s.mid(2) : s);
183 result.append(QLatin1StringView(QGenericUnixTheme::name));
188
189
190
191QPlatformTheme *QGenericUnixTheme::createUnixTheme(
const QString &name)
193 if (name == QLatin1StringView(QGenericUnixTheme::name))
194 return new QGenericUnixTheme;
195#if QT_CONFIG(dbus) && QT_CONFIG(settings) && (QT_CONFIG(xcb) || QT_CONFIG(wayland))
196 if (name == QLatin1StringView(QKdeTheme::name))
197 return QKdeTheme::createKdeTheme();
199 if (name == QLatin1StringView(QGnomeTheme::name))
200 return new QGnomeTheme;
205QStringList QGenericUnixTheme::xdgIconThemePaths()
209 const QFileInfo homeIconDir(QDir::homePath() +
"/.icons"_L1);
210 if (homeIconDir.isDir())
211 paths.prepend(homeIconDir.absoluteFilePath());
213 paths.append(QStandardPaths::locateAll(QStandardPaths::GenericDataLocation,
214 QStringLiteral(
"icons"),
215 QStandardPaths::LocateDirectory));
220QStringList QGenericUnixTheme::iconFallbackPaths()
223 const QFileInfo pixmapsIconsDir(QStringLiteral(
"/usr/share/pixmaps"));
224 if (pixmapsIconsDir.isDir())
225 paths.append(pixmapsIconsDir.absoluteFilePath());
230QString QGenericUnixTheme::mouseCursorTheme()
232 static QString themeName = qEnvironmentVariable(
"XCURSOR_THEME");
236QSize QGenericUnixTheme::mouseCursorSize()
238 constexpr int defaultCursorSize = 24;
239 static const int xCursorSize = qEnvironmentVariableIntValue(
"XCURSOR_SIZE");
240 static const int s = xCursorSize > 0 ? xCursorSize : defaultCursorSize;
245static bool checkDBusGlobalMenuAvailable()
247 const QDBusConnection connection = QDBusConnection::sessionBus();
248 static const QString registrarService = QStringLiteral(
"com.canonical.AppMenu.Registrar");
249 if (
const auto iface = connection.interface())
250 return iface->isServiceRegistered(registrarService);
254bool QGenericUnixTheme::isDBusGlobalMenuAvailable()
256 static bool dbusGlobalMenuAvailable = checkDBusGlobalMenuAvailable();
257 return dbusGlobalMenuAvailable;
261#if QT_CONFIG(mimetype)
262QIcon QGenericUnixTheme::xdgFileIcon(
const QFileInfo &fileInfo)
264 QMimeDatabase mimeDatabase;
265 QMimeType mimeType = mimeDatabase.mimeTypeForFile(fileInfo);
266 if (!mimeType.isValid())
268 const QString &iconName = mimeType.iconName();
269 if (!iconName.isEmpty()) {
270 QIcon icon = QIcon::fromTheme(iconName);
274 const QString &genericIconName = mimeType.genericIconName();
275 return genericIconName.isEmpty() ? QIcon() : QIcon::fromTheme(genericIconName);
280#if QT_CONFIG(dbus) && QT_CONFIG(systemtrayicon)
281bool QGenericUnixTheme::shouldUseDBusTray()
285 if (QGuiApplication::platformName() !=
"xcb"_L1)
287 const bool result = QDBusMenuConnection().isWatcherRegistered();
288 qCDebug(qLcTray) <<
"D-Bus tray available:" << result;
294QList<QSize> QGenericUnixTheme::availableXdgFileIconSizes()
296 return QIcon::fromTheme(QStringLiteral(
"inode-directory")).availableSizes();
QGenericUnixThemePrivate()