# Handling IME for International Text Input in Dear ImGui: A Complete Guide

> Master IME for international text input in Dear ImGui. This guide explains how platform backends handle OS composition events for CJK and complex script input.

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

---

**Dear ImGui supports Input Method Editor (IME) integration through platform-specific backends that forward OS composition events to the input buffer, enabling CJK and complex script input.**

Dear ImGui provides built-in infrastructure for handling IME for international text input, allowing users to type Chinese, Japanese, Korean, and other complex scripts. The implementation spans both the core library in `ocornut/imgui` and platform-specific backend files that translate native OS events into ImGui input. Understanding this architecture is essential for applications that require robust multilingual text entry beyond basic ASCII input.

## Core IME Architecture in ImGui

The IME system centers on the **ImGuiPlatformImeData** structure stored within **ImGuiIO**, which acts as the communication bridge between ImGui's input handling and the operating system's text composition services.

### ImGuiIO and PlatformImeData

In [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) at line 5810, the `ImGuiIO` structure contains an `ImGuiPlatformImeData` field that tracks the current cursor position and the **WantTextInput** flag. This flag signals to platform backends when to activate or deactivate the IME composition window. The `PlatformImeData` structure also includes a `Ready` boolean and `Pos` vector that determines where the OS should display the candidate window relative to the active text widget.

### Per-Frame IME State Management

At the beginning of every frame, ImGui clears the IME data to ensure fresh state for the current input context (line 6102 in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp)). After the UI construction phase completes, ImGui calls the platform-specific IME update function between lines 6102-6105 to notify the OS of cursor movements. This two-phase approach ensures that the composition window position updates only after the final widget layout is determined.

When `IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS` is not defined, ImGui automatically installs a default Win32 IME handler at lines 16349-16385 in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) that forwards composition results to the input buffer using `ImmSetCompositionWindow`.

## Platform Backend Implementations

Platform backends handle the translation of native IME events into ImGui's character input system. Each major platform implements specific message handlers or event callbacks to capture composition strings.

### Win32 Backend (WM_IME_COMPOSITION)

The Win32 backend in [`backends/imgui_impl_win32.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_win32.cpp) processes WM_IME_COMPOSITION messages at line 800 to capture ongoing text composition. When the `GCS_RESULTSTR` flag indicates a completed composition, the backend forwards the final string to ImGui via `io.AddInputCharacterUTF16`. For legacy MBCS applications, the backend also handles WM_IME_CHAR at line 808, converting ANSI characters to Unicode before injection.

### SDL2 and SDL3 Backends

The SDL2 backend enables native IME UI support through the **SDL_HINT_IME_SHOW_UI** hint, which example projects set before window creation in [`examples/example_sdl2_opengl3/main.cpp`](https://github.com/ocornut/imgui/blob/main/examples/example_sdl2_opengl3/main.cpp). At lines 117-124 in [`backends/imgui_impl_sdl2.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_sdl2.cpp), the backend monitors `ImGuiPlatformImeData::WantTextInput` to call `SDL_StartTextInput` or `SDL_StopTextInput`, opening and closing the IME composition window on mobile and desktop platforms.

The SDL3 backend follows a similar pattern but adds guards against double-calling `SDL_StartTextInput` at lines 117-124 in [`backends/imgui_impl_sdl3.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_sdl3.cpp), while also respecting `WantTextInput` for on-screen keyboard activation.

## Enabling IME in Your Application

To activate IME support in your Dear ImGui application, you must configure both the core library flags and the platform backend state.

First, ensure your platform backend is compiled into the project (e.g., `#include "backends/imgui_impl_win32.cpp"`). Do not define `IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS` unless implementing custom IME handling.

Next, set the configuration flags in your initialization code:

```cpp
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;  // Required for IME cursor
io.ConfigFlags |= ImGuiConfigFlags_EnableIme;          // Explicitly enable IME (since v1.91)

```

After laying out UI elements that require text input, update the `ImGuiPlatformImeData` structure to position the composition window:

```cpp
ImGuiPlatformImeData& ime = io.PlatformImeData;
ime.Ready = true;
ime.Pos = ImGui::GetCursorScreenPos();  // Position for IME candidate window
ime.WantTextInput = true;               // Request text input activation

```

ImGui automatically calls the backend's update function during `ImGui::Render()`, which notifies the OS of the cursor location.

## Code Examples

The following examples demonstrate complete IME integration for Win32 and SDL2 platforms.

### Win32 Integration Example

```cpp
#include "imgui.h"
#include "backends/imgui_impl_win32.cpp"
#include "backends/imgui_impl_opengl3.cpp"

int main()
{
    // Initialize window and OpenGL context...
    ImGui::CreateContext();
    ImGuiIO& io = ImGui::GetIO();
    io.ConfigFlags |= ImGuiConfigFlags_EnableIme;

    while (!glfwWindowShouldClose(window))
    {
        ImGui_ImplWin32_NewFrame();
        ImGui_ImplOpenGL3_NewFrame();
        ImGui::NewFrame();

        static char buf[256] = "";
        ImGui::InputText("Japanese Input", buf, sizeof(buf));

        if (ImGui::IsItemActive())
        {
            ImGuiPlatformImeData& ime = io.PlatformImeData;
            ime.Ready = true;
            ime.Pos = ImGui::GetItemRectMax();
            ime.WantTextInput = true;
        }

        ImGui::Render();
        ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
        // Swap buffers and poll events...
    }
}

```

### SDL2 Native IME UI

```cpp
// Must be called before SDL_CreateWindow
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");

SDL_Window* window = SDL_CreateWindow("IME Example", 
    SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 
    1280, 720, SDL_WINDOW_OPENGL);

ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_EnableIme;

```

## Summary

- **ImGuiPlatformImeData** in `ImGuiIO` stores cursor position and `WantTextInput` flags that control IME activation
- The core library resets IME state each frame at line 6102 in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) and triggers platform updates after UI layout
- Win32 backends handle `WM_IME_COMPOSITION` at line 800 and `WM_IME_CHAR` at line 808 in [`imgui_impl_win32.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_impl_win32.cpp)
- SDL2/3 backends use `SDL_StartTextInput` and `SDL_StopTextInput` at lines 117-124, controlled by the `WantTextInput` flag
- Enable IME explicitly by setting `ImGuiConfigFlags_EnableIme` in the `io.ConfigFlags` (available since Dear ImGui 1.91)
- Position the candidate window by updating `io.PlatformImeData.Pos` when text widgets are active

## Frequently Asked Questions

### How do I enable IME support in Dear ImGui?

Set the `ImGuiConfigFlags_EnableIme` flag in `ImGuiIO::ConfigFlags` and ensure your platform backend (Win32, SDL2, or SDL3) is properly integrated. For Win32, avoid defining `IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS` to use the built-in handlers at lines 16349-16385 in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp).

### Why is the IME composition window not appearing?

Verify that `io.PlatformImeData.WantTextInput` is set to `true` when your text widget is active, and that `io.PlatformImeData.Pos` contains valid screen coordinates. For SDL2, ensure you called `SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1")` before creating the window.

### Does Dear ImGui support mobile on-screen keyboards via IME?

Yes. The SDL2 and SDL3 backends automatically call `SDL_StartTextInput` and `SDL_StopTextInput` based on the `WantTextInput` flag, which triggers the on-screen keyboard on mobile platforms. This implementation is located at lines 117-124 in both [`imgui_impl_sdl2.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_impl_sdl2.cpp) and [`imgui_impl_sdl3.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_impl_sdl3.cpp).

### How do I position the IME candidate window correctly?

Update `io.PlatformImeData.Pos` with the screen coordinates where the composition window should appear, typically at the cursor location or the end of the active text field. Set `io.PlatformImeData.Ready = true` and `io.PlatformImeData.WantTextInput = true` after calling `ImGui::InputText()` or similar widgets, and ImGui will forward this position to the OS during the render phase.