Clipper: further mitigation/improvements for abnormally large contents ranges (larger than e.g. 2^31). (#3609, #8215)
diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt
index 4b123e5..8fd49b5 100644
--- a/docs/CHANGELOG.txt
+++ b/docs/CHANGELOG.txt
@@ -108,6 +108,7 @@
- TextLinkOpenURL(): added bool return value on click. (#8645, #8451, #7660)
- Scroll: fixed contents size, scrollbar visibility and scrolling resetting issues
with abnormally large contents ranges. (#3609, #8215)
+- Clipper: some mitigation/improvements for abnormally large contents ranges. (#3609, #8215)
- Nav: fixed assertion when holding gamepad FaceLeft/West button to open
CTRL+Tab windowing + pressing a keyboard key. (#8525)
- Error Handling: added better error report and recovery for extraneous
diff --git a/imgui.cpp b/imgui.cpp
index 4e85502..fb49662 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -3195,10 +3195,17 @@
if (table)
IM_ASSERT(table->RowPosY1 == clipper->StartPosY && table->RowPosY2 == window->DC.CursorPos.y);
- clipper->ItemsHeight = (window->DC.CursorPos.y - clipper->StartPosY) / (float)(clipper->DisplayEnd - clipper->DisplayStart);
- bool affected_by_floating_point_precision = ImIsFloatAboveGuaranteedIntegerPrecision(clipper->StartPosY) || ImIsFloatAboveGuaranteedIntegerPrecision(window->DC.CursorPos.y);
+ bool affected_by_floating_point_precision = ImIsFloatAboveGuaranteedIntegerPrecision((float)clipper->StartPosY) || ImIsFloatAboveGuaranteedIntegerPrecision(window->DC.CursorPos.y);
if (affected_by_floating_point_precision)
+ {
+ // Mitigation/hack for very large range: assume last time height constitute line height.
clipper->ItemsHeight = window->DC.PrevLineSize.y + g.Style.ItemSpacing.y; // FIXME: Technically wouldn't allow multi-line entries.
+ window->DC.CursorPos.y = (float)(clipper->StartPosY + clipper->ItemsHeight);
+ }
+ else
+ {
+ clipper->ItemsHeight = (float)(window->DC.CursorPos.y - clipper->StartPosY) / (float)(clipper->DisplayEnd - clipper->DisplayStart);
+ }
if (clipper->ItemsHeight == 0.0f && clipper->ItemsCount == INT_MAX) // Accept that no item have been submitted if in indeterminate mode.
return false;
IM_ASSERT(clipper->ItemsHeight > 0.0f && "Unable to calculate item height! First item hasn't moved the cursor vertically!");
diff --git a/imgui.h b/imgui.h
index 8e0e09b..6d062c1 100644
--- a/imgui.h
+++ b/imgui.h
@@ -2708,7 +2708,7 @@
int DisplayEnd; // End of items to display (exclusive)
int ItemsCount; // [Internal] Number of items
float ItemsHeight; // [Internal] Height of item after a first step and item submission can calculate it
- float StartPosY; // [Internal] Cursor position at the time of Begin() or after table frozen rows are all processed
+ double StartPosY; // [Internal] Cursor position at the time of Begin() or after table frozen rows are all processed
double StartSeekOffsetY; // [Internal] Account for frozen rows in a table and initial loss of precision in very large windows.
void* TempData; // [Internal] Internal data