Touch API
The Touch API is an out-of-process interface that lets third-party apps consume touch and gesture data directly — and ask Gatecaster to mute system input for kiosk-style experiences. It ships with every edition, including Free.
Connection
A Unix-domain socket, owner-only (0600):
~/Library/Application Support/Gatecaster/api.sockThe protocol is NDJSON — newline-delimited JSON, both directions. Every
message carries a v field; clients must ignore unknown fields and unknown
gesture kinds for forward compatibility. Up to 16 concurrent clients are
supported, each with independent subscription and suppression state.
Subscribing
Send a subscribe command listing the channels you want:
{ "subscribe": ["fingers", "gestures"] }| Channel | Delivers |
|---|---|
fingers | Post-palm-rejection contacts — what the pointer sees. |
rawFingers | Every contact, each flagged with its palm-rejection verdict. |
gestures | Recognized gestures, after the engine’s intent latch. |
Finger frames
{
"v": 1,
"type": "fingers",
"t": 1717000000.123,
"dropped": 0,
"fingers": [
{ "id": 3, "x": 0.412, "y": 0.875, "sx": 791.0, "sy": 945.0, "phase": "moved", "palm": false }
]
}x/y— normalized0–1in calibrated panel space.sx/sy— screen pixels, already mapped through calibration and the active display.phase—began·moved·ended·cancelled.dropped— frames discarded since the last delivery for a slow consumer.
Gesture frames
{ "v": 1, "type": "gesture", "gesture": "pinch", "value": 0.034, "phase": "changed" }
{ "v": 1, "type": "gesture", "gesture": "rotate", "value": -1.2, "phase": "changed" }
{ "v": 1, "type": "gesture", "gesture": "scroll", "dx": 0.0, "dy": -13.5, "phase": "changed" }
{ "v": 1, "type": "gesture", "gesture": "swipe", "direction": "left", "fingers": 3 }Suppression
Ask Gatecaster to stop driving the system so your app can own the panel:
{ "suppress": ["input", "gestures", "edges"] }
{ "suppress": true }
{ "suppress": false }| Category | Mutes |
|---|---|
input | Pointer move / click / drag / scroll / keystroke injection. |
gestures | Synthesized pinch / rotate trackpad events. |
edges | Edge-pull triggers (Notification Center, and the on-screen keyboard). Accepted and honoured, but a no-op in the beta — edge gestures aren’t armed yet, so there is nothing to mute. Request it anyway: your app keeps working unchanged when they ship. |
Suppression is a connection-scoped lease with union semantics: a mute stays on while any client requests it, and is released automatically when the socket closes. There’s no TTL or heartbeat to manage — and a crashed client can never leave touch wedged off.
Backpressure
The panel reports at roughly 120 fps with up to 10 contacts per frame. The
server never blocks on a slow client: it drops frames and reports the count in the
next delivered frame’s dropped field (≈256 KB buffer cap). If you fall behind,
coalesce.
Reference clients
Dependency-free clients live in the
gatecaster-examples
repo under touch-api/ (see Examples):
Python
import json, socket, os
path = os.path.expanduser(
"~/Library/Application Support/Gatecaster/api.sock")
s = socket.socket(socket.AF_UNIX)
s.connect(path)
s.sendall(b'{"subscribe":["fingers","gestures"]}\n')
for line in s.makefile():
msg = json.loads(line)
if msg["type"] == "gesture":
print(msg["gesture"], msg.get("value"), msg["phase"])Versioning
The v field bumps only on breaking changes — a field removal or a semantics
change. Additive fields don’t bump it, so always ignore unknown fields and unknown
gesture kinds.