# How to Handle IME (Input Method Editor) Input for International Text in Dear ImGui

> Learn how Dear ImGui handles IME input for international text seamlessly. Discover its platform abstraction layer and callbacks for efficient text input without extra code.

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

---

**Dear ImGui supports IME input for international languages through a platform abstraction layer where `ImGuiPlatformImeData` communicates cursor position and visibility to the OS via the `Platform_SetImeDataFn` callback, requiring no additional application code when using official backends.**

The **ocornut/imgui** library provides robust support for Input Method Editors (IME), enabling users to type non-Latin characters such as Chinese, Japanese, and Korean (CJK) in `InputText` widgets. This functionality relies on a cooperative effort between Dear ImGui's core logic and platform-specific backend implementations to position the IME composition window correctly.

## Understanding the IME Architecture in Dear ImGui

IME support in Dear ImGui is split between a data structure that describes the text input state and a backend function that forwards this data to the operating system.

### The Platform IME Data Structure

The **`ImGuiPlatformImeData`** struct, defined in [[`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h)](https://github.com/ocornut/imgui/blob/master/imgui.h#L4109), contains the information necessary to position the IME candidate window:

- **`WantVisible`** – Boolean indicating whether the IME UI should be displayed
- **`WantTextInput`** – Boolean requesting text input focus from the OS
- **`InputPos`** – Screen coordinates (`ImVec2`) where the IME window should appear
- **`InputLineHeight`** – Height of the text line for proper candidate list positioning
- **`ViewportId`** – Target viewport ID for multi-window setups

### The Backend Hook

The **`Platform_SetImeDataFn`** callback is stored in `ImGuiPlatformIO` (declared at [[`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h)](https://github.com/ocornut/imgui/blob/master/imgui.h#L4064)). Dear ImGui invokes this function pointer at the end of each frame in `ImGui::EndFrame()` (around line 5810 in [[`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp)](https://github.com/ocornut/imgui/blob/master/imgui.cpp#L5810)) to notify the backend of IME state changes.

## How IME Input Works in Dear ImGui

The IME workflow follows a five-step pipeline that bridges OS composition events with Dear ImGui's text input widgets:

1. **OS generates composition events** – When the user types, the OS sends platform-specific messages (e.g., `WM_IME_COMPOSITION` on Windows or `SDL_TEXTINPUT` on SDL).

2. **Backend translates events** – The platform backend (Win32, SDL2, SDL3, etc.) receives these messages and calls `io.AddInputCharacter()` or `io.AddKeyEvent()` to feed them into Dear ImGui.

3. **ImGui calculates cursor position** – After processing widgets, Dear ImGui updates the global `g.PlatformImeData` with the current text cursor screen position and line height.

4. **Backend forwards data** – The `Platform_SetImeDataFn` callback is invoked with the filled `ImGuiPlatformImeData` struct. The backend then calls OS-specific APIs (e.g., `ImmSetCompositionWindow` on Win32, `SDL_SetTextInputRect` on SDL) to position the native IME UI.

5. **OS renders the candidate window** – The operating system displays the IME composition interface at the specified coordinates, allowing character selection.

Because the backend drives this entire pipeline, **most applications require no additional ImGui code** to support international text input.

## Backend-Specific Implementation Details

Different platform backends handle the `Platform_SetImeDataFn` callback in their respective source files.

### Win32 Backend

In [`backends/imgui_impl_win32.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_win32.cpp), the backend processes `WM_IME_COMPOSITION` and `WM_IME_CHAR` messages to handle character composition. When `Platform_SetImeDataFn` is called, the backend translates the `ImGuiPlatformImeData` coordinates and invokes `ImmSetCompositionWindow()` to position the IME candidate list.

### SDL2 and SDL3 Backends

The SDL implementations in [`backends/imgui_impl_sdl2.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_sdl2.cpp) and [`backends/imgui_impl_sdl3.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_sdl3.cpp) follow the same pattern but require specific window hints to enable the IME UI. You must set the **`SDL_HINT_IME_SHOW_UI`** hint to `"1"` before creating the window:

```cpp
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
SDL_Window* window = SDL_CreateWindow("My App", ...);

```

The backend then calls `SDL_SetTextInputRect()` when the IME callback fires.

### Custom Backend Implementation

If you are writing a custom backend, you must implement a function matching the `Platform_SetImeDataFn` signature and assign it to `io.Platform_SetImeDataFn` during initialization.

## Practical Code Examples

### Basic Usage (Zero Configuration)

When using an official backend with IME support enabled, international text input works automatically:

```cpp
// Standard frame loop
ImGui::NewFrame();
ImGui::Begin("Chat Window");
ImGui::InputTextMultiline("##message", buffer, sizeof(buffer));
ImGui::End();
ImGui::Render();

```

For SDL2/SDL3, ensure you set the hint before window creation as shown in the backend section above.

### Customizing IME Cursor Position

To manually control where the IME candidate window appears, modify the `ImGuiPlatformImeData` structure before the frame ends:

```cpp
ImGuiIO& io = ImGui::GetIO();
ImGui::InputText("Username", buf, sizeof(buf));

// Position IME at a specific location
io.PlatformImeData.WantVisible = true;
io.PlatformImeData.WantTextInput = true;
io.PlatformImeData.InputPos = ImGui::GetCursorScreenPos();
io.PlatformImeData.InputLineHeight = ImGui::GetTextLineHeight();

```

### Implementing a Custom Backend IME Hook

For custom backends, implement the callback and register it during setup:

```cpp
void MyBackend_SetImeData(ImGuiContext* ctx, ImGuiViewport* viewport, ImGuiPlatformImeData* data)
{
    MyNativeWindow* window = (MyNativeWindow*)viewport->PlatformHandle;
    
    // Convert ImGui screen coordinates to native window coordinates
    NativeSetCompositionWindow(window, data->InputPos.x, data->InputPos.y, data->InputLineHeight);
    NativeShowIme(data->WantVisible);
}

// During initialization
ImGuiIO& io = ImGui::GetIO();
io.Platform_SetImeDataFn = MyBackend_SetImeData;

```

## Advanced IME Handling Scenarios

Several situations require manual intervention in the IME data.

**Conditional Visibility for Password Fields**
Set `WantVisible = false` to hide the IME candidate window while still receiving composed characters. This is useful for password inputs where you want to prevent on-screen character previews:

```cpp
ImGui::InputText("Password", pass, sizeof(pass), ImGuiInputTextFlags_Password);
io.PlatformImeData.WantVisible = false;

```

**Multi-Viewport Support**
When using multiple viewports with `ImGuiConfigFlags_ViewportsEnable`, the `ViewportId` field in `ImGuiPlatformImeData` indicates which native window should receive the IME data. Custom backends must forward the IME position to the correct window handle associated with that viewport ID.

## Summary

- **IME support** in Dear ImGui relies on the `ImGuiPlatformImeData` struct and `Platform_SetImeDataFn` callback to communicate with the OS.
- **No application code** is required when using official backends like Win32 or SDL, provided SDL applications set `SDL_HINT_IME_SHOW_UI` to `"1"`.
- **Cursor positioning** is handled automatically in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) around line 5810, but can be overridden manually via `io.PlatformImeData`.
- **Custom backends** must implement the `Platform_SetImeDataFn` hook to call native IME APIs such as `ImmSetCompositionWindow` or `SDL_SetTextInputRect`.
- **Advanced features** like hiding the IME UI for password fields or supporting multi-viewport setups require modifying the `WantVisible` and `ViewportId` fields respectively.

## Frequently Asked Questions

### Does Dear ImGui support Chinese, Japanese, and Korean input out of the box?

Yes, Dear ImGui fully supports CJK input through the IME mechanism described in `ImGuiPlatformImeData`. As long as your platform backend implements the `Platform_SetImeDataFn` callback (as seen in [`imgui_impl_win32.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_impl_win32.cpp) and the SDL backends), users can compose international text in `InputText` widgets without additional application code.

### Why isn't the IME candidate window showing in my SDL2 application?

SDL2 requires the **`SDL_HINT_IME_SHOW_UI`** hint to be set to `"1"` before window creation. Without this hint, SDL suppresses the IME composition UI even though it still sends text events. Add `SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");` before calling `SDL_CreateWindow()`, as demonstrated in the official SDL2 examples in the Dear ImGui repository.

### How do I hide the IME UI for password fields while still receiving input?

Set `io.PlatformImeData.WantVisible = false` immediately after the `InputText` widget with the `ImGuiInputTextFlags_Password` flag. This prevents the operating system from displaying the character composition window while still allowing the user to type and confirm their input. Note that you should only modify this field when the widget is active to avoid affecting other text inputs.

### Where is the IME callback actually invoked in the Dear ImGui source code?

The `Platform_SetImeDataFn` callback is invoked in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) around line 5810, inside the `ImGui::EndFrame()` function. This occurs after all widgets have been processed, ensuring that `g.PlatformImeData` contains the final cursor position for the active text input widget for the current frame.