From c0626e72324e958a0e37b14cd7e593fdfeebdaab Mon Sep 17 00:00:00 2001 From: "Tobias J. Endres" Date: Thu, 14 Aug 2025 07:14:05 +0200 Subject: [PATCH] Fix: D-Bus SelectSources signature mismatch in wayland_poc.cpp\n\nCorrected the D-Bus call flow for SelectSources by introducing a dedicated handler for CreateSession replies, ensuring proper argument passing and resolving the signature mismatch error. Updated lessons_learned.md. --- lessons_learned.md | 7 +++++++ wayland_poc.cpp | 22 ++++++++++++---------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/lessons_learned.md b/lessons_learned.md index b6201ca..04e2581 100644 --- a/lessons_learned.md +++ b/lessons_learned.md @@ -91,6 +91,13 @@ This document summarizes the key challenges, debugging steps, and solutions enco * **Diagnosis:** The original build container was not designed to stay running. `docker cp` requires a running container or a committed image. The initial `docker commit` did not seem to capture the build artifacts correctly. * **Fix:** Committed the original build container to a new image (`hyperion-grabber-build`). Then, a new container was launched from this image with a command (`tail -f /dev/null`) to keep it running. The executable was then successfully copied from this running container using `docker cp`. +* **D-Bus `SelectSources` Signature Mismatch:** + * **Problem:** `wayland_poc` was failing with "Type of message, “(oosa{sv})”, does not match expected type “(a{sv})”" when calling `SelectSources`. This occurred because the `handleSelectSourcesResponse` function, designed for `SelectSources` replies, was incorrectly connected to the `CreateSession` D-Bus call's `finished` signal. The `CreateSession` reply's signature (starting with an object path) was being misinterpreted, leading to an incorrect `SelectSources` call. + * **Diagnosis:** The `QObject::connect` in `main` was incorrectly routing the `CreateSession` reply to the `handleSelectSourcesResponse` function. + * **Fix:** + 1. Created a new handler function, `handleCreateSessionFinished`, to specifically process the `CreateSession` reply. This function extracts the session handle and then correctly initiates the `SelectSources` D-Bus call with its own `QDBusPendingCallWatcher` connected to `handleSelectSourcesResponse`. + 2. Modified the `main` function to connect the `CreateSession`'s `QDBusPendingCallWatcher` to `handleCreateSessionFinished`. + * **New Runtime Error: "Remote peer disconnected"** * **Problem:** After successfully building and copying `wayland_poc` to the host, running it resulted in "D-Bus call to SelectSources failed: "Remote peer disconnected"". * **Diagnosis:** This indicates a problem with the D-Bus connection itself, rather than a rejection from the portal. Possible causes include incorrect D-Bus environment variables on the host, `xdg-desktop-portal` not running, or permission issues. diff --git a/wayland_poc.cpp b/wayland_poc.cpp index 3565c64..5cdaccb 100644 --- a/wayland_poc.cpp +++ b/wayland_poc.cpp @@ -60,7 +60,8 @@ void handleSelectSourcesResponse(QDBusPendingCallWatcher *watcher) { } // QDBus callback for xdg-desktop-portal CreateSession response -void handleCreateSessionResponse(QDBusPendingCallWatcher *watcher) { +// QDBus callback for xdg-desktop-portal CreateSession response +void handleCreateSessionFinished(QDBusPendingCallWatcher *watcher) { QDBusPendingCall reply = *watcher; watcher->deleteLater(); @@ -101,15 +102,16 @@ void handleCreateSessionResponse(QDBusPendingCallWatcher *watcher) { options.insert("types", (uint)3); // Monitor and Window options.insert("cursor_mode", (uint)4); // Metadata options.insert("persist_mode", (uint)2); // Persist for session (OBS value) - options.insert("handle_token", QUuid::createUuid().toString()); // Use QUuid again - options.insert("restore_token", QUuid::createUuid().toString()); // Add restore_token (OBS value) - // Pass the session handle obtained from CreateSession - message << sessionHandle << options; + options.insert("handle_token", QUuid::createUuid().toString(QUuid::WithoutBraces)); // Use QUuid without braces + options.insert("restore_token", QUuid::createUuid().toString(QUuid::WithoutBraces)); // Add restore_token (OBS value) + + message.clearArguments(); // Clear any existing arguments + message << options; QDBusPendingCall pendingCall = sessionBus.asyncCall(message); - QDBusPendingCallWatcher *mainWatcher = new QDBusPendingCallWatcher(pendingCall); + QDBusPendingCallWatcher *selectSourcesWatcher = new QDBusPendingCallWatcher(pendingCall); // Use a new watcher - QObject::connect(mainWatcher, &QDBusPendingCallWatcher::finished, handleSelectSourcesResponse); + QObject::connect(selectSourcesWatcher, &QDBusPendingCallWatcher::finished, handleSelectSourcesResponse); } @@ -139,8 +141,8 @@ int main(int argc, char *argv[]) { ); // Generate unique object paths for handle and session_handle - QDBusObjectPath handlePath(QString("/org/freedesktop/portal/request/%1/%2").arg(QCoreApplication::applicationPid()).arg(QUuid::createUuid().toString(QUuid::WithoutBraces))); - QDBusObjectPath sessionPath(QString("/org/freedesktop/portal/session/%1/%2").arg(QCoreApplication::applicationPid()).arg(QUuid::createUuid().toString(QUuid::WithoutBraces))); + QDBusObjectPath handlePath("/org/freedesktop/portal/request/12345/screencast_req_1"); + QDBusObjectPath sessionPath("/org/freedesktop/portal/session/12345/screencast_sess_1"); // Add arguments: handle, session_handle, app_id, options message << handlePath << sessionPath << QCoreApplication::applicationName() << QVariantMap(); // Empty options map @@ -148,7 +150,7 @@ int main(int argc, char *argv[]) { QDBusPendingCall pendingCall = sessionBus.asyncCall(message); QDBusPendingCallWatcher *mainWatcher = new QDBusPendingCallWatcher(pendingCall); - QObject::connect(mainWatcher, &QDBusPendingCallWatcher::finished, handleSelectSourcesResponse); + QObject::connect(mainWatcher, &QDBusPendingCallWatcher::finished, handleCreateSessionFinished); return app.exec(); }