This commit updates the lessons learned document to include details about the D-Bus connection issues encountered when running the wayland_poc executable on the host. It covers the fixes for method name mismatches (PickSource to SelectSources), argument type mismatches (string to QDBusObjectPath), and QDBusMessage API versioning. This provides a more complete record of the debugging process for the xdg-desktop-portal interaction.
70 lines
8.7 KiB
Markdown
70 lines
8.7 KiB
Markdown
# Lessons Learned from Hyperion Grabber Wayland Adaptation
|
||
|
||
This document summarizes the key challenges, debugging steps, and solutions encountered during the process of adapting the Hyperion Grabber for Wayland, specifically focusing on the `wayland_poc` executable.
|
||
|
||
## 1. Initial Problem & Diagnosis
|
||
|
||
* **Problem:** The user's existing `Hyperion_Grabber_X11_QT` application was not logging "picture recorded and sent" messages when run on a Wayland session, indicating a failure in screen capture and transmission.
|
||
* **Initial Analysis:** The grabber is designed for X11, relying on `XDamage` and other X11-specific features. Wayland's security model prevents direct screen access, requiring applications to use `xdg-desktop-portal` and PipeWire for screen sharing with user consent.
|
||
* **Conclusion:** The X11 grabber would not work natively on Wayland. A Wayland-compatible screen grabbing solution was needed.
|
||
|
||
## 2. Wayland Grabber Adaptation Strategy
|
||
|
||
* **Approach:** Replace the X11 screen grabbing logic with a Wayland-compatible one, primarily using PipeWire for video streaming and `xdg-desktop-portal` for user consent.
|
||
* **Proof of Concept (POC):** Developed `wayland_poc.cpp` to test the `xdg-desktop-portal` interaction and PipeWire stream connection. Also used `tutorial5.c` from PipeWire documentation to verify core PipeWire API usage.
|
||
|
||
## 3. Build Environment Challenges & Docker Adoption
|
||
|
||
* **Initial Host Compilation Issues:** Attempting to compile `wayland_poc.cpp` directly on the user's Arch Linux host resulted in a persistent `fatal error: pipewire/extensions/session-manager/session-manager.h: No such file or directory`.
|
||
* **Troubleshooting:** Confirmed file existence and permissions, verified `pkg-config` output, modified `CMakeLists.txt` for include paths and C++ standards, tried different compilers (GCC). None resolved the issue.
|
||
* **Conclusion:** The error was highly unusual and suggested a deep, system-specific problem with how PipeWire headers were exposed or how the compiler resolved includes on the host.
|
||
* **Adoption of Docker:** Decided to use Docker to create a reproducible and controlled build environment, aiming to bypass host-specific compilation issues.
|
||
|
||
## 4. Docker Build Troubleshooting (Arch Linux Base)
|
||
|
||
* **Dockerfile (Arch):** Initial Dockerfile used `archlinux:latest` as base.
|
||
* **Error 1: `sudo: command not found`:** Occurred because `pacman` commands were run as `builder` user without `sudo` installed or configured.
|
||
* **Fix:** Moved `pacman` commands to run as `root` before switching to `builder` user.
|
||
* **Error 2: `mkdir: cannot create directory ‘build’: File exists` (Permission Denied):** Occurred because `build` directory was copied from host with `root` ownership, and `builder` user lacked permissions to modify it.
|
||
* **Fix:** Added `chown -R builder:builder` after `COPY` to transfer ownership to `builder` user.
|
||
* **Error 3: `CMakeCache.txt` mismatch:** Occurred because `CMakeCache.txt` from host's project root was copied into container, confusing CMake.
|
||
* **Fix:** Added `CMakeCache.txt` and `CMakeFiles/` to `.dockerignore` to prevent them from being copied.
|
||
* **Error 4: `X11/extensions/Xdamage.h: No such file or directory` (and `scrnsaver.h`, `Xrender.h`):** Occurred because necessary X11 development headers were missing in the Docker image.
|
||
* **Fix:** Added `libx11`, `libxext`, `libxdamage`, `libxss`, `libxrender` to `pacman` install list.
|
||
* **Persistent `session-manager.h` error:** Despite all fixes, the `fatal error: pipewire/extensions/session-manager/session-manager.h: No such file or directory` persisted even in the Arch Docker environment. This indicated the problem was not specific to the host Arch setup, but a deeper issue with PipeWire headers or their interaction with the compiler.
|
||
|
||
## 5. Docker Build Troubleshooting (Ubuntu Base & Clang)
|
||
|
||
* **Switch to Ubuntu:** Decided to switch the Docker base image to `ubuntu:latest` to rule out Arch-specific packaging issues. Also switched to `clang` as the compiler.
|
||
* **Error: `fatal error: 'pipewire/extensions/session-manager/impl-session-manager.h' file not found`:** The `session-manager.h` issue persisted, even with Ubuntu and Clang. This confirmed the problem was not distribution-specific.
|
||
* **Attempt to bypass umbrella header:** Modified `wayland_poc.cpp` to include individual headers (`introspect.h`, `interfaces.h`, etc.) instead of `session-manager.h`. This also failed with similar "file not found" errors for the individual headers.
|
||
* **Conclusion:** The `session-manager.h` (and related `impl-session-manager.h`) compilation issue is extremely persistent and baffling, suggesting a very subtle, low-level problem that cannot be resolved by standard means or remote debugging.
|
||
|
||
## 6. Refocusing on `xdg-desktop-portal` with `QDBus`
|
||
|
||
* **Realization:** The `tutorial5.c` (core PipeWire API) compiled successfully. The `session-manager.h` problem was specific to the `xdg-desktop-portal` interaction using PipeWire's session manager headers.
|
||
* **New Strategy:** Isolate the `xdg-desktop-portal` interaction using Qt's `QDBus` module, completely bypassing direct PipeWire session manager header includes.
|
||
* **`wayland_poc.cpp` Refactoring:** Simplified `wayland_poc.cpp` to *only* handle the `QDBus` interaction to get the `pipewire_node_id`. Removed all PipeWire stream creation/processing logic.
|
||
* **QDBus API Challenges:**
|
||
* **`QDBusMessage::createMethodCall` vs `createMethod`:** Discovered `createMethodCall` is the correct static method for creating method call messages in Qt 5.15.
|
||
* **`QDBusMessage` constructor:** Found that the direct constructor `QDBusMessage("service", "path", "interface", "method");` is the correct way to initialize `QDBusMessage` for method calls in the specific Qt5 version in Ubuntu.
|
||
* **`QDBusPendingCall` conversion:** Ensured `sessionBus.asyncCall(message)` is used, which returns `QDBusPendingCall`.
|
||
* **Successful Compilation:** The simplified `wayland_poc.cpp` (QDBus-only) compiled successfully in the Ubuntu Docker container with Clang. This is a major breakthrough, confirming that the `QDBus` approach for `xdg-desktop-portal` interaction is viable.
|
||
|
||
## 7. Runtime Challenges (D-Bus Connection)
|
||
|
||
* **Problem:** Running the compiled `wayland_poc` executable (from Docker) on the host failed with `Failed to connect to D-Bus session bus.`
|
||
* **Reason:** Docker containers are isolated and do not have direct access to the host's D-Bus session bus by default. Environment variables (`DBUS_SESSION_BUS_ADDRESS`, `XDG_RUNTIME_DIR`, `DISPLAY`, `WAYLAND_DISPLAY`) and volume mounts (`/tmp/.X11-unix`, `$XDG_RUNTIME_DIR`) are needed.
|
||
* **Further Problem:** Even with correct `docker run` parameters, the `wayland_poc` on the host failed with `D-Bus call to xdg-desktop-portal failed: "Invalid session"`.
|
||
* **Diagnosis:** This error indicates `xdg-desktop-portal` is not recognizing the session context. It's often related to `XDG_SESSION_ID`, `XDG_SESSION_TYPE`, or `XDG_CURRENT_DESKTOP` not being correctly propagated or interpreted.
|
||
* **Method Name Mismatch:** The `wayland_poc` was initially calling `PickSource` on `org.freedesktop.portal.ScreenCast`, but the correct method name is `SelectSources`.
|
||
* **Fix:** Changed method call from `PickSource` to `SelectSources` in `wayland_poc.cpp`.
|
||
* **Argument Type Mismatch:** The `SelectSources` method expects an object path (`o`) for the `parent_window` argument, but `wayland_poc` was sending an empty string (`s`).
|
||
* **Fix:** Changed the first argument to `QDBusObjectPath("/")` in `wayland_poc.cpp`.
|
||
* **Current Status:** The `wayland_poc` executable now compiles successfully. The D-Bus connection issue (`Failed to connect to D-Bus session bus.` or `Invalid session`) is still occurring when run on the host, indicating a persistent runtime environment issue with D-Bus access from the application.
|
||
|
||
## 8. Next Steps
|
||
|
||
* **Verify `wayland_poc` execution on host:** The user needs to run the `wayland_poc` executable on their host with the provided `docker run` command (or directly if copied out) and confirm if the `xdg-desktop-portal` dialog appears and a PipeWire node ID is printed. The current D-Bus connection failure needs to be resolved.
|
||
* **Integrate:** If successful, the next phase will involve integrating the `QDBus` based `xdg-desktop-portal` interaction with the core PipeWire stream capture logic (from `tutorial5.c`) into the main Hyperion grabber.
|
||
* **Persistent `session-manager.h`:** The original `session-manager.h` compilation issue remains unresolved for direct PipeWire session manager API usage. The `QDBus` approach is a workaround. If direct PipeWire session manager API interaction is ever needed, this issue would need further, likely local, investigation. |