Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qgtk3theme.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 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
4#include "qgtk3theme.h"
6#include "qgtk3menu.h"
7#include <QVariant>
8#include <QGuiApplication>
9#include <qpa/qwindowsysteminterface.h>
10
11#undef signals
12#include <gtk/gtk.h>
13
14#if QT_CONFIG(xcb_xlib)
15#include <X11/Xlib.h>
16#endif
17
19
20using namespace Qt::StringLiterals;
21
22const char *QGtk3Theme::name = "gtk3";
23
24template <typename T>
25static T gtkSetting(const gchar *propertyName)
26{
27 GtkSettings *settings = gtk_settings_get_default();
28 T value;
29 g_object_get(settings, propertyName, &value, NULL);
30 return value;
31}
32
33static QString gtkSetting(const gchar *propertyName)
34{
35 gchararray value = gtkSetting<gchararray>(propertyName);
37 g_free(value);
38 return str;
39}
40
41void gtkMessageHandler(const gchar *log_domain,
42 GLogLevelFlags log_level,
43 const gchar *message,
44 gpointer unused_data) {
45 /* Silence false-positive Gtk warnings (we are using Xlib to set
46 * the WM_TRANSIENT_FOR hint).
47 */
48 if (g_strcmp0(message, "GtkDialog mapped without a transient parent. "
49 "This is discouraged.") != 0) {
50 /* For other messages, call the default handler. */
51 g_log_default_handler(log_domain, log_level, message, unused_data);
52 }
53}
54
56{
57 // Ensure gtk uses the same windowing system, but let it
58 // fallback in case GDK_BACKEND environment variable
59 // filters the preferred one out
60 if (QGuiApplication::platformName().startsWith("wayland"_L1))
61 gdk_set_allowed_backends("wayland,x11");
62 else if (QGuiApplication::platformName() == "xcb"_L1)
63 gdk_set_allowed_backends("x11,wayland");
64
65#if QT_CONFIG(xcb_xlib)
66 // gtk_init will reset the Xlib error handler, and that causes
67 // Qt applications to quit on X errors. Therefore, we need to manually restore it.
68 int (*oldErrorHandler)(Display *, XErrorEvent *) = XSetErrorHandler(nullptr);
69#endif
70
71 gtk_init(nullptr, nullptr);
72
73#if QT_CONFIG(xcb_xlib)
74 XSetErrorHandler(oldErrorHandler);
75#endif
76
77 /* Initialize some types here so that Gtk+ does not crash when reading
78 * the treemodel for GtkFontChooser.
79 */
80 g_type_ensure(PANGO_TYPE_FONT_FAMILY);
81 g_type_ensure(PANGO_TYPE_FONT_FACE);
82
83 /* Use our custom log handler. */
84 g_log_set_handler("Gtk", G_LOG_LEVEL_MESSAGE, gtkMessageHandler, nullptr);
85
86#define SETTING_CONNECT(setting) g_signal_connect(settings, "notify::" setting, G_CALLBACK(notifyThemeChanged), nullptr)
87 auto notifyThemeChanged = [] {
89 };
90
91 GtkSettings *settings = gtk_settings_get_default();
92 SETTING_CONNECT("gtk-cursor-blink-time");
93 SETTING_CONNECT("gtk-double-click-distance");
94 SETTING_CONNECT("gtk-double-click-time");
95 SETTING_CONNECT("gtk-long-press-time");
96 SETTING_CONNECT("gtk-entry-password-hint-timeout");
97 SETTING_CONNECT("gtk-dnd-drag-threshold");
98 SETTING_CONNECT("gtk-icon-theme-name");
99 SETTING_CONNECT("gtk-fallback-icon-theme");
100 SETTING_CONNECT("gtk-font-name");
101 SETTING_CONNECT("gtk-application-prefer-dark-theme");
102 SETTING_CONNECT("gtk-theme-name");
103 SETTING_CONNECT("gtk-cursor-theme-name");
104 SETTING_CONNECT("gtk-cursor-theme-size");
105#undef SETTING_CONNECT
106
107 m_storage.reset(new QGtk3Storage);
108}
109
111{
112 const char *gtk_long_press_time = "gtk-long-press-time";
113 static bool found = g_object_class_find_property(G_OBJECT_GET_CLASS(gtk_settings_get_default()), gtk_long_press_time);
114 if (!found)
115 return QVariant();
116 return QVariant(gtkSetting<guint>(gtk_long_press_time)); // Since 3.14, apparently we support >= 3.6
117}
118
120{
121 switch (hint) {
123 return QVariant(gtkSetting<gint>("gtk-cursor-blink-time"));
125 return QVariant(gtkSetting<gint>("gtk-double-click-distance"));
127 return QVariant(gtkSetting<gint>("gtk-double-click-time"));
130 if (!v.isValid())
132 return v;
133 }
135 return QVariant(gtkSetting<guint>("gtk-entry-password-hint-timeout"));
137 return QVariant(gtkSetting<gint>("gtk-dnd-drag-threshold"));
139 return QVariant(gtkSetting("gtk-icon-theme-name"));
141 return QVariant(gtkSetting("gtk-fallback-icon-theme"));
143 return QVariant(gtkSetting("gtk-cursor-theme-name"));
145 int s = gtkSetting<gint>("gtk-cursor-theme-size");
146 if (s > 0)
147 return QVariant(QSize(s, s));
149 }
150 default:
152 }
153}
154
156{
157 QString cfgFontName = gtkSetting("gtk-font-name");
158 if (!cfgFontName.isEmpty())
159 return cfgFontName;
161}
162
164{
165 Q_ASSERT(m_storage);
166 return m_storage->colorScheme();
167}
168
170{
171 switch (type) {
172 case ColorDialog:
173 return true;
174 case FileDialog:
175 return useNativeFileDialog();
176 case FontDialog:
177 return true;
178 default:
179 return false;
180 }
181}
182
184{
185 switch (type) {
186 case ColorDialog:
187 return new QGtk3ColorDialogHelper;
188 case FileDialog:
189 if (!useNativeFileDialog())
190 return nullptr;
191 return new QGtk3FileDialogHelper;
192 case FontDialog:
193 return new QGtk3FontDialogHelper;
194 default:
195 return nullptr;
196 }
197}
198
200{
201 return new QGtk3Menu;
202}
203
208
209bool QGtk3Theme::useNativeFileDialog()
210{
211 /* Require GTK3 >= 3.15.5 to avoid running into this bug:
212 * https://bugzilla.gnome.org/show_bug.cgi?id=725164
213 *
214 * While this bug only occurs when using widget-based file dialogs
215 * (native GTK3 dialogs are fine) we have to disable platform file
216 * dialogs entirely since we can't avoid creation of a platform
217 * dialog helper.
218 */
219 return gtk_check_version(3, 15, 5) == nullptr;
220}
221
223{
224 Q_ASSERT(m_storage);
225 return m_storage->palette(type);
226}
227
229{
230 Q_ASSERT(m_storage);
231 return m_storage->standardPixmap(sp, size);
232}
233
235{
236 Q_ASSERT(m_storage);
237 return m_storage->font(type);
238}
239
241 QPlatformTheme::IconOptions iconOptions) const
242{
243 Q_UNUSED(iconOptions);
244 Q_ASSERT(m_storage);
245 return m_storage->fileIcon(fileInfo);
246}
247
\reentrant
Definition qfont.h:22
virtual QString gtkFontName() const
QVariant themeHint(ThemeHint hint) const override
QIcon fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions iconOptions={ }) const override
Return an icon for fileInfo, observing iconOptions.
Qt::ColorScheme colorScheme() const override
bool usePlatformNativeDialog(DialogType type) const override
virtual QVariant themeHint(ThemeHint hint) const override
QPlatformDialogHelper * createPlatformDialogHelper(DialogType type) const override
static const char * name
Definition qgtk3theme.h:35
QPlatformMenuItem * createPlatformMenuItem() const override
const QPalette * palette(Palette type=SystemPalette) const override
QPlatformMenu * createPlatformMenu() const override
virtual QString gtkFontName() const override
QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const override
const QFont * font(Font type=SystemFont) const override
QString platformName
The name of the underlying platform plugin.
The QIcon class provides scalable icons in different modes and states.
Definition qicon.h:20
The QPalette class contains color groups for each widget state.
Definition qpalette.h:19
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
Definition qpixmap.h:27
The QPlatformDialogHelper class allows for platform-specific customization of dialogs.
ThemeHint
This enum describes the available theme hints.
\inmodule QtCore
Definition qsize.h:208
\inmodule QtCore
Definition qsize.h:25
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:6018
\inmodule QtCore
Definition qvariant.h:65
static void handleThemeChange(QWindow *window=nullptr)
QString str
[2]
Combined button and popup list for selecting options.
ColorScheme
Definition qnamespace.h:50
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
void gtkMessageHandler(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer unused_data)
static T gtkSetting(const gchar *propertyName)
static QVariant gtkGetLongPressTime()
#define SETTING_CONNECT(setting)
GLsizei const GLfloat * v
[13]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum type
GLuint GLsizei const GLchar * message
GLdouble s
[6]
Definition qopenglext.h:235
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static QT_BEGIN_NAMESPACE QVariant hint(QPlatformIntegration::StyleHint h)
#define sp
#define Q_UNUSED(x)
QSettings settings("MySoft", "Star Runner")
[0]