https://bugs.kde.org/show_bug.cgi?id=523515

            Bug ID: 523515
           Summary: InputCapture session not torn down when the portal
                    frontend crashes -> all keyboard/pointer input stays
                    diverted (desktop input freeze)
    Classification: Plasma
           Product: xdg-desktop-portal-kde
      Version First 6.6.4
       Reported In:
          Platform: Other
                OS: Linux
            Status: REPORTED
          Severity: major
          Priority: NOR
         Component: general
          Assignee: [email protected]
          Reporter: [email protected]
                CC: [email protected]
  Target Milestone: ---

If the xdg-desktop-portal *frontend* process dies while an InputCapture session
is active (an app such as Deskflow / Input Leap holding a screen-edge barrier),
the input-capture session is never torn down. KWin keeps diverting ALL pointer
and keyboard input into the now-ownerless EIS channel: the desktop keeps
rendering and the cursor still moves, but nothing accepts input -- no clicks,
no
keyboard, no Alt+Tab, no taskbar. Recovery requires an out-of-band action (SSH,
or the built-in Meta+Shift+Escape disable shortcut if it still reaches KWin).

This is a fail-safe problem, not merely a crash follow-on: when the owner of an
InputCapture session goes away, the compositor must release capture rather than
divert all input into a dead session. It is a denial-of-input hazard.

STEPS TO REPRODUCE
1. Have an InputCapture consumer running with a screen-edge barrier (e.g.
   Deskflow linking this machine to another; the pointer crossing the shared
   edge engages capture).
2. Kill the portal frontend:
      systemctl --user kill -s ABRT xdg-desktop-portal.service
   (In the wild this happened via an unrelated portal crash during a PipeWire
   audio-stack restart.)
3. Move the pointer across the barrier to engage capture.

OBSERVED
All input is diverted; the desktop accepts no keyboard/pointer input while
continuing to render. Journal shows "Invalid session type for signal" and a
flood of "Error disabling capture on zone change".

EXPECTED
When the session's owner (the portal frontend / the app) is gone, the capture
is
released and local input is restored.

ROOT CAUSE (source analysis of current master: xdg-desktop-portal-kde 449b1ae,
kwin 9ec0d6f)
The teardown chain that would release capture is only driven by an explicit
session Close(), which a crashed frontend can never send:

* xdg-desktop-portal-kde -- src/session.cpp: Session::close() (line 56) emits
  closed() and is only reached via the D-Bus method Session::Close() (line 77).
  The class registers NO QDBusServiceWatcher and does not react to its owning
  peer disconnecting.
* The KWin-side teardown is wired to that signal -- src/inputcapture.cpp:90-94:
  connect(session, &Session::closed, ... removeInputCapture ...). Without
  closed(), removeInputCapture is never sent to KWin.
* KWin -- src/plugins/eis/eisinputcapturemanager.cpp: it does have a fail-safe
  (QDBusServiceWatcher, lines 125-135) but it watches its immediate caller, the
  xdg-desktop-portal-kde backend (message().service(), line 193), which stays
  alive when the frontend dies. The input filter installed at barrierHit()
  (line 210) therefore stays installed.

So a frontend crash leaves the backend Session alive (no caller watcher), KWin
is
never told to remove the capture, and input stays diverted.

The same codebase already uses the missing pattern elsewhere:
src/appchooser.cpp:124-125 creates a
QDBusServiceWatcher(WatchForUnregistration)
on its caller and cleans up on serviceUnregistered.

SUGGESTED FIX DIRECTION (not a patch)
* Primary (xdg-desktop-portal-kde): tie the Session -- at least InputCapture
  sessions -- to the lifetime of the D-Bus peer that owns it (the frontend,
i.e.
  the sender of CreateSession/Start). Watch it with QDBusServiceWatcher and
call
  close() on unregistration, mirroring appchooser.cpp. This drives the existing
  correct teardown: closed() -> removeInputCapture -> KWin deactivate().
* Secondary (KWin, defense-in-depth): independently release an active capture
if
  the session it serves is gone, rather than relying on the backend to always
  call removeInputCapture.

ENVIRONMENT
* KDE Plasma 6.6.4 / kwin_wayland 6.6.4 (Wayland)
* xdg-desktop-portal 1.21.1; xdg-desktop-portal-kde from Plasma 6.6.4
* Reproduced on the running system; root cause re-checked against current
master
  (xdg-desktop-portal-kde 449b1ae, kwin 9ec0d6f).

NOTES
Related but distinct: the frontend crash that first triggered this on my
machine
is a separate use-after-free in xdg-desktop-portal
(flatpak/xdg-desktop-portal PR #2074). This report is about the compositor /
portal backend NOT releasing capture once the owner is gone -- an independent
fail-safe defect that would strand input on any frontend death.

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to