Replace the single file-structure.md with a stratified layout designed
for AI/agent skill consumption: tables and concrete identifiers over
prose, files loaded on demand, content separated by churn rate.
Layers:
- architecture/ stable structural reference (overview, source-map,
test-map, data-flow)
- patterns/ memory, commands, autocomplete, events, xmpp,
encryption, ui, plugins
- testing/ unit-tests, stubs, functional-tests, bench
- build/ local, docker, ci
- playbooks/ add-command, add-test, add-autocomplete,
add-event-handler, add-encryption
- gotchas.md append-only dated entries (seven seed entries)
- wip/ branch-specific notes; deleted on merge to master
Stable layers describe cproof on master only. In-flight feature
branches (currently feat/ai) get a single file under wip/.
INDEX.md is the entry map with churn labels; SKILL.md is the
always-loaded skill hint pointing to it.
2.3 KiB
UI
src/ui/ is built on ncurses (wide-char). It owns windows, the input line,
status/title bars, and tray notifications.
Window types
| File | Window | Notes |
|---|---|---|
chatwin.c |
One-on-one chat | One per peer JID. |
mucwin.c |
MUC room | Tracks occupants list, subject, role. |
privwin.c |
MUC private chat | Per-occupant private window inside a room. |
console.c |
Console | Always present, index 1; system messages. |
confwin.c |
Form / config | Used for ad-hoc commands and data forms. |
xmlwin.c |
XML console | Raw stanza tracer. |
vcardwin.c |
vCard view | Read-only viewer. |
win_types.h declares the window-type enum used to discriminate at runtime.
window.c/h is the base type; window_list.c/h manages the open-windows
collection.
Buffers
buffer.c/h — append-only ring of rendered lines per window. UI rendering
reads from the buffer; chatlog persists separately.
Bars and chrome
| File | Role |
|---|---|
statusbar.c/h |
Bottom status line (window list, unread counts). |
titlebar.c/h |
Top bar (current window title, encryption state). |
tray.c/h |
System-tray notifications via libnotify. |
screen.c/h |
Screen-level helpers (resize, refresh). |
notifier.c |
Sound and visual notifications dispatch. |
inputwin.c/h |
Input line: line editor, history, completion trigger. |
core.c |
UI lifecycle (init / shutdown / refresh loop). |
Roster panel
rosterwin.c and occupantswin.c render the side panels (roster and MUC
occupants). They subscribe to roster / muc state changes via the event layer.
Input → completion
inputwin.c calls into cmd_ac.c on Tab. See patterns/autocomplete.md for
how that flow continues.
Conventions
- Public UI calls used from outside
src/ui/:cons_show("...")— formatted line into the console.cons_bad_cmd_usage(cmd)— print canonical "wrong usage" line.chatwin_*,mucwin_*,privwin_*— write into a specific window type.
- UI code does not block on XMPP. State queries go through getters in
src/xmpp/andsrc/config/. - Color / theme lookups go through
src/config/color.candsrc/config/theme.c— do not hardcode ncurses attribute pairs.
Testing
UI is heavily stubbed in unit tests — see tests/unittests/ui/stub_ui.c and
sibling stubs. Real ncurses calls do not run under make check.