# How to Use InputText with Callbacks for Custom Text Processing in ImGui

> Learn ImGui InputText callbacks for custom text processing. Dynamically resize buffers, filter chars, add autocomplete, and monitor cursor changes effectively.

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

---

**ImGui::InputText() accepts an `ImGuiInputTextCallback` function pointer that lets you intercept editing events to resize buffers dynamically, filter characters, implement autocomplete, or monitor cursor changes.**

The `ocornut/imgui` library exposes a sophisticated callback system for text input widgets. By combining callback flags with the `ImGuiInputTextCallbackData` structure, you can hook into the edit lifecycle of `InputText`, `InputTextMultiline`, and `InputTextWithHint` to perform custom validation, memory management, or command-line-style features.

## Callback Types and Flags

`InputText()` supports several distinct callback events triggered by specific flags. You can combine these flags to register multiple callbacks within a single function, checking `data->EventFlag` to distinguish the event type.

**ImGuiInputTextFlags_CallbackResize** – Triggered when the internal buffer needs to grow. Essential when using resizable containers like `std::string` instead of fixed-size char arrays. The callback must reallocate memory and update `data->Buf` and `data->BufSize`.

**ImGuiInputTextFlags_CallbackCharFilter** – Called for each character input before it is inserted. Return `1` to discard the character, or modify `data->EventChar` to substitute a different character.

**ImGuiInputTextFlags_CallbackCompletion** and **ImGuiInputTextFlags_CallbackHistory** – Standard events for Tab-completion and Up/Down arrow history navigation, commonly used in console or command-palette interfaces.

**ImGuiInputTextFlags_CallbackAlways** and **ImGuiInputTextFlags_CallbackEdit** – Called every frame or on every edit, allowing you to inspect cursor position, selection ranges, or modify buffer content while the widget maintains focus.

## The ImGuiInputTextCallbackData Structure

According to the declaration on line 194 of [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h), the callback receives a pointer to `ImGuiInputTextCallbackData`, which contains the following key members:

- **EventFlag** – Identifies which flag triggered the callback (e.g., `ImGuiInputTextFlags_CallbackResize`).
- **Buf / BufTextLen / BufSize** – The current text buffer, its length, and total capacity. For resize callbacks, you must update these fields after reallocation.
- **CursorPos / SelectionStart / SelectionEnd** – Current cursor location and text selection bounds, useful for context-aware processing.
- **UserData** – The opaque pointer passed as the last argument to `InputText()`, typically used to access your application-specific buffer or state.

The callback function signature, defined on line 286 of [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h), is:

```cpp
int MyCallback(ImGuiInputTextCallbackData* data);

```

## Example: Dynamic Buffer Resizing with std::string

When using `std::string` as your backing storage, you must handle the resize callback to avoid buffer overflows. The implementation in [`misc/cpp/imgui_stdlib.h`](https://github.com/ocornut/imgui/blob/main/misc/cpp/imgui_stdlib.h) (lines 30-34) demonstrates the standard pattern:

```cpp
#include "imgui.h"
#include "misc/cpp/imgui_stdlib.h"

std::string text;
ImGui::InputText("Label", &text, ImGuiInputTextFlags_None);

```

For a manual implementation using a custom buffer structure:

```cpp
struct MyBuffer { 
    char* data; 
    int capacity; 
};

static int ResizeCallback(ImGuiInputTextCallbackData* data)
{
    if (data->EventFlag == ImGuiInputTextFlags_CallbackResize)
    {
        MyBuffer* buf = (MyBuffer*)data->UserData;
        buf->capacity = data->BufSize;
        buf->data = (char*)realloc(buf->data, buf->capacity);
        data->Buf = buf->data;
    }
    return 0;
}

// Usage
MyBuffer mybuf = { (char*)malloc(128), 128 };
ImGui::InputText("Dynamic", mybuf.data, mybuf.capacity,
                 ImGuiInputTextFlags_CallbackResize,
                 ResizeCallback, &mybuf);

```

## Example: Character Filtering

To restrict input to digits only, use the `CallbackCharFilter` flag and return `1` to reject non-matching characters:

```cpp
static int FilterDigitsCallback(ImGuiInputTextCallbackData* data)
{
    if (data->EventFlag == ImGuiInputTextFlags_CallbackCharFilter)
    {
        if (!isdigit(data->EventChar))
            return 1;  // Discard non-digit
    }
    return 0;
}

char buf[64] = "";
ImGui::InputText("Only digits", buf, sizeof(buf),
                 ImGuiInputTextFlags_CallbackCharFilter,
                 FilterDigitsCallback, nullptr);

```

## Example: Tab Completion

Implement command palette behavior by handling the completion callback:

```cpp
static const char* commands[] = { "help", "quit", "reset", nullptr };

static int CompletionCallback(ImGuiInputTextCallbackData* data)
{
    if (data->EventFlag == ImGuiInputTextFlags_CallbackCompletion)
    {
        for (int i = 0; commands[i]; ++i)
        {
            if (strncmp(commands[i], data->Buf, data->BufTextLen) == 0)
            {
                data->InsertChars(data->BufTextLen, 
                    commands[i] + data->BufTextLen);
                break;
            }
        }
    }
    return 0;
}

char cmd[64] = "";
ImGui::InputText("Cmd", cmd, sizeof(cmd),
                 ImGuiInputTextFlags_CallbackCompletion,
                 CompletionCallback, nullptr);

```

## Internal Implementation Details

As implemented in `ocornut/imgui`, the `InputText()` function forwards to `InputTextEx` (see line 3796 of [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp)), which manages the actual editing state and invokes your callback at the appropriate moments. The internal state is maintained in `ImGuiInputTextState` (declared on line 1260 of [`imgui_internal.h`](https://github.com/ocornut/imgui/blob/main/imgui_internal.h)), allowing callbacks to access low-level details such as undo/redo history and word selection when using the `CallbackAlways` flag.

## Summary

- **InputText callbacks** enable custom text processing through the `ImGuiInputTextCallback` function pointer defined in [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h).
- Use **ImGuiInputTextFlags_CallbackResize** to support dynamic buffers like `std::string`, updating `data->Buf` and `data->BufSize` in your callback.
- Use **ImGuiInputTextFlags_CallbackCharFilter** to validate or replace individual characters before insertion.
- The **ImGuiInputTextCallbackData** struct provides access to buffer state, cursor position, and selection ranges.
- Internal implementation routes through `InputTextEx` in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) and maintains state in `ImGuiInputTextState`.

## Frequently Asked Questions

### How do I automatically resize a std::string with InputText?

Include [`misc/cpp/imgui_stdlib.h`](https://github.com/ocornut/imgui/blob/main/misc/cpp/imgui_stdlib.h) and pass the string pointer to `ImGui::InputText()`. This header implements a resize callback that calls `std::string::resize()` when the `ImGuiInputTextFlags_CallbackResize` event fires, ensuring the buffer grows as the user types.

### Can I block specific characters from being entered?

Yes. Set the `ImGuiInputTextFlags_CallbackCharFilter` flag and provide a callback that checks `data->EventChar`. Return `1` from the callback to discard the character, or modify `data->EventChar` to substitute a different value.

### How do I implement command history navigation?

Use the `ImGuiInputTextFlags_CallbackHistory` flag. When the user presses Up or Down arrow keys, your callback receives this event with `data->EventFlag` set accordingly. You can then replace the buffer content using `data->InsertChars()` or `data->DeleteChars()` to show previous commands.

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

`CallbackAlways` invokes your callback every frame while the widget is active, allowing continuous monitoring of cursor position or selection. `CallbackEdit` only fires when the buffer content actually changes, making it more efficient for validation that only needs to run on modifications.