Skip to content

The selection cursor moves incorrectly in lists when it is offscreen and clipping is used #9079

@TnS-hun

Description

@TnS-hun

Version/Branch of Dear ImGui:

Version 1.92.4, Branch: master

Back-ends:

imgui_impl_win32.cpp + imgui_impl_dx9.cpp

Compiler, OS:

Windows + MSVC 2022

Full config/build information:

Dear ImGui 1.92.4 (19240)
--------------------------------
sizeof(size_t): 8, sizeof(ImDrawIdx): 2, sizeof(ImDrawVert): 20
define: __cplusplus=199711
define: _WIN32
define: _WIN64
define: _MSC_VER=1944
define: _MSVC_LANG=201402
--------------------------------
io.BackendPlatformName: imgui_impl_win32
io.BackendRendererName: imgui_impl_dx9
io.ConfigFlags: 0x00000003
 NavEnableKeyboard
 NavEnableGamepad
io.ConfigNavCaptureKeyboard
io.ConfigInputTextCursorBlink
io.ConfigWindowsResizeFromEdges
io.ConfigMemoryCompactTimer = 60.0
io.BackendFlags: 0x0000001E
 HasMouseCursors
 HasSetMousePos
 RendererHasVtxOffset
 RendererHasTextures
--------------------------------
io.Fonts: 1 fonts, Flags: 0x00000000, TexSize: 512,128
io.Fonts->FontLoaderName: stb_truetype
io.DisplaySize: 1264.00,761.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 ImGuiListClipper and the selection cursor is not visible then pressing Up/Down/Page Up/Page Down keys behaves differently compared to when the selection cursor is visible in a list of Selectable().

Repro:

  • start the Dear ImGui Demo
  • go to Widgets -> Selection State & Multi-Select -> Multi-Select (with clipper)
  • select the second item (Arugula)
  • scroll it out of screen with the mouse wheel
  • press the Down key
  • notice that selection is not on the third item (Asparagus)

Pressing Page Down make the originally selected item visible, but does not move the selection. Pressing Page Up moves the selection to the first visible item.

I found this weird because ImGuiListClipper_StepInternal() seemingly adds the navigation range at "// Add range selected to be included for navigation".

(When using the Multi-Select without clipper then the Down and the Page Down keys work as expected, but Page Up moves the selection to the first visible item. This might be a related bug.)

I managed to work around this problem with a code like this that always adds a screenful of items before and after the cursor item when navigation happens:

ImGuiContext &g = *ImGui::GetCurrentContext();
ImGuiWindow *window = ImGui::GetCurrentWindowRead();
const bool isNavRequest = g.NavMoveScoringItems && g.NavWindow && g.NavWindow->RootWindowForNav == window->RootWindowForNav;
if (isNavRequest)
{
    const int rangeSrcItemIndex = get cursor index from ImGui::BeginMultiSelect()->RangeSrcItem;
    const float windowInnerHeight = ImGui::GetCurrentWindowRead()->InnerRect.GetHeight();
    const float totalItemHeight = ImGui::GetTextLineHeightWithSpacing();
    const int itemsPerPage = (int)ceilf(windowInnerHeight / totalItemHeight);
    const int startIndex = max(rangeSrcItemIndex - itemsPerPage, 0);
    const int endIndex = min(rangeSrcItemIndex + itemsPerPage, (int)totalItemCount);
    clipper.IncludeItemsByIndex(startIndex, endIndex);
}

Screenshots/Video:

No response

Minimal, Complete and Verifiable Example code:

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugclippernavkeyboard/gamepad navigation

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions