This document describes Dear ImGui's input handling and navigation systems. These systems enable user interaction through mouse, keyboard, and gamepad inputs, and provide keyboard/gamepad navigation for accessibility and console/TV applications. The input system manages how input events flow from platform backends into the library and how they are routed to individual widgets. The navigation system enables directional movement between UI elements without a mouse.
For information about backend implementation of input handling, see Backend Architecture. For text input specifics, see Text Input System.
Dear ImGui uses an event-based input system where platform backends submit input events to the ImGuiIO structure each frame. These events are processed during NewFrame() and consumed by widgets throughout the frame.
The ImGuiIO structure serves as the primary interface for input data. Platform backends call event functions to submit input:
| Event Function | Purpose |
|---|---|
AddKeyEvent(ImGuiKey key, bool down) | Submit keyboard key press/release |
AddKeyAnalogEvent(ImGuiKey key, bool down, float v) | Submit analog key/axis (gamepad) |
AddMousePosEvent(float x, float y) | Submit mouse position |
AddMouseButtonEvent(int button, bool down) | Submit mouse button press/release |
AddMouseWheelEvent(float x, float y) | Submit mouse wheel movement |
AddInputCharacter(unsigned int c) | Submit text input character (UTF-32) |
AddFocusEvent(bool focused) | Submit window focus state |
Input Event Flow
Sources: imgui.cpp6000-6300 imgui.h2200-2500 imgui_internal.h2100-2200
Dear ImGui distinguishes between three input sources, tracked by the ImGuiInputSource enum:
The input source affects behavior such as:
Sources: imgui.cpp11500-12000 imgui_internal.h1450-1470
The ID stack is fundamental to Dear ImGui's input routing. Every widget requires a unique ID within its scope to track state across frames. IDs are used for input routing, state storage, and navigation targeting.
IDs are generated by hashing string labels or explicit ID values. The current ID stack context affects the final hash:
Key Functions:
PushID(const char*) / PushID(int) / PushID(void*) - Push ID component onto stackPopID() - Pop ID component from stackGetID(const char*) - Generate ID from label in current stack contextGetItemID() - Get ID of last submitted itemThe "###" operator in labels separates the visible label from the ID portion:
"Save###save_button" → Display "Save", ID derived from "save_button"Sources: imgui.cpp8700-8900 imgui_internal.h365-368
Both buttons can have label "OK" because they're in different ID stack contexts.
Sources: imgui.cpp8700-8900 imgui_demo.cpp2500-2600
Keyboard and gamepad navigation enables full UI control without a mouse, essential for console platforms, accessibility, and power users.
Enable navigation via configuration flags in ImGuiIO:
| Flag | Purpose |
|---|---|
ImGuiConfigFlags_NavEnableKeyboard | Enable keyboard navigation (Tab, arrows, etc.) |
ImGuiConfigFlags_NavEnableGamepad | Enable gamepad navigation |
ImGuiConfigFlags_NavNoCaptureKeyboard | Don't set io.WantCaptureKeyboard during navigation |
When enabled, additional output flags indicate navigation state:
io.NavActive - Navigation is active (window has focus and can navigate)io.NavVisible - Navigation cursor is visibleSources: imgui.h2200-2300 imgui.cpp154-174
Sources: imgui.cpp154-185 imgui_demo.cpp8500-8600
Dear ImGui uses two navigation layers that can be toggled with Alt or Gamepad Y button:
| Layer | Description | Usage |
|---|---|---|
ImGuiNavLayer_Main | Main layer (default) | Regular widgets, most content |
ImGuiNavLayer_Menu | Menu layer | Menu bars, popups, window titles |
Sources: imgui.cpp11500-11800 imgui_internal.h1420-1450
The navigation system maintains state in ImGuiContext (accessible via g. in internal code):
Key State Variables:
g.NavId - ID of currently navigated itemg.NavWindow - Window containing navigated itemg.NavLayer - Current navigation layerg.NavDisableHighlight - Whether to show highlightg.NavDisableMouseHover - Disable mouse hover during navg.NavMoveDir - Direction of current move requestg.NavMoveFlags - Flags for move requestg.NavMoveResultLocal - Best candidate within current windowg.NavMoveResultOther - Best candidate in other windowsSources: imgui.cpp11500-13500 imgui_internal.h2300-2400
When a navigation direction is requested (e.g., pressing the down arrow), Dear ImGui:
g.NavIdThe scoring algorithm prioritizes:
Sources: imgui.cpp12200-12800 imgui_internal.h3300-3350
The shortcuts system enables global or local keyboard shortcuts with proper input routing and conflict resolution.
Key Functions:
Shortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags = 0) - Test if shortcut is pressedSetNextItemShortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags = 0) - Assign shortcut to next itemImGuiKeyChord: A key combined with optional modifiers:
ImGuiKey_A - Just 'A' keyImGuiMod_Ctrl | ImGuiKey_S - Ctrl+SImGuiMod_Ctrl | ImGuiMod_Shift | ImGuiKey_Z - Ctrl+Shift+ZSources: imgui.cpp9700-10100 imgui.h3000-3050
The ImGuiInputFlags enum controls how shortcuts are routed:
| Flag | Behavior |
|---|---|
ImGuiInputFlags_None | Default routing to hovered/active item |
ImGuiInputFlags_RouteActive | Route only to active item |
ImGuiInputFlags_RouteFocused | Route only to focused item |
ImGuiInputFlags_RouteGlobal | Route globally (when nothing is active/focused) |
ImGuiInputFlags_RouteAlways | Always route (bypass regular routing) |
ImGuiInputFlags_Repeat | Enable key repeat |
Example Usage:
Sources: imgui_internal.h1470-1520 imgui.cpp9700-10200
The Active ID system tracks which widget currently "owns" input, preventing conflicts when multiple widgets want the same input.
Key State Variables:
g.ActiveId - ID of currently active item (ImGuiID)g.ActiveIdSource - Input source that activated (Mouse/Keyboard/Gamepad)g.ActiveIdIsJustActivated - True on activation frameg.ActiveIdTimer - Time since activationg.ActiveIdWindow - Window containing active itemSources: imgui.cpp9200-9500 imgui_internal.h2200-2250
Widgets can "steal" active ID from others for behaviors like drag-and-drop.
Sources: imgui.cpp9200-9600 imgui_widgets.cpp500-800
Navigation and focus systems work together to provide keyboard control:
Window Focus:
FocusWindow() - Set focused windowIsWindowFocused(flags) - Check if window has focusSetWindowFocus() - Request focus for windowItem Focus:
SetKeyboardFocusHere(offset = 0) - Request focus for next item (or offset items ahead)Sources: imgui.cpp7500-7800 imgui.cpp11000-11200
Understanding when input is processed helps with correct API usage:
Important Timing Notes:
NewFrame()NewFrame()io.WantCaptureKeyboard are updated DURING frameRender()Sources: imgui.cpp4500-4800 imgui.cpp6000-6300
When dragging, Dear ImGui can capture the mouse to track movement even outside the window:
io.ConfigWindowsMoveFromTitleBarOnly - Restrict window dragging to title bario.MouseDrawCursor - Let ImGui draw mouse cursor (for software cursor)io.WantCaptureMouse - Application should not process mouse inputImGuiBackendFlags_HasMouseCursors for cursor changesio.WantCaptureKeyboard - Application should not process keyboardio.WantTextInput - Text input widget is active (show on-screen keyboard)io.AddInputCharacter() for text (not key events)For non-ASCII text input:
io.SetPlatformImeDataFn - Callback to position IME windowSources: imgui.cpp6000-6200 imgui.h2300-2500 backends/imgui_impl_win32.cpp300-400
Advanced navigation behavior can be configured via ImGuiIO:
| Option | Default | Description |
|---|---|---|
ConfigNavMoveSetMousePos | false | Move mouse cursor with navigation |
ConfigNavCaptureKeyboard | true | Set io.WantCaptureKeyboard when navigating |
Window-level navigation flags in ImGuiWindowFlags:
ImGuiWindowFlags_NoNav - Disable all navigation in this windowImGuiWindowFlags_NoNavInputs - Disable navigation input (but allow focus)ImGuiWindowFlags_NoNavFocus - Prevent window from being focused via navigationItem-level navigation flags in ImGuiItemFlags (internal):
ImGuiItemFlags_NoNav - Item is not navigableImGuiItemFlags_NoNavDefaultFocus - Item won't be default focus targetSources: imgui.h2200-2300 imgui.h1650-1750 imgui_internal.h1050-1100
When implementing a platform backend, follow this input submission pattern:
NewFrame()io.WantCaptureMouse - Don't process mouse in applicationio.WantCaptureKeyboard - Don't process keyboard in applicationio.WantSetMousePos - Move OS cursor to io.MousePosGamepad Support:
io.BackendFlags |= ImGuiBackendFlags_HasGamepadAddKeyAnalogEvent(ImGuiKey_GamepadXXX, ...)Sources: imgui.cpp280-360 docs/BACKENDS.md backends/imgui_impl_glfw.cpp400-600
Refresh this wiki