The Text Input System manages all text editing functionality in Dear ImGui, including single-line and multi-line text fields, undo/redo operations, clipboard integration, IME (Input Method Editor) support for international text input, and text selection. This system bridges user input events with STB textedit library functionality to provide a complete text editing experience.
For information about input routing and keyboard navigation, see Input and Navigation. For widget-level behaviors, see Widget System.
The text input system consists of three main layers:
InputText(), InputTextMultiline(), InputTextWithHint())ImGuiInputTextState maintains editing state across framesSources: imgui_widgets.cpp3700-5400 imgui_internal.h1050-1090 imstb_textedit.h1-280
ImGuiInputTextState is the central structure that maintains all state for an active text editing widget. It persists across frames as long as the widget remains active.
| Field | Type | Purpose |
|---|---|---|
Ctx | ImGuiContext* | Parent UI context |
Stb | ImStbTexteditState | STB textedit state (cursor, selection, undo) |
ID | ImGuiID | Widget ID owning this state |
CurLenW, CurLenA | int | Buffer lengths in wchar and UTF-8 |
TextW | ImVector<ImWchar> | Internal edit buffer (UTF-16/UTF-32) |
TextA | ImVector<char> | Temporary UTF-8 buffer for callbacks |
InitialTextA | ImVector<char> | Backup of user buffer at focus time |
BufCapacityA | int | User buffer capacity |
Scroll | ImVec2 | Scrolling position |
CursorAnim | float | Cursor blink timer |
Flags | ImGuiInputTextFlags | Copy of InputText() flags |
Edited | bool | Was edited this frame |
ReloadUserBuf | bool | User buffer needs reload (undo/callback) |
The state is stored in g.InputTextState and activated when a text field becomes active.
Sources: imgui_internal.h1050-1090
Dear ImGui uses a modified version of STB textedit (imstb_textedit.h) for core text editing operations. This library provides:
The macros STB_TEXTEDIT_* are defined to integrate STB textedit with ImGui's internal structures.
Sources: imstb_textedit.h1-1800 imgui_widgets.cpp3700-3900
Sources: imgui_widgets.cpp4100-5300
Input events flow through several filtering and processing stages:
Sources: imgui_widgets.cpp3920-4000 imgui_widgets.cpp4500-4800
When callbacks are triggered, they receive an ImGuiInputTextCallbackData structure:
| Field | Type | Purpose |
|---|---|---|
EventFlag | ImGuiInputTextFlags | Which callback event triggered |
Flags | ImGuiInputTextFlags | Copy of all InputText flags |
EventChar | ImWchar | Character input (for CharFilter) |
EventKey | ImGuiKey | Key pressed (for Completion/History) |
Buf | char* | Text buffer pointer |
BufTextLen | int | Text length in UTF-8 |
BufSize | int | Buffer size |
BufDirty | bool | Set to true if you modify Buf |
CursorPos | int | Cursor position in UTF-8 bytes |
SelectionStart, SelectionEnd | int | Selection range |
ID | ImGuiID | Widget ID (v1.92.6+) |
EventActivated | bool | Widget was just activated (v1.92.6+) |
Helper Methods:
DeleteChars(int pos, int bytes_count) - Delete bytes from bufferInsertChars(int pos, const char* text, const char* text_end) - Insert textSelectAll() - Select all textClearSelection() - Clear selectionHasSelection() - Check if selection existsSetSelection(int start, int end) - Set selection range (v1.92.6+)Sources: imgui.h2230-2280
Key flags controlling text input behavior:
ImGuiInputTextFlags_CharsDecimal - Allow 0-9, '.', '+', '-'ImGuiInputTextFlags_CharsHexadecimal - Allow 0-9, A-F, a-fImGuiInputTextFlags_CharsScientific - Allow scientific notationImGuiInputTextFlags_CharsUppercase - Convert to uppercaseImGuiInputTextFlags_CharsNoBlank - Filter out spaces, tabsImGuiInputTextFlags_Password - Display as '*' charactersImGuiInputTextFlags_ReadOnly - Read-only mode, no editingImGuiInputTextFlags_DisplayEmptyRefVal - Display empty value differentlyImGuiInputTextFlags_AllowTabInput - Allow Tab character inputImGuiInputTextFlags_CtrlEnterForNewLine - Ctrl+Enter for newline (multiline)ImGuiInputTextFlags_NoHorizontalScroll - Disable horizontal scrollImGuiInputTextFlags_AlwaysOverwrite - Overwrite modeImGuiInputTextFlags_AutoSelectAll - Select all when focusedImGuiInputTextFlags_CallbackCompletion - Tab key pressedImGuiInputTextFlags_CallbackHistory - Up/Down arrows pressedImGuiInputTextFlags_CallbackAlways - Every frameImGuiInputTextFlags_CallbackCharFilter - Character inputImGuiInputTextFlags_CallbackEdit - Any edit occurredImGuiInputTextFlags_CallbackResize - Buffer capacity needs increaseSources: imgui.h1375-1425
IME allows input of complex scripts (Chinese, Japanese, Korean) using composition:
ImGuiPlatformImeData communicates IME window position to the platform:
The platform backend calls io.PlatformSetImeDataFn to position the IME composition window near the text cursor.
Sources: imgui.h2800-2820 imgui_widgets.cpp4900-5100
STB textedit provides built-in undo/redo with configurable depth:
ImStbTexteditState.undo_state[]ImStbTexteditState.undo_char[]STB_TEXTEDIT_UNDOSTATECOUNT (default 99)Sources: imstb_textedit.h100-106 imgui_widgets.cpp3700-3750
Selection Features:
Sources: imgui_widgets.cpp4700-4900 imgui.cpp142-152
For InputTextMultiline() with ImGuiInputTextFlags_WordWrap:
Word wrapping changes in v1.92.6:
Sources: imgui_widgets.cpp5100-5300 docs/CHANGELOG.txt193-202
This is the internal function that implements all text input variants.
Sources: imgui_internal.h3050-3060 imgui_widgets.cpp4100-5400
InputTextFilterCharacter() filters and transforms input characters based on flags:
Handles:
Sources: imgui_widgets.cpp3920-4050
Calculates text dimensions for layout and scrolling, accounting for word wrap.
Sources: imgui_widgets.cpp4050-4100
Sources: imgui_demo.cpp2400-2700
ImGui maintains two parallel buffers:
TextW (ImWchar) - Internal editing buffer, UTF-16 or UTF-32TextA (char) - UTF-8 buffer for user and callbacksThis allows efficient editing while maintaining UTF-8 compatibility with user code.
ImGuiInputTextState is stored in g.InputTextState and persists only while a text field is active. When a field loses focus, its state is cleared.
ImGuiInputTextDeactivateData briefly stores text from a deactivating field when another field steals the active ID, allowing proper cleanup.
Sources: imgui_internal.h1050-1090 imgui_internal.h1100-1110
Refresh this wiki