# `Emerge.Runtime.Viewport`
[🔗](https://github.com/emerge-elixir/emerge/blob/v0.5.1/lib/emerge/runtime/viewport.ex#L1)

Runtime for viewports defined with `use Emerge`.

Application mount arguments remain keyword lists. The configuration returned
by `mount/1` is an `Emerge.Config` struct, not renderer keywords:

    def mount(opts) do
      output = %Emerge.Config.Window{title: Keyword.get(opts, :title, "My App")}
      {:ok, %Emerge.Config{output: output, input: [events: [:key]]}}
    end

Implement neither or exactly one of `config/1` and `config/2`. They receive
the previous normalized desired config; `config/2` also receives application
state. The first call receives mount config, before renderer creation. Later
calls run during coalesced rerenders, even if the tree has not changed.
Callback/validation failures retain the previous valid config. Operational
renderer failures retain the new desired config for the next callback and
recovery; the complete live snapshot is retried on the next rerender. Accepted
config is not proof of hardware application or presentation completion.

    def config(%Emerge.Config{output: %Emerge.Config.Window{} = output} = previous, state) do
      output = %Emerge.Config.Window{output | title: state.title}
      %Emerge.Config{previous | output: output}
    end

Nested keyword shorthand expands from record defaults, not previous values.
Use typed struct updates to preserve untouched fields. See `Emerge.Config`
for groups, output variants, defaults and current implementation limits.

Raw input observation is opt-in through `Emerge.Config.Input.events`.
`Emerge.Input` documents every callback payload. This filter does not disable
element interactions or window-close notifications.

Adapter selection and liveness policy live in `Emerge.Config.Runtime`.
Native ownership is managed internally, not configured by applications.
See the [viewport configuration documentation](Emerge.html#module-viewport-configuration),
[input guide](handle_input.html) and [0.5 migration guide](0-5.html).

Initially-off DRM viewports still acquire and bind output ownership without
rendering/uploading. Off preserves application messages, config reconciliation,
latest tree/intent and ownership, while suspending native UI input and destroying
the presenter. On recreates resources; no GPU state is restored. Power/brightness
controls require explicit OpenGL, Vulkan or raster (CPU or GPU-upload
presentation). GPU upload requires an OpenGL-enabled DRM build; automatic API
power controls remain unsupported. Invalid live/startup controls report errors.
Software support does not qualify physical panel behavior.

# `t`

```elixir
@type t() :: map()
```

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `default_wrap_payload`

```elixir
@spec default_wrap_payload(term(), term(), term()) :: term()
```

# `notify_source_reloaded`

```elixir
@spec notify_source_reloaded(term()) :: :ok
```

# `renderer`

```elixir
@spec renderer(pid()) :: term()
```

# `rerender`

```elixir
@spec rerender(map()) :: map()
```

---

*Consult [api-reference.md](api-reference.md) for complete listing*
