Skip to content

winpane-host JSON-RPC 2.0 Protocol Reference

winpane-host JSON-RPC 2.0 Protocol Reference

Section titled “winpane-host JSON-RPC 2.0 Protocol Reference”

winpane-host is a CLI binary that exposes the winpane SDK over a JSON-RPC 2.0 protocol using stdin/stdout. Any language that can spawn a subprocess and read/write lines can create Windows overlay surfaces, HUDs, panels, PiP thumbnails, and system tray icons.

Transport: Line-delimited JSON over stdin (requests) and stdout (responses and event notifications). Each message is a single JSON object terminated by a newline (\n). Stderr is reserved for diagnostics (startup banner, fatal errors).

JSON-RPC 2.0 compliance: All messages include "jsonrpc": "2.0". Requests have an id field; responses echo it back. Event notifications have no id.

Lifecycle: The host process creates surfaces on demand. All surfaces are destroyed when the host exits. The host exits when stdin reaches EOF (parent process closed the pipe or died). There is no daemon mode.

Event interleaving: Event notifications may arrive on stdout at any time, interspersed with responses. Clients must inspect each line: messages with an id field are responses to requests; messages with a method field and no id are event notifications.

Spawn the host and send line-delimited JSON:

Terminal window
winpane-host < requests.jsonl

Minimal session (create a HUD, add text, show it, destroy it):

{"jsonrpc":"2.0","method":"create_hud","params":{"placement":{"monitor":{"index":0,"anchor":"top_left","margin":40}},"width":400,"height":200},"id":1}
{"jsonrpc":"2.0","result":{"surface_id":"s1"},"id":1}
{"jsonrpc":"2.0","method":"set_text","params":{"surface_id":"s1","key":"hello","text":"Hello World","x":20,"y":20,"font_size":24},"id":2}
{"jsonrpc":"2.0","result":{},"id":2}
{"jsonrpc":"2.0","method":"show","params":{"surface_id":"s1"},"id":3}
{"jsonrpc":"2.0","result":{},"id":3}
{"jsonrpc":"2.0","method":"destroy","params":{"surface_id":"s1"},"id":4}
{"jsonrpc":"2.0","result":{},"id":4}

Creates a click-through HUD overlay. Returns a surface ID.

ParamTypeRequiredDescription
placementobjectnoPlacement object (see below)
xintegernoX position (fallback if no placement)
yintegernoY position (fallback if no placement)
widthunsigned integeryesWidth in pixels
heightunsigned integeryesHeight in pixels
position_keystringnoKey for position persistence

Placement object: Either {"position": {"x": 100, "y": 100}} or {"monitor": {"index": 0, "anchor": "top_left", "margin": 20}}. If omitted, falls back to top-level x/y params.

Anchor values: "top_left", "top_right", "bottom_left", "bottom_right".

Request:

{"jsonrpc":"2.0","method":"create_hud","params":{"placement":{"monitor":{"index":0,"anchor":"top_left","margin":40}},"width":400,"height":200},"id":1}

Response:

{"jsonrpc":"2.0","result":{"surface_id":"s1"},"id":1}

HUDs are always topmost, click-through, and have no taskbar entry. They support text, rect, and image elements via the scene graph.

Creates an interactive panel surface with selective click-through.

ParamTypeRequiredDefaultDescription
placementobjectnoPlacement object (see create_hud)
xintegernoX position (fallback)
yintegernoY position (fallback)
widthunsigned integeryesWidth
heightunsigned integeryesHeight
draggablebooleannofalseEnable title-bar dragging
drag_heightunsigned integerno0Height of the drag region from the top
position_keystringnoKey for position persistence

Request:

{"jsonrpc":"2.0","method":"create_panel","params":{"placement":{"monitor":{"index":0,"anchor":"bottom_right","margin":20}},"width":300,"height":250,"draggable":true,"drag_height":40,"position_key":"my_panel"},"id":1}

Response:

{"jsonrpc":"2.0","result":{"surface_id":"s1"},"id":1}

Panels support interactive elements (buttons, clickable regions). Non-interactive areas are click-through. Events are delivered as notifications.

Creates a Picture-in-Picture surface showing a live DWM thumbnail of another window.

ParamTypeRequiredDescription
source_hwndintegeryesWindow handle (HWND) of the source window
placementobjectnoPlacement object (see create_hud)
xintegernoX position (fallback)
yintegernoY position (fallback)
widthunsigned integeryesWidth
heightunsigned integeryesHeight
position_keystringnoKey for position persistence

Request:

{"jsonrpc":"2.0","method":"create_pip","params":{"source_hwnd":12345,"placement":{"position":{"x":0,"y":0}},"width":320,"height":240},"id":1}

Response:

{"jsonrpc":"2.0","result":{"surface_id":"s1"},"id":1}

PiP surfaces do not support scene graph operations (set_text, set_rect, set_image, remove_element). They support set_source_region and clear_source_region for cropping.

Creates a system tray icon.

ParamTypeRequiredDefaultDescription
tooltipstringyesTooltip text
icon_pathstringno16x16 whitePath to icon image file (PNG/JPEG/BMP)

Request:

{"jsonrpc":"2.0","method":"create_tray","params":{"tooltip":"My App"},"id":1}

Response:

{"jsonrpc":"2.0","result":{"surface_id":"t1"},"id":1}

Tray IDs use the t prefix (e.g., "t1", "t2"). If no icon is provided, a default 16x16 white icon is used.

These methods add or update elements in a surface’s scene graph. They require a surface_id pointing to a HUD or Panel (not a PiP).

Adds or updates a text element.

ParamTypeRequiredDefaultDescription
surface_idstringyesTarget surface
keystringyesElement key (unique within the surface)
textstringyesText content
xnumberyesX position
ynumberyesY position
font_sizenumberyesFont size in pixels
colorstringno"#ffffff"Text color (hex)
font_familystringnosystem defaultFont family name
boldbooleannofalseBold text
italicbooleannofalseItalic text
interactivebooleannofalseReceives click/hover events (Panel only)

Request:

{"jsonrpc":"2.0","method":"set_text","params":{"surface_id":"s1","key":"title","text":"Hello","x":10,"y":10,"font_size":24,"color":"#ffffff","bold":true},"id":2}

Response:

{"jsonrpc":"2.0","result":{},"id":2}

Adds or updates a rectangle element.

ParamTypeRequiredDefaultDescription
surface_idstringyesTarget surface
keystringyesElement key
xnumberyesX position
ynumberyesY position
widthnumberyesWidth
heightnumberyesHeight
fillstringno"#ffffff"Fill color (hex)
corner_radiusnumberno0Corner radius for rounded rects
border_colorstringnononeBorder color (hex)
border_widthnumberno0Border width
interactivebooleannofalseReceives click/hover events (Panel only)

Request:

{"jsonrpc":"2.0","method":"set_rect","params":{"surface_id":"s1","key":"bg","x":0,"y":0,"width":400,"height":200,"fill":"#1a1a2eee","corner_radius":8},"id":2}

Response:

{"jsonrpc":"2.0","result":{},"id":2}

Adds or updates an image element. The image is loaded from a file path accessible to the host process.

ParamTypeRequiredDefaultDescription
surface_idstringyesTarget surface
keystringyesElement key
pathstringyesPath to image file (PNG/JPEG/BMP)
xnumberyesX position
ynumberyesY position
widthnumberyesDisplay width
heightnumberyesDisplay height
interactivebooleannofalseReceives click/hover events (Panel only)

Request:

{"jsonrpc":"2.0","method":"set_image","params":{"surface_id":"s1","key":"logo","path":"C:/icons/logo.png","x":10,"y":10,"width":64,"height":64},"id":2}

Response:

{"jsonrpc":"2.0","result":{},"id":2}

The image is decoded and converted to premultiplied RGBA8 internally. Supported formats: PNG, JPEG, BMP.

Removes an element by key.

ParamTypeRequiredDescription
surface_idstringyesTarget surface
keystringyesElement key to remove

Request:

{"jsonrpc":"2.0","method":"remove_element","params":{"surface_id":"s1","key":"counter"},"id":3}

Response:

{"jsonrpc":"2.0","result":{},"id":3}

These methods control surface visibility, position, size, and opacity. They work on all surface types (HUD, Panel, PiP).

Makes a surface visible.

ParamTypeRequiredDescription
surface_idstringyesTarget surface

Request:

{"jsonrpc":"2.0","method":"show","params":{"surface_id":"s1"},"id":3}

Makes a surface invisible.

ParamTypeRequiredDescription
surface_idstringyesTarget surface

Request:

{"jsonrpc":"2.0","method":"hide","params":{"surface_id":"s1"},"id":3}

Moves a surface to a new position.

ParamTypeRequiredDescription
surface_idstringyesTarget surface
xintegeryesNew X position
yintegeryesNew Y position

Request:

{"jsonrpc":"2.0","method":"set_position","params":{"surface_id":"s1","x":500,"y":300},"id":4}

Resizes a surface.

ParamTypeRequiredDescription
surface_idstringyesTarget surface
widthunsigned integeryesNew width
heightunsigned integeryesNew height

Request:

{"jsonrpc":"2.0","method":"set_size","params":{"surface_id":"s1","width":600,"height":400},"id":4}

Sets surface opacity.

ParamTypeRequiredDescription
surface_idstringyesTarget surface
opacitynumberyesOpacity from 0.0 (invisible) to 1.0 (opaque)

Request:

{"jsonrpc":"2.0","method":"set_opacity","params":{"surface_id":"s1","opacity":0.8},"id":4}

Anchors a surface to a corner of another window. The surface follows the target window as it moves.

ParamTypeRequiredDefaultDescription
surface_idstringyesSurface to anchor
target_hwndintegeryesTarget window handle (HWND)
anchorstringyesAnchor corner: "top_left", "top_right", "bottom_left", "bottom_right"
offset_xintegerno0Horizontal offset from anchor point
offset_yintegerno0Vertical offset from anchor point

Request:

{"jsonrpc":"2.0","method":"anchor_to","params":{"surface_id":"s1","target_hwnd":65538,"anchor":"top_right","offset_x":10,"offset_y":0},"id":5}

Response:

{"jsonrpc":"2.0","result":{},"id":5}

If the target window is closed, an anchor_target_closed event is emitted.

Removes anchoring from a surface.

ParamTypeRequiredDescription
surface_idstringyesSurface to unanchor

Request:

{"jsonrpc":"2.0","method":"unanchor","params":{"surface_id":"s1"},"id":5}

Sets a DWM backdrop effect on a surface. Requires Windows 11 22H2 or later. Silent no-op on older versions.

ParamTypeRequiredDescription
surface_idstringyesTarget surface
backdropstringyesBackdrop type: "none", "mica", "acrylic"

Request:

{"jsonrpc":"2.0","method":"set_backdrop","params":{"surface_id":"s1","backdrop":"mica"},"id":10}

Response:

{"jsonrpc":"2.0","result":{},"id":10}

Returns whether the current system supports DWM backdrop effects (Windows 11 22H2+).

ParamTypeRequiredDescription
(none)

Request:

{"jsonrpc":"2.0","method":"backdrop_supported","params":{},"id":10}

Response:

{"jsonrpc":"2.0","result":{"supported":true},"id":10}

Shows the surface and animates its opacity from 0 to 1 over the given duration using DirectComposition.

ParamTypeRequiredDescription
surface_idstringyesTarget surface
duration_msunsigned integeryesAnimation duration in milliseconds

Request:

{"jsonrpc":"2.0","method":"fade_in","params":{"surface_id":"s1","duration_ms":300},"id":11}

Response:

{"jsonrpc":"2.0","result":{},"id":11}

Animates the surface opacity from 1 to 0 over the given duration, then hides the surface.

ParamTypeRequiredDescription
surface_idstringyesTarget surface
duration_msunsigned integeryesAnimation duration in milliseconds

Request:

{"jsonrpc":"2.0","method":"fade_out","params":{"surface_id":"s1","duration_ms":500},"id":12}

Response:

{"jsonrpc":"2.0","result":{},"id":12}

Excludes a surface from screen capture (screenshots, screen sharing).

ParamTypeRequiredDescription
surface_idstringyesTarget surface
excludedbooleanyestrue to exclude from capture, false to include

Request:

{"jsonrpc":"2.0","method":"set_capture_excluded","params":{"surface_id":"s1","excluded":true},"id":5}

Requires Windows 10 2004+ (SetWindowDisplayAffinity). Silently degrades on older versions.

Crops the PiP source window to show only a specific region.

ParamTypeRequiredDescription
surface_idstringyesPiP surface ID
xintegeryesSource crop X
yintegeryesSource crop Y
widthintegeryesSource crop width
heightintegeryesSource crop height

Request:

{"jsonrpc":"2.0","method":"set_source_region","params":{"surface_id":"s1","x":0,"y":0,"width":800,"height":600},"id":6}

Only valid on PiP surfaces. Returns an error if called on HUD or Panel.

Clears the source crop, showing the full source window.

ParamTypeRequiredDescription
surface_idstringyesPiP surface ID

Request:

{"jsonrpc":"2.0","method":"clear_source_region","params":{"surface_id":"s1"},"id":6}

These methods operate on tray icons (IDs starting with t).

Updates the tray icon tooltip text.

ParamTypeRequiredDescription
surface_idstringyesTray ID
tooltipstringyesNew tooltip text

Request:

{"jsonrpc":"2.0","method":"set_tooltip","params":{"surface_id":"t1","tooltip":"Updated status"},"id":7}

Updates the tray icon image.

ParamTypeRequiredDescription
surface_idstringyesTray ID
icon_pathstringyesPath to icon image file

Request:

{"jsonrpc":"2.0","method":"set_tray_icon","params":{"surface_id":"t1","icon_path":"C:/icons/active.png"},"id":7}

Associates a Panel surface as the tray popup. Left-clicking the tray icon toggles the panel’s visibility.

ParamTypeRequiredDescription
surface_idstringyesTray ID
panel_surface_idstringyesPanel surface ID to use as popup

Request:

{"jsonrpc":"2.0","method":"set_popup","params":{"surface_id":"t1","panel_surface_id":"s2"},"id":7}

The panel must have been created with create_panel. Using a HUD or PiP surface returns an error.

Sets the right-click context menu for a tray icon.

ParamTypeRequiredDescription
surface_idstringyesTray ID
itemsarrayyesMenu items (see below)

Each menu item:

FieldTypeRequiredDefaultDescription
idunsigned integeryesUnique item ID (returned in tray_menu_item_clicked events)
labelstringyesDisplay text
enabledbooleannotrueWhether the item is clickable

Request:

{"jsonrpc":"2.0","method":"set_menu","params":{"surface_id":"t1","items":[{"id":1,"label":"Settings"},{"id":2,"label":"Quit"}]},"id":7}

Returns the current screen position of a surface.

ParamTypeRequiredDescription
surface_idstringyesTarget surface

Request:

{"jsonrpc":"2.0","method":"get_position","params":{"surface_id":"s1"},"id":9}

Response:

{"jsonrpc":"2.0","result":{"x":150,"y":200},"id":9}

Destroys a surface or tray by ID.

ParamTypeRequiredDescription
surface_idstringyesSurface or tray ID to destroy

Request:

{"jsonrpc":"2.0","method":"destroy","params":{"surface_id":"s1"},"id":8}

Response:

{"jsonrpc":"2.0","result":{},"id":8}

The surface window is destroyed immediately. Elements and resources are freed. Using a destroyed surface ID in subsequent calls returns an error.

Events are delivered as JSON-RPC notifications (no id field) with "method": "event". The params object contains the event details.

An interactive element was clicked.

{"jsonrpc":"2.0","method":"event","params":{"type":"element_clicked","surface_id":"s2","key":"btn1"}}

The mouse entered an interactive element.

{"jsonrpc":"2.0","method":"event","params":{"type":"element_hovered","surface_id":"s2","key":"btn1"}}

The mouse left an interactive element.

{"jsonrpc":"2.0","method":"event","params":{"type":"element_left","surface_id":"s2","key":"btn1"}}

A tray icon was clicked.

{"jsonrpc":"2.0","method":"event","params":{"type":"tray_clicked","button":"left"}}

button is one of: "left", "right", "middle".

Note: tray_clicked does not include a tray ID (SDK limitation). If multiple trays exist, events cannot distinguish which tray was clicked.

A tray context menu item was selected.

{"jsonrpc":"2.0","method":"event","params":{"type":"tray_menu_item_clicked","item_id":2}}

Note: Like tray_clicked, this event does not include a tray ID.

The source window of a PiP surface was closed.

{"jsonrpc":"2.0","method":"event","params":{"type":"pip_source_closed","surface_id":"s3"}}

The target window of an anchored surface was closed.

{"jsonrpc":"2.0","method":"event","params":{"type":"anchor_target_closed","surface_id":"s1"}}

A surface was moved (e.g., dragged by the user).

{"jsonrpc":"2.0","method":"event","params":{"type":"surface_moved","surface_id":"s1","x":250,"y":300}}

The GPU device was lost and all surfaces have been automatically recovered from the scene graph. No action is required from the client, but this event can be used for logging or to refresh custom draw content.

{"jsonrpc":"2.0","method":"event","params":{"type":"device_recovered"}}

Colors are specified as CSS-style hex strings:

FormatExampleDescription
#rgb"#f00"3-digit hex, expanded to 6 digits, alpha 255
#rrggbb"#ff0000"6-digit hex, alpha 255
#rrggbbaa"#ff000080"8-digit hex with explicit alpha

The # prefix is optional. Alpha 00 is fully transparent, ff is fully opaque.

Default colors when omitted:

  • Text color: #ffffff (white)
  • Rect fill: #ffffff (white)
  • Border color: none (no border)

Standard JSON-RPC 2.0 error codes:

CodeNameDescription
-32700Parse errorInvalid JSON
-32600Invalid requestMissing jsonrpc: "2.0"
-32601Method not foundUnknown method name
-32602Invalid paramsMissing required params, wrong types, unknown surface ID
-32603Internal errorSurface creation failure or other internal error

Example error response:

{"jsonrpc":"2.0","error":{"code":-32602,"message":"unknown surface_id: s99"},"id":5}
  • Custom draw not available: The custom draw escape hatch (Direct2D drawing operations) requires in-process access to the GPU context. It is not exposed over the JSON-RPC protocol. Use the Rust or C API for custom draw.
  • Image paths must be local: The path parameter in set_image and icon_path in tray methods must point to files accessible from the host process. URLs are not supported.
  • No batch operations: Each request is processed individually. There is no transaction or batch mode.
  • Tray event ambiguity: tray_clicked and tray_menu_item_clicked events do not include a tray ID. If multiple trays exist, events cannot be attributed to a specific tray.
  • Sequential processing: Requests are processed one at a time in the order received. High-frequency updates (more than ~100/sec) may cause latency.