imgui: Menu's and window dragging doesn't respond well to empty update
In our engine, we process all input messages which were sent during the last frame including a paint message which pumps ImGui every frame regardless of the number of additional input messages.
The goal here is to respond to input as early as possible and to capture all user input and not discard anything.
A frame with a mouse click would look something like this
Game_BeginFrame();
UpdateGui_LMB_Click();
Update_ImGuiIO();
ImGui::NewFrame();
UpdateImGuiWindows(); // Do the actual gui work
UpdateGui_Paint();
Update_ImGuiIO();
ImGui::NewFrame();
UpdateImGuiWindows(); // Do the actual gui work
DrawImGui()
Game_EndFrame()
A frame with a mouse move and a mouse click would look something like this
Game_BeginFrame();
UpdateGui_Mouse_Move();
Update_ImGuiIO();
ImGui::NewFrame();
UpdateImGuiWindows(); // Do the actual gui work
UpdateGui_LMB_Click();
Update_ImGuiIO();
ImGui::NewFrame();
UpdateImGuiWindows(); // Do the actual gui work
UpdateGui_Paint();
Update_ImGuiIO();
ImGui::NewFrame();
UpdateImGuiWindows(); // Do the actual gui work
DrawImGui()
Game_EndFrame()
A frame without a mouse click would be
Game_BeginFrame();
UpdateGui_Paint();
Update_ImGuiIO();
ImGui::NewFrame();
UpdateImGuiWindows(); // Do the actual gui work
DrawImGui()
Game_EndFrame()
In this setup, I’m able to click on widgets in an open window, scroll the scroll bar both with the wheel or by dragging it and I can also resize the window by dragging the resize grip.
I cannot however click in the empty space of the window to bring it into focus, or click out of the window to move it out of focus. I also cannot click and drag the window.
In a MenuBar I’m able to click on and open a Menu, I can click MenuItems and they’ll do whatever they’re supposed to do. But I cannot click off the menu (say into another window or just empty space) to close the menu or cause it to lose focus.
What’s most odd to me (and what I’m hoping makes the sense to you) is that if I put the Paint update first instead of last, everything seems to behave correctly?
I’m not sure if this is a bug, something I’m doing wrong or both?
Thanks for keeping this project going!
About this issue
- Original URL
- State: closed
- Created 9 years ago
- Comments: 27 (24 by maintainers)
Commits related to this issue
- Extracted a EndFrame() function out of Render() but kept it internal/private + clarified some asserts (#335) — committed to ocornut/imgui by ocornut 9 years ago
- Comments (#335) — committed to ocornut/imgui by ocornut 8 years ago
@kylawl
The code within widgets calls (layout, calculating text size) + the cost of executing user code and touching lots of memory.
edit Within widgets call there is a cost of rendering but that only happens for visible widgets so it is quickly capped to how much you can have visible on-screen.
That cost of rendering vs the rest would depend on how many items you have visible vs clipped ones, so it’s hard to give a rough metrics. The worst case for rendering if when everything is visible (nothing is out of view, no scrollbar, etc.) but if everything is visible then you probably aren’t dealing with so many widgets? It would be interesting to hook such boolean flag in all the RenderXXX functions in imgui.cpp to get a number for your use case, would probably be trivial to add such flag and cover 95% of the rendering.
It would be very interesting to look at perfs (in another topic) if you have issues. Performing clipping of large list with a ImGuiListClipper pattern is generally a good way to deal with large amount of data.
@EliasD For the records, I would like to change inputs processing so it would actually process events and among other things play a little better with very low framerates. So that is in my to do list, it just hasn’t been a top priority and isn’t a small change. The small workaround trick that the example back-end are using is that if a click came in during the frame we always pass the mouse button as “down” even if a release came in during that frame. It is imperfect but alleviate the issue a lot.
So both of you are totally right, I’m just saying that IHMO it isn’t nearly as bad as one would think.
I am closing this as it looks like we are on the same page here. I added a TODO note to eventually add a helper “DisableRender” flag, and the need to process events is already recorded.