Open xevgeny opened 3 months ago
Changing the behavior of the ComboBox's button fixes the issue. Is there a reason why "pressed on click" is not the default option?
bool pressed = ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_PressedOnClick);
You are not well explaining how your sleeping logic works but any mouse press OR release should enforce the next 3 frames to be updated, then you won’t have issues.
The problem might be that ImGUI needs 4 frames to draw an open combo box, not 3.
The sleeping logic is very simple. Instead of using glfwPollEvents();
, I use glfwWaitEventsTimeout(3.0)
. The rest is pretty much the same as in example_glfw_opengl3/main.cpp
. Code to reproduce the issue is here https://gist.github.com/xevgeny/9bc7bc2d4e185cde2b71c52a0270fbb6
From the example above:
Frame 75: click happens
Frame 76: (MOUSE_PRESS)
Frame 77: (MOUSE_RELEASE)
Frame 78: (set popup open = true)
Frame 79: popup opens
Frames 76, 77, and 78 are rendered immediately after the initial mouse click. But nothing triggers frame 79, so the rendering loop waits for 3 seconds as configured.
Then maybe 4 frames is a better wait time for now.
Down the line we should replace the “wait 3-4 frames” by a signal emitted by the lib. I believe our idling system could be made better by noting when a popup is opened or a window is just appearing.
While I am open to discuss the possibility of making combo box start opening on mouse-down, I believe this is not your actual problem here.
Between #7569 and some comments above there is something is miunderstood: (1) If I change combo-box to starts its opening process on mouse-down rather than mouse-up, in theory it should not change anything with your idling system, because mouse-up is an equally important event than mouse-down.
(2) I ran your repro and things works for me, I do get the combo appearing without delay as soon as I release the mouse button. I wonder if it could be caused by a swap-chain setup requiring an extra glfwSwapBuffers()
to make visible the previous one?
(3) The general logic should look like:
static int run_frames = 2;
if (run_frames > 0)
{
glfwPollEvents();
run_frames--;
}
else
{
glfwWaitEventsTimeout(3.0);
run_frames = 2; // FIXME: No need to increase run_frames if timeout elapsed, how to detect?
}
Tho it is not ideal to set run_frames = 2
when wait events had a timeout.
I believe since the GLFW API doesn't allow it, the easier way to detect this currently is to read GImGui->InputEventsNextEventId
before and after the call, to see if it changed. If it did it means our callbacks have generated events. it's not perfect because e.g. MonitorCallback doesn't immediately registers an event.
(Once we formalize idling we can probably expose a simple IO value to help detect this.)
Version/Branch of Dear ImGui:
master
Back-ends:
imgui_impl_glfw.cpp + imgui_impl_opengl3.cpp
Compiler, OS:
Any
Full config/build information:
No response
Details:
I'm building a simple monitoring app using ImGUI and experimenting with resource-friendly rendering strategies. I use
glfwWaitEventsTimeout
with N-second granularity, which significantly reduces GPU load when there are no user inputs or events.While I recognize that this may not be the intended use case for ImGUI, all widgets function well in this mode (
Menu
,TreeNode
,CollapsingHeader
), except theComboBox
- the popup opens with a delay when clicked.In the attached video, the click occurs at frame 75, but the popup only appears at frame 79. Extra frames in between are rendered due to mouse input (GLFW_PRESS, GLFW_RELEASE). The thread sleeps between frames 78 and 79 due to
glfwWaitEventsTimeout
, which causes a noticeable delay. In the video, the timeout is set to 3 seconds.I could not reproduce the issue with the keyboard input by selecting the ComboBox and pressing Enter.
Screenshots/Video:
Video: https://github.com/ocornut/imgui/assets/1928818/02641263-fb67-469e-9e53-75ccc0104766
Minimal, Complete and Verifiable Example code:
To reproduce the issue replace
glfwPollEvents
withglfwWaitEventsTimeout
inexapmle_glfw_opengl3/main.cpp
file.