# Dear ImGui Advanced Text Input with Callbacks: A Complete Developer Guide

> Master Dear ImGui advanced text input with callbacks. Learn to implement dynamic resizing character filtering TAB completion and history navigation with this essential developer guide.

- Repository: [omar/imgui](https://github.com/ocornut/imgui)
- Tags: how-to-guide
- Published: 2026-07-19

---

**TLDR:** Dear ImGui's `InputText`, `InputTextMultiline`, and `InputTextWithHint` widgets support a flexible `ImGuiInputTextCallback` system defined in [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h), enabling dynamic buffer resizing, character filtering, TAB completion, and history navigation through dedicated event flags.

Dear ImGui enables advanced text input with callbacks that extend the basic `InputText` widget into a flexible editing framework. By supplying callback flags and user functions, developers can intercept keystrokes, resize buffers dynamically, and implement IDE-style auto-completion. In the `ocornut/imgui` repository, this behavior is driven by the core `InputTextEx` implementation declared in [`imgui_internal.h`](https://github.com/ocornut/imgui/blob/main/imgui_internal.h) and the shared per-context `ImGuiInputTextState`.

## How the Callback API Works

The public API lives in **[`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h)** and exposes three entry points:

```cpp
bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
bool InputTextMultiline(...);
bool InputTextWithHint(...);

```

These functions follow the same signature and are routed through [`imgui_widgets.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_widgets.cpp) to the internal **`InputTextEx`** implementation. When any callback flag is present, `InputTextEx` populates an **`ImGuiInputTextCallbackData`** structure and invokes the user-provided function. The callback can inspect `data->EventFlag` to determine the reason for the call and modify the buffer or cursor state accordingly.

## Supported Callback Flags

The **`ImGuiInputTextFlags_`** enum in [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h) enumerates the events that `InputTextEx` can forward:

- **`ImGuiInputTextFlags_CallbackResize`** — Requests a resize of the buffer; commonly used for dynamic strings.
- **`ImGuiInputTextFlags_CallbackEdit`** — Called after any edit operation.
- **`ImGuiInputTextFlags_CallbackAlways`** — Called on every frame while the widget is active.
- **`ImGuiInputTextFlags_CallbackCharFilter`** — Allows filtering or replacing incoming characters.
- **`ImGuiInputTextFlags_CallbackCompletion`** — Triggered when **TAB** is pressed.
- **`ImGuiInputTextFlags_CallbackHistory`** — Triggered when **↑** or **↓** arrow keys are pressed.

## Internal State and Buffer Safety

All active text inputs share a per-context **`ImGuiInputTextState`** instance stored in `g.InputTextState`. This structure holds the buffer, cursor position, selection range, and a temporary backup called **`CallbackTextBackup`**. The backup enables the `CallbackEdit` and `CallbackAlways` mechanisms to safely modify the buffer while preserving undo and redo history. This state is defined in [`imgui_internal.h`](https://github.com/ocornut/imgui/blob/main/imgui_internal.h).

## Auto-Resizing std::string with CallbackResize

A common pattern is to use `std::string` with the **Resize** callback. The helper wrapper lives in **[`misc/cpp/imgui_stdlib.cpp`](https://github.com/ocornut/imgui/blob/main/misc/cpp/imgui_stdlib.cpp)** and defines a small `InputTextCallback_UserData` structure. It sets up a callback that expands the `std::string` when the buffer overflows, then forwards the call to the core `InputText` function.

```cpp
// Wrapper automatically adds ImGuiInputTextFlags_CallbackResize
static std::string name = "Bob";
ImGui::InputText("Name", &name);

```

The wrapper internally adds the `ImGuiInputTextFlags_CallbackResize` flag together with a small callback that expands the `std::string` when needed, as implemented in [`misc/cpp/imgui_stdlib.cpp`](https://github.com/ocornut/imgui/blob/main/misc/cpp/imgui_stdlib.cpp).

## Filtering Characters with CallbackCharFilter

You can reject specific characters by returning `1` inside a `CallbackCharFilter` handler. The callback checks `data->EventFlag` to confirm the event type.

```cpp
int MyCharFilter(ImGuiInputTextCallbackData* data)
{
    if (data->EventFlag == ImGuiInputTextFlags_CallbackCharFilter)
    {
        if (data->EventChar >= '0' && data->EventChar <= '9')
            return 1;               // 1 = discard
    }
    return 0;                       // 0 = keep
}

// Usage
char buf[128] = "";
ImGui::InputText("Alpha only", buf, sizeof(buf),
                 ImGuiInputTextFlags_CallbackCharFilter,
                 MyCharFilter);

```

## Growing a Raw C Buffer with CallbackResize

For dynamically allocated C strings, the resize callback receives the desired buffer size and must update `data->Buf` and `data->BufSize` directly.

```cpp
int MyResizeCallback(ImGuiInputTextCallbackData* data)
{
    if (data->EventFlag == ImGuiInputTextFlags_CallbackResize)
    {
        char* new_buf = (char*)realloc(data->Buf, data->BufSize * 2);
        data->Buf = new_buf;
        data->BufSize *= 2;
    }
    return 0;
}

// Usage
static char* dyn_buf = (char*)malloc(64);
static size_t dyn_buf_size = 64;
ImGui::InputText("Dynamic", dyn_buf, dyn_buf_size,
                 ImGuiInputTextFlags_CallbackResize,
                 MyResizeCallback);

```

## Handling TAB Completion

The **`ImGuiInputTextFlags_CallbackCompletion`** flag fires when the user presses **TAB**. The callback can inspect `data->CursorPos` and replace the buffer contents to provide completion suggestions.

```cpp
int MyCompletionCallback(ImGuiInputTextCallbackData* data)
{
    if (data->EventFlag == ImGuiInputTextFlags_CallbackCompletion)
    {
        const char* candidates[] = { "apple", "apricot", "banana" };
        // Use data->CursorPos and data->Buf to insert a match
    }
    return 0;
}

// Usage
static char buf[64] = "";
ImGui::InputText("Fruit", buf, sizeof(buf),
                 ImGuiInputTextFlags_CallbackCompletion,
                 MyCompletionCallback);

```

## Summary

- The `InputText` family in Dear ImGui forwards all callback-enabled calls to **`InputTextEx`**, which is declared in [`imgui_internal.h`](https://github.com/ocornut/imgui/blob/main/imgui_internal.h) and invoked through [`imgui_widgets.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_widgets.cpp).
- **`ImGuiInputTextCallbackData`** provides the current state, event flag, and buffer pointers to your callback function.
- Use **`ImGuiInputTextFlags_CallbackResize`** for dynamic strings; the [`misc/cpp/imgui_stdlib.cpp`](https://github.com/ocornut/imgui/blob/main/misc/cpp/imgui_stdlib.cpp) wrapper handles `std::string` automatically.
- Use **`ImGuiInputTextFlags_CallbackCharFilter`** to reject or mutate characters before they enter the buffer.
- Use **`ImGuiInputTextFlags_CallbackCompletion`** and **`ImGuiInputTextFlags_CallbackHistory`** for IDE-style TAB completion and arrow-key navigation.
- Internal backup state in **`ImGuiInputTextState`** ensures undo and redo safety when callbacks modify the text.

## Frequently Asked Questions

### What is the difference between CallbackAlways and CallbackEdit?

**`ImGuiInputTextFlags_CallbackAlways`** invokes your callback on every frame while the widget remains active, whereas **`ImGuiInputTextFlags_CallbackEdit`** fires only after an actual edit occurs. Both mechanisms rely on the temporary backup buffer inside `ImGuiInputTextState` to preserve undo and redo history if you modify the text.

### How do I use std::string with ImGui::InputText without writing a callback manually?

Include **[`misc/cpp/imgui_stdlib.h`](https://github.com/ocornut/imgui/blob/main/misc/cpp/imgui_stdlib.h)** and pass a pointer to your `std::string` directly to `ImGui::InputText`. The helper wrapper defined in [`misc/cpp/imgui_stdlib.cpp`](https://github.com/ocornut/imgui/blob/main/misc/cpp/imgui_stdlib.cpp) automatically supplies the `ImGuiInputTextFlags_CallbackResize` flag and a local callback that expands the string capacity when the internal character buffer overflows.

### Can I combine multiple callback behaviors in one InputText call?

Yes. Because `InputTextEx` tests the flag field with bitwise AND (`flags & ImGuiInputTextFlags_Callback*`), multiple behaviors can be requested simultaneously by combining the corresponding enum values. The callback should inspect `data->EventFlag` inside its handler to distinguish which event is currently being processed.

### Why must my resize callback update data->Buf directly?

When `InputTextEx` triggers a **`ImGuiInputTextFlags_CallbackResize`** event, it sets the required size on the `ImGuiInputTextCallbackData` object and expects your callback to reallocate memory and assign the new pointer to `data->Buf`. The widget does not perform the allocation itself; it only reads back the pointer and size you provide, which is why the raw C buffer example uses `realloc` to grow the heap block.