# Debugging Layout Issues with Dear ImGui's Built-in Metrics Window

> Debug Dear ImGui layout issues fast using the built-in metrics window. Diagnose misplaced widgets, clipping errors, and focus problems with real-time UI state.

- Repository: [omar/imgui](https://github.com/ocornut/imgui)
- Tags: how-to-guide
- Published: 2026-07-14

---

**Dear ImGui's Metrics/Debugger window exposes real-time internal UI state—including window rectangles, ID stacks, and draw-list statistics—to rapidly diagnose misplaced widgets, clipping errors, and incorrect focus behavior.**

Dear ImGui (ocornut/imgui) ships with a powerful built-in debugging interface that allows developers to visualize the internal layout engine state while the application runs. Activating `ImGui::ShowMetricsWindow()` provides immediate access to render statistics, window hierarchies, and input routing data. This makes it the primary tool for resolving **debugging layout issues with Dear ImGui's built-in metrics window**.

## Opening the Metrics/Debugger Window

The debugger is exposed through a single function call defined in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp). The implementation at [line 16777](https://github.com/ocornut/imgui/blob/master/imgui.cpp#L16777) handles the entire interface initialization and rendering.

```cpp
bool show_metrics = true;
ImGui::ShowMetricsWindow(&show_metrics);

```

Pass a boolean pointer to control the window's visibility state. When the boolean is `true`, the window renders immediately, capturing the current frame's statistics from the `ImGuiIO` structure.

## Visualizing Window Rectangles and Clipping

One of the most effective features for layout debugging is **Show windows rectangles**, accessible under **Tools → Windows** in the Metrics panel. Enabling this draws colored outlines around every window boundary, revealing exactly where parent and child windows extend.

If a child window clips incorrectly, the outline visibly extends beyond the parent's clipping region. This helps identify **misaligned boundaries** without guessing coordinates or manually checking `ImVec2` calculations.

## Tracking Widget Identity via the ID Stack

Layout issues often stem from **ID collisions** or mismatched `PushID()`/`PopID()` calls. When you hover over any UI element, the **ID Stack** panel (populated at [line 18480 in imgui.cpp](https://github.com/ocornut/imgui/blob/master/imgui.cpp#L18480)) displays the complete hierarchy of ID pushes that generated the final widget identifier.

Mismatched IDs commonly cause widgets to disappear or appear in the wrong location. The stack trace shows exactly which scope introduced the error, allowing you to verify that `PopID()` calls match their corresponding `PushID()` calls.

## Analyzing Render Statistics

The Metrics window aggregates frame-level data updated at specific points in the rendering pipeline:

- **Render vertices/indices**: Read from `io.MetricsRenderVertices` and `io.MetricsRenderIndices`, populated during the render loop at [imgui.cpp:6225](https://github.com/ocornut/imgui/blob/master/imgui.cpp#L6225)
- **Visible windows**: Tracked in `io.MetricsRenderWindows`, incremented at the [frame start](https://github.com/ocornut/imgui/blob/master/imgui.cpp#L5903) (imgui.cpp:5903)
- **Active allocations**: Calculated as `g.DebugAllocInfo.TotalAllocCount - g.DebugAllocInfo.TotalFreeCount` (see [imgui.cpp:722](https://github.com/ocornut/imgui/blob/master/imgui.cpp#L722))

An unusually high vertex count often indicates that a widget is being rendered repeatedly—such as a `Begin()` call missing its corresponding `End()`—which corrupts the layout and wastes GPU resources.

## Inspecting Draw Lists and Input State

### Draw List Diagnostics

Under **Tools → Draw List**, the debugger displays the exact number of vertices per window and texture usage statistics. This data originates from the same buffers built in [`imgui_draw.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_draw.cpp) at [line 2309](https://github.com/ocornut/imgui/blob/master/imgui_draw.cpp#L2309).

Sudden spikes in vertex counts for specific windows reveal redundant drawing operations that indicate layout logic errors, such as widgets being drawn outside their intended containers.

### Input Routing Visualization

The **Inputs** panel shows which widget currently owns a key or mouse button. This data lives in `g.KeyOwner*` structures throughout the input handling code.

If a widget steals focus unintentionally, it prevents other windows from receiving input, making them appear "dead" in the layout. The visualizer highlights the active owner for each input device, revealing focus conflicts.

## Detecting Font Glyph Overlaps

The **Fonts** sub-tab reveals overlapping glyphs from multiple font sources (implemented at [imgui.cpp:532](https://github.com/ocornut/imgui/blob/master/imgui.cpp#L532)). Overlapping glyphs shift baseline metrics and cause vertical spacing glitches that appear as layout issues but originate from font atlas configuration errors.

## Practical Implementation Examples

Integrate the debugger into your application using a menu toggle:

```cpp
bool show_metrics = false;

if (ImGui::BeginMainMenuBar()) {
    if (ImGui::MenuItem("Metrics/Debugger"))
        show_metrics = !show_metrics;
    ImGui::EndMainMenuBar();
}

ImGui::ShowMetricsWindow(&show_metrics);

```

For immediate visual debugging, force the rectangle outlines via configuration flags:

```cpp
ImGui::ShowMetricsWindow(&show_metrics);
ImGui::GetIO().ConfigDebugFlags |= ImGuiConfigFlags_DebugWindows;

```

## Key Source Files

The Metrics window relies on implementation details across the codebase:

| File | Relevance | Key Location |
|------|-----------|--------------|
| [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) | Core `ShowMetricsWindow` implementation and metric counters | [Line 16777](https://github.com/ocornut/imgui/blob/master/imgui.cpp#L16777) |
| [`imgui_draw.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_draw.cpp) | Low-level draw-list handling and vertex buffer construction | [Line 2309](https://github.com/ocornut/imgui/blob/master/imgui_draw.cpp#L2309) |
| [`imgui_internal.h`](https://github.com/ocornut/imgui/blob/main/imgui_internal.h) | Internal structures like `ImGuiMetricsConfig` and allocation tracking | Debug info structures |
| [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h) | Public API declaration for `ShowMetricsWindow` | Public header |

## Summary

- **Dear ImGui's built-in metrics window** is accessed via `ImGui::ShowMetricsWindow()` defined in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp).
- Enable **Show windows rectangles** to visualize clipping boundaries and parent-child relationships.
- Use the **ID Stack** panel to trace mismatched `PushID()` calls that cause widgets to disappear or render in incorrect positions.
- Monitor `io.MetricsRenderVertices` to detect redundant widget rendering that corrupts layout.
- Inspect the **Inputs** panel to identify focus-stealing widgets that make other UI elements unresponsive.
- Check the **Fonts** tab for glyph overlaps that cause vertical spacing issues.

## Frequently Asked Questions

### How do I programmatically open the Metrics window?

Call `ImGui::ShowMetricsWindow(&show_metrics)` where `show_metrics` is a boolean flag. Toggle this flag from a menu item or hotkey to show or hide the debugger at runtime. The function implementation resides at [line 16777 of imgui.cpp](https://github.com/ocornut/imgui/blob/master/imgui.cpp#L16777).

### Why are my child windows clipped incorrectly?

Enable **Tools → Windows → Show windows rectangles** in the Metrics window. If the colored outline extends beyond the parent's bounds, the child window size exceeds its available content region. Adjust the child's `ImVec2` size parameters or ensure proper `BeginChild()`/`EndChild()` pairing to constrain the clipping rectangle.

### What causes unusually high vertex counts in the Draw List?

High vertex counts indicate redundant rendering. This typically occurs when `ImGui::Begin()` is called without a matching `ImGui::End()`, or when widgets are drawn in a loop without proper ID scoping. Check the **Draw List** tab to identify which window generates excess vertices, then verify its begin/end pairs in your code.

### How can I detect which widget is stealing focus?

Open the **Inputs** panel in the Metrics window. This displays the current owner for each keyboard key and mouse button. If a widget appears "dead" or unresponsive, check if another widget owns the input by looking for non-zero owner IDs in the shortcut routing table.