fix: use xdg-desktop-portal for folder dialog in plasmoid

plasmashell is QGuiApplication so QFileDialog (QtWidgets) cannot work.
Use org.freedesktop.portal.FileChooser.OpenFile via D-Bus instead.
Also fix StandardPaths ReferenceError in main.qml.
This commit is contained in:
Levi Neely 2026-07-08 19:33:48 +02:00
parent d97d2fb1af
commit a988930dbc
4 changed files with 50 additions and 10 deletions

View File

@ -74,7 +74,6 @@ if(OLLIE_KF5)
target_link_libraries(ollie-plasmoid-plugin
Qt5::Core
Qt5::DBus
Qt5::Widgets
Qt5::Quick
Qt5::Qml
)
@ -148,7 +147,6 @@ else()
target_link_libraries(ollie-plasmoid-plugin PRIVATE
Qt6::Core
Qt6::DBus
Qt6::Widgets
Qt6::Quick
)
target_include_directories(ollie-plasmoid-plugin PRIVATE

View File

@ -17,7 +17,7 @@ PlasmoidItem {
FolderDialog {
id: folderDialog
title: "Choose working directory"
currentFolder: dbus.activeCwd ? "file://" + dbus.activeCwd : StandardPaths.writableLocation(StandardPaths.HomeLocation)
currentFolder: dbus.activeCwd ? "file://" + dbus.activeCwd : ""
onAccepted: {
let path = selectedFolder.toString().replace("file://", "")
dbus.setConfig(dbus.activeSessionId, "cwd", path)

View File

@ -5,7 +5,8 @@
#include <QDBusServiceWatcher>
#include <QDBusPendingReply>
#include <QDir>
#include <QFileDialog>
#include <QUrl>
static const char *SERVICE = "org.ollie.SessionManager";
static const char *OBJ_PATH = "/org/ollie/SessionManager";
@ -230,12 +231,52 @@ QString OllieDBusClient::createSession(const QString &cwd)
void OllieDBusClient::createSessionWithDialog()
{
QString startDir = m_activeCwd.isEmpty() ? QDir::homePath() : m_activeCwd;
QString dir = QFileDialog::getExistingDirectory(nullptr,
tr("Choose working directory for new session"), startDir,
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
if (!dir.isEmpty()) {
createSession(dir);
// Use xdg-desktop-portal FileChooser — plasmashell is QGuiApplication,
// so QFileDialog (QtWidgets) cannot be used.
QDBusMessage msg = QDBusMessage::createMethodCall(
"org.freedesktop.portal.Desktop",
"/org/freedesktop/portal/desktop",
"org.freedesktop.portal.FileChooser",
"OpenFile");
QString parentWindow; // empty — no parent window handle in plasmoid context
QString title = "Choose working directory for new session";
QVariantMap options;
options["directory"] = true;
options["modal"] = true;
msg << parentWindow << title << options;
QDBusPendingCall pending = QDBusConnection::sessionBus().asyncCall(msg);
auto *watcher = new QDBusPendingCallWatcher(pending, this);
connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *w) {
w->deleteLater();
QDBusPendingReply<QDBusObjectPath> reply = *w;
if (reply.isError()) return;
// Connect to the Response signal on the request object
QString requestPath = reply.value().path();
QDBusConnection::sessionBus().connect(
"org.freedesktop.portal.Desktop",
requestPath,
"org.freedesktop.portal.Request",
"Response",
this,
SLOT(onPortalFolderResponse(uint,QVariantMap)));
});
}
void OllieDBusClient::onPortalFolderResponse(uint response, const QVariantMap &results)
{
if (response != 0) return; // 0 = success, 1 = cancelled, 2 = other
QStringList uris = results.value("uris").toStringList();
if (uris.isEmpty()) return;
// Portal returns file:// URIs
QString path = QUrl(uris.first()).toLocalFile();
if (!path.isEmpty()) {
createSession(path);
}
}

View File

@ -63,6 +63,7 @@ private slots:
void onRefreshSessionsFinished(QDBusPendingCallWatcher *watcher);
void onFetchChatFinished(QDBusPendingCallWatcher *watcher);
void onFetchConfigFinished(QDBusPendingCallWatcher *watcher);
void onPortalFolderResponse(uint response, const QVariantMap &results);
private:
QDBusInterface *m_iface;