How to Handle Mouse and Keyboard Input Dispatch Between Dear ImGui and Your Application

To handle mouse and keyboard input dispatch between Dear ImGui and your application, initialize a platform backend (such as GLFW or Win32) to capture native OS events, forward them to ImGui via the ImGuiIO event APIs, and optionally chain custom callbacks to process the same events in your application logic.

Dear ImGui uses a platform-agnostic input system that requires you to handle mouse and keyboard input dispatch between Dear ImGui and your application through dedicated backend implementations. The library receives raw hardware events via platform-specific backends like imgui_impl_glfw.cpp or imgui_impl_win32.cpp, which translate native windowing system messages into ImGui's internal event format. Understanding this dispatch pipeline is essential for building interactive applications where both ImGui widgets and your custom rendering logic must respond to user input.

Understanding the Platform Backend Architecture

Dear ImGui delegates all platform-specific input handling to backend implementations that bridge your operating system's windowing API with ImGui's abstract ImGuiIO interface. These backends install native event callbacks during initialization, translate OS-specific messages (such as GLFW mouse buttons or Win32 WM_* messages) into portable events, and feed them to the current context through the Add*Event API family.

The Event Translation Pipeline

When you initialize a backend like GLFW, the system establishes a data flow from raw OS events to ImGui's internal state:

  1. Native Callback Installation – The backend replaces your window system's event callbacks with wrapper functions (e.g., ImGui_ImplGlfw_InstallCallbacks in backends/imgui_impl_glfw.cpp).
  2. Event Translation – Each wrapper converts native parameters into ImGui-compatible data structures.
  3. ImGui Ingestion – Wrappers call specific ImGuiIO methods: AddMouseButtonEvent for clicks, AddMousePosEvent for cursor movement, AddKeyEvent for keyboard state changes, and AddInputCharacter for text entry.

Implementing Input Dispatch with GLFW

The GLFW backend demonstrates the canonical pattern for handling mouse and keyboard input dispatch between Dear ImGui and your application. Located in backends/imgui_impl_glfw.cpp, this implementation supports both exclusive ImGui processing and shared event consumption.

Basic Initialization with Automatic Callbacks

For applications where ImGui handles all input, initialize the backend with automatic callback installation:

// Create context and configure IO
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;

// Initialize GLFW backend (true = install callbacks)
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init("#version 150");

Setting the second parameter to true invokes ImGui_ImplGlfw_InstallCallbacks, which stores your existing GLFW callbacks internally and registers ImGui's wrapper functions for mouse, keyboard, and scroll events.

Chaining Custom Application Callbacks

When your application requires access to raw input events alongside ImGui, enable callback chaining to preserve both processing paths:

// Install your custom callback first
GLFWmousebuttonfun prevCallback = glfwSetMouseButtonCallback(window, MyMouseButtonCallback);

// Initialize ImGui (stores prevCallback internally)
ImGui_ImplGlfw_InitForOpenGL(window, true);

// Enable chaining so ImGui wrappers call your callbacks
ImGui_ImplGlfw_SetCallbacksChainForAllWindows(true);

With chaining enabled, ImGui's wrapper functions (defined in backends/imgui_impl_glfw.cpp) invoke your stored previous callbacks before calling io.AddMouseButtonEvent and related functions. This allows your application logic to process mouse coordinates and button states while still feeding the same events to ImGui's widget system.

Core ImGuiIO Event APIs

The ImGuiIO structure provides atomic methods for injecting specific event types, which backends call after translating native windowing messages:

  • Mouse buttons: io.AddMouseButtonEvent(button, bool down) processes clicks.
  • Cursor position: io.AddMousePosEvent(x, y) updates mouse coordinates.
  • Scroll wheels: io.AddMouseWheelEvent(x, y) handles horizontal and vertical scrolling.
  • Keyboard: io.AddKeyEvent(key, bool down) registers key state changes, often paired with io.SetKeyEventNativeData for platform-specific key codes.
  • Text input: io.AddInputCharacter(c) accepts Unicode character values from the OS text input system.

These functions queue events for the current frame, which ImGui::NewFrame processes to update widget states and navigation.

Managing Multiple Viewports and Contexts

For multi-window applications using ImGui viewports, the GLFW backend maintains an internal map (g_ContextMap) that associates each GLFWwindow* with its active ImGuiContext*. When processing events, the backend retrieves the correct context via ImGui_ImplGlfw_GetBackendData(window) before calling the Add*Event functions. This architecture ensures that input events route to the appropriate ImGui instance even when multiple windows and contexts exist simultaneously.

Controlling Mouse Cursor Behavior

By default, ImGui updates the OS mouse cursor shape based on hover states (text input, resize handles, etc.). To handle mouse and keyboard input dispatch between Dear ImGui and your application without cursor interference, disable automatic cursor management:

io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange;
// Or completely disable mouse input processing:
io.ConfigFlags |= ImGuiConfigFlags_NoMouse;

The ImGui_ImplGlfw_UpdateMouseCursor function (called during ImGui_ImplGlfw_NewFrame) checks these flags before invoking glfwSetCursor to modify the system cursor appearance.

Win32 Backend Considerations

If using the Win32 backend (backends/imgui_impl_win32.cpp), the pattern remains identical but uses message procedures rather than GLFW callbacks. The entry point ImGui_ImplWin32_WndProcHandler processes WM_LBUTTONDOWN, WM_KEYDOWN, and related messages, calling the same ImGuiIO event APIs. For pointer device discrimination (pen versus touch), the Win32 backend additionally injects io.AddMouseSourceEvent to distinguish between input types.

Summary

  • Initialize backends using ImGui_ImplGlfw_InitForOpenGL or ImGui_ImplWin32_Init to establish the event translation layer.
  • Enable callback chaining with ImGui_ImplGlfw_SetCallbacksChainForAllWindows when your application needs parallel access to input events.
  • Use ImGuiIO event APIs (AddMouseButtonEvent, AddKeyEvent, etc.) to manually inject events if implementing custom backends.
  • Manage multiple contexts through the backend's internal window-to-context mapping for viewport support.
  • Configure cursor behavior via ImGuiConfigFlags_NoMouseCursorChange to prevent ImGui from modifying system cursor states.

Frequently Asked Questions

How do I prevent ImGui from consuming all mouse input?

Set ImGuiConfigFlags_NoMouse in io.ConfigFlags to disable ImGui's internal mouse processing, or enable callback chaining in the GLFW backend using ImGui_ImplGlfw_SetCallbacksChainForAllWindows(true) to ensure your application's callbacks execute alongside ImGui's event processing.

Can I use multiple ImGui contexts with different windows?

Yes. The GLFW backend maintains a global g_ContextMap that associates each GLFWwindow* with its corresponding ImGuiContext*. When events arrive, ImGui_ImplGlfw_GetBackendData retrieves the correct context, ensuring input dispatch routes to the appropriate instance even with multiple active viewports.

How do I disable ImGui's automatic cursor changes?

Set io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange before calling ImGui_ImplGlfw_NewFrame. This prevents ImGui_ImplGlfw_UpdateMouseCursor from calling glfwSetCursor, allowing your application to maintain full control over the OS cursor appearance.

What is the difference between AddKeyEvent and AddInputCharacter?

AddKeyEvent registers physical key state changes (e.g., "A key pressed") for keyboard navigation and shortcuts, while AddInputCharacter submits text input values (e.g., the Unicode character 'a') for text widgets. The former handles hardware scancodes; the latter handles OS text composition and character encoding.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →