Perch
Building modsWidgets & contexts

Widgets & contexts

Where a widget can appear — the context catalog, urgency, the degradation ladder, and live previews.

3 min readUpdated Jul 21, 2026

A widget declares which contexts it can render — named placements in the notch’s world. The engine decides what’s present and where it goes; your widget just states what forms it has. Modders never deal with the engine’s internals (variants, regions, envelopes) — contexts are the whole surface.

"widgets": [
  {
    "id": "media_player", "label": "Media", "urgency": "ambient",
    "contexts": {
      "notch_single":    { "display": "solo" },
      "notch_secondary": { "display": "tail", "with": "clock" },
      "expanded":        { "display": "card" },
      "peek":            { "display": "peek" },
      "transient":       { "display": "hud", "timeout_ms": 2200 }
    },
    "preview": { "title": "Song", "artist": "Artist", "playing": true }
  }
]

The context catalog

ContextWhere it rendersNotes
notch_singlethe collapsed notch — alone, or as the LEADING pill of a dual-pill notchthe compact pill form
notch_secondarydual-pill notch, trailing seatoptional "with": "<widget id>" — a companion form used only beside that leader
expandeda 370×100 slot in the expanded panelplaceable on pages by the user
peekthe tiny idle peek stripordinary stack ambient
transientthe widened transient HUDrequires timeout_ms; may set "envelope": "tall" for the 265×60 tall pill

Urgency

One of three tiers, and it’s a class, not a priority number:

  • transient — interrupts briefly, always wins, retracts on its own (volume, connect events, low battery).
  • event — something happened worth surfacing (a notification, a ring).
  • ambient — steady-state presence (media, a call, a clock).

Within a tier, order comes from the user’s priority stack. Across tiers, transient > event > ambient, always. You declare honestly; the user arbitrates.

The degradation ladder

Context order in your declaration is the fallback ladder. When space tightens — a second widget arrives, the notch shrinks, a transient interrupts — the solver walks your contexts in declared order and takes the first that fits the situation. Declare from most expressive to most compact. A widget with only expanded simply never competes for the notch.

Transients auto-retract

A transient context’s timeout_ms is enforced by the host: after set_presence(id, true, data), the widget retracts by itself when the timeout lapses. Push fresh data to extend the moment (the volume slider staying up while you keep scrolling); never fake a transient with an ambient plus your own timer.

Live previews

preview is a demo payload for the settings picker. There are no canned screenshots — the picker renders your real display tree over this data (or over the widget’s live last-known data once it has run). Make the preview payload representative: it’s your widget’s face in the store.

esc
Type to search
navigate open