# Creating Popup Modals and Context Menus in Dear ImGui: A Complete Guide

> Master ImGui popup modals and context menus. Learn the three-step pattern OpenPopup BeginPopup CloseCurrentPopup for seamless UI overlays in this complete guide.

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

---

**Dear ImGui implements popups, modals, and context menus as temporary overlay windows managed by an internal popup stack, using a three-step pattern of triggering with `OpenPopup()`, beginning with `BeginPopup()` or `BeginPopupModal()`, and closing automatically or via `CloseCurrentPopup()`.**

When building immediate-mode interfaces with the **ocornut/imgui** repository, creating popup modals and context menus in ImGui follows a consistent stack-based architecture that differs from traditional window management. Unlike persistent window objects, these elements live only for the duration of the frame loop as temporary overlays, making them lightweight, naturally nestable, and simple to implement.

## The Three-Step Popup Lifecycle

Every popup in Dear ImGui follows an identical workflow regardless of whether it is a simple tooltip, a blocking modal dialog, or a right-click context menu. This pattern relies on an internal `g.OpenPopupStack` that tracks which overlays are currently active.

### Step 1: Triggering the Popup

To display a popup, you must first signal Dear ImGui to open it by calling `ImGui::OpenPopup()` or a helper variant such as `ImGui::OpenPopupOnItemClick()`. This function pushes an `ImGuiPopupData` entry onto the global `g.OpenPopupStack`, storing the popup's identifier, opening position, and frame count. According to the source in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) around line 12413, `OpenPopupEx` performs this stack manipulation.

```cpp
if (ImGui::Button("Show Options"))
    ImGui::OpenPopup("MyPopup");  // Stores ID in g.OpenPopupStack

```

### Step 2: Beginning the Popup Window

Inside your frame loop, call `ImGui::BeginPopup()` for standard overlays or `ImGui::BeginPopupModal()` for dialogs that block interaction with the rest of the UI. These functions check `g.OpenPopupStack` against the current `BeginPopupStack` and return **true** only if the popup was actually triggered this frame, allowing you to render contents safely inside the conditional block. The core logic resides in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) near line 12653, where `BeginPopupEx` validates the stack and creates a temporary window with `ImGuiWindowFlags_Popup`.

```cpp
if (ImGui::BeginPopup("MyPopup"))
{
    // Contents only render when popup is active
    ImGui::EndPopup();
}

```

### Step 3: Rendering Content and Handling Closure

Once inside the popup block, add any widgets needed. The overlay closes automatically when the user clicks outside, selects a menu item, or you explicitly call `ImGui::CloseCurrentPopup()`, which removes the top entry from the stack as implemented in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) near line 12575. For modal dialogs, you must also manage a boolean state variable to prevent immediate reopening.

## Core Implementation Details

The robustness of Dear ImGui's popup system comes from its centralized stack management in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp). Key functions include:

- **`OpenPopupEx`** (`imgui.cpp#L12413‑L12430`): Validates the popup ID and appends it to `g.OpenPopupStack`, handling positioning and focus.
- **`BeginPopupEx`** (`imgui.cpp#L12653‑L12663`): Compares the requested ID against the open stack and initializes the window with `ImGuiWindowFlags_Popup` or `ImGuiWindowFlags_Modal`.
- **`CloseCurrentPopup`** (`imgui.cpp#L12575‑L12592`): Pops the topmost entry from the stack, effectively closing the current overlay.

Because popups use string identifiers (or `ImGuiID`) relative to the current ID stack, you can maintain several independent popups simultaneously without naming collisions, and nesting works naturally when a popup trigger is placed inside another popup's block.

## Practical Code Examples

### Simple Popup Window (Non-Modal)

This example demonstrates a basic popup triggered by a button, referencing the "Color Picker" implementation in [`imgui_demo.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_demo.cpp) around line 1255.

```cpp
if (ImGui::Button("Show Popup"))
    ImGui::OpenPopup("MySimplePopup");

if (ImGui::BeginPopup("MySimplePopup"))
{
    ImGui::Text("This is a regular popup.");
    if (ImGui::Button("Close"))
        ImGui::CloseCurrentPopup();  // Optional: clicking elsewhere also closes
    ImGui::EndPopup();
}

```

### Modal Dialog Implementation

Modal windows block background interaction until dismissed. This pattern appears in the "Delete?" confirmation dialog in [`imgui_demo.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_demo.cpp) near line 5554.

```cpp
static bool show_modal = false;
if (ImGui::Button("Delete…")) 
    show_modal = true;

if (show_modal)
    ImGui::OpenPopup("DeleteConfirm");

if (ImGui::BeginPopupModal("DeleteConfirm", nullptr,
                           ImGuiWindowFlags_AlwaysAutoResize))
{
    ImGui::Text("Are you sure you want to delete the item?");
    if (ImGui::Button("Yes"))
    {
        // …perform deletion…
        show_modal = false;
        ImGui::CloseCurrentPopup();
    }
    ImGui::SameLine();
    if (ImGui::Button("Cancel"))
    {
        show_modal = false;
        ImGui::CloseCurrentPopup();
    }
    ImGui::EndPopup();
}

```

### Context Menu on Items

Context menus use helper functions from [`imgui_widgets.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_widgets.cpp) to automatically handle right-click detection. The following pattern appears throughout [`imgui_demo.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_demo.cpp) near lines 2360 and 5466.

```cpp
ImGui::Text("Right‑click me");
if (ImGui::BeginPopupContextItem())   // Uses last item's ID as popup identifier
{
    if (ImGui::MenuItem("Copy"))
        /* …copy logic… */;
    if (ImGui::MenuItem("Delete"))
        /* …delete logic… */;
    ImGui::EndPopup();
}

```

For window-level context menus (triggered by right-clicking the background), use `ImGui::BeginPopupContextWindow()` instead.

## Summary

- **Popups are stack-based**: Dear ImGui uses `g.OpenPopupStack` to manage overlay state, with `OpenPopup()` to push and `CloseCurrentPopup()` to pop.
- **Three functions define the lifecycle**: Trigger with `OpenPopup()`, begin rendering with `BeginPopup()` or `BeginPopupModal()`, and close implicitly or explicitly.
- **Identifiers are hierarchical**: Popup IDs respect the current ID stack, enabling natural nesting and scoping without global name pollution.
- **Reference implementations**: Study [`imgui_demo.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_demo.cpp) for usage patterns, [`imgui_widgets.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_widgets.cpp) for context menu helpers, and [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) for the core stack logic.

## Frequently Asked Questions

### What is the difference between `BeginPopup` and `BeginPopupModal`?

**`BeginPopup`** creates a standard overlay that allows interaction with the rest of the UI and closes automatically when clicking outside. **`BeginPopupModal`** creates a blocking dialog that disables interaction with background windows and requires explicit closure via `CloseCurrentPopup()` or programmatic state management, as shown in the delete confirmation example in `imgui_demo.cpp#L5554‑L5608`.

### Can I nest popups inside other popups in ImGui?

Yes. Because popup identifiers are resolved relative to the current ID stack, you can call `OpenPopup()` and `BeginPopup()` from within another popup's rendering block. Dear ImGui maintains separate entries in `g.OpenPopupStack` for each level, allowing unlimited nesting depth provided each popup has a unique identifier within its parent's scope.

### How do I prevent a popup from closing when the user clicks outside?

Use `ImGui::BeginPopupModal()` instead of `ImGui::BeginPopup()`. Modal windows explicitly block background clicks from closing the overlay and remain open until you call `CloseCurrentPopup()` or manually clear the trigger state. Standard popups created with `BeginPopup()` always close on outside clicks by design.

### What is the difference between `BeginPopupContextItem` and `BeginPopupContextWindow`?

**`BeginPopupContextItem()`** opens a context menu when right-clicking the last drawn item, automatically using that item's ID as the popup identifier. **`BeginPopupContextWindow()`** opens a menu when right-clicking anywhere in the current window's background or empty space. Both helpers are implemented in [`imgui_widgets.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_widgets.cpp) and handle the `OpenPopup()` call internally.