nova_protocol
Nova Protocol Reference
Detailed wire protocol definitions, message formats, and event semantics.
Nova uses a compact framed protocol over a UNIX domain socket. Each frame begins with a fixed-size header, followed by an optional payload.
Nova Frame Header
All messages begin with a NovaFrameHeader:
typedef struct {
uint32_t magic;
uint16_t version;
uint16_t flags;
uint32_t msg_type;
uint32_t payload_size;
} __attribute__((packed)) NovaFrameHeader;
magicmust be0x4E4F5641("NOVA").versionis currently 2.0 but for the forseeable future this will not stop Nova from rejecting frames with other version numbers.flagsis reserved for future use.msg_typeidentifies the request or event type.payload_sizeis the number of bytes following the header.
Request message types (Client → Nova)
| Constant | Meaning |
|---|---|
MSG_CREATE_SURFACE |
Create a new surface. |
MSG_RESIZE_SURFACE |
Request a new shared buffer for resize. |
MSG_MOVE_SURFACE |
Move an existing surface. |
MSG_DAMAGE |
Notify Nova that surface pixels have changed. |
MSG_SET_TITLE |
Update the surface title text. |
MSG_DESTROY_SURFACE |
Destroy a surface and free its resources. |
MSG_SET_INPUT_FOCUS |
(Unused in current implementation) |
MSG_QUERY_SCREEN |
(Unused in current implementation) |
MSG_SET_STATE |
Update surface state flags. |
MSG_SET_ICON |
Update surface icon path. |
MSG_QUERY_WINDOWS |
Request a window list from Nova. |
MSG_SET_FLAGS |
Update surface flags. |
MSG_QUIT |
Ask Nova compositor to exit. |
MSG_GET_SURFACE_GEOMETRY |
Query position and size of an existing surface. |
Event message types (Nova → Client)
| Constant | Meaning |
|---|---|
EVT_KEY |
Keyboard event for the surface. |
EVT_POINTER |
Mouse pointer event for the surface. |
EVT_RESIZE_REQUEST |
Nova asks the client to resize its surface. |
EVT_CLOSE_REQUEST |
Client should close the surface. |
EVT_FOCUS_IN |
Surface gained keyboard focus. |
EVT_FOCUS_OUT |
Surface lost keyboard focus. |
EVT_THEME_UPDATE |
Theme or config reload has occurred. |
EVT_STATE_CHANGED |
The surface state changed. |
EVT_WINDOW_CREATED |
Window list report or overlay notification. |
EVT_WINDOW_DESTROYED |
Window was destroyed. |
EVT_WINDOW_TITLE_CHANGED |
Window title or icon path changed. |
EVT_WINDOW_LIST_END |
End of window query response. |
Core client messages
MSG_CREATE_SURFACE
Payload:
struct {
uint32_t w, h;
uint8_t layer;
uint32_t flags;
} __attribute__((packed));
Reply payload:
struct {
uint32_t surface_id;
char shm_path[108];
} __attribute__((packed));
The `flags` field can configure custom surface traits:
- `SURFACE_FLAG_TRANSPARENT` (`0x1`): Configures the surface to support transparent pixel blending.
- `SURFACE_FLAG_NO_RESIZE` (`0x2`): Disables sizing borders and controls, preventing user resizing of the surface.
Nova allocates a new surface and returns a shared memory path such as /dev/shm/nova_surf_fd%d_%u.
MSG_RESIZE_SURFACE
Payload:
struct {
uint32_t surface_id;
uint32_t w, h;
} __attribute__((packed));
Reply payload:
struct {
char shm_path[108];
} __attribute__((packed));
Nova provides a new shared memory segment for the resized content. Clients must open() and mmap() the returned path before rendering.
MSG_MOVE_SURFACE
Payload:
struct {
uint32_t surface_id;
int x, y;
} __attribute__((packed));
MSG_DAMAGE
Payload:
uint32_t surface_id;
uint32_t rect_count;
NovaRect rects[rect_count];
Notify Nova that one or more rectangles of the surface have changed. Nova will composite the surface contents during the next render pass.
MSG_SET_TITLE
Payload:
struct {
uint32_t surface_id;
char title[128];
} __attribute__((packed));
MSG_SET_ICON
Payload:
struct {
uint32_t surface_id;
char icon_path[256];
} __attribute__((packed));
MSG_SET_STATE
Payload:
struct {
uint32_t surface_id;
uint32_t state_flags;
} __attribute__((packed));
Current Nova behavior uses state_flags & 1 to denote the active/focused state.
MSG_SET_FLAGS
Payload:
struct {
uint32_t surface_id;
uint32_t flags;
} __attribute__((packed));
Updates the surface flags (such as transparent and no-resize options) at runtime.
MSG_DESTROY_SURFACE
Payload:
uint32_t surface_id;
MSG_QUERY_WINDOWS
No payload.
Nova replies with one or more EVT_WINDOW_CREATED events followed by a final EVT_WINDOW_LIST_END event.
MSG_GET_SURFACE_GEOMETRY
Payload:
uint32_t surface_id;
Reply payload:
struct {
uint32_t surface_id;
int x, y;
uint32_t w, h;
} __attribute__((packed));
Requests the current coordinates and dimensions of the specified surface.
MSG_QUIT
No payload.
Instructs the Nova compositor to exit.
Event payloads
EVT_KEY
Payload:
struct {
uint32_t surface_id;
uint32_t keycode;
uint32_t modifiers;
uint8_t pressed;
uint8_t text_len;
char text[5];
uint32_t codepoint;
} __attribute__((packed));
keycodeis a value fromNovaKeycode.modifiersuses bit flags:Shift(0x01),Ctrl(0x02),Alt(0x04),AltGr(0x08),CapsLock(0x10).pressedis1for key down,0for key release.text_lenis the number of valid bytes intext(maximum 4).textis a null-terminated UTF-8 translation of the key event.codepointis the Unicode codepoint representing the key input.
EVT_POINTER
Payload:
struct {
uint32_t surface_id;
int x, y;
uint32_t buttons;
} __attribute__((packed));
Coordinates are relative to the top-left of the surface content region.
EVT_RESIZE_REQUEST
Payload:
struct {
uint32_t surface_id;
uint32_t w, h;
} __attribute__((packed));
Nova sends this when the compositor requests a client to resize its backing store.
EVT_CLOSE_REQUEST, EVT_FOCUS_IN, EVT_FOCUS_OUT, EVT_WINDOW_DESTROYED, EVT_WINDOW_LIST_END
Payload:
uint32_t surface_id;
EVT_WINDOW_CREATED, EVT_WINDOW_TITLE_CHANGED
Payload:
struct {
uint32_t surface_id;
char title[128];
uint32_t state_flags;
char icon_path[256];
} __attribute__((packed));
EVT_STATE_CHANGED
Payload:
struct {
uint32_t surface_id;
uint32_t state_flags;
} __attribute__((packed));
EVT_THEME_UPDATE
No payload in the current implementation, but it is dispatched when Nova reloads theme configuration.
Shared structures
NovaRect
typedef struct {
int x, y;
uint32_t w, h;
} NovaRect;
NovaKeycode
Nova defines a small virtual keycode enum for keyboard events. It includes letters, digits, navigation keys, modifiers, and common control keys.
NovaEvent
Clients receive events through the NovaEvent structure, which includes the event type, the target surface, and event-specific data.
typedef struct {
uint32_t type;
uint32_t surface_id;
union {
struct { int x, y; uint32_t buttons; } pointer;
struct {
uint32_t keycode;
uint32_t modifiers;
uint8_t pressed;
uint8_t text_len;
char text[5];
uint32_t codepoint;
} key;
struct { uint32_t w, h; } resize;
struct { uint32_t state_flags; } state;
struct { char title[128]; uint32_t state_flags; char icon_path[256]; } window;
} data;
} NovaEvent;
Client helper functions
The Nova client library provides these helpers:
nova_connect(const char *socket_path)nova_create_surface(...)nova_resize_surface(...)nova_damage_surface(...)nova_move_surface(...)nova_set_state(...)nova_set_flags(...)nova_set_icon(...)nova_set_title(...)nova_destroy_surface(...)nova_query_windows(...)nova_quit(...)nova_poll_event(...)nova_pending_events(void)
Protocol behavior notes
- Nova uses a simple request/reply pattern for
MSG_CREATE_SURFACEandMSG_RESIZE_SURFACE. - Events may arrive out of order; the client library queues them internally.
nova_pending_events()allows clients to poll previously received events without blocking.MSG_DAMAGEis a hint only. Nova will composite the damage on the next render pass and may merge multiple rectangles.- Clients must not assume the shared memory path remains valid after a resize without re-opening it.
Example: frame header creation
NovaFrameHeader header;
header.magic = NOVA_MAGIC;
header.version = NOVA_VERSION;
header.flags = 0;
header.msg_type = MSG_CREATE_SURFACE;
header.payload_size = sizeof(payload);
Example: receiving events
if (nova_pending_events() || poll(&pfd, 1, timeout) > 0) {
NovaEvent ev;
while (nova_poll_event(fd, &ev) == 0) {
switch (ev.type) {
case EVT_CLOSE_REQUEST:
return;
case EVT_RESIZE_REQUEST:
resize_surface(...);
break;
case EVT_KEY:
handle_key(&ev.data.key);
break;
}
}
}