imgui: Infinite loop in TabBar resizing
Version/Branch of Dear ImGui:
Version: “1.89 WIP” e13913ed Branch: master
Back-end/Renderer/Compiler/OS
Back-ends: imgui_impl_vulkan.cpp + imgui_impl_glfw.cpp Compiler: clang Operating System: linux/debian sid
My Issue/Question:
since i updated to a new version of imgui, i’m experiencing random hangs at times. i think i tracked the issue down to commit c4b91017, in particular the excess width handling in the TabBar. what seems to happen when i step through the code in gdb is that
https://github.com/ocornut/imgui/blob/master/imgui_widgets.cpp#L1578 <= this becomes an infinite while loop (in current master same code)
because in the following the line if (items[n].Width + 1.0f <= items[n].InitialWidth) is always unfortunate enough to only contain fractional bits, so the +1.0f case never triggers:
Thread 1 "vkdt" received signal SIGINT, Interrupt.
0x00005555555f527e in ImGui::ShrinkWidths (items=0x55555a389dd0, count=4, width_excess=0.760025024) at ../ext/imgui/imgui_widgets.cpp:1581
1581 if (items[n].Width + 1.0f <= items[n].InitialWidth)
(gdb) p items[n]
$1 = {Index = 3, Width = 100, InitialWidth = 100.479996}
(gdb)
today i can always reproduce it with my settings and screen resolution using https://github.com/hanatos/vkdt/commits/master but i’m hoping it would be possible to fix this conceptually so i don’t have to prepare a minimal example. for context, i have four tabs that almost fill the width of the containing window. they all run into this rounding issue:
(gdb) p items[0]
$2 = {Index = 2, Width = 163, InitialWidth = 163.480011}
(gdb) p items[1]
$3 = {Index = 0, Width = 119, InitialWidth = 119.479996}
(gdb) p items[2]
$4 = {Index = 1, Width = 107, InitialWidth = 107.479996}
(gdb) p items[3]
$5 = {Index = 3, Width = 100, InitialWidth = 100.479996}
for now i have commented out the while(width_excess > 0.0f) loop to get back a working version.
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 2
- Comments: 16 (10 by maintainers)
Commits related to this issue
- Tabs: Fixed ShrinkWidths() redistribution of remainder leading to infinite bug + over redistribution. (#5652) Amend c4b91017 — committed to ocornut/imgui by ocornut 2 years ago
- Tabs: Fixed ShrinkWidths() redistribution of remainder leading to infinite bug + over redistribution. (#5652) Amend c4b91017 — committed to ocornut/imgui by ocornut 2 years ago
- Tabs: Fixed ShrinkWidths() redistribution of remainder leading to infinite bug (second fix). (#5652, #5262) Amend b137f31 — committed to ocornut/imgui by ocornut 2 years ago
- Tabs: Fixed ShrinkWidths() redistribution of remainder leading to infinite bug + over redistribution. (#5652) Amend c4b91017 — committed to kjblanchard/imgui by ocornut 2 years ago
- Tabs: Fixed ShrinkWidths() redistribution of remainder leading to infinite bug (second fix). (#5652, #5262) Amend b137f31 — committed to kjblanchard/imgui by ocornut 2 years ago
Can you try this version.? Only replacing the final loop from the current commit:
The thing I checked are:
Issues (that are not new)
It’s not perfect for non-rounded width but nothing in Dear ImGui currently is (*)
* Amusingly, at the time I am typing this into Firefox, the textbox height keeps resizing back-and-worth between +0 and +1 pixels whenever I type… Guess some other code has tricky rounding issue…
so probably what happens is that there is more than one pixel
width_excessbut all the individual tabs still only receive less than one pixel offset? how about a single-pass floyd-steinberg diffusion instead?(patch attached, had to gzip it so github would accept it) 0001-tabbar-propose-to-distribute-widths-via-floyd-steinb.patch.gz
These are two example inputs that lead to inifinite loops for me with the code in its current state:
From my limited testing the single pass floyd steinberg diffusion approach appears to be working quite well here without any obvious issues 👍🏿