/** * Xvfb (X virtual framebuffer) process wrapper, plus a minimal window * manager (matchbox) so headed Chromium's --kiosk flag actually takes * effect. * * Spins up a virtual X display that headed Chromium can render to. Used by * cloud clip capture so the recording surface is reachable by ffmpeg via * `x11grab` — bypassing the slow `Page.captureScreenshot` CDP path that * software-rasterized Linux compositors cap at ~6 fps on heavy React UIs. * * Why matchbox: Chromium's --kiosk / --start-fullscreen flags request * fullscreen mode from the WM via _NET_WM_STATE_FULLSCREEN. Without a WM * to honor that request, Chromium silently falls back to a normal * decorated window with the full chrome (tab bar, address bar, infobars) * visible — and ffmpeg x11grab captures all of it, ruining clips. * matchbox-window-manager (~100KB, designed for embedded kiosks) * auto-fullscreens every window with no decorations. With matchbox, * --kiosk takes effect and the page fills the whole framebuffer cleanly. * * Lifecycle: Xvfb + matchbox both run for the entire browser process * lifetime. ffmpeg recording starts/stops per BEGIN_CLIP/END_CLIP and * grabs from the same display. */ export interface XvfbProcessOptions { /** Display number (without leading colon). E.g. 99 → DISPLAY=:99. */ displayNumber: number; /** Screen width in pixels. Should match the Chromium window size. */ width: number; /** Screen height in pixels. Should match the Chromium window size. */ height: number; } export declare class XvfbProcess { private readonly opts; private process; private wmProcess; private exited; constructor(opts: XvfbProcessOptions); /** DISPLAY string suitable for `process.env.DISPLAY` (e.g. `:99`). */ get display(): string; start(): Promise; /** * Start matchbox-window-manager. Required for Chromium's --kiosk to * actually take effect: kiosk requests fullscreen via the WM, and * without a WM Chromium falls back to a normal decorated window with * the full chrome leaking into x11grab captures. matchbox is tiny * (~100KB), auto-fullscreens every window, and removes decorations. * `-use_titlebar no` and `-use_cursor no` are belt-and-suspenders; * matchbox already defaults to no decorations, but the explicit flags * also stop it from drawing its own cursor (which would superimpose * on Chromium's cursor and confuse the cursor overlay script). */ private startWindowManager; stop(): Promise; }