fix: gnome-screenshot fallback for background screenshot capture (#20)#22
Conversation
The screenshot tool failed from background processes (systemd user services, non-interactive parent shells) on GNOME Wayland. Both existing capture rungs are structurally unavailable in that context: - GNOME Shell's `org.gnome.Shell.Screenshot` rejects callers that do not own an allowlisted bus name (DBusSenderChecker), so the direct DBus call returns ACCESS_DENIED. - The XDG portal cancels with response code 2 when there is no foreground window to parent its (non-interactive) request to. Add `gnome-screenshot` as a third fallback rung: it claims an allowlisted bus name and works regardless of session context. The subprocess is bounded by a 20s timeout (matching the portal) and the child is killed + temp file cleaned on timeout, so a hung capture degrades to a clear error instead of blocking the tool forever. Also add `COMPUTER_USE_LINUX_SCREENSHOT_BACKEND` to force a single backend (gnome-shell | portal | gnome-screenshot), skipping the fallback chain for pinned/background deployments and debugging. Diagnostics now probe gnome-screenshot and surface it in capabilities.screenshot when present. Fixes #20.
There was a problem hiding this comment.
Code Review
This pull request introduces a fallback screenshot mechanism using the gnome-screenshot CLI tool to handle background and systemd contexts where DBus paths are denied. It also adds a COMPUTER_USE_LINUX_SCREENSHOT_BACKEND environment variable to force a specific backend. The reviewer suggested refactoring the gnome-screenshot execution to use tokio::process::Command instead of manual polling with std::process::Child::try_wait, which would reduce latency, save CPU cycles, and eliminate the need for a manual PATH lookup helper.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Address review feedback: replace the manual try_wait polling loop and the hand-rolled PATH lookup with tokio::process::Command. It searches PATH natively when spawning and provides a real async wait, removing the 50ms poll latency and CPU spin. Bound the wait with tokio::time::timeout and kill the child on deadline. Enables the tokio "process" feature.
Summary
Fixes #20 — the
screenshottool failed from background processes (systemd user services, non-interactive parent shells) on GNOME Wayland. Both existing capture rungs are structurally unavailable in that context:org.gnome.Shell.Screenshot) rejects callers that don't own an allowlisted bus name (DBusSenderChecker) →ACCESS_DENIED.This adds
gnome-screenshotas a third fallback rung — it claims an allowlisted bus name and works regardless of session context. Capture chain is now: GNOME Shell → portal → gnome-screenshot.Also:
COMPUTER_USE_LINUX_SCREENSHOT_BACKENDenv override (gnome-shell|portal|gnome-screenshot) to force a single backend, skipping the fallback chain.gnome-screenshotis killed + temp cleaned, degrading to a clear error instead of blocking forever.gnome-screenshotand surface it incapabilities.screenshotwhen present.Test Plan
Verified via A/B counterfactual on the same machine + a real X11 display (Xvfb) — the OLD binary fails the exact scenario the NEW binary passes:
Error: GNOME Shell screenshot failed… XDG portal screenshot failed…source: gnome-screenshot, real 1280×800 PNGAlso proven:
gnome-screenshot→ real 1280×800 capture, decoded PNG.gnome-screenshotnever invoked (poison-stub probe).Local gates:
cargo fmt --check,cargo clippy --locked --all-targets -D warnings,cargo test --locked(108+4 pass),mcp_safety_check.py(16 tools, v0.2.5),cargo package. No version bump (no tool/schema change).Related Issues
Fixes #20.