diff options
Diffstat (limited to 'src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp')
-rw-r--r-- | src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp | 146 |
1 files changed, 94 insertions, 52 deletions
diff --git a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp index fb324afbd8..355d3e6cc9 100644 --- a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp +++ b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 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 "qxdgdesktopportaltheme.h" #include "qxdgdesktopportalfiledialog_p.h" @@ -50,14 +14,24 @@ #include <QDBusPendingCall> #include <QDBusPendingCallWatcher> #include <QDBusPendingReply> +#include <QDBusReply> QT_BEGIN_NAMESPACE -class QXdgDesktopPortalThemePrivate : public QPlatformThemePrivate -{ +using namespace Qt::StringLiterals; + +class QXdgDesktopPortalThemePrivate : public QObject + { + Q_OBJECT public: + enum XdgColorschemePref { + None, + PreferDark, + PreferLight + }; + QXdgDesktopPortalThemePrivate() - : QPlatformThemePrivate() + : QObject() { } ~QXdgDesktopPortalThemePrivate() @@ -65,8 +39,44 @@ public: delete baseTheme; } + /*! \internal + + Converts the given Freedesktop color scheme setting \a colorschemePref to a Qt::ColorScheme value. + Specification: https://github.com/flatpak/xdg-desktop-portal/blob/d7a304a00697d7d608821253cd013f3b97ac0fb6/data/org.freedesktop.impl.portal.Settings.xml#L33-L45 + + Unfortunately the enum numerical values are not defined identically, so we have to convert them. + + The mapping is as follows: + + Enum Index: Freedesktop definition | Qt definition + ----------------------------------- | ------------- + 0: No preference | 0: Unknown + 1: Prefer dark appearance | 2: Dark + 2: Prefer light appearance | 1: Light + */ + static Qt::ColorScheme colorSchemeFromXdgPref(const XdgColorschemePref colorschemePref) + { + switch (colorschemePref) { + case PreferDark: return Qt::ColorScheme::Dark; + case PreferLight: return Qt::ColorScheme::Light; + default: return Qt::ColorScheme::Unknown; + } + } + +public Q_SLOTS: + void settingChanged(const QString &group, const QString &key, + const QDBusVariant &value) + { + if (group == "org.freedesktop.appearance"_L1 && key == "color-scheme"_L1) { + colorScheme = colorSchemeFromXdgPref(static_cast<XdgColorschemePref>(value.variant().toUInt())); + QWindowSystemInterface::handleThemeChange(); + } + } + +public: QPlatformTheme *baseTheme = nullptr; uint fileChooserPortalVersion = 0; + Qt::ColorScheme colorScheme = Qt::ColorScheme::Unknown; }; QXdgDesktopPortalTheme::QXdgDesktopPortalTheme() @@ -77,7 +87,7 @@ QXdgDesktopPortalTheme::QXdgDesktopPortalTheme() QStringList themeNames; themeNames += QGuiApplicationPrivate::platform_integration->themeNames(); // 1) Look for a theme plugin. - for (const QString &themeName : qAsConst(themeNames)) { + for (const QString &themeName : std::as_const(themeNames)) { d->baseTheme = QPlatformThemeFactory::create(themeName, nullptr); if (d->baseTheme) break; @@ -86,7 +96,7 @@ QXdgDesktopPortalTheme::QXdgDesktopPortalTheme() // 2) If no theme plugin was found ask the platform integration to // create a theme if (!d->baseTheme) { - for (const QString &themeName : qAsConst(themeNames)) { + for (const QString &themeName : std::as_const(themeNames)) { d->baseTheme = QGuiApplicationPrivate::platform_integration->createPlatformTheme(themeName); if (d->baseTheme) break; @@ -99,19 +109,40 @@ QXdgDesktopPortalTheme::QXdgDesktopPortalTheme() d->baseTheme = new QPlatformTheme; // Get information about portal version - QDBusMessage message = QDBusMessage::createMethodCall(QLatin1String("org.freedesktop.portal.Desktop"), - QLatin1String("/org/freedesktop/portal/desktop"), - QLatin1String("org.freedesktop.DBus.Properties"), - QLatin1String("Get")); - message << QLatin1String("org.freedesktop.portal.FileChooser") << QLatin1String("version"); + QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.portal.Desktop"_L1, + "/org/freedesktop/portal/desktop"_L1, + "org.freedesktop.DBus.Properties"_L1, + "Get"_L1); + message << "org.freedesktop.portal.FileChooser"_L1 << "version"_L1; QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall); - QObject::connect(watcher, &QDBusPendingCallWatcher::finished, [d] (QDBusPendingCallWatcher *watcher) { + QObject::connect(watcher, &QDBusPendingCallWatcher::finished, watcher, [d] (QDBusPendingCallWatcher *watcher) { QDBusPendingReply<QVariant> reply = *watcher; if (reply.isValid()) { d->fileChooserPortalVersion = reply.value().toUInt(); } + watcher->deleteLater(); }); + + // Get information about system theme preference + message = QDBusMessage::createMethodCall("org.freedesktop.portal.Desktop"_L1, + "/org/freedesktop/portal/desktop"_L1, + "org.freedesktop.portal.Settings"_L1, + "Read"_L1); + message << "org.freedesktop.appearance"_L1 << "color-scheme"_L1; + + // this must not be asyncCall() because we have to set appearance now + QDBusReply<QVariant> reply = QDBusConnection::sessionBus().call(message); + if (reply.isValid()) { + const QDBusVariant dbusVariant = qvariant_cast<QDBusVariant>(reply.value()); + const QXdgDesktopPortalThemePrivate::XdgColorschemePref xdgPref = static_cast<QXdgDesktopPortalThemePrivate::XdgColorschemePref>(dbusVariant.variant().toUInt()); + d->colorScheme = QXdgDesktopPortalThemePrivate::colorSchemeFromXdgPref(xdgPref); + } + + QDBusConnection::sessionBus().connect( + "org.freedesktop.portal.Desktop"_L1, "/org/freedesktop/portal/desktop"_L1, + "org.freedesktop.portal.Settings"_L1, "SettingChanged"_L1, d_ptr.get(), + SLOT(settingChanged(QString, QString, QDBusVariant))); } QPlatformMenuItem* QXdgDesktopPortalTheme::createPlatformMenuItem() const @@ -152,11 +183,12 @@ QPlatformDialogHelper* QXdgDesktopPortalTheme::createPlatformDialogHelper(Dialog { Q_D(const QXdgDesktopPortalTheme); - if (type == FileDialog) { + if (type == FileDialog && d->fileChooserPortalVersion) { // Older versions of FileChooser portal don't support opening directories, therefore we fallback // to native file dialog opened inside the sandbox to open a directory. - if (d->fileChooserPortalVersion < 3 && d->baseTheme->usePlatformNativeDialog(type)) - return new QXdgDesktopPortalFileDialog(static_cast<QPlatformFileDialogHelper*>(d->baseTheme->createPlatformDialogHelper(type))); + if (d->baseTheme->usePlatformNativeDialog(type)) + return new QXdgDesktopPortalFileDialog(static_cast<QPlatformFileDialogHelper*>(d->baseTheme->createPlatformDialogHelper(type)), + d->fileChooserPortalVersion); return new QXdgDesktopPortalFileDialog; } @@ -190,6 +222,14 @@ QVariant QXdgDesktopPortalTheme::themeHint(ThemeHint hint) const return d->baseTheme->themeHint(hint); } +Qt::ColorScheme QXdgDesktopPortalTheme::colorScheme() const +{ + Q_D(const QXdgDesktopPortalTheme); + if (d->colorScheme == Qt::ColorScheme::Unknown) + return d->baseTheme->colorScheme(); + return d->colorScheme; +} + QPixmap QXdgDesktopPortalTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const { Q_D(const QXdgDesktopPortalTheme); @@ -224,3 +264,5 @@ QString QXdgDesktopPortalTheme::standardButtonText(int button) const } QT_END_NAMESPACE + +#include "qxdgdesktopportaltheme.moc" |