""" Clipboard management with 60-second auto-clear. Uses xclip/xdotool for SteamOS (KDE Plasma). """ import asyncio import subprocess import time from typing import Optional # Clipboard state _clipboard_timers: dict = {} _clipboard_contents: dict = {} async def copy_to_clipboard(text: str, clear_after: int = 60, label: str = "default") -> dict: """Copy text to clipboard with auto-clear after specified seconds.""" global _clipboard_timers, _clipboard_contents try: # Cancel any existing timer for this label if label in _clipboard_timers: _clipboard_timers[label].cancel() # Store the text _clipboard_contents[label] = text # Copy to clipboard using xclip process = await asyncio.create_subprocess_exec( "xclip", "-selection", "clipboard", stdin=asyncio.subprocess.PIPE, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, ) await process.communicate(input=text.encode("utf-8")) if process.returncode != 0: # Fallback to xsel if xclip not available process = await asyncio.create_subprocess_exec( "xsel", "--clipboard", "--input", stdin=asyncio.subprocess.PIPE, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, ) await process.communicate(input=text.encode("utf-8")) if process.returncode != 0: return {"success": False, "error": "No clipboard tool available (xclip or xsel)"} # Set up auto-clear timer async def clear_clipboard(): await asyncio.sleep(clear_after) await clear_clipboard_label(label) timer = asyncio.create_task(clear_clipboard()) _clipboard_timers[label] = timer return { "success": True, "clear_after": clear_after, "expires_at": int(time.time()) + clear_after, } except FileNotFoundError: return {"success": False, "error": "xclip/xsel not found. Install with: pacman -S xclip"} except Exception as e: return {"success": False, "error": str(e)} async def clear_clipboard_label(label: str = "default") -> dict: """Clear the clipboard for a specific label.""" global _clipboard_timers, _clipboard_contents # Cancel timer if exists if label in _clipboard_timers: _clipboard_timers[label].cancel() del _clipboard_timers[label] # Clear clipboard content if label in _clipboard_contents: del _clipboard_contents[label] # Clear the actual clipboard try: process = await asyncio.create_subprocess_exec( "xclip", "-selection", "clipboard", stdin=asyncio.subprocess.PIPE, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, ) await process.communicate(input=b"") except FileNotFoundError: pass return {"success": True} async def clear_all_clipboards() -> dict: """Clear all clipboard contents and cancel all timers.""" global _clipboard_timers, _clipboard_contents for label in list(_clipboard_timers.keys()): _clipboard_timers[label].cancel() _clipboard_timers.clear() _clipboard_contents.clear() await clear_clipboard_label("default") return {"success": True} def get_clipboard_status(label: str = "default") -> dict: """Get the status of clipboard content for a label.""" global _clipboard_contents, _clipboard_timers if label not in _clipboard_contents: return {"has_content": False} return { "has_content": True, "label": label, "has_timer": label in _clipboard_timers, }