Skip to content

fix: gnome-screenshot fallback for background screenshot capture (#20)#22

Merged
avifenesh merged 2 commits into
mainfrom
fix/screenshot-gnome-screenshot-fallback
Jun 6, 2026
Merged

fix: gnome-screenshot fallback for background screenshot capture (#20)#22
avifenesh merged 2 commits into
mainfrom
fix/screenshot-gnome-screenshot-fallback

Conversation

@avifenesh
Copy link
Copy Markdown
Collaborator

Summary

Fixes #20 — 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 (org.gnome.Shell.Screenshot) rejects callers that don't own an allowlisted bus name (DBusSenderChecker) → ACCESS_DENIED.
  • XDG portal cancels with response code 2 when there's no foreground window to parent its non-interactive request to.

This adds gnome-screenshot as 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_BACKEND env override (gnome-shell | portal | gnome-screenshot) to force a single backend, skipping the fallback chain.
  • 20s subprocess timeout (matching the portal): a hung gnome-screenshot is killed + temp cleaned, degrading to a clear error instead of blocking forever.
  • Diagnostics probe gnome-screenshot and surface it in capabilities.screenshot when 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:

Scenario OLD (pre-fix) NEW (fix)
Dead session bus (rungs 1+2 fail like #20) + real display, default chain, no override Error: GNOME Shell screenshot failed… XDG portal screenshot failed… source: gnome-screenshot, real 1280×800 PNG

Also proven:

  • End-to-end: real binary → real gnome-screenshot → real 1280×800 capture, decoded PNG.
  • No regression: working bus → portal used, gnome-screenshot never invoked (poison-stub probe).
  • Timeout kills hung child + cleans temp file.
  • Not-found / nonzero-exit / invalid-env-value → distinct correct errors.
  • Unit tests for backend parsing + env override.

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.

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.
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread src/screenshot.rs Outdated
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.
@avifenesh avifenesh merged commit 7d9e0ef into main Jun 6, 2026
20 checks passed
@avifenesh avifenesh deleted the fix/screenshot-gnome-screenshot-fallback branch June 6, 2026 14:17
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.

Screenshot tool fails from background processes (systemd services, MCP parent shells) on GNOME Wayland

1 participant