diff options
Diffstat (limited to 'src/plugins/platformthemes/gtk3/qgtk3theme.cpp')
-rw-r--r-- | src/plugins/platformthemes/gtk3/qgtk3theme.cpp | 119 |
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 |