How ImGuiIO Configuration Controls Input Handling and Frame Timing in Dear ImGui

The ImGuiIO structure serves as the single bidirectional interface between your application and Dear ImGui, dictating how input events are queued and processed, how frame timing drives animations, and which UI features are active.

Dear ImGui (ocornut/imgui) centralizes all platform communication through the ImGuiIO structure defined in imgui.h. Proper ImGuiIO configuration determines whether your UI responds correctly to high-DPI displays, maintains responsiveness during frame drops, and captures input exclusively when needed. Understanding these fields allows developers to bridge their platform backend with ImGui's immediate-mode rendering system effectively.

Input Queue and Event Processing

The backend pushes raw OS events into Dear ImGui via Add* functions such as AddKeyEvent and AddMousePosEvent (defined at lines 2556–2565 in imgui.h). These functions populate an internal queue that ImGui::NewFrame() consumes at the start of each render loop.

The ConfigInputTrickleEventQueue field (default: true) controls event distribution. When enabled, rapid sequences like "mouse-down + mouse-up" submitted within the same application frame are spread across multiple ImGui frames. This prevents event collapse during low frame rates, ensuring that quick clicks register as distinct actions rather than being merged into a single frame.

Frame Timing and Animation Control

Timing behavior is governed by the DeltaTime field (default: 1.0f/60.0f), which represents the elapsed seconds since the previous frame. In imgui.cpp (lines 215–245), the NewFrame() implementation uses DeltaTime to update the internal frame counter and calculate the moving-average framerate stored in io.Framerate. Incorrect values here directly distort animation speeds, tooltip delays, and scroll momentum.

For persistence, IniSavingRate (default: 5.0f seconds) sets the minimum interval between automatic .ini file writes. This prevents disk I/O thrashing while ensuring window layouts and settings are preserved periodically.

Display Configuration and High-DPI Handling

Viewport dimensions and scaling are configured through two critical vectors:

  • DisplaySize: Sets the main viewport dimensions in pixels (updated each frame by the backend). This value drives clipping rectangles and mouse coordinate conversion.
  • DisplayFramebufferScale: Defines the ratio between framebuffer pixels and screen-space pixels (e.g., 2.0f for Retina displays). This affects font rasterization and the FramebufferScale value passed to renderers.

These fields reside in the configuration section of imgui.h (lines 2435–2440) and must be set before the first NewFrame() call.

Configuration Flags and Backend Capabilities

ImGuiIO stores two distinct flag bitfields that negotiate capabilities between the application and backend:

ConfigFlags (application-controlled): Enables global features such as docking (ImGuiConfigFlags_DockingEnable), multi-viewports (ImGuiConfigFlags_ViewportsEnable), and keyboard navigation. Toggling these flags triggers resource allocation inside NewFrame().

BackendFlags (backend-controlled): Set by the platform layer (e.g., line 124 in backends/imgui_impl_glfw.cpp) to advertise capabilities like mouse cursor support (ImGuiBackendFlags_HasMouseCursors) or platform clipboard access. ImGui only queries features explicitly flagged as available.

Input Capture and Navigation Output

After processing input, ImGuiIO sets several output booleans that signal the application to withhold events from underlying game logic:

  • WantCaptureMouse: True when hovering or interacting with any ImGui window. The application should not process game mouse events when this is set.
  • WantCaptureKeyboard: True when an InputText widget is active or navigation requires keyboard focus.
  • WantTextInput: Signals that an on-screen keyboard should be displayed (relevant for mobile/console platforms).
  • WantSetMousePos: Indicates the backend must reposition the OS cursor, typically when ConfigNavMoveSetMousePos is enabled for TV-style navigation.

These capture flags are updated during NewFrame() based on the current widget state (referenced at lines 7879–7885 in imgui.h).

Interaction Timing Parameters

Several float values fine-tune gesture recognition and auto-repeat behavior:

  • MouseDoubleClickTime (0.30s) and MouseDoubleClickMaxDist (6px): Thresholds used by IsMouseDoubleClicked() to distinguish double-clicks from separate actions.
  • MouseDragThreshold (6px): Minimum pixel movement before IsMouseDragging() returns true, preventing accidental drags on touchpads.
  • KeyRepeatDelay (0.275s) and KeyRepeatRate (0.050s): Control the initial wait and subsequent frequency of repeated key events when holding buttons.

Practical Configuration Examples

Below are three minimal snippets demonstrating common ImGuiIO configuration patterns.

Basic Display and Timing Setup

ImGuiIO& io = ImGui::GetIO();
io.DisplaySize = ImVec2((float)windowWidth, (float)windowHeight);
io.DisplayFramebufferScale = ImVec2(hiDPI ? 2.0f : 1.0f);
io.DeltaTime = 1.0f / 60.0f;  // Update with actual frame time each loop

Enabling Docking and Multi-Viewports

ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
// Backend must also set BackendFlags_HasMouseCursors and 
// BackendFlags_PlatformHasViewports (see imgui_impl_glfw.cpp)

Custom Input Timing for Competitive Games

ImGuiIO& io = ImGui::GetIO();
io.ConfigInputTrickleEventQueue = true;  // Prevent input loss at low FPS
io.MouseDoubleClickTime = 0.25f;         // Faster double-click detection
io.MouseDoubleClickMaxDist = 4.0f;       // Tighter tolerance
io.KeyRepeatRate = 0.030f;               // Faster key repeat

Summary

  • ImGuiIO acts as the exclusive communication bridge between your application and Dear ImGui, defined in imgui.h (lines 2429–2639).
  • DeltaTime drives all temporal behavior; incorrect values distort animations and the internal framerate estimator.
  • ConfigInputTrickleEventQueue ensures reliable input during frame drops by distributing rapid events across multiple frames.
  • Capture flags (WantCaptureMouse, WantCaptureKeyboard) allow the application to filter input and prevent game logic from processing UI interactions.
  • BackendFlags and ConfigFlags negotiate feature support between the platform layer and ImGui core, with backends setting capabilities in files like imgui_impl_glfw.cpp.

Frequently Asked Questions

What happens if DeltaTime is set incorrectly in ImGuiIO?

Incorrect DeltaTime values cause UI animations to run too fast or too slow, and affect tooltip delays, scrolling inertia, and the io.Framerate calculation. Always set this to the actual elapsed time between frames, or to a fixed timestep for deterministic behavior in specific scenarios.

How does ConfigInputTrickleEventQueue improve input reliability?

When enabled, ConfigInputTrickleEventQueue prevents rapid input sequences (such as quick mouse clicks) from being collapsed into a single frame when the application runs at low frame rates. This ensures that distinct physical actions generate distinct logical events within Dear ImGui's immediate-mode loop.

What is the difference between ConfigFlags and BackendFlags?

ConfigFlags are set by the application to enable ImGui features like docking or viewports, while BackendFlags are set by the platform backend (e.g., GLFW, SDL) to advertise hardware capabilities such as mouse cursor control or clipboard access. ImGui only attempts to use features that are enabled in ConfigFlags and supported according to BackendFlags.

When should an application check WantCaptureMouse?

Check io.WantCaptureMouse immediately after calling ImGui::NewFrame() but before processing game input. If this flag is true, the application should consume mouse events for ImGui and skip passing them to the underlying game world or camera controls.

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 →