From 844967d297327dc72a1aa67644c1b2fa3fe6839c Mon Sep 17 00:00:00 2001 From: Jan Grulich Date: Tue, 21 Apr 2020 21:42:51 +0200 Subject: Support opening directories over portal Recent version of xdg-desktop-portal got support for opening directories through the portal, which means we no longer need to rely on opening the dialog inside sandbox, hoping we have permissions to user directories. [ChangeLog][Linux] QFileDialog will open directories through the portal if required version of xdg-desktop-portal is running on the system. Change-Id: Ifc9035e268f1cc8d9d6a93480e651e0d9e1e9929 Reviewed-by: Thiago Macieira --- .../qxdgdesktopportalfiledialog.cpp | 5 +++++ .../xdgdesktopportal/qxdgdesktopportaltheme.cpp | 26 +++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) (limited to 'src/plugins/platformthemes') diff --git a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp index 13c39436ba..4b37367ad0 100644 --- a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp +++ b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp @@ -107,6 +107,7 @@ public: { } WId winId = 0; + bool directoryMode = false; bool modal = false; bool multipleFiles = false; bool saveFile = false; @@ -145,6 +146,9 @@ void QXdgDesktopPortalFileDialog::initializeDialog() if (options()->fileMode() == QFileDialogOptions::ExistingFiles) d->multipleFiles = true; + if (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly) + d->directoryMode = true; + if (options()->isLabelExplicitlySet(QFileDialogOptions::Accept)) d->acceptLabel = options()->labelText(QFileDialogOptions::Accept); @@ -179,6 +183,7 @@ void QXdgDesktopPortalFileDialog::openPortal() options.insert(QLatin1String("modal"), d->modal); options.insert(QLatin1String("multiple"), d->multipleFiles); + options.insert(QLatin1String("directory"), d->directoryMode); if (d->saveFile) { if (!d->directory.isEmpty()) diff --git a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp index fb65f6d909..30c43b67dc 100644 --- a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp +++ b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp @@ -45,6 +45,12 @@ #include #include +#include +#include +#include +#include +#include + QT_BEGIN_NAMESPACE class QXdgDesktopPortalThemePrivate : public QPlatformThemePrivate @@ -60,6 +66,7 @@ public: } QPlatformTheme *baseTheme; + uint fileChooserPortalVersion = 0; }; QXdgDesktopPortalTheme::QXdgDesktopPortalTheme() @@ -90,6 +97,21 @@ QXdgDesktopPortalTheme::QXdgDesktopPortalTheme() // 3) Fall back on the built-in "null" platform theme. if (!d->baseTheme) 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"); + QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall); + QObject::connect(watcher, &QDBusPendingCallWatcher::finished, [d] (QDBusPendingCallWatcher *watcher) { + QDBusPendingReply reply = *watcher; + if (reply.isValid()) { + d->fileChooserPortalVersion = reply.value().toUInt(); + } + }); } QPlatformMenuItem* QXdgDesktopPortalTheme::createPlatformMenuItem() const @@ -131,7 +153,9 @@ QPlatformDialogHelper* QXdgDesktopPortalTheme::createPlatformDialogHelper(Dialog Q_D(const QXdgDesktopPortalTheme); if (type == FileDialog) { - if (d->baseTheme->usePlatformNativeDialog(type)) + // 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(d->baseTheme->createPlatformDialogHelper(type))); return new QXdgDesktopPortalFileDialog; -- cgit v1.2.3