Sophie

Sophie

distrib > Mageia > cauldron > x86_64 > media > core-release-src > by-pkgid > 4c532bfb9916518564da5ba2805999f5 > files > 47

qtbase5-5.15.12-3.mga10.src.rpm

From de87b9d9e9d25e9a11b42149ab17553d3289f764 Mon Sep 17 00:00:00 2001
From: Ilya Fedin <fedin-ilja2010@ya.ru>
Date: Wed, 1 Jun 2022 15:40:56 +0400
Subject: [PATCH 047/147] 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>
(cherry picked from commit fb981a0954119ed0dfa4a402fdef78e7257ffc96)

* asturmlechner 2022-06-11: Fix conflict with dev branch commit
    ceaa7d6341e666f6fe0d071ea34cad9877961a0e
---
 .../qxdgdesktopportalfiledialog.cpp           | 68 +++++++++++--------
 .../qxdgdesktopportalfiledialog_p.h           | 11 ++-
 .../qxdgdesktopportaltheme.cpp                |  7 +-
 3 files changed, 53 insertions(+), 33 deletions(-)

diff --git a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
index 3ab19afea6..b2301c8c15 100644
--- a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
+++ b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
@@ -102,15 +102,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;
@@ -122,11 +119,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);
 
@@ -134,6 +136,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()
@@ -177,7 +182,7 @@ void QXdgDesktopPortalFileDialog::initializeDialog()
     setDirectory(options()->initialDirectory());
 }
 
-void QXdgDesktopPortalFileDialog::openPortal()
+void QXdgDesktopPortalFileDialog::openPortal(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
 {
     Q_D(QXdgDesktopPortalFileDialog);
 
@@ -185,13 +190,13 @@ void QXdgDesktopPortalFileDialog::openPortal()
                                                           QLatin1String("/org/freedesktop/portal/desktop"),
                                                           QLatin1String("org.freedesktop.portal.FileChooser"),
                                                           d->saveFile ? QLatin1String("SaveFile") : QLatin1String("OpenFile"));
-    QString parentWindowId = QLatin1String("x11:") + QString::number(d->winId, 16);
+    QString parentWindowId = QLatin1String("x11:") + QString::number(parent ? parent->winId() : 0, 16);
 
     QVariantMap options;
     if (!d->acceptLabel.isEmpty())
         options.insert(QLatin1String("accept_label"), d->acceptLabel);
 
-    options.insert(QLatin1String("modal"), d->modal);
+    options.insert(QLatin1String("modal"), windowModality != Qt::NonModal);
     options.insert(QLatin1String("multiple"), d->multipleFiles);
     options.insert(QLatin1String("directory"), d->directoryMode);
 
@@ -290,10 +295,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(),
@@ -410,10 +423,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()
@@ -430,13 +440,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;
 }
@@ -466,13 +473,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 5c1231bb54..65e22a5cf2 100644
--- a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h
+++ b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h
@@ -51,6 +51,11 @@ class QXdgDesktopPortalFileDialog : public QPlatformFileDialogHelper
     Q_OBJECT
     Q_DECLARE_PRIVATE(QXdgDesktopPortalFileDialog)
 public:
+    enum FallbackType {
+        GenericFallback,
+        OpenFallback
+    };
+
     enum ConditionType : uint {
         GlobalPattern = 0,
         MimeType = 1
@@ -69,7 +74,7 @@ public:
     };
     typedef QVector<Filter> FilterList;
 
-    QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog = nullptr);
+    QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog = nullptr, uint fileChooserPortalVersion = 0);
     ~QXdgDesktopPortalFileDialog();
 
     bool defaultNameFilterDisables() const override;
@@ -92,8 +97,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 2fc3167fd5..b809503122 100644
--- a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
+++ b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
@@ -153,11 +153,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;
     }
-- 
2.40.1