Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qgnometheme.cpp
Go to the documentation of this file.
1// Copyright (C) 2025 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
6#include <qpa/qplatformdialoghelper.h>
7#include <qpa/qplatformfontdatabase.h>
8#if QT_CONFIG(dbus) && QT_CONFIG(systemtrayicon)
9# include <private/qdbustrayicon_p.h>
10#endif
11#if QT_CONFIG(dbus)
12# include <private/qdbusmenubar_p.h>
13#endif
14#include <qpa/qwindowsysteminterface.h>
15
17
18/*!
19 \class QGnomeTheme
20 \brief QGnomeTheme is a theme implementation for the Gnome desktop.
21 \since 5.0
22 \internal
23 \ingroup qpa
24*/
25const char *QGnomeTheme::name = "gnome";
26
27QGnomeThemePrivate::QGnomeThemePrivate()
28{
29#if QT_CONFIG(dbus)
30 QObject::connect(&m_gnomePortal, &QGnomePortalInterface::themeNameChanged, &m_gnomePortal,
31 [this](const QString &themeName) { m_themeName = themeName; });
32#endif // QT_CONFIG(dbus)
33}
34
35QGnomeThemePrivate::~QGnomeThemePrivate()
36{
37 if (systemFont)
38 delete systemFont;
39 if (fixedFont)
40 delete fixedFont;
41}
42
43void QGnomeThemePrivate::configureFonts(const QString &gtkFontName) const
44{
45 Q_ASSERT(!systemFont);
46 const int split = gtkFontName.lastIndexOf(QChar::Space);
47 float size = QStringView{gtkFontName}.mid(split + 1).toFloat();
48 QString fontName = gtkFontName.left(split);
49
50 systemFont = new QFont(fontName, size);
51 fixedFont = new QFont(QLatin1StringView(QGenericUnixTheme::defaultFixedFontNameC), systemFont->pointSize());
52 fixedFont->setStyleHint(QFont::TypeWriter);
53 qCDebug(lcQpaFonts) << "default fonts: system" << systemFont << "fixed" << fixedFont;
54}
55
56Qt::ColorScheme QGnomeThemePrivate::colorScheme() const
57{
58 if (hasRequestedColorScheme())
59 return m_requestedColorScheme;
60
61#if QT_CONFIG(dbus)
62 if (Qt::ColorScheme colorScheme = m_gnomePortal.colorScheme();
63 colorScheme != Qt::ColorScheme::Unknown)
64 return colorScheme;
65
66 // If the color scheme is set to Unknown by mistake or is not set at all,
67 // then maybe the theme name contains a hint about the color scheme.
68 // Let's hope the theme name does not include any accent color name
69 // which contains "dark" or "light" in it (e.g. lightblue). At the moment they don't.
70 if (m_themeName.contains(QLatin1StringView("light"), Qt::CaseInsensitive))
71 return Qt::ColorScheme::Light;
72 else if (m_themeName.contains(QLatin1StringView("dark"), Qt::CaseInsensitive))
73 return Qt::ColorScheme::Dark;
74#endif // QT_CONFIG(dbus)
75
76 // Fallback to Unknown if no color scheme is set or detected
77 return Qt::ColorScheme::Unknown;
78}
79
80bool QGnomeThemePrivate::hasRequestedColorScheme() const
81{
82 return m_requestedColorScheme != Qt::ColorScheme::Unknown;
83}
84
85QGnomeTheme::QGnomeTheme()
86 : QGenericUnixTheme(new QGnomeThemePrivate())
87{
88#if QT_CONFIG(dbus)
89 Q_D(QGnomeTheme);
90
91 QGnomePortalInterface *portal = &d->m_gnomePortal;
92
93 QObject::connect(portal, &QGnomePortalInterface::colorSchemeChanged, portal,
94 [this](Qt::ColorScheme colorScheme) { updateColorScheme(colorScheme); });
95
96 QObject::connect(portal, &QGnomePortalInterface::contrastChanged, portal,
97 [this](Qt::ContrastPreference contrast) { updateHighContrast(contrast); });
98#endif // QT_CONFIG(dbus)
99}
100
101QVariant QGnomeTheme::themeHint(QPlatformTheme::ThemeHint hint) const
102{
103 switch (hint) {
104 case QPlatformTheme::DialogButtonBoxButtonsHaveIcons:
105 return QVariant(true);
106 case QPlatformTheme::DialogButtonBoxLayout:
107 return QVariant(QPlatformDialogHelper::GnomeLayout);
108 case QPlatformTheme::SystemIconThemeName:
109 return QVariant(QStringLiteral("Adwaita"));
110 case QPlatformTheme::SystemIconFallbackThemeName:
111 return QVariant(QStringLiteral("gnome"));
112 case QPlatformTheme::IconThemeSearchPaths:
113 return QVariant(xdgIconThemePaths());
114 case QPlatformTheme::IconPixmapSizes:
115 return QVariant::fromValue(availableXdgFileIconSizes());
116 case QPlatformTheme::StyleNames: {
117 QStringList styleNames;
118 styleNames << QStringLiteral("Fusion") << QStringLiteral("windows");
119 return QVariant(styleNames);
120 }
121 case QPlatformTheme::KeyboardScheme:
122 return QVariant(int(GnomeKeyboardScheme));
123 case QPlatformTheme::PasswordMaskCharacter:
124 return QVariant(QChar(0x2022));
125 case QPlatformTheme::UiEffects:
126 return QVariant(int(HoverEffect));
127 case QPlatformTheme::ButtonPressKeys:
128 return QVariant::fromValue(
129 QList<Qt::Key>({ Qt::Key_Space, Qt::Key_Return, Qt::Key_Enter, Qt::Key_Select }));
130 case QPlatformTheme::PreselectFirstFileInDirectory:
131 return true;
132 case QPlatformTheme::MouseCursorTheme:
133 return QVariant(mouseCursorTheme());
134 case QPlatformTheme::MouseCursorSize:
135 return QVariant(mouseCursorSize());
136 case QPlatformTheme::PreferFileIconFromTheme:
137 return true;
138 default:
139 break;
140 }
141 return QPlatformTheme::themeHint(hint);
142}
143
144QIcon QGnomeTheme::fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions) const
145{
146#if QT_CONFIG(mimetype)
147 return xdgFileIcon(fileInfo);
148#else
149 Q_UNUSED(fileInfo);
150 return QIcon();
151#endif
152}
153
154const QFont *QGnomeTheme::font(Font type) const
155{
156 Q_D(const QGnomeTheme);
157 if (!d->systemFont)
158 d->configureFonts(gtkFontName());
159 switch (type) {
160 case QPlatformTheme::SystemFont:
161 return d->systemFont;
162 case QPlatformTheme::FixedFont:
163 return d->fixedFont;
164 default:
165 return nullptr;
166 }
167}
168
169QString QGnomeTheme::gtkFontName() const
170{
171 return QStringLiteral("%1 %2").arg(QLatin1StringView(defaultSystemFontNameC))
172 .arg(defaultSystemFontSize);
173}
174
175void QGnomeTheme::requestColorScheme(Qt::ColorScheme scheme)
176{
177 Q_D(QGnomeTheme);
178 if (d->m_requestedColorScheme == scheme)
179 return;
180 QPlatformTheme::requestColorScheme(scheme);
181 d->m_requestedColorScheme = scheme;
182 QWindowSystemInterface::handleThemeChange();
183}
184
185Qt::ColorScheme QGnomeTheme::colorScheme() const
186{
187 Q_D(const QGnomeTheme);
188 if (auto colorScheme = d->colorScheme(); colorScheme != Qt::ColorScheme::Unknown)
189 return colorScheme;
190 // If the color scheme is not set or detected, fall back to the default
191 return QPlatformTheme::colorScheme();
192}
193
194#if QT_CONFIG(dbus)
195void QGnomeTheme::updateColorScheme(Qt::ColorScheme colorScheme)
196{
197 Q_UNUSED(colorScheme);
198 QWindowSystemInterface::handleThemeChange();
199}
200
201void QGnomeTheme::updateHighContrast(Qt::ContrastPreference contrast)
202{
203 Q_UNUSED(contrast);
204 QWindowSystemInterface::handleThemeChange();
205}
206
207QPlatformMenuBar *QGnomeTheme::createPlatformMenuBar() const
208{
209 if (isDBusGlobalMenuAvailable())
210 return new QDBusMenuBar();
211 return nullptr;
212}
213
214Qt::ContrastPreference QGnomeTheme::contrastPreference() const
215{
216 Q_D(const QGnomeTheme);
217 return d->m_gnomePortal.contrastPreference();
218}
219
220# if QT_CONFIG(systemtrayicon)
221QPlatformSystemTrayIcon *QGnomeTheme::createPlatformSystemTrayIcon() const
222{
223 if (shouldUseDBusTray())
224 return new QDBusTrayIcon();
225 return nullptr;
226}
227# endif // QT_CONFIG(systemtrayicon)
228#endif // QT_CONFIG(dbus)
229
230QString QGnomeTheme::standardButtonText(int button) const
231{
232 switch (button) {
233 case QPlatformDialogHelper::Ok:
234 return QCoreApplication::translate("QGnomeTheme", "&OK");
235 case QPlatformDialogHelper::Save:
236 return QCoreApplication::translate("QGnomeTheme", "&Save");
237 case QPlatformDialogHelper::Cancel:
238 return QCoreApplication::translate("QGnomeTheme", "&Cancel");
239 case QPlatformDialogHelper::Close:
240 return QCoreApplication::translate("QGnomeTheme", "&Close");
241 case QPlatformDialogHelper::Discard:
242 return QCoreApplication::translate("QGnomeTheme", "Close without Saving");
243 default:
244 break;
245 }
246 return QPlatformTheme::standardButtonText(button);
247}
248
249QT_END_NAMESPACE
Combined button and popup list for selecting options.