Add support for FileChooser flatpak portal

Adds support for FileChooser Flatpak portal. To support them we just do
specific DBus calls, which are then caught and forwarded by xdg-desktop-
portal daemon/service. This is needed for Qt applications running in
sandbox.

[ChangeLog][Platform Specific Changes][Linux] Added support for flatpak
portals. Flatpak is a software utility for software deployment and
package management. It provides a sandbox environment in which users
can run applications in isolation from the rest of the system. To
communicate with the system flatpak uses portals, which are designed to
be a bridge between sandboxed applications and desktop/system running on
user's computer. Flatpak runs this service (called xdg-desktop-portal)
automatically. It exports the portals via DBus and they are visible by
default to all applications running under Flatpak.

Change-Id: I4de1402434ba7cbcc805eab51c30f84f8ba0c5c5
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Jan Grulich 2017-12-11 09:53:49 +01:00
parent 91aa782f01
commit 84731fbb2b
9 changed files with 902 additions and 4 deletions

View File

@ -53,6 +53,7 @@
#include <qpa/qplatformdrag.h>
#include <QtCore/QAbstractEventDispatcher>
#include <QtCore/QStandardPaths>
#include <QtCore/QVariant>
#include <QtCore/private/qcoreapplication_p.h>
#include <QtCore/private/qabstracteventdispatcher_p.h>
@ -244,6 +245,15 @@ static inline void clearFontUnlocked()
QGuiApplicationPrivate::app_font = 0;
}
static bool checkRunningUnderFlatpak()
{
#if QT_CONFIG(dbus)
return !QStandardPaths::locate(QStandardPaths::RuntimeLocation, QLatin1String("flatpak-info")).isEmpty();
#else
return false;
#endif // QT_CONFIG(dbus)
}
// Using aggregate initialization instead of ctor so we can have a POD global static
#define Q_WINDOW_GEOMETRY_SPECIFICATION_INITIALIZER { Qt::TopLeftCorner, -1, -1, -1, -1 }
@ -1179,16 +1189,21 @@ static void init_platform(const QString &pluginArgument, const QString &platform
if (!platformThemeName.isEmpty())
themeNames.append(platformThemeName);
// 2) Ask the platform integration for a list of theme names
// 2) Special case - check whether we are in sandbox to use flatpak platform theme for portals support
if (checkRunningUnderFlatpak()) {
themeNames.append(QStringLiteral("flatpak"));
}
// 3) Ask the platform integration for a list of theme names
themeNames += QGuiApplicationPrivate::platform_integration->themeNames();
// 3) Look for a theme plugin.
// 4) Look for a theme plugin.
for (const QString &themeName : qAsConst(themeNames)) {
QGuiApplicationPrivate::platform_theme = QPlatformThemeFactory::create(themeName, platformPluginPath);
if (QGuiApplicationPrivate::platform_theme)
break;
}
// 4) If no theme plugin was found ask the platform integration to
// 5) If no theme plugin was found ask the platform integration to
// create a theme
if (!QGuiApplicationPrivate::platform_theme) {
for (const QString &themeName : qAsConst(themeNames)) {
@ -1199,7 +1214,7 @@ static void init_platform(const QString &pluginArgument, const QString &platform
// No error message; not having a theme plugin is allowed.
}
// 5) Fall back on the built-in "null" platform theme.
// 6) Fall back on the built-in "null" platform theme.
if (!QGuiApplicationPrivate::platform_theme)
QGuiApplicationPrivate::platform_theme = new QPlatformTheme;

View File

@ -0,0 +1,3 @@
{
"Keys": [ "flatpak" ]
}

View File

@ -0,0 +1,17 @@
TARGET = qflatpak
PLUGIN_TYPE = platformthemes
PLUGIN_EXTENDS = -
PLUGIN_CLASS_NAME = QFlatpakThemePlugin
load(qt_plugin)
QT += core-private dbus gui-private theme_support-private
HEADERS += \
qflatpaktheme.h \
qflatpakfiledialog_p.h
SOURCES += \
main.cpp \
qflatpaktheme.cpp \
qflatpakfiledialog.cpp

View File

@ -0,0 +1,65 @@
/****************************************************************************
**
** Copyright (C) 2017 Red Hat, Inc
** 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$
**
****************************************************************************/
#include <qpa/qplatformthemeplugin.h>
#include "qflatpaktheme.h"
QT_BEGIN_NAMESPACE
class QFlatpakThemePlugin : public QPlatformThemePlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID QPlatformThemeFactoryInterface_iid FILE "flatpak.json")
public:
QPlatformTheme *create(const QString &key, const QStringList &params) override;
};
QPlatformTheme *QFlatpakThemePlugin::create(const QString &key, const QStringList &params)
{
Q_UNUSED(params);
if (!key.compare(QLatin1String("flatpak"), Qt::CaseInsensitive))
return new QFlatpakTheme;
return nullptr;
}
QT_END_NAMESPACE
#include "main.moc"

View File

@ -0,0 +1,347 @@
/****************************************************************************
**
** Copyright (C) 2017 Red Hat, Inc
** 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$
**
****************************************************************************/
#include "qflatpakfiledialog_p.h"
#include <QtCore/qeventloop.h>
#include <QtDBus/QtDBus>
#include <QDBusConnection>
#include <QDBusMessage>
#include <QDBusPendingCall>
#include <QDBusPendingCallWatcher>
#include <QDBusPendingReply>
#include <QMetaType>
#include <QMimeType>
#include <QMimeDatabase>
#include <QWindow>
QT_BEGIN_NAMESPACE
QDBusArgument &operator <<(QDBusArgument &arg, const QFlatpakFileDialog::FilterCondition &filterCondition)
{
arg.beginStructure();
arg << filterCondition.type << filterCondition.pattern;
arg.endStructure();
return arg;
}
const QDBusArgument &operator >>(const QDBusArgument &arg, QFlatpakFileDialog::FilterCondition &filterCondition)
{
uint type;
QString filterPattern;
arg.beginStructure();
arg >> type >> filterPattern;
filterCondition.type = (QFlatpakFileDialog::ConditionType)type;
filterCondition.pattern = filterPattern;
arg.endStructure();
return arg;
}
QDBusArgument &operator <<(QDBusArgument &arg, const QFlatpakFileDialog::Filter filter)
{
arg.beginStructure();
arg << filter.name << filter.filterConditions;
arg.endStructure();
return arg;
}
const QDBusArgument &operator >>(const QDBusArgument &arg, QFlatpakFileDialog::Filter &filter)
{
QString name;
QFlatpakFileDialog::FilterConditionList filterConditions;
arg.beginStructure();
arg >> name >> filterConditions;
filter.name = name;
filter.filterConditions = filterConditions;
arg.endStructure();
return arg;
}
class QFlatpakFileDialogPrivate
{
public:
WId winId = 0;
bool modal = false;
bool multipleFiles = false;
bool saveFile = false;
QString acceptLabel;
QString directory;
QString title;
QStringList nameFilters;
QStringList mimeTypesFilters;
QStringList selectedFiles;
};
QFlatpakFileDialog::QFlatpakFileDialog()
: QPlatformFileDialogHelper()
, d_ptr(new QFlatpakFileDialogPrivate)
{
}
QFlatpakFileDialog::~QFlatpakFileDialog()
{
}
void QFlatpakFileDialog::initializeDialog()
{
Q_D(QFlatpakFileDialog);
if (options()->fileMode() == QFileDialogOptions::ExistingFiles)
d->multipleFiles = true;
if (options()->isLabelExplicitlySet(QFileDialogOptions::Accept))
d->acceptLabel = options()->labelText(QFileDialogOptions::Accept);
if (!options()->windowTitle().isEmpty())
d->title = options()->windowTitle();
if (options()->acceptMode() == QFileDialogOptions::AcceptSave)
d->saveFile = true;
if (!options()->nameFilters().isEmpty())
d->nameFilters = options()->nameFilters();
if (!options()->mimeTypeFilters().isEmpty())
d->mimeTypesFilters = options()->mimeTypeFilters();
setDirectory(options()->initialDirectory());
}
bool QFlatpakFileDialog::defaultNameFilterDisables() const
{
return false;
}
void QFlatpakFileDialog::setDirectory(const QUrl &directory)
{
Q_D(QFlatpakFileDialog);
d->directory = directory.path();
}
QUrl QFlatpakFileDialog::directory() const
{
Q_D(const QFlatpakFileDialog);
return d->directory;
}
void QFlatpakFileDialog::selectFile(const QUrl &filename)
{
Q_D(QFlatpakFileDialog);
d->selectedFiles << filename.path();
}
QList<QUrl> QFlatpakFileDialog::selectedFiles() const
{
Q_D(const QFlatpakFileDialog);
QList<QUrl> files;
for (const QString &file : d->selectedFiles) {
files << QUrl(file);
}
return files;
}
void QFlatpakFileDialog::setFilter()
{
// TODO
}
void QFlatpakFileDialog::selectNameFilter(const QString &filter)
{
Q_UNUSED(filter);
// TODO
}
QString QFlatpakFileDialog::selectedNameFilter() const
{
// TODO
return QString();
}
void QFlatpakFileDialog::exec()
{
Q_D(const QFlatpakFileDialog);
QDBusMessage message = QDBusMessage::createMethodCall(QLatin1String("org.freedesktop.portal.Desktop"),
QLatin1String("/org/freedesktop/portal/desktop"),
QLatin1String("org.freedesktop.portal.FileChooser"),
d->saveFile ? QLatin1String("SaveFile") : QLatin1String("OpenFile"));
QString parentWindowId = QLatin1String("x11:") + QString::number(d->winId);
QVariantMap options;
if (!d->acceptLabel.isEmpty())
options.insert(QLatin1String("accept_label"), d->acceptLabel);
options.insert(QLatin1String("modal"), d->modal);
options.insert(QLatin1String("multiple"), d->multipleFiles);
if (d->saveFile) {
if (!d->directory.isEmpty())
options.insert(QLatin1String("current_folder"), d->directory.toLatin1());
if (!d->selectedFiles.isEmpty())
options.insert(QLatin1String("current_file"), d->selectedFiles.first().toLatin1());
}
// Insert filters
qDBusRegisterMetaType<FilterCondition>();
qDBusRegisterMetaType<FilterConditionList>();
qDBusRegisterMetaType<Filter>();
qDBusRegisterMetaType<FilterList>();
FilterList filterList;
if (!d->mimeTypesFilters.isEmpty()) {
for (const QString &mimeTypefilter : d->mimeTypesFilters) {
QMimeDatabase mimeDatabase;
QMimeType mimeType = mimeDatabase.mimeTypeForName(mimeTypefilter);
// Creates e.g. (1, "image/png")
FilterCondition filterCondition;
filterCondition.type = MimeType;
filterCondition.pattern = mimeTypefilter;
// Creates e.g. [((1, "image/png"))]
FilterConditionList filterConditions;
filterConditions << filterCondition;
// Creates e.g. [("Images", [((1, "image/png"))])]
Filter filter;
filter.name = mimeType.comment();
filter.filterConditions = filterConditions;
filterList << filter;
}
} else if (!d->nameFilters.isEmpty()) {
for (const QString &filter : d->nameFilters) {
// Do parsing:
// Supported format is ("Images (*.png *.jpg)")
QRegularExpression regexp(QPlatformFileDialogHelper::filterRegExp);
QRegularExpressionMatch match = regexp.match(filter);
if (match.hasMatch()) {
QString userVisibleName = match.captured(0);
QStringList filterStrings = match.captured(1).split(QLatin1String(" "));
FilterConditionList filterConditions;
for (const QString &filterString : filterStrings) {
FilterCondition filterCondition;
filterCondition.type = GlobalPattern;
filterCondition.pattern = filterString;
filterConditions << filterCondition;
}
Filter filter;
filter.name = userVisibleName;
filter.filterConditions = filterConditions;
filterList << filter;
}
}
}
if (!filterList.isEmpty())
options.insert(QLatin1String("filters"), QVariant::fromValue(filterList));
// TODO choices a(ssa(ss)s)
// List of serialized combo boxes to add to the file chooser.
message << parentWindowId << d->title << options;
QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message);
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall);
connect(watcher, &QDBusPendingCallWatcher::finished, this, [this] (QDBusPendingCallWatcher *watcher) {
QDBusPendingReply<QDBusObjectPath> reply = *watcher;
if (reply.isError()) {
Q_EMIT reject();
} else {
QDBusConnection::sessionBus().connect(nullptr,
reply.value().path(),
QLatin1String("org.freedesktop.portal.Request"),
QLatin1String("Response"),
this,
SLOT(gotResponse(uint,QVariantMap)));
}
});
// HACK we have to avoid returning until we emit that the dialog was accepted or rejected
QEventLoop loop;
loop.connect(this, SIGNAL(accept()), SLOT(quit()));
loop.connect(this, SIGNAL(reject()), SLOT(quit()));
loop.exec();
}
void QFlatpakFileDialog::hide()
{
}
bool QFlatpakFileDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
{
Q_D(QFlatpakFileDialog);
Q_UNUSED(windowFlags);
initializeDialog();
d->modal = windowModality != Qt::NonModal;
d->winId = parent ? parent->winId() : 0;
return true;
}
void QFlatpakFileDialog::gotResponse(uint response, const QVariantMap &results)
{
Q_D(QFlatpakFileDialog);
if (!response) {
if (results.contains(QLatin1String("uris")))
d->selectedFiles = results.value(QLatin1String("uris")).toStringList();
Q_EMIT accept();
} else {
Q_EMIT reject();
}
}
QT_END_NAMESPACE

View File

@ -0,0 +1,105 @@
/****************************************************************************
**
** Copyright (C) 2017 Red Hat, Inc
** 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$
**
****************************************************************************/
#ifndef QFLATPAKFILEDIALOG_P_H
#define QFLATPAKFILEDIALOG_P_H
#include <qpa/qplatformdialoghelper.h>
#include <QVector>
QT_BEGIN_NAMESPACE
class QFlatpakFileDialogPrivate;
class QFlatpakFileDialog : public QPlatformFileDialogHelper
{
Q_OBJECT
Q_DECLARE_PRIVATE(QFlatpakFileDialog)
public:
enum ConditionType {
GlobalPattern = 0,
MimeType = 1
};
// Filters a(sa(us))
// Example: [('Images', [(0, '*.ico'), (1, 'image/png')]), ('Text', [(0, '*.txt')])]
struct FilterCondition {
ConditionType type;
QString pattern; // E.g. '*ico' or 'image/png'
};
typedef QVector<FilterCondition> FilterConditionList;
struct Filter {
QString name; // E.g. 'Images' or 'Text
FilterConditionList filterConditions;; // E.g. [(0, '*.ico'), (1, 'image/png')] or [(0, '*.txt')]
};
typedef QVector<Filter> FilterList;
QFlatpakFileDialog();
~QFlatpakFileDialog();
bool defaultNameFilterDisables() const override;
QUrl directory() const override;
void setDirectory(const QUrl &directory) override;
void selectFile(const QUrl &filename) override;
QList<QUrl> selectedFiles() const override;
void setFilter() override;
void selectNameFilter(const QString &filter) override;
QString selectedNameFilter() const override;
void exec() override;
bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) override;
void hide() override;
private Q_SLOTS:
void gotResponse(uint response, const QVariantMap &results);
private:
void initializeDialog();
QScopedPointer<QFlatpakFileDialogPrivate> d_ptr;
};
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QFlatpakFileDialog::FilterCondition);
Q_DECLARE_METATYPE(QFlatpakFileDialog::FilterConditionList);
Q_DECLARE_METATYPE(QFlatpakFileDialog::Filter);
Q_DECLARE_METATYPE(QFlatpakFileDialog::FilterList);
#endif // QFLATPAKFILEDIALOG_P_H

View File

@ -0,0 +1,254 @@
/****************************************************************************
**
** 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$
**
****************************************************************************/
#include "qflatpaktheme.h"
#include "qflatpakfiledialog_p.h"
#include <private/qguiapplication_p.h>
#include <qpa/qplatformtheme_p.h>
#include <qpa/qplatformthemefactory_p.h>
#include <qpa/qplatformintegration.h>
QT_BEGIN_NAMESPACE
class QFlatpakThemePrivate : public QPlatformThemePrivate
{
public:
QFlatpakThemePrivate()
: QPlatformThemePrivate()
{ }
~QFlatpakThemePrivate()
{
delete baseTheme;
}
QPlatformTheme *baseTheme;
};
QFlatpakTheme::QFlatpakTheme()
: d_ptr(new QFlatpakThemePrivate)
{
Q_D(QFlatpakTheme);
QStringList themeNames;
themeNames += QGuiApplicationPrivate::platform_integration->themeNames();
// 1) Look for a theme plugin.
for (const QString &themeName : qAsConst(themeNames)) {
d->baseTheme = QPlatformThemeFactory::create(themeName, nullptr);
if (d->baseTheme)
break;
}
// 2) If no theme plugin was found ask the platform integration to
// create a theme
if (!d->baseTheme) {
for (const QString &themeName : qAsConst(themeNames)) {
d->baseTheme = QGuiApplicationPrivate::platform_integration->createPlatformTheme(themeName);
if (d->baseTheme)
break;
}
// No error message; not having a theme plugin is allowed.
}
// 3) Fall back on the built-in "null" platform theme.
if (!d->baseTheme)
d->baseTheme = new QPlatformTheme;
}
QPlatformMenuItem* QFlatpakTheme::createPlatformMenuItem() const
{
Q_D(const QFlatpakTheme);
if (d->baseTheme)
return d->baseTheme->createPlatformMenuItem();
return QPlatformTheme::createPlatformMenuItem();
}
QPlatformMenu* QFlatpakTheme::createPlatformMenu() const
{
Q_D(const QFlatpakTheme);
if (d->baseTheme)
return d->baseTheme->createPlatformMenu();
return QPlatformTheme::createPlatformMenu();
}
QPlatformMenuBar* QFlatpakTheme::createPlatformMenuBar() const
{
Q_D(const QFlatpakTheme);
if (d->baseTheme)
return d->baseTheme->createPlatformMenuBar();
return QFlatpakTheme::createPlatformMenuBar();
}
void QFlatpakTheme::showPlatformMenuBar()
{
Q_D(const QFlatpakTheme);
if (d->baseTheme)
return d->baseTheme->showPlatformMenuBar();
return QFlatpakTheme::showPlatformMenuBar();
}
bool QFlatpakTheme::usePlatformNativeDialog(DialogType type) const
{
Q_D(const QFlatpakTheme);
if (type == FileDialog)
return true;
if (d->baseTheme)
return d->baseTheme->usePlatformNativeDialog(type);
return QFlatpakTheme::usePlatformNativeDialog(type);
}
QPlatformDialogHelper* QFlatpakTheme::createPlatformDialogHelper(DialogType type) const
{
Q_D(const QFlatpakTheme);
if (type == FileDialog)
return new QFlatpakFileDialog;
if (d->baseTheme)
return d->baseTheme->createPlatformDialogHelper(type);
return QFlatpakTheme::createPlatformDialogHelper(type);
}
#ifndef QT_NO_SYSTEMTRAYICON
QPlatformSystemTrayIcon* QFlatpakTheme::createPlatformSystemTrayIcon() const
{
Q_D(const QFlatpakTheme);
if (d->baseTheme)
return d->baseTheme->createPlatformSystemTrayIcon();
return QPlatformTheme::createPlatformSystemTrayIcon();
}
#endif
const QPalette *QFlatpakTheme::palette(Palette type) const
{
Q_D(const QFlatpakTheme);
if (d->baseTheme)
return d->baseTheme->palette(type);
return QPlatformTheme::palette(type);
}
const QFont* QFlatpakTheme::font(Font type) const
{
Q_D(const QFlatpakTheme);
if (d->baseTheme)
return d->baseTheme->font(type);
return QPlatformTheme::font(type);
}
QVariant QFlatpakTheme::themeHint(ThemeHint hint) const
{
Q_D(const QFlatpakTheme);
if (d->baseTheme)
return d->baseTheme->themeHint(hint);
return QPlatformTheme::themeHint(hint);
}
QPixmap QFlatpakTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const
{
Q_D(const QFlatpakTheme);
if (d->baseTheme)
return d->baseTheme->standardPixmap(sp, size);
return QPlatformTheme::standardPixmap(sp, size);
}
QIcon QFlatpakTheme::fileIcon(const QFileInfo &fileInfo,
QPlatformTheme::IconOptions iconOptions) const
{
Q_D(const QFlatpakTheme);
if (d->baseTheme)
return d->baseTheme->fileIcon(fileInfo, iconOptions);
return QPlatformTheme::fileIcon(fileInfo, iconOptions);
}
QIconEngine * QFlatpakTheme::createIconEngine(const QString &iconName) const
{
Q_D(const QFlatpakTheme);
if (d->baseTheme)
return d->baseTheme->createIconEngine(iconName);
return QPlatformTheme::createIconEngine(iconName);
}
QList<QKeySequence> QFlatpakTheme::keyBindings(QKeySequence::StandardKey key) const
{
Q_D(const QFlatpakTheme);
if (d->baseTheme)
return d->baseTheme->keyBindings(key);
return QPlatformTheme::keyBindings(key);
}
QString QFlatpakTheme::standardButtonText(int button) const
{
Q_D(const QFlatpakTheme);
if (d->baseTheme)
return d->baseTheme->standardButtonText(button);
return QPlatformTheme::standardButtonText(button);
}
QT_END_NAMESPACE

View File

@ -0,0 +1,90 @@
/****************************************************************************
**
** 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$
**
****************************************************************************/
#ifndef QFLATPAKTHEME_H
#define QFLATPAKTHEME_H
#include <qpa/qplatformtheme.h>
QT_BEGIN_NAMESPACE
class QFlatpakThemePrivate;
class QFlatpakTheme : public QPlatformTheme
{
Q_DECLARE_PRIVATE(QFlatpakTheme)
public:
QFlatpakTheme();
QPlatformMenuItem *createPlatformMenuItem() const override;
QPlatformMenu *createPlatformMenu() const override;
QPlatformMenuBar *createPlatformMenuBar() const override;
void showPlatformMenuBar() override;
bool usePlatformNativeDialog(DialogType type) const override;
QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const override;
#ifndef QT_NO_SYSTEMTRAYICON
QPlatformSystemTrayIcon *createPlatformSystemTrayIcon() const override;
#endif
const QPalette *palette(Palette type = SystemPalette) const override;
const QFont *font(Font type = SystemFont) const override;
QVariant themeHint(ThemeHint hint) const override;
QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const override;
QIcon fileIcon(const QFileInfo &fileInfo,
QPlatformTheme::IconOptions iconOptions = 0) const;
QIconEngine *createIconEngine(const QString &iconName) const override;
QList<QKeySequence> keyBindings(QKeySequence::StandardKey key) const override;
QString standardButtonText(int button) const override;
private:
QScopedPointer<QFlatpakThemePrivate> d_ptr;
Q_DISABLE_COPY(QFlatpakTheme)
};
QT_END_NAMESPACE
#endif // QFLATPAKTHEME_H

View File

@ -1,4 +1,6 @@
TEMPLATE = subdirs
QT_FOR_CONFIG += widgets-private
qtConfig(dbus): SUBDIRS += flatpak
qtHaveModule(widgets):qtConfig(gtk3): SUBDIRS += gtk3