summaryrefslogtreecommitdiffstats
path: root/src/plugins/platformthemes
diff options
context:
space:
mode:
authorIlya Fedin <fedin-ilja2010@ya.ru>2022-06-01 15:40:56 +0400
committerIlya Fedin <fedin-ilja2010@ya.ru>2022-06-09 01:49:41 +0400
commitfb981a0954119ed0dfa4a402fdef78e7257ffc96 (patch)
tree30ca313836422a64447b52d9018b3516452e51be /src/plugins/platformthemes
parent17454bf9c60d9a7f836461234f48e1bb9d7d5bf9 (diff)
Fallback to another file dialog implementation when XDP is inaccessible
Fixes: QTBUG-98988 Pick-to: 6.4 6.3 6.2 5.15 Change-Id: Idca1ab4cae0e9eabebc599f3c8efa136a7973918 Reviewed-by: Jan Grulich <jgrulich@redhat.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/plugins/platformthemes')
-rw-r--r--src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp68
-rw-r--r--src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h11
-rw-r--r--src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp7
3 files changed, 53 insertions, 33 deletions
diff --git a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
index 8c35c0efec..54e600fcbe 100644
--- a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
+++ b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
@@ -69,15 +69,12 @@ const QDBusArgument &operator >>(const QDBusArgument &arg, QXdgDesktopPortalFile
class QXdgDesktopPortalFileDialogPrivate
{
public:
- QXdgDesktopPortalFileDialogPrivate(QPlatformFileDialogHelper *nativeFileDialog)
+ QXdgDesktopPortalFileDialogPrivate(QPlatformFileDialogHelper *nativeFileDialog, uint fileChooserPortalVersion)
: nativeFileDialog(nativeFileDialog)
+ , fileChooserPortalVersion(fileChooserPortalVersion)
{ }
- WId winId = 0;
- bool directoryMode = false;
- bool modal = false;
- bool multipleFiles = false;
- bool saveFile = false;
+ QEventLoop loop;
QString acceptLabel;
QString directory;
QString title;
@@ -89,11 +86,16 @@ public:
QString selectedNameFilter;
QStringList selectedFiles;
std::unique_ptr<QPlatformFileDialogHelper> nativeFileDialog;
+ uint fileChooserPortalVersion = 0;
+ bool failedToOpen = false;
+ bool directoryMode = false;
+ bool multipleFiles = false;
+ bool saveFile = false;
};
-QXdgDesktopPortalFileDialog::QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog)
+QXdgDesktopPortalFileDialog::QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog, uint fileChooserPortalVersion)
: QPlatformFileDialogHelper()
- , d_ptr(new QXdgDesktopPortalFileDialogPrivate(nativeFileDialog))
+ , d_ptr(new QXdgDesktopPortalFileDialogPrivate(nativeFileDialog, fileChooserPortalVersion))
{
Q_D(QXdgDesktopPortalFileDialog);
@@ -101,6 +103,9 @@ QXdgDesktopPortalFileDialog::QXdgDesktopPortalFileDialog(QPlatformFileDialogHelp
connect(d->nativeFileDialog.get(), SIGNAL(accept()), this, SIGNAL(accept()));
connect(d->nativeFileDialog.get(), SIGNAL(reject()), this, SIGNAL(reject()));
}
+
+ d->loop.connect(this, SIGNAL(accept()), SLOT(quit()));
+ d->loop.connect(this, SIGNAL(reject()), SLOT(quit()));
}
QXdgDesktopPortalFileDialog::~QXdgDesktopPortalFileDialog()
@@ -144,7 +149,7 @@ void QXdgDesktopPortalFileDialog::initializeDialog()
setDirectory(options()->initialDirectory());
}
-void QXdgDesktopPortalFileDialog::openPortal()
+void QXdgDesktopPortalFileDialog::openPortal(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
{
Q_D(QXdgDesktopPortalFileDialog);
@@ -152,13 +157,13 @@ void QXdgDesktopPortalFileDialog::openPortal()
"/org/freedesktop/portal/desktop"_L1,
"org.freedesktop.portal.FileChooser"_L1,
d->saveFile ? "SaveFile"_L1 : "OpenFile"_L1);
- QString parentWindowId = "x11:"_L1 + QString::number(d->winId, 16);
+ QString parentWindowId = "x11:"_L1 + QString::number(parent ? parent->winId() : 0, 16);
QVariantMap options;
if (!d->acceptLabel.isEmpty())
options.insert("accept_label"_L1, d->acceptLabel);
- options.insert("modal"_L1, d->modal);
+ options.insert("modal"_L1, windowModality != Qt::NonModal);
options.insert("multiple"_L1, d->multipleFiles);
options.insert("directory"_L1, d->directoryMode);
@@ -261,10 +266,18 @@ void QXdgDesktopPortalFileDialog::openPortal()
QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message);
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall);
- connect(watcher, &QDBusPendingCallWatcher::finished, this, [this] (QDBusPendingCallWatcher *watcher) {
+ connect(watcher, &QDBusPendingCallWatcher::finished, this, [=] (QDBusPendingCallWatcher *watcher) {
QDBusPendingReply<QDBusObjectPath> reply = *watcher;
- if (reply.isError()) {
- Q_EMIT reject();
+ // Any error means the dialog is not shown and we need to fallback
+ d->failedToOpen = reply.isError();
+ if (d->failedToOpen) {
+ if (d->nativeFileDialog) {
+ d->nativeFileDialog->show(windowFlags, windowModality, parent);
+ if (d->loop.isRunning())
+ d->nativeFileDialog->exec();
+ } else {
+ Q_EMIT reject();
+ }
} else {
QDBusConnection::sessionBus().connect(nullptr,
reply.value().path(),
@@ -381,10 +394,7 @@ void QXdgDesktopPortalFileDialog::exec()
}
// 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();
+ d->loop.exec();
}
void QXdgDesktopPortalFileDialog::hide()
@@ -401,13 +411,10 @@ bool QXdgDesktopPortalFileDialog::show(Qt::WindowFlags windowFlags, Qt::WindowMo
initializeDialog();
- d->modal = windowModality != Qt::NonModal;
- d->winId = parent ? parent->winId() : 0;
-
- if (d->nativeFileDialog && useNativeFileDialog())
+ if (d->nativeFileDialog && useNativeFileDialog(OpenFallback))
return d->nativeFileDialog->show(windowFlags, windowModality, parent);
- openPortal();
+ openPortal(windowFlags, windowModality, parent);
return true;
}
@@ -437,13 +444,20 @@ void QXdgDesktopPortalFileDialog::gotResponse(uint response, const QVariantMap &
}
}
-bool QXdgDesktopPortalFileDialog::useNativeFileDialog() const
+bool QXdgDesktopPortalFileDialog::useNativeFileDialog(QXdgDesktopPortalFileDialog::FallbackType fallbackType) const
{
- if (options()->fileMode() == QFileDialogOptions::Directory)
- return true;
- else if (options()->fileMode() == QFileDialogOptions::DirectoryOnly)
+ Q_D(const QXdgDesktopPortalFileDialog);
+
+ if (d->failedToOpen && fallbackType != OpenFallback)
return true;
+ if (d->fileChooserPortalVersion < 3) {
+ if (options()->fileMode() == QFileDialogOptions::Directory)
+ return true;
+ else if (options()->fileMode() == QFileDialogOptions::DirectoryOnly)
+ return true;
+ }
+
return false;
}
diff --git a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h
index 30b17fdc52..f309307cd6 100644
--- a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h
+++ b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h
@@ -15,6 +15,11 @@ class QXdgDesktopPortalFileDialog : public QPlatformFileDialogHelper
Q_OBJECT
Q_DECLARE_PRIVATE(QXdgDesktopPortalFileDialog)
public:
+ enum FallbackType {
+ GenericFallback,
+ OpenFallback
+ };
+
enum ConditionType : uint {
GlobalPattern = 0,
MimeType = 1
@@ -33,7 +38,7 @@ public:
};
typedef QList<Filter> FilterList;
- QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog = nullptr);
+ QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog = nullptr, uint fileChooserPortalVersion = 0);
~QXdgDesktopPortalFileDialog();
bool defaultNameFilterDisables() const override;
@@ -56,8 +61,8 @@ private Q_SLOTS:
private:
void initializeDialog();
- void openPortal();
- bool useNativeFileDialog() const;
+ void openPortal(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent);
+ bool useNativeFileDialog(FallbackType fallbackType = GenericFallback) const;
QScopedPointer<QXdgDesktopPortalFileDialogPrivate> d_ptr;
};
diff --git a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
index 60d5474ed2..e6a72e4289 100644
--- a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
+++ b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
@@ -166,11 +166,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;
}