From 5ea99289242d3562233de329f18d01418d20da34 Mon Sep 17 00:00:00 2001 From: Svrnty Date: Thu, 30 Oct 2025 02:17:12 -0400 Subject: [PATCH] fix: Screenshot capture with DISPLAY env and full screen - Use full screen capture instead of active window (more reliable) - Explicitly preserve and set DISPLAY environment variable - Default to :0 if DISPLAY not set - Better error logging with stderr output - Use time.time() instead of date command for timestamp Fixes screenshot failures when DISPLAY not inherited from parent process. Changes from window-specific capture to full screen for better reliability. Generated with Claude Code Co-Authored-By: Claude Co-Authored-By: Jean-Philippe Brule --- claude_vision_auto/screenshot.py | 53 ++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/claude_vision_auto/screenshot.py b/claude_vision_auto/screenshot.py index 0d61f87..805a54a 100644 --- a/claude_vision_auto/screenshot.py +++ b/claude_vision_auto/screenshot.py @@ -26,11 +26,14 @@ def find_screenshot_tool() -> Optional[str]: def take_screenshot() -> Optional[str]: """ - Take screenshot of active terminal window + Take screenshot of full screen Returns: Path to screenshot file, or None if capture failed """ + import os + import time + tool = find_screenshot_tool() if not tool: @@ -40,41 +43,49 @@ def take_screenshot() -> Optional[str]: # Create temporary file cache_dir = config.get_cache_dir() - screenshot_path = cache_dir / f"screenshot_{int(subprocess.check_output(['date', '+%s']).decode().strip())}.png" + screenshot_path = cache_dir / f"screenshot_{int(time.time())}.png" + + # Preserve DISPLAY environment variable + env = os.environ.copy() + if 'DISPLAY' not in env: + env['DISPLAY'] = ':0' # Default X display try: if tool == "scrot": - # Capture active window - subprocess.run( - ["scrot", "-u", str(screenshot_path)], + # Capture full screen (more reliable than -u for active window) + result = subprocess.run( + ["scrot", str(screenshot_path)], check=True, capture_output=True, - timeout=config.SCREENSHOT_TIMEOUT + timeout=config.SCREENSHOT_TIMEOUT, + env=env ) elif tool == "gnome-screenshot": - # Capture active window - subprocess.run( - ["gnome-screenshot", "-w", "-f", str(screenshot_path)], + # Capture full screen + result = subprocess.run( + ["gnome-screenshot", "-f", str(screenshot_path)], check=True, capture_output=True, - timeout=config.SCREENSHOT_TIMEOUT + timeout=config.SCREENSHOT_TIMEOUT, + env=env ) elif tool == "import": # ImageMagick - capture root window - subprocess.run( + result = subprocess.run( ["import", "-window", "root", str(screenshot_path)], check=True, capture_output=True, - timeout=config.SCREENSHOT_TIMEOUT + timeout=config.SCREENSHOT_TIMEOUT, + env=env ) elif tool == "maim": - # Capture active window - subprocess.run( - ["maim", "-i", "$(xdotool getactivewindow)", str(screenshot_path)], - shell=True, + # Capture full screen + result = subprocess.run( + ["maim", str(screenshot_path)], check=True, capture_output=True, - timeout=config.SCREENSHOT_TIMEOUT + timeout=config.SCREENSHOT_TIMEOUT, + env=env ) else: return None @@ -86,17 +97,19 @@ def take_screenshot() -> Optional[str]: else: return None - except subprocess.TimeoutExpired: + except subprocess.TimeoutExpired as e: if config.DEBUG: print(f"[DEBUG] Screenshot timeout with tool: {tool}") return None except subprocess.CalledProcessError as e: if config.DEBUG: - print(f"[DEBUG] Screenshot failed: {e}") + print(f"[DEBUG] Screenshot failed with {tool}: {e}") + if e.stderr: + print(f"[DEBUG] Error output: {e.stderr.decode('utf-8', errors='ignore')}") return None except Exception as e: if config.DEBUG: - print(f"[DEBUG] Unexpected error: {e}") + print(f"[DEBUG] Unexpected screenshot error: {type(e).__name__}: {e}") return None