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:
- Native Callback Installation – The backend replaces your window system's event callbacks with wrapper functions (e.g.,
ImGui_ImplGlfw_InstallCallbacksinbackends/imgui_impl_glfw.cpp). - Event Translation – Each wrapper converts native parameters into ImGui-compatible data structures.
- ImGui Ingestion – Wrappers call specific
ImGuiIOmethods:AddMouseButtonEventfor clicks,AddMousePosEventfor cursor movement,AddKeyEventfor keyboard state changes, andAddInputCharacterfor 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 withio.SetKeyEventNativeDatafor 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_InitForOpenGLorImGui_ImplWin32_Initto establish the event translation layer. - Enable callback chaining with
ImGui_ImplGlfw_SetCallbacksChainForAllWindowswhen your application needs parallel access to input events. - Use
ImGuiIOevent 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_NoMouseCursorChangeto 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →