summaryrefslogtreecommitdiffstats
path: root/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platformthemes/gtk3/qgtk3theme.cpp')
-rw-r--r--src/plugins/platformthemes/gtk3/qgtk3theme.cpp119
1 files changed, 78 insertions, 41 deletions
diff --git a/src/plugins/platformthemes/gtk3/qgtk3theme.cpp b/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
index 22a079732a..9d23ba7e48 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
+++ b/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
@@ -5,15 +5,20 @@
#include "qgtk3dialoghelpers.h"
#include "qgtk3menu.h"
#include <QVariant>
-#include <QtCore/qregularexpression.h>
+#include <QGuiApplication>
+#include <qpa/qwindowsysteminterface.h>
#undef signals
#include <gtk/gtk.h>
+#if QT_CONFIG(xcb_xlib)
#include <X11/Xlib.h>
+#endif
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
const char *QGtk3Theme::name = "gtk3";
template <typename T>
@@ -49,13 +54,25 @@ void gtkMessageHandler(const gchar *log_domain,
QGtk3Theme::QGtk3Theme()
{
+ // Ensure gtk uses the same windowing system, but let it
+ // fallback in case GDK_BACKEND environment variable
+ // filters the preferred one out
+ if (QGuiApplication::platformName().startsWith("wayland"_L1))
+ gdk_set_allowed_backends("wayland,x11");
+ else if (QGuiApplication::platformName() == "xcb"_L1)
+ gdk_set_allowed_backends("x11,wayland");
+
+#if QT_CONFIG(xcb_xlib)
// gtk_init will reset the Xlib error handler, and that causes
// Qt applications to quit on X errors. Therefore, we need to manually restore it.
int (*oldErrorHandler)(Display *, XErrorEvent *) = XSetErrorHandler(nullptr);
+#endif
gtk_init(nullptr, nullptr);
+#if QT_CONFIG(xcb_xlib)
XSetErrorHandler(oldErrorHandler);
+#endif
/* Initialize some types here so that Gtk+ does not crash when reading
* the treemodel for GtkFontChooser.
@@ -65,6 +82,29 @@ QGtk3Theme::QGtk3Theme()
/* Use our custom log handler. */
g_log_set_handler("Gtk", G_LOG_LEVEL_MESSAGE, gtkMessageHandler, nullptr);
+
+#define SETTING_CONNECT(setting) g_signal_connect(settings, "notify::" setting, G_CALLBACK(notifyThemeChanged), nullptr)
+ auto notifyThemeChanged = [] {
+ QWindowSystemInterface::handleThemeChange();
+ };
+
+ GtkSettings *settings = gtk_settings_get_default();
+ SETTING_CONNECT("gtk-cursor-blink-time");
+ SETTING_CONNECT("gtk-double-click-distance");
+ SETTING_CONNECT("gtk-double-click-time");
+ SETTING_CONNECT("gtk-long-press-time");
+ SETTING_CONNECT("gtk-entry-password-hint-timeout");
+ SETTING_CONNECT("gtk-dnd-drag-threshold");
+ SETTING_CONNECT("gtk-icon-theme-name");
+ SETTING_CONNECT("gtk-fallback-icon-theme");
+ SETTING_CONNECT("gtk-font-name");
+ SETTING_CONNECT("gtk-application-prefer-dark-theme");
+ SETTING_CONNECT("gtk-theme-name");
+ SETTING_CONNECT("gtk-cursor-theme-name");
+ SETTING_CONNECT("gtk-cursor-theme-size");
+#undef SETTING_CONNECT
+
+ m_storage.reset(new QGtk3Storage);
}
static inline QVariant gtkGetLongPressTime()
@@ -99,8 +139,14 @@ QVariant QGtk3Theme::themeHint(QPlatformTheme::ThemeHint hint) const
return QVariant(gtkSetting("gtk-icon-theme-name"));
case QPlatformTheme::SystemIconFallbackThemeName:
return QVariant(gtkSetting("gtk-fallback-icon-theme"));
- case QPlatformTheme::PreselectFirstFileInDirectory:
- return true;
+ case QPlatformTheme::MouseCursorTheme:
+ return QVariant(gtkSetting("gtk-cursor-theme-name"));
+ case QPlatformTheme::MouseCursorSize: {
+ int s = gtkSetting<gint>("gtk-cursor-theme-size");
+ if (s > 0)
+ return QVariant(QSize(s, s));
+ return QGnomeTheme::themeHint(hint);
+ }
default:
return QGnomeTheme::themeHint(hint);
}
@@ -114,45 +160,10 @@ QString QGtk3Theme::gtkFontName() const
return QGnomeTheme::gtkFontName();
}
-QPlatformTheme::Appearance QGtk3Theme::appearance() const
+Qt::ColorScheme QGtk3Theme::colorScheme() const
{
- /*
- https://docs.gtk.org/gtk3/running.html
-
- It's possible to set a theme variant after the theme name when using GTK_THEME:
-
- GTK_THEME=Adwaita:dark
-
- Some themes also have "-dark" as part of their name.
-
- We test this environment variable first because the documentation says
- it's mainly used for easy debugging, so it should be possible to use it
- to override any other settings.
- */
- QString themeName = qEnvironmentVariable("GTK_THEME");
- const QRegularExpression darkRegex(QStringLiteral("[:-]dark"), QRegularExpression::CaseInsensitiveOption);
- if (!themeName.isEmpty())
- return darkRegex.match(themeName).hasMatch() ? Appearance::Dark : Appearance::Light;
-
- /*
- https://docs.gtk.org/gtk3/property.Settings.gtk-application-prefer-dark-theme.html
-
- This setting controls which theme is used when the theme specified by
- gtk-theme-name provides both light and dark variants. We can save a
- regex check by testing this property first.
- */
- const auto preferDark = gtkSetting<bool>("gtk-application-prefer-dark-theme");
- if (preferDark)
- return Appearance::Dark;
-
- /*
- https://docs.gtk.org/gtk3/property.Settings.gtk-theme-name.html
- */
- themeName = gtkSetting("gtk-theme-name");
- if (!themeName.isEmpty())
- return darkRegex.match(themeName).hasMatch() ? Appearance::Dark : Appearance::Light;
-
- return Appearance::Unknown;
+ Q_ASSERT(m_storage);
+ return m_storage->colorScheme();
}
bool QGtk3Theme::usePlatformNativeDialog(DialogType type) const
@@ -208,4 +219,30 @@ bool QGtk3Theme::useNativeFileDialog()
return gtk_check_version(3, 15, 5) == nullptr;
}
+const QPalette *QGtk3Theme::palette(Palette type) const
+{
+ Q_ASSERT(m_storage);
+ return m_storage->palette(type);
+}
+
+QPixmap QGtk3Theme::standardPixmap(StandardPixmap sp, const QSizeF &size) const
+{
+ Q_ASSERT(m_storage);
+ return m_storage->standardPixmap(sp, size);
+}
+
+const QFont *QGtk3Theme::font(Font type) const
+{
+ Q_ASSERT(m_storage);
+ return m_storage->font(type);
+}
+
+QIcon QGtk3Theme::fileIcon(const QFileInfo &fileInfo,
+ QPlatformTheme::IconOptions iconOptions) const
+{
+ Q_UNUSED(iconOptions);
+ Q_ASSERT(m_storage);
+ return m_storage->fileIcon(fileInfo);
+}
+
QT_END_NAMESPACE