SetNextWindowRefreshPolicy on docked window triggers EndFrame() assertion
Version/Branch of Dear ImGui:
Version 1.91.3-docking
Back-ends:
imgui_impl_glfw.cpp + imgui_impl_opengl3.cpp
Compiler, OS:
CLang 18.1.3 and GCC 13.2.0, Linux Mint 22, x64
Full config/build information:
Dear ImGui 1.91.3 (19130)
--------------------------------
sizeof(size_t): 8, sizeof(ImDrawIdx): 2, sizeof(ImDrawVert): 20
define: __cplusplus=201103
define: __linux__
define: __GNUC__=13
define: IMGUI_HAS_VIEWPORT
define: IMGUI_HAS_DOCK
--------------------------------
io.BackendPlatformName: imgui_impl_glfw
io.BackendRendererName: imgui_impl_opengl3
io.ConfigFlags: 0x00000483
NavEnableKeyboard
NavEnableGamepad
DockingEnable
ViewportsEnable
io.ConfigViewportsNoDecoration
io.ConfigInputTextCursorBlink
io.ConfigWindowsResizeFromEdges
io.ConfigMemoryCompactTimer = 60.0
io.BackendFlags: 0x00001C0E
HasMouseCursors
HasSetMousePos
PlatformHasViewports
HasMouseHoveredViewport
RendererHasVtxOffset
RendererHasViewports
--------------------------------
io.Fonts: 1 fonts, Flags: 0x00000000, TexSize: 512,64
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:
Hello, if I clone v1.91.3-docking and edit example_glfw_opengl3/main.cpp to add:
ImGui::SetNextWindowRefreshPolicy(ImGuiWindowRefreshFlags_RefreshOnHover | ImGuiWindowRefreshFlags_TryToAvoidRefresh);
before the "Hello, World!" window Begin() (line 163) then dock the "Hello, World!" window to the Demo window then move my mouse outside that window, the program fails with:
../imgui.cpp:5808: void ImGui::EndFrame(): Assertion `g.Windows.Size == g.WindowsTempSortBuffer.Size' failed.
And will fail the same on next launch as it tries to recreate these docked windows from imgui.ini
This is the easiest reproducible example I could think of. It happens with any two windows too.
Thank you very much for the help
Screenshots/Video:
No response
Minimal, Complete and Verifiable Example code:
// 2. Show a simple window that we create ourselves. We use a Begin/End pair to create a named window.
{
static float f = 0.0f;
static int counter = 0;
ImGui::SetNextWindowRefreshPolicy(ImGuiWindowRefreshFlags_RefreshOnHover | ImGuiWindowRefreshFlags_TryToAvoidRefresh); // <-- ADD THIS then dock this window to the Demo window
ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it.
ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too)
Linking to #7797 FYI this function is imgui_internal.h and is experimental and for my own research, I'm not expecting people to be using this at this point.
Hello, yes I'm well aware this is experimental, I'm just raising this narrow issue. I found this in CPP, it has nothing to do with the CSharp bindings.
I spent an hour toying with this and came to the conclusion that the feature is going to be too difficult to fully implement and maintain so I am tempted to remove it. I'm a bit worried that we will stumble on a whole new class of bugs which are going to be difficult to work with.
Yes it's quite user-specific. Could we have the means to save the results of a window rendering (after End()) and then decide ourselves to re-use that cached result after Begin() if we see fit? Then users can decide for themselves if they want to re-render on user interaction, drag, resize, a widget becoming blue, etc. Thank you
if(begin())
if(last_render_was_less_than_one_second_ago and no_user_interaction_since)
end(cached_drawings)
else
text("Hello");
expensive_stuff();
tabs();
table();
end();
cached_drawings = ImGui::previousWindowDrawings();
The current power saving tools are nice but if one window needs a render, they suddenly all do.
I understand ImGui was made to be rendered in game engines and not to make usual CRUD GUIs. I also understand I could cache the expensive calls myself but this would be highly convenient and quickly applicable to any window. And would leave us the opportunity to have some windows at VSync frequency and some at 1Hz (example).
Thank you
Yes it's quite user-specific. Could we have the means to save the results of a window rendering (after End()) and then decide ourselves to re-use that cached result after Begin() if we see fit? Then users can decide for themselves if they want to re-render on user interaction, drag, resize, a widget becoming blue, etc. Thank you
That's exactly equivalent to what we are aiming to do. The problem is figuring out the right rule for re-rendering, which include e.g. parents moving. User is able to give a correct "don't skip this frame" signal but won't be able to tell "definitively can skip this frame" better than the library would.
But there's a large hairy nest of inter-dependency and states which may be used by other subsystems and that are difficult to get right and are going to be incredibly tricky to get from 90% to 100%. I will another afternoon someday having a pass at this but I am not super hopeful.
I understand ImGui was made to be rendered in game engines and not to make usual CRUD GUIs.
Yes.
If you have expensive stuff, cache it or make it less expensive.