KDEAmbi/lessons_learned.md
Tobias J. Endres e760af9f43 docs: Document lessons learned during Wayland grabber adaptation
This commit adds a comprehensive document summarizing the challenges,
debugging steps, and solutions encountered while attempting to adapt
the Hyperion Grabber for Wayland. It covers issues related to build
environments, PipeWire header compilation, and xdg-desktop-portal
interaction.

This document serves as a reference for future development and
troubleshooting efforts.
2025-08-14 04:28:05 +02:00

7.6 KiB
Raw Blame History

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::callMethod vs createMethodCall: 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", ...) 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) and volume mounts (/tmp/.X11-unix, $XDG_RUNTIME_DIR) are needed.
  • Current Status: The docker run command with D-Bus access parameters is provided to the user for execution on their host. The problem is now with the user executing the command correctly and the D-Bus connection working on their host.

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.
  • 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.