Treat bare desktop canvas as ready

Allow the Linux Desktop state collector to report a healthy canvas when XFCE has no active application window, as long as the display, visible windows, and screenshots are available.

Document the readiness rule in the linux-desktop skill and add regression coverage for the bare-desktop active_window=null case.
This commit is contained in:
Alessandro 2026-05-10 00:07:04 +02:00
parent c8e239d5a2
commit 854a96e880
3 changed files with 57 additions and 1 deletions

View file

@ -372,7 +372,6 @@ def collect_active_window(env: dict[str, str], capabilities: dict[str, str], err
return None
result = run([capabilities["xdotool"], "getactivewindow"], env=env, timeout=3)
if result.returncode != 0:
errors.append(command_output(result) or "xdotool could not read the active window.")
return None
window_id = result.stdout.strip().splitlines()[0] if result.stdout.strip() else ""
if not window_id:

View file

@ -60,6 +60,8 @@ $DESKTOP key ctrl+s
The script targets the persistent `agent-zero-desktop` X display, sets `DISPLAY`, `XAUTHORITY`, and `HOME` to the XFCE profile, then uses `xdotool` for input. Startup normally prepares this session. If `check` fails during explicit Desktop work, report that the Desktop runtime is not ready instead of installing packages ad hoc.
If `observe --json --screenshot` shows a reachable display, visible Desktop/window entries, and a fresh screenshot, the Desktop is usable even when `active_window` is `null`; a bare XFCE desktop can have no active application window. Treat missing screenshots, missing display, or unavailable `xdotool`/`xwd` as blockers and stop with the specific readiness message instead of repeating clicks or inventing a fallback.
For direct app launches without coordinates:
```bash

View file

@ -92,6 +92,61 @@ def test_desktop_state_collects_x11_state_from_mocked_tools(tmp_path, monkeypatc
assert [window["title"] for window in state["windows"]] == ["LibreOffice Calc", "Terminal"]
def test_desktop_state_allows_missing_active_window_when_display_is_reachable(tmp_path, monkeypatch):
session_dir = tmp_path / "sessions"
profile_dir = tmp_path / "profiles" / desktop_state.SESSION_ID
session_dir.mkdir(parents=True)
profile_dir.mkdir(parents=True)
(session_dir / f"{desktop_state.SESSION_ID}.json").write_text(
'{"display": 120, "profile_dir": "%s"}' % profile_dir,
encoding="utf-8",
)
monkeypatch.setattr(desktop_state, "SESSION_DIR", session_dir)
monkeypatch.setattr(desktop_state, "PROFILE_DIR", tmp_path / "profiles")
monkeypatch.setattr(desktop_state.shutil, "which", lambda name: f"/usr/bin/{name}")
def fake_run(command, **kwargs):
del kwargs
name = Path(command[0]).name
if name == "xrandr":
return _completed(command, stdout="Screen 0: current 543 x 792, maximum 1920 x 1080\n")
if name == "xdotool" and command[1:3] == ["getmouselocation", "--shell"]:
return _completed(command, stdout="X=43\nY=244\nSCREEN=0\nWINDOW=18874412\n")
if name == "xdotool" and command[1] == "getactivewindow":
return _completed(
command,
returncode=1,
stderr="XGetWindowProperty[_NET_ACTIVE_WINDOW] failed (code=1)\n",
)
if name == "xdotool" and command[1] == "search":
return _completed(command, stdout="18874412\n")
if name == "xdotool" and command[1] == "getwindowname":
return _completed(command, stdout="Desktop\n")
if name == "xwininfo":
return _completed(
command,
stdout=(
" Absolute upper-left X: 0\n"
" Absolute upper-left Y: 0\n"
" Width: 543\n"
" Height: 792\n"
),
)
if name == "xprop":
return _completed(command, stdout='WM_CLASS(STRING) = "xfdesktop", "Xfdesktop"\n')
raise AssertionError(f"unexpected command: {command}")
monkeypatch.setattr(desktop_state.subprocess, "run", fake_run)
state = desktop_state.collect_state()
assert state["ok"] is True
assert state["active_window"] is None
assert state["errors"] == []
assert [window["title"] for window in state["windows"]] == ["Desktop"]
def test_desktop_state_screenshot_capture_uses_xwd_and_pillow_when_available(tmp_path, monkeypatch):
monkeypatch.setattr(desktop_state, "SCREENSHOT_DIR", tmp_path)
capabilities = {"xwd": "/usr/bin/xwd"}