Handling IME for International Text Input in Dear ImGui: A Complete Guide
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 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). 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 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 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. At lines 117-124 in 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, 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:
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:
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
#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
// 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
ImGuiIOstores cursor position andWantTextInputflags that control IME activation - The core library resets IME state each frame at line 6102 in
imgui.cppand triggers platform updates after UI layout - Win32 backends handle
WM_IME_COMPOSITIONat line 800 andWM_IME_CHARat line 808 inimgui_impl_win32.cpp - SDL2/3 backends use
SDL_StartTextInputandSDL_StopTextInputat lines 117-124, controlled by theWantTextInputflag - Enable IME explicitly by setting
ImGuiConfigFlags_EnableImein theio.ConfigFlags(available since Dear ImGui 1.91) - Position the candidate window by updating
io.PlatformImeData.Poswhen 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.
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 and 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →