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 <thiago.macieira@intel.com>
This commit is contained in:
parent
1736746228
commit
844967d297
@ -107,6 +107,7 @@ public:
|
|||||||
{ }
|
{ }
|
||||||
|
|
||||||
WId winId = 0;
|
WId winId = 0;
|
||||||
|
bool directoryMode = false;
|
||||||
bool modal = false;
|
bool modal = false;
|
||||||
bool multipleFiles = false;
|
bool multipleFiles = false;
|
||||||
bool saveFile = false;
|
bool saveFile = false;
|
||||||
@ -145,6 +146,9 @@ void QXdgDesktopPortalFileDialog::initializeDialog()
|
|||||||
if (options()->fileMode() == QFileDialogOptions::ExistingFiles)
|
if (options()->fileMode() == QFileDialogOptions::ExistingFiles)
|
||||||
d->multipleFiles = true;
|
d->multipleFiles = true;
|
||||||
|
|
||||||
|
if (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly)
|
||||||
|
d->directoryMode = true;
|
||||||
|
|
||||||
if (options()->isLabelExplicitlySet(QFileDialogOptions::Accept))
|
if (options()->isLabelExplicitlySet(QFileDialogOptions::Accept))
|
||||||
d->acceptLabel = options()->labelText(QFileDialogOptions::Accept);
|
d->acceptLabel = options()->labelText(QFileDialogOptions::Accept);
|
||||||
|
|
||||||
@ -179,6 +183,7 @@ void QXdgDesktopPortalFileDialog::openPortal()
|
|||||||
|
|
||||||
options.insert(QLatin1String("modal"), d->modal);
|
options.insert(QLatin1String("modal"), d->modal);
|
||||||
options.insert(QLatin1String("multiple"), d->multipleFiles);
|
options.insert(QLatin1String("multiple"), d->multipleFiles);
|
||||||
|
options.insert(QLatin1String("directory"), d->directoryMode);
|
||||||
|
|
||||||
if (d->saveFile) {
|
if (d->saveFile) {
|
||||||
if (!d->directory.isEmpty())
|
if (!d->directory.isEmpty())
|
||||||
|
@ -45,6 +45,12 @@
|
|||||||
#include <qpa/qplatformthemefactory_p.h>
|
#include <qpa/qplatformthemefactory_p.h>
|
||||||
#include <qpa/qplatformintegration.h>
|
#include <qpa/qplatformintegration.h>
|
||||||
|
|
||||||
|
#include <QDBusConnection>
|
||||||
|
#include <QDBusMessage>
|
||||||
|
#include <QDBusPendingCall>
|
||||||
|
#include <QDBusPendingCallWatcher>
|
||||||
|
#include <QDBusPendingReply>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class QXdgDesktopPortalThemePrivate : public QPlatformThemePrivate
|
class QXdgDesktopPortalThemePrivate : public QPlatformThemePrivate
|
||||||
@ -60,6 +66,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
QPlatformTheme *baseTheme;
|
QPlatformTheme *baseTheme;
|
||||||
|
uint fileChooserPortalVersion = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
QXdgDesktopPortalTheme::QXdgDesktopPortalTheme()
|
QXdgDesktopPortalTheme::QXdgDesktopPortalTheme()
|
||||||
@ -90,6 +97,21 @@ QXdgDesktopPortalTheme::QXdgDesktopPortalTheme()
|
|||||||
// 3) Fall back on the built-in "null" platform theme.
|
// 3) Fall back on the built-in "null" platform theme.
|
||||||
if (!d->baseTheme)
|
if (!d->baseTheme)
|
||||||
d->baseTheme = new QPlatformTheme;
|
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<QVariant> reply = *watcher;
|
||||||
|
if (reply.isValid()) {
|
||||||
|
d->fileChooserPortalVersion = reply.value().toUInt();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
QPlatformMenuItem* QXdgDesktopPortalTheme::createPlatformMenuItem() const
|
QPlatformMenuItem* QXdgDesktopPortalTheme::createPlatformMenuItem() const
|
||||||
@ -131,7 +153,9 @@ QPlatformDialogHelper* QXdgDesktopPortalTheme::createPlatformDialogHelper(Dialog
|
|||||||
Q_D(const QXdgDesktopPortalTheme);
|
Q_D(const QXdgDesktopPortalTheme);
|
||||||
|
|
||||||
if (type == FileDialog) {
|
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<QPlatformFileDialogHelper*>(d->baseTheme->createPlatformDialogHelper(type)));
|
return new QXdgDesktopPortalFileDialog(static_cast<QPlatformFileDialogHelper*>(d->baseTheme->createPlatformDialogHelper(type)));
|
||||||
|
|
||||||
return new QXdgDesktopPortalFileDialog;
|
return new QXdgDesktopPortalFileDialog;
|
||||||
|
Loading…
Reference in New Issue
Block a user