feat(foreground): track topmost process + browser page title
Lint & Test / test (push) Failing after 8s
Lint & Test / test (push) Failing after 8s
Adds cross-platform foreground-window tracking and exposes it over REST (/api/foreground) and the existing WebSocket feed. - foreground_service.py: Windows probe via ctypes (HANDLE-correct argtypes to avoid 64-bit handle truncation); macOS via AppKit; Linux via Xlib (Wayland returns unavailable). TTL cache + per-platform fallback. - browser_url_service.py: when foreground is a recognised browser, extract the page title from the window title (browser-name suffix stripped) and surface `is_browser` + `browser_page_title`. Optional UIA-based URL extraction behind MEDIA_SERVER_BROWSER_UIA env flag (off by default — Chromium browsers keep their accessibility tree dormant otherwise). - websocket_manager: poll foreground every 1s inside the existing status loop, broadcast `foreground` on connect and `foreground_update` on change. Diff only on user-visible fields to avoid geometry spam. - WebUI: new editorial card rendered under the monitor list on the Display tab — process name, window title, fullscreen/minimized/monitor chips, browser block when applicable, exe path, PID, started-ago, geometry, platform. 16px inter-section gap matches Settings cadence. - i18n: 25 new keys added to both en.json and ru.json. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
"""Foreground (topmost) window/process API."""
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
|
||||
from fastapi import APIRouter, Depends
|
||||
|
||||
from ..auth import verify_token
|
||||
from ..services.foreground_service import get_foreground_info
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
router = APIRouter(prefix="/api/foreground", tags=["foreground"])
|
||||
|
||||
|
||||
@router.get("")
|
||||
async def get_foreground(
|
||||
refresh: bool = False, _: str = Depends(verify_token)
|
||||
) -> dict:
|
||||
"""Return metadata about the foreground window and owning process.
|
||||
|
||||
The probe is cached for ~500ms server-side; pass ``?refresh=1`` to bypass
|
||||
the cache for one-shot queries.
|
||||
"""
|
||||
info = await asyncio.to_thread(get_foreground_info, refresh)
|
||||
return info.to_dict()
|
||||
Reference in New Issue
Block a user