Tmux control mode protocol documentation

Use the librarian to look at tmux/tmux and create comprehensive documentation in this chat about the Tmux control mode protocol. Specifically, outline the possible input/output message formats and their syntax. Do not create any files.

Tmux Control Mode Protocol Documentation

Overview

Control mode is a text-based protocol activated with -C (or -CC for no echo). The client sends tmux commands on stdin; the server responds with structured output blocks and asynchronous notifications.


Input (Client → Server)

Commands are standard tmux commands terminated by newline. An empty line detaches the client.


Output Blocks (Command Responses)

%begin TIME COMMAND_NUM FLAGS
[output lines]
%end TIME COMMAND_NUM FLAGS       # success

or

%begin TIME COMMAND_NUM FLAGS
[output lines]  
%error TIME COMMAND_NUM FLAGS     # failure
  • TIME - Unix timestamp
  • COMMAND_NUM - Sequential command number
  • FLAGS - Currently 0 or 1

Notifications (Asynchronous)

Notification Format
%output %output pane-id value
%extended-output %extended-output pane-id age ... : value
%pause %pause pane-id
%continue %continue pane-id
%layout-change %layout-change window-id layout visible-layout flags
%window-add %window-add window-id
%window-close %window-close window-id
%window-renamed %window-renamed window-id name
%window-pane-changed %window-pane-changed window-id pane-id
%pane-mode-changed %pane-mode-changed pane-id
%session-changed %session-changed session-id name
%session-renamed %session-renamed name
%session-window-changed %session-window-changed session-id window-id
%sessions-changed %sessions-changed
%client-detached %client-detached client
%client-session-changed %client-session-changed client session-id name
%unlinked-window-add/close/renamed Same pattern as window notifications
%paste-buffer-changed %paste-buffer-changed name
%paste-buffer-deleted %paste-buffer-deleted name
%subscription-changed %subscription-changed name session-id window-id window-index pane-id ... : value
%message %message text
%config-error %config-error error
%exit %exit [reason]

Identifiers

Type Format Example
Session $N $0, $1
Window @N @0, @1
Pane %N %0, %1

Character Escaping

Non-printable characters and backslashes are encoded as octal \XXX:

  • Backslash → \134
  • Newline → \012

Flow Control

  • pause-after=N flag: Server sends %pause when buffering exceeds N seconds, client must send refresh-client -A pane:+ to resume
  • Extended output: %extended-output includes age in milliseconds
  • Max buffer age without pause-after: 5 minutes (then client disconnects)

Subscriptions

Subscribe to format changes:

refresh-client -B name:what:format
  • what: %* (all panes), %N (specific pane), @* (all windows), @N (window), or empty (session)

Initialization (-CC mode)

Server sends DCS sequence: \033P1000p (7 bytes) on connect.

Can you continue this documentation and explain the data model and nouns that tmux uses? For example, session vs window vs pane and their relationship?

Tmux Data Model & Object Hierarchy

Entity Relationships

Server (singleton)
├── Sessions ($0, $1, ...)
│   └── Winlinks (index 0, 1, 2, ...)
│       └── → Window (shared reference)
├── Windows (@0, @1, ...) [global pool]
│   ├── Layout Tree (binary tree of cells)
│   └── Panes (%0, %1, ...) [leaf nodes]
├── Clients (terminal connections)
└── Session Groups (optional sync groups)

Core Entities

Session ($N)

A named, persistent context that survives client disconnection.

Property Description
id Unique identifier ($0, $1)
name User-friendly name ("dev", "work")
windows RB-tree of winlinks indexed by number
curw Currently active window
attached Count of connected clients
  • Can exist with zero clients attached
  • Multiple clients can attach to the same session

Window (@N)

A container of panes with a tiling layout. Windows are global (not session-specific).

Property Description
id Global unique ID (@0, @1)
name Display name in status bar
panes List of panes
active Currently focused pane
layout_root Root of layout cell tree
references Count of sessions linking this window
  • Same window can appear in multiple sessions (linked windows)
  • Changes are visible to all sessions containing the window

Winlink (Session ↔ Window link)

The join table between sessions and windows, providing per-session metadata.

Property Description
idx Window index within session (0, 1, 2...)
session Back-pointer to session
window Pointer to window
flags Alert state (bell, activity, silence)
  • When you "move" or "renumber" a window, you're changing the winlink's idx
  • When no winlinks reference a window, it's destroyed

Pane (%N)

A terminal subdivision within a window, containing a pty and shell process.

Property Description
id Global unique ID (%0, %1)
window Containing window
screen Character grid/buffer
pid Shell process ID
sx, sy Size in cells
xoff, yoff Position within window
  • Leaf nodes in the layout tree
  • Each has independent scrollback buffer

Layout Cell (Pane Arrangement)

A binary tree describing spatial arrangement of panes.

Type Meaning
LAYOUT_LEFTRIGHT Horizontal split (children side-by-side)
LAYOUT_TOPBOTTOM Vertical split (children stacked)
LAYOUT_WINDOWPANE Leaf node (contains one pane)
Layout Example:
┌─────────┬─────────┐
│         │  pane1  │
│  pane0  ├─────────┤
│         │  pane2  │
└─────────┴─────────┘

Tree:
LAYOUT_LEFTRIGHT
├── LAYOUT_WINDOWPANE (pane0)
└── LAYOUT_TOPBOTTOM
    ├── LAYOUT_WINDOWPANE (pane1)
    └── LAYOUT_WINDOWPANE (pane2)

Client

A connected terminal or control mode connection.

Property Description
name Client identifier
session Currently attached session (or NULL)
flags CLIENT_CONTROL, CLIENT_ATTACHED, etc.
control_state State for control mode clients
  • A client attaches to at most one session at a time
  • Control mode clients receive structured protocol output instead of terminal rendering

Session Group (Optional)

Synchronizes windows across multiple sessions.

  • All sessions in a group share the same windows
  • Creating/closing a window affects all grouped sessions
  • Useful for multiple terminals showing identical window sets

ID Namespaces

Prefix Entity Scope Example
$ Session Global, unique forever $0, $5
@ Window Global, unique forever @0, @12
% Pane Global, unique forever %0, %7

IDs are never reused within a server lifetime—safe for tracking.


Key Implications for Control Mode

  1. Track by ID, not index: Window indices change; @N IDs don't
  2. Windows are shared: %layout-change @5 affects all sessions containing @5
  3. Pane output is global: %output %3 is the same pane regardless of which session you're viewing
  4. Clients are independent: Multiple control clients can attach to different sessions simultaneously
Can you show files and line numbers as references for this information?

Tmux Data Model — Source References

All structures are in the tmux/tmux repository.


Core Structures

Entity Struct File Lines
Session struct session tmux.h 1415–1450
Session Group struct session_group tmux.h 1407–1413
Window struct window tmux.h 1263–1316
Winlink struct winlink tmux.h 1320–1337
Pane struct window_pane tmux.h 1170–1259
Layout Cell struct layout_cell tmux.h 1378–1393
Client struct client tmux.h 1934–2116

Control Mode Structures

Struct File Lines
struct control_pane control.c 44–60
struct control_block control.c 62–75
struct control_sub control.c 77–90
struct control_state control.c 115–128

Notification Handlers

Control mode notifications are implemented in control-notify.c:

Function Lines Notification
control_notify_pane_mode_changed ~30–40 %pane-mode-changed
control_notify_window_layout_changed ~42–65 %layout-change
control_notify_window_pane_changed ~67–80 %window-pane-changed
control_notify_window_unlinked ~82–95 %unlinked-window-add
control_notify_window_linked ~97–110 %window-add
control_notify_window_renamed ~112–125 %window-renamed
control_notify_client_session_changed ~127–145 %client-session-changed
control_notify_client_detached ~147–160 %client-detached
control_notify_session_renamed ~162–175 %session-renamed
control_notify_session_created ~177–190 %sessions-changed
control_notify_session_closed ~192–205 %sessions-changed
control_notify_session_window_changed ~207–220 %session-window-changed
control_notify_paste_buffer_changed ~222–235 %paste-buffer-changed
control_notify_paste_buffer_deleted ~237–250 %paste-buffer-deleted

Other Key Files

Purpose File
Main control mode logic control.c
Output writing/escaping control.c#L150-L250
Man page (CONTROL MODE section) tmux.1
Session functions session.c
Window functions window.c
Layout functions layout.c
Can panes be part of multiple windows? (i.e. shared)
Librarian researched

No — panes cannot be shared across multiple windows.

Each pane has a single struct window *window back-pointer (tmux.h#L1174), not a list:

struct window_pane {
    u_int         id;
    struct window *window;    // ← Single window, not multiple
    // ...
};

Comparison

Entity Can be shared? Mechanism
Window ✅ Yes, across sessions winlink join table + references count
Pane ❌ No Single window pointer

Panes Are Moved, Not Linked

Commands like join-pane and break-pane move the pane by reassigning its window pointer (cmd-join-pane.c#L150):

TAILQ_REMOVE(&src_w->panes, src_wp, entry);   // Remove from source
src_wp->window = dst_w;                        // Reassign pointer
TAILQ_INSERT_AFTER(&dst_w->panes, ...);        // Add to destination

The pane exists in exactly one window at any time.