Skip to content

ImGui::MarkItemEdited hits assertion when un-docking a window with ImGui::BeginMultiSelect and ImGui::Selectable #8997

@itsdanott

Description

@itsdanott

Version/Branch of Dear ImGui:

Version 1.92.2b, Branch: docking

Back-ends:

imgui_impl_sdl3.cpp + iimgui_impl_sdlgpu3.cpp (But probably occurs with all backends)

Compiler, OS:

tested with MSVC 2022 and Apple Clang 17

Full config/build information:

Dear ImGui 1.92.2b (19222)
--------------------------------
sizeof(size_t): 8, sizeof(ImDrawIdx): 2, sizeof(ImDrawVert): 20
define: __cplusplus=202002
define: __APPLE__
define: __GNUC__=4
define: __clang_version__=17.0.0 (clang-1700.3.19.1)
define: IMGUI_HAS_VIEWPORT
define: IMGUI_HAS_DOCK
--------------------------------
io.BackendPlatformName: imgui_impl_sdl3 (3.3.0; 3.3.0)
io.BackendRendererName: imgui_impl_sdlgpu3
io.ConfigFlags: 0x00000081
 NavEnableKeyboard
 DockingEnable
io.ConfigViewportsNoDecoration
io.ConfigMacOSXBehaviors
io.ConfigNavCaptureKeyboard
io.ConfigInputTextCursorBlink
io.ConfigWindowsResizeFromEdges
io.ConfigMemoryCompactTimer = 60.0
io.BackendFlags: 0x0000141E
 HasMouseCursors
 HasSetMousePos
 PlatformHasViewports
 RendererHasVtxOffset
 RendererHasTextures
 RendererHasViewports
--------------------------------
io.Fonts: 1 fonts, Flags: 0x00000000, TexSize: 512,128
io.Fonts->FontLoaderName: stb_truetype
io.DisplaySize: 1280.00,720.00
io.DisplayFramebufferScale: 1.00,1.00
--------------------------------
style.WindowPadding: 8.00,8.00
style.WindowBorderSize: 1.00
style.FramePadding: 4.00,3.00
style.FrameRounding: 0.00
style.FrameBorderSize: 0.00
style.ItemSpacing: 8.00,4.00
style.ItemInnerSpacing: 4.00,4.00

Details:

My Issue/Question:

When using ImGui::BeginMultiSelect and ImGui::Selectable inside a ImGui::Window an assertion in MarkItemEdited is hit when un-docking that window.

The assertion in question:

IM_ASSERT(g.DragDropActive || g.ActiveId == id || g.ActiveId == 0 || g.ActiveIdPreviousFrame == id || (g.CurrentMultiSelect != NULL && g.BoxSelectState.IsActive));

imgui.cpp:4715

It seems like the issue could be related to DragDropActive not being updated during the un-docking - but this is just a wild guess.

Screenshots/Video:

Screen.Recording.2025-10-09.at.09.59.48.mp4

Minimal, Complete and Verifiable Example code:

Here's a minimal reproducable example with a entity creation and selection window.

Steps to reproduce:

  1. Arrange the windows in any way
  2. Notice how you can drag and drop the "Entity Selection" window and dock it to the other window or the dockspace as expected and how un-docking also works without issues
  3. Create one or more entites via the "Entity Creation" window
  4. Notice how you can still dock the "Entity Selection" window that now contains selectable entries
  5. Notice how the assertion is hit when dragging the "Entity Selection" window to un-dock it (MarkItemEdited in imgui.cpp:4715) caused by ImGui::Selectable()
  6. Notice how all conditions in the assertions are false, including g.DragDropActive and g.BoxSelectState.IsActive
//Copy this code into your draw function inbetween ImGui::NewFrame() and ImGui::Render() for instance into your backend's example main function.
ImGui::DockSpaceOverViewport(0, ImGui::GetMainViewport());

constexpr auto ENTITY_NAME_LEN = 62;
struct Entity {
    char    name[ENTITY_NAME_LEN];
    ImGuiID id;
};
static ImGuiID id_increment = 0;

static ImGuiSelectionBasicStorage imgui_storage = {};
static std::vector<Entity>        entities;

if (ImGui::Begin("Entity Creation")) {
    static char name[ENTITY_NAME_LEN] = "Entity Name";
    ImGui::InputText("entity name", name, ENTITY_NAME_LEN);

    if (ImGui::Button("Create Entity")) {
        Entity entity = {
            .id = ++id_increment
        };

        memcpy(entity.name, name, ENTITY_NAME_LEN * sizeof(char));
        entities.emplace_back(entity);
    }
    ImGui::End();
}

if (ImGui::Begin("Entity Selection")) {
    constexpr ImGuiMultiSelectFlags flags = ImGuiMultiSelectFlags_ClearOnEscape
        | ImGuiMultiSelectFlags_BoxSelect1d
        | ImGuiMultiSelectFlags_ClearOnClickVoid;
    const auto ms_io = ImGui::BeginMultiSelect(flags, imgui_storage.Size, static_cast<int>(entities.size()));
    imgui_storage.ApplyRequests(ms_io);

    for (const auto& entity : entities) {
        const auto is_entity_selected = imgui_storage.Contains(entity.id);
        ImGui::SetNextItemSelectionUserData(entity.id);
        ImGui::PushID(static_cast<int>(entity.id));
        if (ImGui::Selectable(entity.name, is_entity_selected, ImGuiSelectableFlags_AllowDoubleClick))
            printf("entity id: %u '%s' was clicked\n", entity.id, entity.name);
        ImGui::PopID();
    }
    ImGui::EndMultiSelect();
    imgui_storage.ApplyRequests(ms_io);
    ImGui::End();
}

EDIT: replaced strlcpy with memcpy. I missed that strlcpy is not available on Windows with MSVC (was using SDL_strlcpy when testing on Windows).

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions