fix kf5 plasmoid install and portal dialog race

- Makefile: directly install plasmoid to /usr/share instead of using
  kpackagetool5 (which doesn't overwrite existing files, causing the
  KF6 main.qml to persist over the KF5 version)
- olliedbusclient: fix portal FileChooser race condition by connecting
  to Response signal before making the OpenFile call using a
  predictable handle_token
This commit is contained in:
Levi Neely 2026-07-10 12:04:12 +02:00
parent 45419393ae
commit d1d113b5fd
2 changed files with 41 additions and 19 deletions

View File

@ -142,13 +142,11 @@ kf5-install:
/usr/lib/x86_64-linux-gnu/qt5/qml/org/ollie/private/
install -m644 plasmoid/plugin/qmldir \
/usr/lib/x86_64-linux-gnu/qt5/qml/org/ollie/private/
# Plasmoid package
cp -a plasmoid /tmp/ollie-plasmoid-kf5
cp plasmoid/metadata-kf5.json /tmp/ollie-plasmoid-kf5/metadata.json
cp plasmoid/contents/ui/main-kf5.qml /tmp/ollie-plasmoid-kf5/contents/ui/main.qml
kpackagetool5 -t Plasma/Applet -u /tmp/ollie-plasmoid-kf5/ 2>/dev/null || \
kpackagetool5 -t Plasma/Applet -i /tmp/ollie-plasmoid-kf5/
$(RM) -r /tmp/ollie-plasmoid-kf5
# Plasmoid package (direct install — kpackagetool5 -u doesn't overwrite)
mkdir -p /usr/share/plasma/plasmoids/org.ollie.plasmoid/contents/ui
cp plasmoid/metadata-kf5.json /usr/share/plasma/plasmoids/org.ollie.plasmoid/metadata.json
cp plasmoid/contents/ui/main-kf5.qml /usr/share/plasma/plasmoids/org.ollie.plasmoid/contents/ui/main.qml
rm -f /usr/share/plasma/plasmoids/org.ollie.plasmoid/contents/ui/main-kf5.qml
# Dolphin service menus + helper scripts
mkdir -p ~/.local/share/kio/servicemenus
rm -f ~/.local/share/kio/servicemenus/ollie-actions.desktop

View File

@ -233,6 +233,30 @@ void OllieDBusClient::createSessionWithDialog()
{
// Use xdg-desktop-portal FileChooser — plasmashell is QGuiApplication,
// so QFileDialog (QtWidgets) cannot be used.
//
// We use handle_token to make the request object path predictable, then
// connect to the Response signal BEFORE making the call. This avoids a
// race where the portal fires Response before we subscribe to the signal.
static int handleSeq = 0;
QString handleToken = QString("ollie_folder_%1").arg(++handleSeq);
// Predict the request object path: /org/freedesktop/portal/desktop/request/<sender>/<handle_token>
QString sender = QDBusConnection::sessionBus().baseService();
sender.replace('.', '_');
if (sender.startsWith(':'))
sender = sender.mid(1);
QString requestPath = QString("/org/freedesktop/portal/desktop/request/%1/%2")
.arg(sender, handleToken);
// Connect to Response BEFORE making the call to avoid race
QDBusConnection::sessionBus().connect(
"org.freedesktop.portal.Desktop",
requestPath,
"org.freedesktop.portal.Request",
"Response",
this,
SLOT(onPortalFolderResponse(uint,QVariantMap)));
QDBusMessage msg = QDBusMessage::createMethodCall(
"org.freedesktop.portal.Desktop",
"/org/freedesktop/portal/desktop",
@ -244,25 +268,25 @@ void OllieDBusClient::createSessionWithDialog()
QVariantMap options;
options["directory"] = true;
options["modal"] = true;
options["handle_token"] = handleToken;
msg << parentWindow << title << options;
QDBusPendingCall pending = QDBusConnection::sessionBus().asyncCall(msg);
auto *watcher = new QDBusPendingCallWatcher(pending, this);
connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *w) {
connect(watcher, &QDBusPendingCallWatcher::finished, this, [this, requestPath](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)));
if (reply.isError()) {
// Clean up the signal connection on failure
QDBusConnection::sessionBus().disconnect(
"org.freedesktop.portal.Desktop",
requestPath,
"org.freedesktop.portal.Request",
"Response",
this,
SLOT(onPortalFolderResponse(uint,QVariantMap)));
}
});
}