summaryrefslogtreecommitdiffstats
path: root/src/gui/platform/unix/qgnometheme.cpp
blob: aafaff3732b8d54eb02d7c018057114c3c8364a7 (plain)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
// Copyright (C) 2025 The Qt Company Ltd.// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only#include"qgnometheme_p.h"#include <qpa/qplatformdialoghelper.h>#include <qpa/qplatformfontdatabase.h>#if QT_CONFIG(dbus)#include"qdbuslistener_p.h"#include <private/qdbustrayicon_p.h>#include <private/qdbustrayicon_p.h>#include <private/qdbusplatformmenu_p.h>#include <private/qdbusmenubar_p.h>#include <QtDBus/QDBusMessage>#include <QtDBus/QDBusPendingCall>#include <QtDBus/QDBusReply>#endif#include <qpa/qwindowsysteminterface.h> QT_BEGIN_NAMESPACE #if QT_CONFIG(dbus)Q_STATIC_LOGGING_CATEGORY(lcQpaThemeGnome,"qt.qpa.theme.gnome")#endif/*! \class QGnomeTheme \brief QGnomeTheme is a theme implementation for the Gnome desktop. \since 5.0 \internal \ingroup qpa*/const char*QGnomeTheme::name ="gnome";QGnomeThemePrivate::QGnomeThemePrivate(){#if QT_CONFIG(dbus)staticconstexpr QLatin1String appearanceNamespace("org.freedesktop.appearance");staticconstexpr QLatin1String colorSchemeKey("color-scheme");staticconstexpr QLatin1String contrastKey("contrast"); QDBusConnection dbus =QDBusConnection::sessionBus();if(dbus.isConnected()) {// ReadAll appears to omit the contrast setting on Ubuntu. QDBusMessage message =QDBusMessage::createMethodCall(QLatin1String("org.freedesktop.portal.Desktop"),QLatin1String("/org/freedesktop/portal/desktop"),QLatin1String("org.freedesktop.portal.Settings"),QLatin1String("ReadOne")); message << appearanceNamespace << colorSchemeKey; QDBusReply<QVariant> reply = dbus.call(message);if(Q_LIKELY(reply.isValid())) { uint xdgColorSchemeValue = reply.value().toUInt();switch(xdgColorSchemeValue) {case1: m_colorScheme =Qt::ColorScheme::Dark;QWindowSystemInterface::handleThemeChange();break;case2: m_colorScheme =Qt::ColorScheme::Light;QWindowSystemInterface::handleThemeChange();break;default:break;}} message.setArguments({}); message << appearanceNamespace << contrastKey; pendingCallWatcher =std::make_unique<QDBusPendingCallWatcher>(dbus.asyncCall(message));QObject::connect(pendingCallWatcher.get(), &QDBusPendingCallWatcher::finished, pendingCallWatcher.get(), [this](QDBusPendingCallWatcher *watcher) {if(!watcher->isError()) { QDBusPendingReply<QVariant> reply = *watcher;if(Q_LIKELY(reply.isValid()))updateHighContrast(static_cast<Qt::ContrastPreference>(reply.value().toUInt()));}initDbus();});}else{qCWarning(lcQpaThemeGnome) <<"dbus connection failed. Last error: "<< dbus.lastError();}#endif// QT_CONFIG(dbus)}QGnomeThemePrivate::~QGnomeThemePrivate(){if(systemFont)delete systemFont;if(fixedFont)delete fixedFont;}voidQGnomeThemePrivate::configureFonts(const QString &gtkFontName)const{Q_ASSERT(!systemFont);const int split = gtkFontName.lastIndexOf(QChar::Space);float size = QStringView{gtkFontName}.mid(split +1).toFloat(); QString fontName = gtkFontName.left(split); systemFont =newQFont(fontName, size); fixedFont =newQFont(QLatin1StringView(QGenericUnixTheme::defaultFixedFontNameC), systemFont->pointSize()); fixedFont->setStyleHint(QFont::TypeWriter);qCDebug(lcQpaFonts) <<"default fonts: system"<< systemFont <<"fixed"<< fixedFont;}#if QT_CONFIG(dbus)boolQGnomeThemePrivate::initDbus(){ dbus.reset(newQDBusListener());Q_ASSERT(dbus);// Wrap slot in a lambda to avoid inheriting QGnomeThemePrivate from QObjectauto wrapper = [this](QDBusListener::Provider provider,QDBusListener::Setting setting,const QVariant &value) {if(provider !=QDBusListener::Provider::Gnome && provider !=QDBusListener::Provider::Gtk) {return;}switch(setting) {caseQDBusListener::Setting::Theme:updateColorScheme(value.toString());break;caseQDBusListener::Setting::Contrast:updateHighContrast(static_cast<Qt::ContrastPreference>(value.toUInt()));break;default:break;}};returnQObject::connect(dbus.get(), &QDBusListener::settingChanged, dbus.get(), wrapper);}voidQGnomeThemePrivate::updateColorScheme(const QString &themeName){constauto oldColorScheme = m_colorScheme;if(themeName.contains(QLatin1StringView("light"),Qt::CaseInsensitive)) { m_colorScheme =Qt::ColorScheme::Light;}else if(themeName.contains(QLatin1StringView("dark"),Qt::CaseInsensitive)) { m_colorScheme =Qt::ColorScheme::Dark;}else{ m_colorScheme =Qt::ColorScheme::Unknown;}if(oldColorScheme != m_colorScheme)QWindowSystemInterface::handleThemeChange();}voidQGnomeThemePrivate::updateHighContrast(Qt::ContrastPreference contrast){if(m_contrast == contrast)return; m_contrast = contrast;QWindowSystemInterface::handleThemeChange();}#endif// QT_CONFIG(dbus)QGnomeTheme::QGnomeTheme():QGenericUnixTheme(newQGnomeThemePrivate()){} QVariant QGnomeTheme::themeHint(QPlatformTheme::ThemeHint hint)const{switch(hint) {caseQPlatformTheme::DialogButtonBoxButtonsHaveIcons:returnQVariant(true);caseQPlatformTheme::DialogButtonBoxLayout:returnQVariant(QPlatformDialogHelper::GnomeLayout);caseQPlatformTheme::SystemIconThemeName:returnQVariant(QStringLiteral("Adwaita"));caseQPlatformTheme::SystemIconFallbackThemeName:returnQVariant(QStringLiteral("gnome"));caseQPlatformTheme::IconThemeSearchPaths:returnQVariant(xdgIconThemePaths());caseQPlatformTheme::IconPixmapSizes:returnQVariant::fromValue(availableXdgFileIconSizes());caseQPlatformTheme::StyleNames: { QStringList styleNames; styleNames <<QStringLiteral("Fusion") <<QStringLiteral("windows");returnQVariant(styleNames);}caseQPlatformTheme::KeyboardScheme:returnQVariant(int(GnomeKeyboardScheme));caseQPlatformTheme::PasswordMaskCharacter:returnQVariant(QChar(0x2022));caseQPlatformTheme::UiEffects:returnQVariant(int(HoverEffect));caseQPlatformTheme::ButtonPressKeys:returnQVariant::fromValue( QList<Qt::Key>({Qt::Key_Space,Qt::Key_Return,Qt::Key_Enter,Qt::Key_Select }));caseQPlatformTheme::PreselectFirstFileInDirectory:return true;caseQPlatformTheme::MouseCursorTheme:returnQVariant(mouseCursorTheme());caseQPlatformTheme::MouseCursorSize:returnQVariant(mouseCursorSize());caseQPlatformTheme::PreferFileIconFromTheme:return true;default:break;}returnQPlatformTheme::themeHint(hint);} QIcon QGnomeTheme::fileIcon(const QFileInfo &fileInfo,QPlatformTheme::IconOptions)const{#if QT_CONFIG(mimetype)returnxdgFileIcon(fileInfo);#elseQ_UNUSED(fileInfo);returnQIcon();#endif}const QFont *QGnomeTheme::font(Font type)const{Q_D(const QGnomeTheme);if(!d->systemFont) d->configureFonts(gtkFontName());switch(type) {caseQPlatformTheme::SystemFont:return d->systemFont;caseQPlatformTheme::FixedFont:return d->fixedFont;default:returnnullptr;}} QString QGnomeTheme::gtkFontName()const{returnQStringLiteral("%1 %2").arg(QLatin1StringView(defaultSystemFontNameC)).arg(defaultSystemFontSize);}#if QT_CONFIG(dbus) QPlatformMenuBar *QGnomeTheme::createPlatformMenuBar()const{if(isDBusGlobalMenuAvailable())return newQDBusMenuBar();returnnullptr;}Qt::ColorScheme QGnomeTheme::colorScheme()const{returnd_func()->m_colorScheme;}Qt::ContrastPreference QGnomeTheme::contrastPreference()const{returnd_func()->m_contrast;}#endif#if QT_CONFIG(dbus) && QT_CONFIG(systemtrayicon) QPlatformSystemTrayIcon *QGnomeTheme::createPlatformSystemTrayIcon()const{if(shouldUseDBusTray())return newQDBusTrayIcon();returnnullptr;}#endif QString QGnomeTheme::standardButtonText(int button)const{switch(button) {caseQPlatformDialogHelper::Ok:returnQCoreApplication::translate("QGnomeTheme","&OK");caseQPlatformDialogHelper::Save:returnQCoreApplication::translate("QGnomeTheme","&Save");caseQPlatformDialogHelper::Cancel:returnQCoreApplication::translate("QGnomeTheme","&Cancel");caseQPlatformDialogHelper::Close:returnQCoreApplication::translate("QGnomeTheme","&Close");caseQPlatformDialogHelper::Discard:returnQCoreApplication::translate("QGnomeTheme","Close without Saving");default:break;}returnQPlatformTheme::standardButtonText(button);} QT_END_NAMESPACE 
close