![]() |
libghostty
|
Represents the state required to render a visible screen (a viewport) of a terminal instance. This is stateful and optimized for repeated updates from a single terminal instance and only updating dirty regions of the screen.
The key design principle of this API is that it only needs read/write access to the terminal instance during the update call. This allows the render state to minimally impact terminal IO performance and also allows the renderer to be safely multi-threaded (as long as a lock is held during the update call to ensure exclusive access to the terminal instance).
The basic usage of this API is:
For callers that synchronize terminal access (e.g. a renderer thread sharing a lock with an IO thread), the update can be split into two phases to minimize the time the terminal must be held exclusively: ghostty_render_state_begin_update requires terminal access, while ghostty_render_state_end_update completes any deferred work using only memory owned by the render state. A typical renderer would lock, begin the update, unlock, and then end the update while the IO thread is free to continue modifying the terminal. ghostty_render_state_update is a convenience that performs both phases in one call.
Dirty tracking is a key feature of the render state that allows renderers to efficiently determine what parts of the screen have changed and only redraw changed regions.
The render state API keeps track of dirty state at two independent layers: a global dirty state that indicates whether the entire frame is clean, partially dirty, or fully dirty, and a per-row dirty state that allows tracking which rows in a partially dirty frame have changed.
The user of the render state API is expected to unset both of these. The update call does not unset dirty state, it only updates it. After successfully rendering a complete frame, use ghostty_render_state_clean() to unset both layers in one call. The granular setters remain available for callers that only consume part of a frame.
An extremely important detail: setting one dirty state doesn't unset the other. For example, setting the global dirty state to false does not reset the row-level dirty flags. So, the caller of the render state API must be careful to manage both layers of dirty state correctly.
A program can ask the terminal to stop updating the screen while it draws a frame, so the user never sees a half-drawn one. Today programs do this with synchronized output (DEC private mode 2026).
ghostty_render_state_update() does not check for this. It always captures the terminal as it is right now, so a renderer that updates on every draw will show half-drawn frames. To avoid that:
See GhosttyTerminalRenderHoldFn for the details and a complete example.
By default, the render state captures exactly the rows visible in the viewport. That is all a renderer needs when it draws whole rows.
Some renderers draw the grid shifted by a fraction of a row, most commonly to scroll smoothly. While the grid is shifted, part of a row just outside the viewport becomes visible at one edge, and the renderer needs that row's content to draw it. Overscan asks the render state to capture extra rows above and below the viewport for this purpose.
Request overscan with GHOSTTY_RENDER_STATE_OPTION_OVERSCAN. The request applies to every update after it is set. The row iterator then visits the extra rows along with the viewport, from top to bottom: the rows above the viewport, the viewport rows, and then the rows below it. GHOSTTY_RENDER_STATE_ROW_DATA_VIEWPORT_Y tells you where each row belongs. Rows above the viewport have negative values, viewport rows are 0 through rows - 1, and rows below the viewport start at rows.
Extra rows are only captured when they exist. There is nothing above the first line of scrollback, and there is nothing below the viewport while it is scrolled to the bottom, which is the usual case. After an update, GHOSTTY_RENDER_STATE_DATA_OVERSCAN reports how many rows were actually captured on each side. Don't shift the grid toward a side where nothing was captured.
Extra rows carry the same data as viewport rows, including cells, styles, dirty flags, and selection. The cursor is only reported when it is inside the viewport.
The render state doesn't store the scroll position. If you need it, read GHOSTTY_TERMINAL_DATA_SCROLLBAR or GHOSTTY_TERMINAL_DATA_VIEWPORT_ACTIVE with ghostty_terminal_get() at the same time as you call ghostty_render_state_begin_update(), while you have exclusive access to the terminal. The values then describe the same moment as the render state.
This example draws one frame of a smooth scroll. offset_px comes from the renderer's own scroll animation. It is how far the grid is shifted up, from zero up to but not including one row height.
Every row has an id (GHOSTTY_RENDER_STATE_ROW_DATA_ID) that stays with the row as it moves. When the viewport scrolls by one row, each row shows up one position higher or lower in the next update but keeps its id. Ids work with or without overscan.
Ids let a renderer keep expensive per-row work, such as shaped text or a prepared texture, in its own cache keyed by id. A cached entry can be reused when both of these are true:
The dirty flag is conservative. A row may be marked dirty even though its content didn't change. For example, every row is currently marked dirty after the viewport scrolls. Rebuilding a dirty row is always correct.
An id disappears when its row is no longer captured, is removed from scrollback, or is changed in place by the terminal (for example, when a program scrolls only part of the screen). Ids are never reused, so an old id can never match a different row. Cache entries for ids that no longer appear can be discarded.
Programs can show images in a terminal through image protocols, such as the Kitty graphics protocol. The render state gives you the images to draw as a list of image placements, which you read with a GhosttyRenderStateImageIterator. Each placement is one rectangle of one image:
These values mean the same thing for every protocol, so one drawing routine handles all of them. The only part that depends on the protocol is getting the image's pixels. Use the placement's protocol to pick the right storage, and its image ID to look the image up. For GHOSTTY_IMAGE_PROTOCOL_KITTY, that is ghostty_kitty_graphics_image().
The list holds every Kitty graphics image on screen:
Earlier versions left some of these images out, so renderers had to draw them from the Kitty graphics placement iterator. That is no longer needed. If your renderer still draws images from that iterator, stop, or those images are drawn twice.
An image is in the list when any part of it is in the captured rows (the viewport plus any overscan rows). Images shown with placeholder cells are split into one placement per row of cells, so each of those placements is always inside the captured rows.
Every other placement is reported at its full size, even when only part of it can be seen. Its GHOSTTY_RENDER_STATE_IMAGE_DATA_VIEWPORT_COL can be negative, and its GHOSTTY_RENDER_STATE_IMAGE_DATA_VIEWPORT_ROW can be above the first overscan row. It can also extend past the right or bottom edge. Clip it to the area you draw. Most graphics APIs can do this for you with a scissor or clip rectangle.
For example, with no overscan, an image 4 rows tall whose top row scrolled 2 rows above the viewport has a row of -2 and covers 4 rows. Draw it at its full size starting 2 rows above the viewport, clipped to the viewport. Its bottom 2 rows show at the top of the viewport.
A program can place a Kitty image at a cell on the screen. The image is attached to that cell, so it moves when the text moves: when new output scrolls the screen, when a program scrolls part of the screen, and when the viewport scrolls through the scrollback.
The render state finds the position of these images during each update, so you don't need to track the cells yourself. This costs very little on a typical frame, including frames where the viewport scrolls.
Later versions may add more protocols and more kinds of placements. Skip any placement whose protocol you don't support, so that your renderer keeps working when that happens.
The Kitty graphics protocol lets a program place an image with text. The program creates a virtual placement, which has no position of its own, and then prints placeholder characters (U+10EEEE) wherever the image should appear. Each placeholder cell says which image it shows and which piece of that image belongs in the cell. Programs such as tmux use this so that images scroll, move and disappear along with the text around them.
Since the cells decide where these images go, the Kitty graphics storage alone can't tell you where to draw them. The render state works this out for you during each update. It finds the placeholder cells, groups neighboring cells that show the same image into runs, and calculates which part of the image each run shows. It only looks at rows that changed, so this costs very little on a typical frame.
A virtual placement usually turns into several placements in the list, one for each row of placeholder cells. For example, an image shown in a block of 10 columns by 4 rows of placeholders gives 4 placements, each 10 cells wide and 1 cell tall, and each drawing a quarter of the image. Drawn together, they form the whole image.
A program can also place a Kitty image relative to another placement, its parent. The image is drawn a number of cells to the right of and below its parent. Negative numbers move it left or up. The parent can be relative to another placement too, so placements can form a chain.
The render state follows the chain to the placement at its start and positions the image from there:
For example, an image placed 3 columns right of and 2 rows below a parent at column 2, row 1 is drawn at column 5, row 3. Like other placements, it is in the list when any part of it is in the captured rows, even if its parent isn't.
Most frames don't change any image. A program prints text or moves the cursor, and every image stays where it was. You don't need to read the iterator again on those frames. After each update, read GHOSTTY_RENDER_STATE_DATA_IMAGE_PLACEMENTS_GENERATION and compare it with the value from the last time you read the list. If the two match, the list is the same as before, and you can keep drawing what you built last time:
The value changes when an update adds or removes an image, moves one, changes which part of one is shown, or changes the pixels of one. It stays the same when only text changes, as long as the changed rows had no Kitty placeholder cells before or after the change. (See "Kitty Graphics Placeholders" above for what those are.)
A new value means "read the list again". It doesn't promise that anything on screen moved. The value can change even when every image ends up exactly where it was, for example:
Only compare the value for equality. It wraps around, so a larger value doesn't mean a newer one. It is always 0 when Kitty graphics are disabled.
Don't confuse this value with GHOSTTY_RENDER_STATE_IMAGE_DATA_IMAGE_GENERATION. That one belongs to a single image and tells you when to upload its pixels again. This one belongs to the whole list and tells you when to read the list again.
Typedefs | |
| typedef struct GhosttyRenderStateImpl * | GhosttyRenderState |
| typedef struct GhosttyRenderStateRowIteratorImpl * | GhosttyRenderStateRowIterator |
| typedef struct GhosttyRenderStateRowCellsImpl * | GhosttyRenderStateRowCells |
| typedef struct GhosttyRenderStateImageIteratorImpl * | GhosttyRenderStateImageIterator |
Data Structures | |
| struct | GhosttyRenderStateOverscan |
| struct | GhosttyRenderStateRowId |
| struct | GhosttyRenderStateRowSelection |
| struct | GhosttyRenderStateCursor |
| struct | GhosttyRenderStateColors |
| typedef struct GhosttyRenderStateImpl* GhosttyRenderState |
Opaque handle to a render state instance.
| typedef struct GhosttyRenderStateImageIteratorImpl* GhosttyRenderStateImageIterator |
Opaque handle to an iterator over the image placements of a render state.
| typedef struct GhosttyRenderStateRowCellsImpl* GhosttyRenderStateRowCells |
| typedef struct GhosttyRenderStateRowIteratorImpl* GhosttyRenderStateRowIterator |
| enum GhosttyImageProtocol |
The image protocols that a terminal supports.
The render state uses this to say which protocol each image placement came from (see GHOSTTY_RENDER_STATE_IMAGE_DATA_PROTOCOL). Use it to decide where to read the image's pixels. Unlike the other image types here, the name has no RenderState prefix, because the protocol isn't specific to the render state.
New protocols may be added in later versions. Skip placements with a protocol you don't support.
| Enumerator | |
|---|---|
| GHOSTTY_IMAGE_PROTOCOL_KITTY | The Kitty graphics protocol. Read the image with ghostty_kitty_graphics_image(). |
Visual style of the cursor.
Queryable data kinds for ghostty_render_state_get().
| Enumerator | |
|---|---|
| GHOSTTY_RENDER_STATE_DATA_INVALID | Invalid / sentinel value. |
| GHOSTTY_RENDER_STATE_DATA_COLS | Viewport width in cells (uint16_t). |
| GHOSTTY_RENDER_STATE_DATA_ROWS | Viewport height in cells (uint16_t). This does not include overscan rows. |
| GHOSTTY_RENDER_STATE_DATA_DIRTY | Current dirty state (GhosttyRenderStateDirty). |
| GHOSTTY_RENDER_STATE_DATA_ROW_ITERATOR | Populate a pre-allocated GhosttyRenderStateRowIterator with row data from the render state (GhosttyRenderStateRowIterator). Row data is only valid as long as the underlying render state is not updated. It is unsafe to use row data after updating the render state. The iterator visits every row the last update captured, from top to bottom. This is exactly the viewport unless overscan was requested with GHOSTTY_RENDER_STATE_OPTION_OVERSCAN. |
| GHOSTTY_RENDER_STATE_DATA_COLOR_BACKGROUND | Default/current background color (GhosttyColorRgb). |
| GHOSTTY_RENDER_STATE_DATA_COLOR_FOREGROUND | Default/current foreground color (GhosttyColorRgb). |
| GHOSTTY_RENDER_STATE_DATA_COLOR_CURSOR | Cursor color when explicitly set by terminal state (GhosttyColorRgb). Returns GHOSTTY_INVALID_VALUE if no explicit cursor color is set; use COLOR_CURSOR_HAS_VALUE to check first. |
| GHOSTTY_RENDER_STATE_DATA_COLOR_CURSOR_HAS_VALUE | Whether an explicit cursor color is set (bool). |
| GHOSTTY_RENDER_STATE_DATA_COLOR_PALETTE | The active 256-color palette (GhosttyColorRgb[256]). |
| GHOSTTY_RENDER_STATE_DATA_CURSOR_VISUAL_STYLE | The visual style of the cursor (GhosttyRenderStateCursorVisualStyle). |
| GHOSTTY_RENDER_STATE_DATA_CURSOR_VISIBLE | Whether the cursor is visible based on terminal modes (bool). |
| GHOSTTY_RENDER_STATE_DATA_CURSOR_BLINKING | Whether the cursor should blink based on terminal modes (bool). |
| GHOSTTY_RENDER_STATE_DATA_CURSOR_PASSWORD_INPUT | Whether the cursor is at a password input field (bool). |
| GHOSTTY_RENDER_STATE_DATA_CURSOR_VIEWPORT_HAS_VALUE | Whether the cursor is visible within the viewport (bool). If false, the cursor viewport position values are undefined. |
| GHOSTTY_RENDER_STATE_DATA_CURSOR_VIEWPORT_X | Cursor viewport x position in cells (uint16_t). Only valid when CURSOR_VIEWPORT_HAS_VALUE is true. |
| GHOSTTY_RENDER_STATE_DATA_CURSOR_VIEWPORT_Y | Cursor viewport y position in cells (uint16_t). Only valid when CURSOR_VIEWPORT_HAS_VALUE is true. |
| GHOSTTY_RENDER_STATE_DATA_CURSOR_VIEWPORT_WIDE_TAIL | Whether the cursor is on the tail of a wide character (bool). Only valid when CURSOR_VIEWPORT_HAS_VALUE is true. |
| GHOSTTY_RENDER_STATE_DATA_CURSOR | All cursor state in one sized struct (GhosttyRenderStateCursor). Initialize the output with GHOSTTY_INIT_SIZED before querying. |
| GHOSTTY_RENDER_STATE_DATA_COLORS | All render-state colors in one sized struct (GhosttyRenderStateColors). Initialize the output with GHOSTTY_INIT_SIZED before querying. |
| GHOSTTY_RENDER_STATE_DATA_OVERSCAN | How many overscan rows the last update captured on each side (GhosttyRenderStateOverscan). This is never more than the request. It is less when those rows don't exist: above is smaller near the top of the scrollback, and below is zero while the viewport is scrolled to the bottom. |
| GHOSTTY_RENDER_STATE_DATA_OVERSCAN_REQUEST | The overscan request most recently set with GHOSTTY_RENDER_STATE_OPTION_OVERSCAN (GhosttyRenderStateOverscan). The next update uses this request. Both sides are zero if it was never set. |
| GHOSTTY_RENDER_STATE_DATA_IMAGE_ITERATOR | Populate an existing GhosttyRenderStateImageIterator with the image placements found by the last update. See "Images" in the render state overview. |
| GHOSTTY_RENDER_STATE_DATA_IMAGE_PLACEMENTS_GENERATION | A value (uint64_t) that changes whenever an update changes the placements that GHOSTTY_RENDER_STATE_DATA_IMAGE_ITERATOR returns. If it matches the value from the last time you read the iterator, the placements are the same and you don't need to read them again. See "Knowing When Images Changed" in the render state overview for an example and for exactly when the value changes. The value belongs to the whole list. To know when the pixels of a single image changed, use GHOSTTY_RENDER_STATE_IMAGE_DATA_IMAGE_GENERATION. Only compare the value for equality. It is always 0 when Kitty graphics are disabled. |
Dirty state of a render state after update.
Data you can read about the current placement of an image iterator with ghostty_render_state_image_get().
The type in parentheses is the type that the out pointer must point to. All pixel values use the cell size set with ghostty_terminal_resize().
Some values only apply to one protocol, and have the protocol in their name. For example, GHOSTTY_RENDER_STATE_IMAGE_DATA_KITTY_KIND only applies to Kitty graphics placements. Reading one of these for a placement from another protocol returns GHOSTTY_NO_VALUE.
| Enumerator | |
|---|---|
| GHOSTTY_RENDER_STATE_IMAGE_DATA_INVALID | Invalid value. Querying it returns GHOSTTY_INVALID_VALUE. |
| GHOSTTY_RENDER_STATE_IMAGE_DATA_PROTOCOL | The protocol the image came from (GhosttyImageProtocol). |
| GHOSTTY_RENDER_STATE_IMAGE_DATA_IMAGE_ID | The ID of the image to draw (uint32_t). IDs are only unique within one protocol, so look the image up in the storage of its protocol. For Kitty graphics, use ghostty_kitty_graphics_image(). |
| GHOSTTY_RENDER_STATE_IMAGE_DATA_IMAGE_GENERATION | The generation of the image's contents (uint64_t). It changes whenever the image's pixels change, including when an animation moves to a new frame. Use it as part of your texture cache key, with the protocol and image ID: if it matches the texture you have, you don't need to read the pixels again. For Kitty graphics, this is the same value as GHOSTTY_KITTY_IMAGE_DATA_GENERATION. To know when the list of placements as a whole changed, use GHOSTTY_RENDER_STATE_DATA_IMAGE_PLACEMENTS_GENERATION. |
| GHOSTTY_RENDER_STATE_IMAGE_DATA_LAYER | The layer to draw the image in (GhosttyRenderStateImageLayer). |
| GHOSTTY_RENDER_STATE_IMAGE_DATA_Z | The z-index (int32_t), which orders images within a layer. Images with a lower z-index are drawn first. The value comes from the image's protocol. For Kitty graphics, it is the z-index the program asked for, and virtual placements are always -1. |
| GHOSTTY_RENDER_STATE_IMAGE_DATA_VIEWPORT_COL | The column of the top-left cell (int32_t), where 0 is the leftmost column of the viewport. Fixed and relative placements are reported at their full size, so they can start to the left of the viewport, which gives a negative value. Virtual placements never do. See "Images Partly Outside the Captured Rows" in the Render State documentation. |
| GHOSTTY_RENDER_STATE_IMAGE_DATA_VIEWPORT_ROW | The row of the top-left cell (int32_t), where 0 is the top row of the viewport. A placement in an overscan row above the viewport has a negative row, the same as GHOSTTY_RENDER_STATE_ROW_DATA_VIEWPORT_Y. Fixed and relative placements are reported at their full size, so they can also start above the first overscan row. Virtual placements are always inside the captured rows. See "Images Partly Outside the Captured Rows" in the Render State documentation. |
| GHOSTTY_RENDER_STATE_IMAGE_DATA_GRID_COLS | The number of columns of cells the placement covers (uint32_t). |
| GHOSTTY_RENDER_STATE_IMAGE_DATA_GRID_ROWS | The number of rows of cells the placement covers (uint32_t). |
| GHOSTTY_RENDER_STATE_IMAGE_DATA_CELL_OFFSET_X | How far the image starts from the left edge of the top-left cell, in pixels (uint32_t). For a virtual placement, an image that is narrower than its cells is centered, so this can be larger than a cell is wide. For fixed and relative placements, this is the offset the program asked for, limited to less than one cell. |
| GHOSTTY_RENDER_STATE_IMAGE_DATA_CELL_OFFSET_Y | How far the image starts from the top edge of the top-left cell, in pixels (uint32_t). For a virtual placement, an image that is shorter than its cells is centered, so this can be larger than a cell is tall. For fixed and relative placements, this is the offset the program asked for, limited to less than one cell. |
| GHOSTTY_RENDER_STATE_IMAGE_DATA_PIXEL_WIDTH | The width to draw the image at, in pixels (uint32_t). |
| GHOSTTY_RENDER_STATE_IMAGE_DATA_PIXEL_HEIGHT | The height to draw the image at, in pixels (uint32_t). |
| GHOSTTY_RENDER_STATE_IMAGE_DATA_SOURCE_X | The left edge of the part of the image to draw, in image pixels (uint32_t). |
| GHOSTTY_RENDER_STATE_IMAGE_DATA_SOURCE_Y | The top edge of the part of the image to draw, in image pixels (uint32_t). |
| GHOSTTY_RENDER_STATE_IMAGE_DATA_SOURCE_WIDTH | The width of the part of the image to draw, in image pixels (uint32_t). Scale it to PIXEL_WIDTH when drawing. |
| GHOSTTY_RENDER_STATE_IMAGE_DATA_SOURCE_HEIGHT | The height of the part of the image to draw, in image pixels (uint32_t). Scale it to PIXEL_HEIGHT when drawing. |
| GHOSTTY_RENDER_STATE_IMAGE_DATA_KITTY_PLACEMENT_ID | Kitty graphics only: the placement ID (uint32_t), or 0 if there isn't one. For a virtual placement, this is the placement ID that the placeholder cells ask for. Cells that don't ask for one show the image's virtual placement, whichever it is, and report 0. For a fixed or relative placement, this is the ID the program gave it, or 0 if it didn't give one. |
| GHOSTTY_RENDER_STATE_IMAGE_DATA_KITTY_KIND | Kitty graphics only: the kind of placement (GhosttyRenderStateKittyPlacementKind). |
Where an image is drawn relative to the terminal's text.
Draw the layers in this order: every image below backgrounds, then cell backgrounds, then images below text, then text, then images above text. Within a layer, draw images in order of their z-index, lowest first.
The kinds of Kitty graphics placements in a render state's image list.
Read with GHOSTTY_RENDER_STATE_IMAGE_DATA_KITTY_KIND. Most renderers can draw every kind the same way. The kind is useful when you need to tell them apart, for example for debugging.
| Enumerator | |
|---|---|
| GHOSTTY_RENDER_STATE_KITTY_PLACEMENT_KIND_VIRTUAL | Part of a virtual placement: one run of neighboring placeholder cells in a single row. It is always one row tall. |
| GHOSTTY_RENDER_STATE_KITTY_PLACEMENT_KIND_RELATIVE | A placement that a program positioned relative to another placement, its parent. Kitty graphics lets a program attach one image to another so that they move together. The parent is either a virtual or a fixed placement, possibly through a chain of other relative placements. With a virtual parent, the position depends on the placeholder cells. It is measured from the top-left corner of the parent's cells on screen. That is the leftmost column and the topmost row that any of its cells use, which matches Kitty. If none of those cells are in the captured rows (the viewport plus any overscan), the relative placement is not included. With a fixed parent, the position is measured from the parent's cell. The relative placement is included at its full size when any part of it is in the captured rows, even if the parent isn't, so it may need to be clipped when drawn. See "Kitty Graphics Relative Placements" in the Render State documentation. |
| GHOSTTY_RENDER_STATE_KITTY_PLACEMENT_KIND_FIXED | A placement at a cell on the screen. It scrolls with the text, like a line of output would. Its z-index is the one the program chose, so it can be in any layer. It is included at its full size when any part of it is in the captured rows, so it may need to be clipped when drawn. See "Images Partly Outside the Captured Rows" in the Render State documentation. |
Settable options for ghostty_render_state_set().
| Enumerator | |
|---|---|
| GHOSTTY_RENDER_STATE_OPTION_DIRTY | Set dirty state (GhosttyRenderStateDirty). |
| GHOSTTY_RENDER_STATE_OPTION_OVERSCAN | Request overscan rows above and below the viewport (GhosttyRenderStateOverscan). The request takes effect on the next update and stays in effect until it is changed. Both sides are zero by default, which captures only the viewport. The rows of the last update can still be read after changing the request. Expect a full redraw on the update after a change. See "Overscan" in the render state overview. |
Queryable data kinds for ghostty_render_state_row_cells_get().
| Enumerator | |
|---|---|
| GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_INVALID | Invalid / sentinel value. |
| GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_RAW | The raw cell value (GhosttyCell). |
| GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_STYLE | The style for the current cell (GhosttyStyle). |
| GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_GRAPHEMES_LEN | The total number of grapheme codepoints including the base codepoint (uint32_t). Returns 0 if the cell has no text. |
| GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_GRAPHEMES_BUF | Write grapheme codepoints into a caller-provided buffer (uint32_t*). The buffer must be at least graphemes_len elements. The base codepoint is written first, followed by any extra codepoints. |
| GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_BG_COLOR | The resolved background color of the cell (GhosttyColorRgb). Flattens the three possible sources: content-tag bg_color_rgb, content-tag bg_color_palette (looked up in the palette), or the style's bg_color. Returns GHOSTTY_INVALID_VALUE if the cell has no background color, in which case the caller should use whatever default background color it wants (e.g. the terminal background). |
| GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_FG_COLOR | The resolved foreground color of the cell (GhosttyColorRgb). Resolves palette indices through the palette. Bold color handling is not applied; the caller should handle bold styling separately. Returns GHOSTTY_INVALID_VALUE if the cell has no explicit foreground color, in which case the caller should use whatever default foreground color it wants (e.g. the terminal foreground). |
| GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_SELECTED | Whether the cell is contained within the current selection (bool). This returns true when the cell's column is within the current row's row-local selection range, and false otherwise. Rendering policy for selected cells (colors, inversion, etc.) is left to the caller. Renderers that can draw cells in spans may be more efficient querying GHOSTTY_RENDER_STATE_ROW_DATA_SELECTION once per row and applying that range directly, avoiding one C API call per cell for selection state. |
| GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_HAS_STYLING | Whether the cell has any explicit styling (bool). This is equivalent to querying the raw cell's GHOSTTY_CELL_DATA_HAS_STYLING value, but avoids materializing the raw GhosttyCell for renderers that only need to know whether fetching the full style is necessary. |
| GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_GRAPHEMES_UTF8 | Encode the current cell's full grapheme cluster as UTF-8 into a caller-provided buffer (GhosttyBuffer). The base codepoint is encoded first, followed by any extra grapheme codepoints. Returns GHOSTTY_SUCCESS with len=0 when the cell has no text. If ptr is NULL or cap is too small for a non-empty cell, returns GHOSTTY_OUT_OF_SPACE without writing any bytes and sets len to the required buffer size in bytes. |
Queryable data kinds for ghostty_render_state_row_get().
| Enumerator | |
|---|---|
| GHOSTTY_RENDER_STATE_ROW_DATA_INVALID | Invalid / sentinel value. |
| GHOSTTY_RENDER_STATE_ROW_DATA_DIRTY | Whether the current row is dirty (bool). |
| GHOSTTY_RENDER_STATE_ROW_DATA_RAW | The raw row value (GhosttyRow). |
| GHOSTTY_RENDER_STATE_ROW_DATA_CELLS | Populate a pre-allocated GhosttyRenderStateRowCells with cell data for the current row (GhosttyRenderStateRowCells). Cell data is only valid as long as the underlying render state is not updated. It is unsafe to use cell data after updating the render state. |
| GHOSTTY_RENDER_STATE_ROW_DATA_SELECTION | Row-local selected cell range (GhosttyRenderStateRowSelection). |
| GHOSTTY_RENDER_STATE_ROW_DATA_CELLS_RAW | A borrowed view of the raw cell values for the current row (GhosttyCellsView). One value per column, identical to querying GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_RAW for each cell. The view is only valid as long as the underlying render state is not updated; it is unsafe to use after updating the render state. This is the bulk alternative to iterating cells one at a time. It lets callers with expensive call boundaries (e.g. WebAssembly embedders) read an entire row with a single call. Bit positions aren't protected by ABI, so callers should parse them out of the manifest from ghostty_type_json. Callers with access to the C header or without high FFI costs should use ghostty_cell_get. |
| GHOSTTY_RENDER_STATE_ROW_DATA_VIEWPORT_Y | The row's position relative to the top of the viewport (int32_t). Viewport rows are 0 through rows - 1. Overscan rows above the viewport are negative, and overscan rows below it start at rows. Without overscan, this equals the y reported by ghostty_render_state_row_iterator_next_dirty(). |
| GHOSTTY_RENDER_STATE_ROW_DATA_ID | The row's identity across updates (GhosttyRenderStateRowId). This works with or without overscan. See "Row Identity" in the render state overview. |
Settable options for ghostty_render_state_row_set().
| Enumerator | |
|---|---|
| GHOSTTY_RENDER_STATE_ROW_OPTION_DIRTY | Set dirty state for the current row (bool). |
| GHOSTTY_API GhosttyResult ghostty_render_state_begin_update | ( | GhosttyRenderState | state, |
| GhosttyTerminal | terminal ) |
Begin an update of a render state instance from a terminal.
Every begin must be completed with a ghostty_render_state_end_update call before the render state is read.
This two-phase structure exists for callers that synchronize access to the terminal state (e.g. with a lock shared with an IO thread): only this function requires terminal access, so a caller can hold its lock for this call only and then call ghostty_render_state_end_update after releasing it. The end phase exclusively reads and writes memory owned by the render state, so it is safe to call while the terminal is being modified.
Work that doesn't require terminal access may be deferred to the end phase to keep this call (and therefore lock hold time) as short as possible. Callers must treat the render state as incomplete until ghostty_render_state_end_update is called.
This consumes terminal/screen dirty state in the same way as the internal render state update path.
| state | The render state handle (NULL returns GHOSTTY_INVALID_VALUE) |
| terminal | The terminal handle to read from (NULL returns GHOSTTY_INVALID_VALUE) |
References ghostty_render_state_begin_update().
Referenced by ghostty_render_state_begin_update().
| GHOSTTY_API GhosttyResult ghostty_render_state_clean | ( | GhosttyRenderState | state | ) |
Mark all dirty render-state data as consumed.
This sets the global dirty state to GHOSTTY_RENDER_STATE_DIRTY_FALSE and clears every per-row dirty flag. It is idempotent and does not modify cell contents or dirty state owned by the terminal. Call this only after a complete frame has been rendered successfully; partial consumers should use ghostty_render_state_set() and ghostty_render_state_row_set() instead.
| state | The render state handle (NULL returns GHOSTTY_INVALID_VALUE) |
References ghostty_render_state_clean().
Referenced by ghostty_render_state_clean().
| GHOSTTY_API GhosttyResult ghostty_render_state_end_update | ( | GhosttyRenderState | state | ) |
Complete a prior ghostty_render_state_begin_update call by performing any deferred work.
This only reads and writes memory owned by the render state, so it is safe to call while the terminal is being modified (no terminal synchronization is required). Calling this without a prior begin is a safe no-op.
| state | The render state handle (NULL returns GHOSTTY_INVALID_VALUE) |
References ghostty_render_state_end_update().
Referenced by ghostty_render_state_end_update().
| GHOSTTY_API void ghostty_render_state_free | ( | GhosttyRenderState | state | ) |
Free a render state instance.
Releases all resources associated with the render state. After this call, the render state handle becomes invalid.
| state | The render state handle to free (may be NULL) |
References ghostty_render_state_free().
Referenced by ghostty_render_state_free().
| GHOSTTY_API GhosttyResult ghostty_render_state_get | ( | GhosttyRenderState | state, |
| GhosttyRenderStateData | data, | ||
| void * | out ) |
Get a value from a render state.
The out pointer must point to a value of the type corresponding to the requested data kind (see GhosttyRenderStateData).
| state | The render state handle (NULL returns GHOSTTY_INVALID_VALUE) | |
| data | The data kind to query | |
| [out] | out | Pointer to receive the queried value |
References ghostty_render_state_get().
Referenced by ghostty_render_state_get().
| GHOSTTY_API GhosttyResult ghostty_render_state_get_multi | ( | GhosttyRenderState | state, |
| size_t | count, | ||
| const GhosttyRenderStateData * | keys, | ||
| void ** | values, | ||
| size_t * | out_written ) |
Get multiple data fields from a render state in a single call.
Each element in the keys array specifies a data kind, and the corresponding element in the values array receives the result.
Processing stops at the first error; on success out_written is set to count, on error it is set to the index of the failing key (i.e. the number of values successfully written).
| state | The render state handle (NULL returns GHOSTTY_INVALID_VALUE) | |
| count | Number of key/value pairs | |
| keys | Array of data kinds to query | |
| values | Array of output pointers (types must match each key's documented output type) | |
| [out] | out_written | On return, receives the number of values successfully written (may be NULL) |
References ghostty_render_state_get_multi().
Referenced by ghostty_render_state_get_multi().
| GHOSTTY_API GhosttyResult ghostty_render_state_image_get | ( | GhosttyRenderStateImageIterator | iterator, |
| GhosttyRenderStateImageData | data, | ||
| void * | out ) |
Read one value from the current placement of an image iterator.
The out pointer must point to a value of the type listed for data in GhosttyRenderStateImageData. To read several values at once, use ghostty_render_state_image_get_multi().
| iterator | The iterator handle, moved to a placement with ghostty_render_state_image_iterator_next() | |
| data | The value to read | |
| [out] | out | Pointer that receives the value |
References ghostty_render_state_image_get().
Referenced by ghostty_render_state_image_get().
| GHOSTTY_API GhosttyResult ghostty_render_state_image_get_multi | ( | GhosttyRenderStateImageIterator | iterator, |
| size_t | count, | ||
| const GhosttyRenderStateImageData * | keys, | ||
| void ** | values, | ||
| size_t * | out_written ) |
Read several values from the current placement of an image iterator in one call.
This works like calling ghostty_render_state_image_get() once for each key. values[i] receives the value for keys[i]. The keys are read in order, and reading stops at the first error.
| iterator | The iterator handle, moved to a placement with ghostty_render_state_image_iterator_next() | |
| count | The number of keys and values | |
| keys | The values to read | |
| values | Output pointers, one for each key | |
| [out] | out_written | If not NULL, receives the number of values written before any error |
References ghostty_render_state_image_get_multi().
Referenced by ghostty_render_state_image_get_multi().
| GHOSTTY_API void ghostty_render_state_image_iterator_free | ( | GhosttyRenderStateImageIterator | iterator | ) |
Free an image iterator.
| iterator | The iterator handle to free (may be NULL) |
References ghostty_render_state_image_iterator_free().
Referenced by ghostty_render_state_image_iterator_free().
| GHOSTTY_API GhosttyResult ghostty_render_state_image_iterator_new | ( | const GhosttyAllocator * | allocator, |
| GhosttyRenderStateImageIterator * | out_iterator ) |
Create a new image iterator.
The iterator starts out empty. Fill it from a render state with ghostty_render_state_get() and GHOSTTY_RENDER_STATE_DATA_IMAGE_ITERATOR. You can keep one iterator for the lifetime of your renderer and fill it again after every update. See "Images" in the render state overview for a complete example.
| allocator | Pointer to allocator, or NULL to use the default allocator | |
| [out] | out_iterator | On success, receives the created iterator handle |
References ghostty_render_state_image_iterator_new().
Referenced by ghostty_render_state_image_iterator_new().
| GHOSTTY_API bool ghostty_render_state_image_iterator_next | ( | GhosttyRenderStateImageIterator | iterator | ) |
Move an image iterator to the next image placement.
Call this before reading the first placement, and keep calling it until it returns false.
The order of placements is not the order to draw them in. Sort them by layer (GHOSTTY_RENDER_STATE_IMAGE_DATA_LAYER) and then by z-index (GHOSTTY_RENDER_STATE_IMAGE_DATA_Z) first.
Only placements with something to draw are returned. For example, placements of an image the terminal hasn't fully received yet are skipped.
The iterator reads from the render state that filled it. After the next update of that render state, fill the iterator again before using it.
| iterator | The iterator handle (NULL returns false) |
References ghostty_render_state_image_iterator_next().
Referenced by ghostty_render_state_image_iterator_next().
| GHOSTTY_API GhosttyResult ghostty_render_state_new | ( | const GhosttyAllocator * | allocator, |
| GhosttyRenderState * | state ) |
Create a new render state instance.
| allocator | Pointer to allocator, or NULL to use the default allocator |
| state | Pointer to store the created render state handle |
References ghostty_render_state_new().
Referenced by ghostty_render_state_new().
| GHOSTTY_API void ghostty_render_state_row_cells_free | ( | GhosttyRenderStateRowCells | cells | ) |
Free a row cells instance.
| cells | The row cells handle to free (may be NULL) |
References ghostty_render_state_row_cells_free().
Referenced by ghostty_render_state_row_cells_free().
| GHOSTTY_API GhosttyResult ghostty_render_state_row_cells_get | ( | GhosttyRenderStateRowCells | cells, |
| GhosttyRenderStateRowCellsData | data, | ||
| void * | out ) |
Get a value from the current cell in a render-state row cells iterator.
The out pointer must point to a value of the type corresponding to the requested data kind (see GhosttyRenderStateRowCellsData). Call ghostty_render_state_row_cells_next() or ghostty_render_state_row_cells_select() at least once before calling this function.
| cells | The row cells handle to query (NULL returns GHOSTTY_INVALID_VALUE) | |
| data | The data kind to query | |
| [out] | out | Pointer to receive the queried value |
References ghostty_render_state_row_cells_get().
Referenced by ghostty_render_state_row_cells_get().
| GHOSTTY_API GhosttyResult ghostty_render_state_row_cells_get_multi | ( | GhosttyRenderStateRowCells | cells, |
| size_t | count, | ||
| const GhosttyRenderStateRowCellsData * | keys, | ||
| void ** | values, | ||
| size_t * | out_written ) |
Get multiple data fields from the current cell in a single call.
Each element in the keys array specifies a data kind, and the corresponding element in the values array receives the result.
Processing stops at the first error; on success out_written is set to count, on error it is set to the index of the failing key (i.e. the number of values successfully written).
| cells | The row cells handle (NULL returns GHOSTTY_INVALID_VALUE) | |
| count | Number of key/value pairs | |
| keys | Array of data kinds to query | |
| values | Array of output pointers (types must match each key's documented output type) | |
| [out] | out_written | On return, receives the number of values successfully written (may be NULL) |
References ghostty_render_state_row_cells_get_multi().
Referenced by ghostty_render_state_row_cells_get_multi().
| GHOSTTY_API GhosttyResult ghostty_render_state_row_cells_new | ( | const GhosttyAllocator * | allocator, |
| GhosttyRenderStateRowCells * | out_cells ) |
Create a new row cells instance.
All fields except the allocator are left undefined until populated via ghostty_render_state_row_get() with GHOSTTY_RENDER_STATE_ROW_DATA_CELLS.
You can reuse this value repeatedly with ghostty_render_state_row_get() to avoid allocating a new cells container for every row.
| allocator | Pointer to allocator, or NULL to use the default allocator | |
| [out] | out_cells | On success, receives the created row cells handle |
References ghostty_render_state_row_cells_new().
Referenced by ghostty_render_state_row_cells_new().
| GHOSTTY_API bool ghostty_render_state_row_cells_next | ( | GhosttyRenderStateRowCells | cells | ) |
Move a render-state row cells iterator to the next cell.
Returns true if the iterator moved successfully and cell data is available to read at the new position.
| cells | The row cells handle to advance (may be NULL) |
References ghostty_render_state_row_cells_next().
Referenced by ghostty_render_state_row_cells_next().
| GHOSTTY_API GhosttyResult ghostty_render_state_row_cells_select | ( | GhosttyRenderStateRowCells | cells, |
| uint16_t | x ) |
Move a render-state row cells iterator to a specific column.
Positions the iterator at the given x (column) index so that subsequent reads return data for that cell.
| cells | The row cells handle to reposition (NULL returns GHOSTTY_INVALID_VALUE) |
| x | The zero-based column index to select |
References ghostty_render_state_row_cells_select().
Referenced by ghostty_render_state_row_cells_select().
| GHOSTTY_API GhosttyResult ghostty_render_state_row_get | ( | GhosttyRenderStateRowIterator | iterator, |
| GhosttyRenderStateRowData | data, | ||
| void * | out ) |
Get a value from the current row in a render-state row iterator.
The out pointer must point to a value of the type corresponding to the requested data kind (see GhosttyRenderStateRowData). Call ghostty_render_state_row_iterator_next() or ghostty_render_state_row_iterator_next_dirty() at least once before calling this function.
| iterator | The iterator handle to query (NULL returns GHOSTTY_INVALID_VALUE) | |
| data | The data kind to query | |
| [out] | out | Pointer to receive the queried value |
References ghostty_render_state_row_get().
Referenced by ghostty_render_state_row_get().
| GHOSTTY_API GhosttyResult ghostty_render_state_row_get_multi | ( | GhosttyRenderStateRowIterator | iterator, |
| size_t | count, | ||
| const GhosttyRenderStateRowData * | keys, | ||
| void ** | values, | ||
| size_t * | out_written ) |
Get multiple data fields from the current row in a single call.
Each element in the keys array specifies a data kind, and the corresponding element in the values array receives the result.
Processing stops at the first error; on success out_written is set to count, on error it is set to the index of the failing key (i.e. the number of values successfully written).
| iterator | The iterator handle (NULL returns GHOSTTY_INVALID_VALUE) | |
| count | Number of key/value pairs | |
| keys | Array of data kinds to query | |
| values | Array of output pointers (types must match each key's documented output type) | |
| [out] | out_written | On return, receives the number of values successfully written (may be NULL) |
References ghostty_render_state_row_get_multi().
Referenced by ghostty_render_state_row_get_multi().
| GHOSTTY_API void ghostty_render_state_row_iterator_free | ( | GhosttyRenderStateRowIterator | iterator | ) |
Free a render-state row iterator.
| iterator | The iterator handle to free (may be NULL) |
References ghostty_render_state_row_iterator_free().
Referenced by ghostty_render_state_row_iterator_free().
| GHOSTTY_API GhosttyResult ghostty_render_state_row_iterator_new | ( | const GhosttyAllocator * | allocator, |
| GhosttyRenderStateRowIterator * | out_iterator ) |
Create a new row iterator instance.
All fields except the allocator are left undefined until populated via ghostty_render_state_get() with GHOSTTY_RENDER_STATE_DATA_ROW_ITERATOR.
| allocator | Pointer to allocator, or NULL to use the default allocator | |
| [out] | out_iterator | On success, receives the created iterator handle |
References ghostty_render_state_row_iterator_new().
Referenced by ghostty_render_state_row_iterator_new().
| GHOSTTY_API bool ghostty_render_state_row_iterator_next | ( | GhosttyRenderStateRowIterator | iterator | ) |
Move a render-state row iterator to the next row.
Rows are visited in order from top to bottom with no gaps. Without overscan, the first row is the top row of the viewport. With overscan, the first row is the highest captured row above the viewport (see GHOSTTY_RENDER_STATE_OPTION_OVERSCAN). Returns true if the iterator moved successfully and row data is available to read at the new position.
| iterator | The iterator handle to advance (may be NULL) |
References ghostty_render_state_row_iterator_next().
Referenced by ghostty_render_state_row_iterator_next().
| GHOSTTY_API bool ghostty_render_state_row_iterator_next_dirty | ( | GhosttyRenderStateRowIterator | iterator, |
| uint16_t * | out_y ) |
Move a render-state row iterator to the next row requiring a redraw.
If the global dirty state is GHOSTTY_RENDER_STATE_DIRTY_FALSE, this returns false. If it is GHOSTTY_RENDER_STATE_DIRTY_PARTIAL, clean rows are skipped. If it is GHOSTTY_RENDER_STATE_DIRTY_FULL, every remaining row is returned regardless of its per-row dirty flag. Rows are returned in ascending viewport order. This function does not clear any dirty state.
| iterator | The iterator handle to advance (NULL returns false) | |
| [out] | out_y | Receives the row's position in the iterator when true is returned (NULL returns false). It is not modified when false is returned. Without overscan, this is the viewport y. With overscan, it counts from the highest captured row, so use GHOSTTY_RENDER_STATE_ROW_DATA_VIEWPORT_Y to place the row. |
References ghostty_render_state_row_iterator_next_dirty().
Referenced by ghostty_render_state_row_iterator_next_dirty().
| GHOSTTY_API GhosttyResult ghostty_render_state_row_set | ( | GhosttyRenderStateRowIterator | iterator, |
| GhosttyRenderStateRowOption | option, | ||
| const void * | value ) |
Set an option on the current row in a render-state row iterator.
The value pointer must point to a value of the type corresponding to the requested option kind (see GhosttyRenderStateRowOption). Call ghostty_render_state_row_iterator_next() or ghostty_render_state_row_iterator_next_dirty() at least once before calling this function.
| iterator | The iterator handle to update (NULL returns GHOSTTY_INVALID_VALUE) | |
| option | The option to set | |
| [in] | value | Pointer to the value to set (NULL returns GHOSTTY_INVALID_VALUE) |
References ghostty_render_state_row_set().
Referenced by ghostty_render_state_row_set().
| GHOSTTY_API GhosttyResult ghostty_render_state_set | ( | GhosttyRenderState | state, |
| GhosttyRenderStateOption | option, | ||
| const void * | value ) |
Set an option on a render state.
The value pointer must point to a value of the type corresponding to the requested option kind (see GhosttyRenderStateOption).
| state | The render state handle (NULL returns GHOSTTY_INVALID_VALUE) | |
| option | The option to set | |
| [in] | value | Pointer to the value to set (NULL returns GHOSTTY_INVALID_VALUE) |
References ghostty_render_state_set().
Referenced by ghostty_render_state_set().
| GHOSTTY_API GhosttyResult ghostty_render_state_update | ( | GhosttyRenderState | state, |
| GhosttyTerminal | terminal ) |
Update a render state instance from a terminal.
This consumes terminal/screen dirty state in the same way as the internal render state update path.
This is a convenience function that performs a full update in one call, equivalent to ghostty_render_state_begin_update immediately followed by ghostty_render_state_end_update. Callers that hold a lock over the terminal state should prefer calling the two phases directly so that the lock is only held for the begin phase.
| state | The render state handle (NULL returns GHOSTTY_INVALID_VALUE) |
| terminal | The terminal handle to read from (NULL returns GHOSTTY_INVALID_VALUE) |
References ghostty_render_state_update().
Referenced by ghostty_render_state_update().