# How to Create Popups, Modals, and Context Menus in Dear ImGui

> Learn to create popups modals and context menus in Dear ImGui using a simple three step pattern. Guide covers opening starting and styling these essential UI elements.

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

---

**Dear ImGui creates popups, modals, and context menus using a three-step pattern where you trigger the overlay with `ImGui::OpenPopup()`, begin it with `ImGui::BeginPopup()` or `ImGui::BeginPopupModal()`, and render content inside a conditional block that automatically closes when the user clicks outside or you call `ImGui::CloseCurrentPopup()`.**

Dear ImGui (ocornut/imgui) implements these UI elements as temporary overlay windows managed by an internal popup stack. To create popups, modals, and context menus in ImGui, you follow a consistent workflow defined in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) that relies on unique identifiers and stack-based state management. This approach allows multiple independent popups to coexist while supporting natural nesting through the ID stack.

## The Three-Step Popup Lifecycle

Every popup in Dear ImGui follows the same execution pattern, implemented in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) (lines 12413-12430 for `OpenPopupEx` and 12653-12663 for `BeginPopup`):

1. **Trigger the popup** – Call `ImGui::OpenPopup()` to push a `ImGuiPopupData` entry onto `g.OpenPopupStack`. This stores the popup ID, opening position, and frame count. You can also use helpers like `ImGui::OpenPopupOnItemClick()` or `ImGui::BeginPopupContextItem()` to trigger automatically on user interaction.
2. **Begin the popup** – Call `ImGui::BeginPopup()` for regular popups, `ImGui::BeginPopupModal()` for modal dialogs, or `ImGui::BeginPopupContextItem()` for context menus. These functions return `true` only when the popup is actually opened, allowing you to safely render contents inside the conditional block.
3. **Render content and close** – Add any ImGui widgets inside the block. The popup closes automatically when the user clicks outside, selects a menu item, or you explicitly call `ImGui::CloseCurrentPopup()` (implemented in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp), lines 12575-12592).

## Creating a Simple Popup

A standard popup appears when triggered and closes when clicking outside. According to the demo code in [`imgui_demo.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_demo.cpp) (lines 1250-1259), you can implement a button-triggered popup like this:

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

// Render content only when open
if (ImGui::BeginPopup("MySimplePopup"))
{
    ImGui::Text("This is a regular popup.");
    if (ImGui::Button("Close"))
        ImGui::CloseCurrentPopup();  // Optional manual close
    ImGui::EndPopup();
}

```

The identifier `"MySimplePopup"` is hashed into an `ImGuiID` and checked against `g.OpenPopupStack` each frame. Because identifiers are relative to the current ID stack, nesting popups inside other UI elements works naturally.

## Building a Modal Dialog

Modal windows block interaction with the rest of the UI until dismissed. The implementation in [`imgui_demo.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_demo.cpp) (lines 5554-5608) demonstrates a confirmation dialog pattern:

```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 logic here
        show_modal = false;
        ImGui::CloseCurrentPopup();
    }
    ImGui::SameLine();
    if (ImGui::Button("Cancel"))
    {
        show_modal = false;
        ImGui::CloseCurrentPopup();
    }
    ImGui::EndPopup();
}

```

Unlike regular popups, `BeginPopupModal()` creates a window with `ImGuiWindowFlags_Modal` that darkens the background and prevents clicking through to other windows.

## Implementing Context Menus

Context menus open when right-clicking specific items or window space. The helper functions in [`imgui_widgets.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_widgets.cpp) wrap the three-step pattern into convenient calls. As shown in [`imgui_demo.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_demo.cpp) (lines 2360 and 5466-5485) and [`imgui_tables.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_tables.cpp) (lines 3661-3670):

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

```

`BeginPopupContextItem()` combines the trigger check and begin step, opening the popup when you right-click the preceding item. For window-level context menus, use `BeginPopupContextWindow()` instead.

## Understanding the Popup Stack

The underlying architecture relies on two stacks in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp): `g.OpenPopupStack` (popups waiting to be opened) and `g.BeginPopupStack` (currently active popups). When you call `OpenPopup()`, the system pushes an `ImGuiPopupData` entry containing the ID and desired position. During the next frame, `BeginPopup()` checks if your ID matches the top of the open stack before creating the temporary window with `ImGuiWindowFlags_Popup`.

This stack-based design means:
- You can have several independent popups active simultaneously
- Popups automatically handle their own lifecycle management
- Nesting works naturally because each popup maintains its own ID scope

## Summary

- **Dear ImGui** implements popups as temporary overlay windows managed through an internal stack in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp).
- **Always use three steps**: trigger with `OpenPopup()`, begin with `BeginPopup()`/`BeginPopupModal()`, and render inside the conditional block.
- **Modal dialogs** block background interaction and require explicit closing via `CloseCurrentPopup()` or button actions.
- **Context menus** use helpers like `BeginPopupContextItem()` that automatically handle right-click detection and identifier management.
- **Identifiers** are relative to the ID stack, allowing natural nesting of popups within other UI elements.

## Frequently Asked Questions

### What's the difference between a popup and a modal in ImGui?

A regular popup created with `ImGui::BeginPopup()` allows interaction with the rest of the application while open, and closes automatically when clicking outside. A modal dialog created with `ImGui::BeginPopupModal()` displays a dimming overlay that blocks interaction with other windows until explicitly closed. Modals also typically use the `ImGuiWindowFlags_AlwaysAutoResize` flag to fit their content.

### How do I close a popup programmatically?

Call `ImGui::CloseCurrentPopup()` (defined in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp), lines 12575-12592) inside the popup's begin/end block. This removes the top entry from the internal popup stack. Alternatively, popups close automatically when the user activates a menu item (via `MenuItem()` or `Selectable()`) or clicks outside the window area for non-modal popups.

### Can I nest popups inside other popups?

Yes. Because Dear ImGui identifies popups using IDs relative to the current ID stack, you can open a child popup from within a parent popup's begin/end block. Each popup maintains its own entry in `g.BeginPopupStack`, and the system handles the layering automatically. The table context menu example in [`imgui_tables.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_tables.cpp) (lines 3661-3670) demonstrates this pattern.

### Why does my popup close immediately after opening?

This usually happens when you call `OpenPopup()` outside the condition that checks for the trigger event, causing it to be called every frame. Ensure you only call `OpenPopup()` when a specific event occurs (button click, right-click, etc.), and place the `BeginPopup()` check immediately afterward in the same frame. The popup stack resets each frame, so you must trigger and begin the popup within the same pass.