-
-
Notifications
You must be signed in to change notification settings - Fork 10.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Assertion failed: g.IO.KeyMods with GLFW backend #3575
Comments
Hello, The assert generally triggers when you have code modifying the |
Note the comment exactly above this assert: // Verify that io.KeyXXX fields haven't been tampered with. Key mods should not be modified between NewFrame() and EndFrame()
// One possible reason leading to this assert is that your backends update inputs _AFTER_ NewFrame().
const ImGuiKeyModFlags expected_key_mod_flags = GetMergedKeyModFlags();
IM_ASSERT(g.IO.KeyMods == expected_key_mod_flags && "Mismatching io.KeyCtrl/io.KeyShift/io.KeyAlt/io.KeySuper vs io.KeyMods"); |
Yes. I already saw that. But my code does is not directly modify those values at all. That was the first thing I looked for. |
In fact, if I add:
and after my code:
I still get the same assertion. I also tried capturing those fields after
Same result. Could something be occuring because the dialog is blocking this loop for a period of seconds (or more)? |
Well, something does and it's not core imgui.
Yes if you keep polling GLFW events, as stated above.
Because that's making it wrong. If you move the first |
I don't see how anything in my code could be modifying
And keyboard shortcuts work delightfully everywhere other than when I launch a native file dialog, delaying this loop. Code down the stack, below |
I gave you all the information you need to debug your issue. You can use printf or a debugger to track it down.
|
The following code resolves the issue. I'll take it from here. Thank you.
|
(Also, thank you for the help... Surely you can understand how these things go. My code doesn't directly alter those values. There's got to be some kind of a compiler side effect or some minor mistake or something. And I'm kind of puzzled how this only happens in this one specific case... but yes, you're right, something is changing those fields between those 2 statements, and it's ultimately my problem... But thanks!) |
As a quick test, I've tried today to use https://github.com/mlabbe/nativefiledialog to create a long blocking dialog in the middle of the Dear ImGui frame, calling it while modifiers were held, and tested this with GLFW, SDL and Win32 backends without a problem. Maybe your and @str0yd app have some kind of reentrant/threaded code calling GLFW back-end events during the blocking call. I'm not sure. |
This is strange. I use my own key callback:
I first set all my callbacks:
Then I initialize ImGui:
Usually ImGui should call my own key callback function at the right time, shouldn't it? I don't use the callbacks anywhere else. Could it maybe be something with the Windows Openfile dialog? I use the GetOpenFileNameA function: https://docs.microsoft.com/en-us/windows/win32/api/commdlg/nf-commdlg-getopenfilenamea |
I definitely do not have any threaded or re-entrant code as part of my application, and certainly none that interact with GLFW directly. I do have a callback registered with GLFW to invoke my draw loop when the host window gets resized. That draw loop contains this code:
But I'm pretty sure that's not causing this issue. I've left my workaround in place because it doesn't seem to be adversely affecting the behavior of any part of my application. I've been through my codebase extensively... there does not seem to be anything that's directly changing the state of any ImGui structures in any way. Reading them... extensively. Changing them... no. |
You know which function in the GLFW backends is altering the key mods so I am surprised you haven’t set breakpoints to figure out exactly what’s calling it and when.
|
I had no time to test it yet, will do this tomorrow. |
I think the problem is in the ImGui_ImplGlfw_KeyCallback. I press "Ctrl + S" to quicksave my things. While pressing "Ctrl + S" the Windows file dialog opens. I relase "Ctrl + S" and choose a file. As soon as I leave the file dialog the Keykallback is triggered (I relased Ctrl and S) and resets the io.KeyCtrl. After resetting the program runs and ASSERTS
This evaluates FALSE because the ImGui_ImplGlfw_KeyCallback has already reset the Ctrl flag (g.IO.KeyMods is set at the beginning of the frame). I think this is a bug beacause if you could press and release the Ctrl button in one frame you should also get this error message. I'm not sure when exactly GLFW calls the kallback function. If it is periodically or inerrupting. But if I'm right with my theory here it should call the callback interrupting. |
You can set a breakpoint to find out but I've also written it above. They are called when you call |
My code does not call Maybe there's some sort of strange side-effect happening in GLFW when opening a dialog, that's causing that callback to execute despite not calling |
My code is structured exactly the same. |
I looked at GLFW codebase and at a first glance it seems like only the _glfwPlatformPollEvents() function dispatch win32 messages which turns into callback events. I have created a minimum repro calling As this point if you would like to correctly get to the end of this, could you try creating a minimum repro for it? Ideally sticking some code inside existing examples/ app. |
I can probably put something together this weekend. |
OK so weirdly I tried to build a repro in another sample project and it worked this time... In examples/example_glfw_opengl3/main.cpp
[...]
This repros it for me. Installed GLFW with debug symbols With callstack:
|
So GLFW is clearing keyboard input when the windows loses focus, and with those native modal dialog the events are pushed mid-frame. With the current direct-write to IO i don't have a super satisfying solution right now. When we transitioning to queuing events (e.g. https://gist.github.com/ocornut/8417344f3506790304742b07887adf9f) it'll be trivial. Considering the nature of that mid-frame modification my suggested solution would be to make the assert more lenient by only asserting on mid-frame presses rather than mid-frame release. This way, the assert would STILL catch on the common error it's trying to catch, while acting friendly on this sort of situation we stumbled on here. |
Commit with this fix: 3600ceb Commit where the check was first added: ccf0cc8 Thanks all for your patience with this, glad we got this through. |
Confirmed. This fixes the issue in my codebase. Thank you! |
Process imgui input before beginning imgui frame (ocornut/imgui#3575)
* Add a few different tonemapper options * Process imgui input before beginning imgui frame (ocornut/imgui#3575) * Fix issue with internal #![rustfmt::skip] attribute on nightly
Otherwise, pressing control or alt key crashes the app triggering an assertion in imgui. See ocornut/imgui#3575 Shouldn't poll events after ImGui starts
…e may cause Assertion failed: g.IO.KeyMods error" bug reason enter chinese may modifying the io.KeyCtrl io.KeyAlt or io.KeyShift modifiers refer to: ocornut/imgui#3575 solution now catch error; label now change to update when blur;
What’s in the draw() function then? I don’t think the 2020 issue is related anymore, as nowadays events are queued so even if a backend receives event’s asynchronously it won’t interfere with what the assert is complaining about. It may be a problem on your end. |
the draw function itself only uses ImGui::GetBackgroundDrawList and ImGui::GetTextSize functions to draw "certain stuff" over video games. until that error occured i have never heard of KeyMods in any situation. Therefore I certainly do not modify them activley and knowingly. Fyi: I am internal, so maybe the game itself interfers with the keymods? idk i started that whole learning process a few weeks ago. |
You’ll need to investigate on your own. We can’t really help with that amount of information. |
I'm running into something that I can't seem to get to the bottom of, and I'm hoping you can help. I'm using a framework on top of ImGui, which implements key bindings and actions. I'm running into a situation where when I execute an action from a key binding, and then I launch a native file dialog, I'm running into an assert in ImGui when the dialog returns control back to ImGui.
I get the following assert:
My code is structured like this:
The
workspace_app::respond
is the concrete overload responding to the_app->respond()
line inhost::draw
above.When I invoke this same code path through clicking on a user interface element, the code path works perfectly. It only triggers this assert when I use the keyboard shortcut (
CTRL-S
) in my case, to invoke the code path. If I change my keyboard shortcut to justS
instead ofCTRL-S
, it also works perfectly. It only seems to hit this assert when modifier keys are involved.Any insight would be very appreciated.
The text was updated successfully, but these errors were encountered: