From e4b10f057acda00e20bfb477babaca71e9008f96 Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Sat, 13 Jun 2026 21:22:20 +0000 Subject: [PATCH] =?UTF-8?q?fix(headless/kde):=20make=20libei=20input=20wor?= =?UTF-8?q?k=20headlessly=20=E2=80=94=20portal=20+=20pre-seeded=20RemoteDe?= =?UTF-8?q?sktop=20grant?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On a headless KDE appliance, libei input injection silently failed: the EIS socket comes from the xdg RemoteDesktop portal, which never came up, and even up it would pop an unanswerable "Allow remote control?" dialog. Three fixes in run-headless-kde.sh, all idempotent + safe on the dev box: - Reach graphical-session.target: xdg-desktop-portal is ordered behind it and its start job fails without it, but a headless linger session never gets there and Fedora's target has RefuseManualStart=yes — drop that in once, then start the target. - Start the portal with `start` (the old `try-restart` is a no-op when inactive — the first-boot case), so it actually comes up. - Pre-seed the RemoteDesktop grant: vendor the `kde-authorized` permission-store GVariant DB and copy it to ~/.local/share/flatpak/db/ (never clobbering an existing one), so the portal grants RemoteDesktop without a dialog. Shipped by the RPM + .deb. Diagnosed + fixed live on the Fedora 44 KDE box: libei devices RESUME and emit (MouseMove/keys). Co-Authored-By: Claude Opus 4.8 (1M context) --- packaging/debian/build-deb.sh | 1 + packaging/rpm/punktfunk.spec | 2 ++ scripts/headless/kde-authorized | Bin 0 -> 227 bytes scripts/headless/run-headless-kde.sh | 35 +++++++++++++++++++++++---- 4 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 scripts/headless/kde-authorized diff --git a/packaging/debian/build-deb.sh b/packaging/debian/build-deb.sh index 017d7e9..7ea31f8 100755 --- a/packaging/debian/build-deb.sh +++ b/packaging/debian/build-deb.sh @@ -47,6 +47,7 @@ sed -i 's#%h/punktfunk/target/release/punktfunk-host#/usr/bin/punktfunk-host#' \ "$STAGE/usr/lib/systemd/user/punktfunk-host.service" install -Dm0755 scripts/headless/run-headless-kde.sh "$SHAREDIR/headless/run-headless-kde.sh" install -Dm0755 scripts/headless/run-headless-sway.sh "$SHAREDIR/headless/run-headless-sway.sh" +install -Dm0644 scripts/headless/kde-authorized "$SHAREDIR/headless/kde-authorized" install -Dm0644 scripts/host.env.example "$SHAREDIR/host.env.example" install -Dm0644 packaging/bazzite/host.env "$SHAREDIR/host.env.bazzite" install -Dm0644 docs/api/openapi.json "$SHAREDIR/openapi.json" diff --git a/packaging/rpm/punktfunk.spec b/packaging/rpm/punktfunk.spec index 67e6184..7d136fb 100644 --- a/packaging/rpm/punktfunk.spec +++ b/packaging/rpm/punktfunk.spec @@ -159,6 +159,8 @@ install -Dm0644 scripts/70-punktfunk-client.rules \ install -d %{buildroot}%{_datadir}/%{name}/headless install -Dm0755 scripts/headless/run-headless-kde.sh %{buildroot}%{_datadir}/%{name}/headless/run-headless-kde.sh install -Dm0755 scripts/headless/run-headless-sway.sh %{buildroot}%{_datadir}/%{name}/headless/run-headless-sway.sh +# RemoteDesktop grant pre-seed for headless libei input (run-headless-kde.sh copies it in). +install -Dm0644 scripts/headless/kde-authorized %{buildroot}%{_datadir}/%{name}/headless/kde-authorized install -Dm0644 scripts/host.env.example %{buildroot}%{_datadir}/%{name}/host.env.example install -Dm0644 packaging/bazzite/host.env %{buildroot}%{_datadir}/%{name}/host.env.bazzite install -Dm0644 packaging/kde/host.env %{buildroot}%{_datadir}/%{name}/host.env.kde diff --git a/scripts/headless/kde-authorized b/scripts/headless/kde-authorized new file mode 100644 index 0000000000000000000000000000000000000000..154d133135e8e3b2679e4c2eaaf443d99707dc6e GIT binary patch literal 227 zcmZ<{ODxJv%qwAl0tp};0by$}LB$w>bXNVWn*Trml4D`;V2A58B}}? zkiG!Kxrv#1KuQCo7X%{SRUHKBZve9S7|IwX0BMk(qSV~{l2qN4)Z*-t`~si=LnT9H zYB2)~BReyLMpF-Q(!9;+w=1IRp(T?|0;K=flEMl+9}A+Z<$j>/dev/null || true dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP DBUS_SESSION_BUS_ADDRESS ${DISPLAY:+DISPLAY} 2>/dev/null || true -# --no-block: queue the restart and return immediately. A synchronous try-restart of the -# portal chain blocks bring-up ~30s (xdg-desktop-portal is Type=dbus and waits for its bus -# name); the portal only needs to be ready before the FIRST client streams (seconds later, -# user-driven), not before plasmashell starts. -systemctl --user --no-block try-restart plasma-xdg-desktop-portal-kde.service xdg-desktop-portal-kde.service xdg-desktop-portal.service 2>/dev/null || true + +# Pre-seed the RemoteDesktop grant for headless input injection (libei). KWin's xdg portal would +# otherwise pop an "Allow remote control?" dialog on every session Start() — which a headless host +# can't answer, so EIS setup times out and input silently fails. The `kde-authorized` permission- +# store table (this tiny GVariant DB, shipped next to this script) pre-authorizes it. Copy it in if +# the user has none yet; never clobber an existing one. +DB="$HOME/.local/share/flatpak/db/kde-authorized" +SELF_DIR="$(cd "$(dirname "$0")" && pwd)" +if [[ ! -s "$DB" && -s "$SELF_DIR/kde-authorized" ]]; then + mkdir -p "$(dirname "$DB")" && cp "$SELF_DIR/kde-authorized" "$DB" + echo "seeded RemoteDesktop grant: $DB" +fi + +# Reach graphical-session.target so xdg-desktop-portal (which is ordered After / fails its start +# job without it) can come up — a headless linger session never gets there on its own, and Fedora's +# target carries RefuseManualStart=yes, so drop that in once. Without the portal, libei input fails. +GST_DROPIN="$HOME/.config/systemd/user/graphical-session.target.d" +if [[ ! -f "$GST_DROPIN/10-punktfunk-headless.conf" ]]; then + mkdir -p "$GST_DROPIN" + printf '[Unit]\nRefuseManualStart=no\n' > "$GST_DROPIN/10-punktfunk-headless.conf" + systemctl --user daemon-reload 2>/dev/null || true +fi +systemctl --user start graphical-session.target 2>/dev/null || true + +# Bring the portal up against the env imported above. `start` (not the old `try-restart`, a no-op +# when inactive — the headless first-boot case) so it actually comes up; `--no-block` since +# xdg-desktop-portal is Type=dbus and blocks ~30s waiting for its bus name, and it only needs to be +# ready before the FIRST client streams (seconds later), not before plasmashell. +systemctl --user --no-block restart plasma-xdg-desktop-portal-kde.service 2>/dev/null || true +systemctl --user --no-block start xdg-desktop-portal.service 2>/dev/null || true # Polkit authentication agent: without it, Discover / PackageKit can't get authorization to # install packages (polkitd is the policy engine; the *agent* is the GUI prompt). A full Plasma