# gleamtk Proof of concept: a **Relm4** (GTK4 / libadwaita) process that acts as an **Erlang foreign node**, controlled by a **Gleam** process over the Erlang distribution protocol. ``` Gleam (beam) ── cookie + epmd ──► Relm4 foreign node (Rust) gleamtk@127.0.0.1 ui@127.0.0.1 controller ── {gui, Node} ! ──► registered name: gui ◄── events ── {controller, …} ── clicks / ready / pong ``` ## Protocol **Gleam → UI** (`{gui, 'ui@127.0.0.1'} ! Term`): | Term | Effect | |------|--------| | `hello` | Handshake; UI records controller pid | | `{set_title, Binary}` | Window title | | `{set_label, Binary}` | Main label | | `{set_count, Int}` | Counter display | | `ping` | UI replies `pong` | **UI → Gleam** (to registered `controller` or the sender pid): | Term | Meaning | |------|---------| | `{ready, <<"ui@…">>}` | UI node is up | | `{clicked, Count}` | Primary button | | `{count_changed, Count}` | − button | | `pong` | Reply to `ping` | | `window_closed` | Window closed | ## Requirements - Nix (recommended) or: Erlang/OTP, Gleam, Rust, GTK4, libadwaita, epmd - A display (Wayland/X11) for the Relm4 window ## Run ```bash cd gleamtk nix develop # or: nix develop -c bash just run # starts UI then Gleam controller ``` Two terminals: ```bash # terminal 1 just ui # terminal 2 just gleam ``` Click **Click me** / **+** in the window. Gleam prints events and updates the label and count over distribution. ## Layout ``` gleamtk/ gleam/ # Gleam controller (BEAM node) ui/ # Relm4 + erl_dist foreign node justfile flake.nix ``` ## Notes - Cookie defaults to `gleamtk`; both sides must match. - Long node names on `127.0.0.1` avoid short-name / hostname mismatches. - The Rust side uses [`erl_dist`](https://crates.io/crates/erl_dist); the UI thread never blocks on distribution I/O. - This is a POC, not a full widget toolkit binding.