wm

Sokhatsky WM

Here’s a clearer, more concrete comparison of what Erlang implementations of these four window managers would actually look like, focused on the differences that matter when you share one C99 X11 Port. These managers I would like you to take into account!

High-level comparison

Aspect TWM (Erlang) CTWM (Erlang) DWM (Erlang) OXWM (Erlang) Style Classic stacking + tabs Stacking + virtual workspaces Dynamic tiling (master/stack) Modern dynamic tiling + rich config Complexity Lowest Low–Medium Medium Highest State Simple window list/focus Windows + workspaces + icons Tags (bitmasks/clients/layouts) Tags/multi-layout/key-chords/status bar Layout Almost none Minimal (stacking/workspace) Pure function layout/2 Multiple pure layout functions + runtime switch Configuration Text Erlang terms Compile-time Full DSL Erlang

How the Erlang architecture differs

Common skeleton (what you already sketched is correct):

wm
├── wm_sup
├── wm_x11            % shared C99 Port (XNextEvent → Erlang messages)
├── wm_event          % receives Port messages, dispatches
├── wm_windows        % gen_server: window registry + focus
├── wm_layout         % pure functions (or gen_server for stateful layouts)
├── wm_config         % load + hot-reload
└── wm_keybind        % key-chord state machine

TWM-style (easiest)

DWM-style (where Erlang really shines)

Core idea: layout is a pure function

 layout(Clients, Screen, #{mfact := M, nmaster := N, layout := tiling}) ->

OXWM-style (most ambitious)

Everything from DWM plus:

You start needing more careful supervision trees and possibly a wm_bar process. Hot-reload of the entire config without killing windows is very natural in Erlang (exactly what OXWM tries to do with Lua).

Practical recommendation for your project

Shared C99 Port surface (keep it tiny)

wm_x11.c (minimal):