Skip to content

Linux/Wayland: respond to KWin compositor pings to prevent window des…#634

Merged
scottdraves merged 1 commit into
e-dream-ai:masterfrom
amillionbouncyballs:628-kwin-colour-representation
May 21, 2026
Merged

Linux/Wayland: respond to KWin compositor pings to prevent window des…#634
scottdraves merged 1 commit into
e-dream-ai:masterfrom
amillionbouncyballs:628-kwin-colour-representation

Conversation

@amillionbouncyballs

Copy link
Copy Markdown
Collaborator

…aturation

On KDE/KWin Wayland sessions the app window would lose colour saturation after a few seconds of playback. KWin periodically sends an xdg_wm_base ping event and desaturates any window that does not pong back promptly.

The pong handler (onXdgWmBasePing → xdg_wm_base_pong) was already wired up correctly, but it never fired because the per-frame pump in checkEvents() only called wl_display_dispatch_pending(), which drains events already in the in-memory queue without reading from the Wayland socket. KWin's ping bytes sat unread on the fd, no pong was sent, and KWin concluded the app was frozen.

Fix: replace the bare wl_display_dispatch_pending() call with the documented prepare_read / poll / read_events (or cancel_read) / dispatch_pending idiom. A non-blocking poll(timeout=0) on the Wayland socket fd is performed each frame; if data is available the socket is drained into the event queue before dispatching. This ensures pings are seen and pongs are sent every frame without ever blocking the render loop.

Also move #include <poll.h> out of the inner HAVE_LIBDECOR guard into the enclosing HAVE_WAYLAND block, since it is now needed for all Wayland builds regardless of libdecor.

Mac and Windows builds are unaffected (all changes are inside #ifdef HAVE_WAYLAND).

Fixes #628.

…aturation

On KDE/KWin Wayland sessions the app window would lose colour saturation
after a few seconds of playback. KWin periodically sends an xdg_wm_base
ping event and desaturates any window that does not pong back promptly.

The pong handler (onXdgWmBasePing → xdg_wm_base_pong) was already wired
up correctly, but it never fired because the per-frame pump in
checkEvents() only called wl_display_dispatch_pending(), which drains
events already in the in-memory queue without reading from the Wayland
socket. KWin's ping bytes sat unread on the fd, no pong was sent, and
KWin concluded the app was frozen.

Fix: replace the bare wl_display_dispatch_pending() call with the
documented prepare_read / poll / read_events (or cancel_read) /
dispatch_pending idiom. A non-blocking poll(timeout=0) on the Wayland
socket fd is performed each frame; if data is available the socket is
drained into the event queue before dispatching. This ensures pings are
seen and pongs are sent every frame without ever blocking the render loop.

Also move #include <poll.h> out of the inner HAVE_LIBDECOR guard into the
enclosing HAVE_WAYLAND block, since it is now needed for all Wayland
builds regardless of libdecor.

Mac and Windows builds are unaffected (all changes are inside
#ifdef HAVE_WAYLAND).

Fixes e-dream-ai#628.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@MacrosV

MacrosV commented May 27, 2026

Copy link
Copy Markdown

Just a quick note, after testing this dockerfile on a fresh Fedora KDE install I found that I had to add python3 and python-is-python3 to the container for the build process to complete. The appimage produced by the following dockerfile works well and no longer reported that it was unresponsive.

FROM ubuntu:24.04

ENV DEBIAN_FRONTEND=noninteractive

# Install CMake 4.x from Kitware (Ubuntu 24.04 ships 3.28 which
# doesn't know CMP0167 used in the project's CMakeLists.txt)
RUN apt-get update && apt-get install -y ca-certificates gpg wget && \
    wget -qO- https://apt.kitware.com/keys/kitware-archive-latest.asc \
      | gpg --dearmor - > /usr/share/keyrings/kitware-archive-keyring.gpg && \
    echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ noble main' \
      > /etc/apt/sources.list.d/kitware.list && \
    apt-get update && apt-get install -y cmake \
    && rm -rf /var/lib/apt/lists/*

RUN apt-get update && apt-get install -y \
        git git-lfs make gcc g++ \
        curl wget perl nasm yasm pkg-config xz-utils ca-certificates \
        zip unzip tar \
        autoconf automake libtool file \
        python3 python-is-python3 \
        libvulkan-dev vulkan-tools glslang-tools glslc \
        libx11-dev libxrandr-dev libxrender-dev libxi-dev \
        libxext-dev libxkbcommon-dev \
        libwayland-dev wayland-protocols libdecor-0-dev \
        libcurl4-openssl-dev libssl-dev zlib1g-dev libpng-dev \
        libboost-all-dev \
        fuse libfuse2 \
    && rm -rf /var/lib/apt/lists/*

RUN curl -fsSL https://ziglang.org/download/0.13.0/zig-linux-x86_64-0.13.0.tar.xz \
      | tar -xJ -C /opt/ \
    && ln -s /opt/zig-linux-x86_64-0.13.0/zig /usr/local/bin/zig

WORKDIR /build

# Now cloning from the official upstream repo on master
RUN git lfs install && \
    git clone https://github.com/e-dream-ai/client.git client && \
    cd client && \
    git submodule update --init --recursive

# Fix: add OpenSSL link dependency after libsioclient_tls.a
RUN printf '%s\n' \
    'import sys' \
    'path = "/build/client/client_generic/LinuxBuild/CMakeLists.txt"' \
    'with open(path, "r") as f:' \
    '    content = f.read()' \
    'old = "socket.io-client-cpp/lib/linux/libsioclient_tls.a"' \
    'if old not in content:' \
    '    print("ERROR: Pattern not found")' \
    '    sys.exit(1)' \
    'new = old + "\n  OpenSSL::SSL\n  OpenSSL::Crypto"' \
    'content = content.replace(old, new, 1)' \
    'with open(path, "w") as f:' \
    '    f.write(content)' \
    'print("Patch applied successfully")' \
    > /tmp/patch_cmake.py && python3 /tmp/patch_cmake.py

WORKDIR /build/client
RUN ./vcpkg/bootstrap-vcpkg.sh -disableMetrics && \
    ./vcpkg/vcpkg install

WORKDIR /build/client/client_generic/LinuxBuild
RUN bash ./build_appimage.sh

RUN mkdir -p /output && \
    cp /build/client/client_generic/LinuxBuild/*.AppImage /output/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Linux Client incorrect color representation on Wayland

3 participants