# Dear ImGui Input Handling Integration: A Complete Technical Guide to Platform Backends

> Master Dear ImGui input handling integration with this technical guide. Learn how platform backends populate raw events for seamless application control.

- Repository: [omar/imgui](https://github.com/ocornut/imgui)
- Tags: deep-dive
- Published: 2026-07-28

---

**Dear ImGui collects raw keyboard, mouse, focus and text events through the `ImGuiIO` API, which platform backends populate via `Add*Event` functions before each `NewFrame()` call.**

Dear ImGui input handling integration relies on a clear separation between the core library and platform-specific code. The `ocornut/imgui` repository implements this architecture through the **ImGuiIO** structure defined in [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h), which acts as a centralized input queue that backends fill with native windowing events every frame. Understanding this contract is essential for implementing custom backends or modifying existing ones like GLFW, Win32, or SDL.

## The ImGuiIO Input Queue API

The heart of Dear ImGui input handling is the **ImGuiIO** structure, which exposes a set of "Add" functions that backends must call to forward platform events. These functions are defined in [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h) and push data into internal queues consumed during `NewFrame()`.

### Core Input Functions

According to the source code in [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h), backends must populate the following event types:

- **`AddKeyEvent`** / **`AddKeyAnalogEvent`** – Queue key-down/up states or analog values (gamepad triggers, joystick axes)
- **`AddMousePosEvent`** – Queue mouse cursor position updates (pass `-FLT_MAX` to signal no mouse)
- **`AddMouseButtonEvent`** – Queue mouse button state changes
- **`AddMouseWheelEvent`** – Queue horizontal and vertical scroll deltas
- **`AddFocusEvent`** – Queue application focus gain/loss events
- **`AddInputCharacter`** / **`AddInputCharacterUTF16`** / **`AddInputCharactersUTF8`** – Queue Unicode text input for `InputText()` widgets

Internally, these calls populate fields within `ImGuiIO`:

```cpp
ImWchar16   InputQueueSurrogate;                // Used only by AddInputCharacterUTF16()
ImVector<ImWchar> InputQueueCharacters;         // Holds characters consumed by InputText()

```

These queues are cleared automatically at the end of each frame, ensuring **frame-accurate** input that preserves event ordering.

## Platform Backend Integration Pattern

All official backends in the `ocornut/imgui` repository follow an identical integration pattern. A backend must store a pointer to its data structure (e.g., `ImGui_ImplGlfw_Data`), install callbacks with the native windowing library, and forward events to `ImGuiIO` inside those callbacks.

### GLFW Backend Example

In [`backends/imgui_impl_glfw.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_glfw.cpp), the character input callback demonstrates this pattern:

```cpp
void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c)
{
    ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window);
    if (bd->PrevUserCallbackChar && ImGui_ImplGlfw_ShouldChainCallback(bd, window))
        bd->PrevUserCallbackChar(window, c);               // Preserve user-provided callback

    ImGuiIO& io = ImGui::GetIO(bd->Context);
    io.AddInputCharacter(c);                               // Forward text input to Dear ImGui
}

```

### Win32 Backend Example

Similarly, [`backends/imgui_impl_win32.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_win32.cpp) handles `WM_CHAR` messages:

```cpp
case WM_CHAR:
    // 2019-05-11: Don't filter the value before forwarding
    io.AddInputCharacter((unsigned int)wParam);           // Forward text input
    break;

```

Both implementations also forward mouse movement (`WM_MOUSEMOVE` or `glfwSetCursorPosCallback`) and button events using the corresponding `AddMousePosEvent` and `AddMouseButtonEvent` functions.

## Frame Input Processing Flow

Understanding the execution order is critical for correct Dear ImGui input handling integration:

1. **Platform callbacks** fire when the operating system delivers events (window messages, GLFW callbacks, etc.)
2. Each callback pushes data into `ImGuiIO` fields via the `Add*Event` functions
3. The application calls `ImGui::NewFrame()`, which reads queued input, updates internal state, and clears the queues
4. UI widgets like `InputText()` consume characters from `InputQueueCharacters` during the frame

This queue-based design guarantees reliable text entry, mouse dragging, and key repeat handling regardless of platform event timing.

## Customizing and Extending Input

### Injecting Synthetic Events

To programmatically inject input for automated testing or macros, call the `Add*Event` functions directly from your application code:

```cpp
ImGuiIO& io = ImGui::GetIO();
io.AddInputCharacter('A');          // Adds 'A' to the next InputText widget
io.AddKeyEvent(ImGuiKey_Space, true);  // Simulates Space key press

```

### Filtering Text Input

To filter or modify characters before they reach widgets, use the `ImGuiInputTextFlags_CallbackCharFilter` flag on `InputText()` and adjust `EventChar` within your callback function.

### High-DPI and Multi-Monitor Support

For high-DPI setups, backends typically scale mouse coordinates before calling `AddMousePosEvent`. The Win32 and GLFW backends handle this by querying monitor DPI and applying scaling factors to raw cursor positions.

## Complete Implementation Example

The following pattern shows a complete GLFW-based input pipeline:

```cpp
// 1. Initialise ImGui and backend
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init("#version 150");

// 2. Main loop
while (!glfwWindowShouldClose(window))
{
    glfwPollEvents();                   // Triggers ImGui_ImplGlfw_* callbacks

    // 3. Start frame (processes queued input)
    ImGui_ImplOpenGL3_NewFrame();
    ImGui_ImplGlfw_NewFrame();
    ImGui::NewFrame();

    // 4. UI code consumes input automatically
    static char buf[128] = "";
    ImGui::InputText("Label", buf, IM_ARRAYSIZE(buf));

    // 5. Render
    ImGui::Render();
    ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
    glfwSwapBuffers(window);
}

```

## Key Source Files

- **[`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h)** – Defines `ImGuiIO`, input queues, and `Add*Event` function signatures
- **[`backends/imgui_impl_glfw.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_glfw.cpp)** – GLFW mouse, keyboard, and text input integration
- **[`backends/imgui_impl_win32.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_win32.cpp)** – Win32 window message handling (`WM_*` events)
- **[`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp)** – Core implementation of `NewFrame()` and input queue processing
- **[`imgui_demo.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_demo.cpp)** – Reference implementations of `InputText` and event handling

## Summary

- **ImGuiIO** is the central contract between Dear ImGui and platform backends, defined in [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h)
- Backends call `AddKeyEvent`, `AddMousePosEvent`, `AddInputCharacter`, and related functions to queue raw input
- Input queues are cleared every frame during `NewFrame()`, ensuring frame-accurate event processing
- Official backends in [`backends/imgui_impl_glfw.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_glfw.cpp) and [`backends/imgui_impl_win32.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_win32.cpp) demonstrate the callback-to-queue pattern
- Synthetic events can be injected directly via `ImGuiIO` for testing or automation

## Frequently Asked Questions

### How do I handle high-DPI mouse coordinates in Dear ImGui?

Scale mouse coordinates before calling `io.AddMousePosEvent()`. The official GLFW and Win32 backends query monitor DPI settings and apply scaling factors to raw cursor positions, ensuring UI elements align correctly with the mouse cursor on high-DPI displays.

### Can I inject synthetic input events for automated testing?

Yes. Obtain the `ImGuiIO` reference via `ImGui::GetIO()` and call any `Add*Event` function directly from your test code. For example, `io.AddInputCharacter('A')` queues a character for the next `InputText` widget, while `io.AddKeyEvent(ImGuiKey_Enter, true)` simulates a key press.

### What is the correct order of operations for input handling?

Platform callbacks must fire before `ImGui::NewFrame()`. The typical sequence is: (1) Poll native events (`glfwPollEvents`, `PeekMessage`), (2) callbacks populate `ImGuiIO` queues, (3) call `NewFrame()` to process input, (4) render UI. Reversing steps 2 and 3 results in one-frame input latency.

### How do I filter characters entering an InputText widget?

Use the `ImGuiInputTextFlags_CallbackCharFilter` flag when calling `InputText()`, then modify `EventChar` in your callback function. This intercepts characters after they enter `InputQueueCharacters` but before the widget consumes them, allowing you to block specific inputs or convert characters programmatically.