How to clear input queue/buffer after App switching (workaround for iOS related bug)

Godot Version

3.5.3, 3.6.1, 4.4.1

Situation / Background

There seems to be a bug in Godot’s iOS implementation in all versions mentioned in combination with certain iOS versions (e.g. 15.8). (I will report this as a bug once I’m sure what’s happening exactly.)

(Everything works fine on Windows, Android and “most” iOS versions.)

When switching from my app (reproducible with any freshly created blank app) to any other app or the iOS desktop and back to the app, with a certain chance (1:2 - 1:5) the app gets focus, but immediately loses it again, but stays active/visible.

Important: Even though the app does NOT have focus and does NOT react in any way, all screen touches are being queued. Once I switch out of the app AGAIN and back to it again, all queued events are being sent at once causing all kinds of problems (e.g. a click which normally leads to a screen transition and can be called only once is being called multiple times).

This seems to happen in all kinds of Nodes, both using _input and _gui_input.

Question

To prevent this “event flooding” I wanted to clear the input queue/buffer once the app gets focus (e.g. when getting NOTIFICATION_WM_FOCUS_IN or NOTIFICATION_APP_RESUMED), but to my surprise couldn’t find a “clear event queue” function or something similar.

So, is this possible at all and if so, how?

Thanks a lot, any help appreciated!

2 Likes

You can disable input accumulation by setting Input.use_accumulated_input to false. You can also flush the buffered events by calling Input.flush_buffered_events(). I don’t think there’s a way to clear the buffer without flushing it.

2 Likes

Thank you very much for your answer! I experimented with both settings you mentioned before and even more so after your reply, but unfortunately neither helps.

Input.flush_buffered_events() obviously is “nearly” what I need, only that the events should be flushed into the digital nirvana instead of being sent to the game loop. (I guess it could even easily be added to that function as an optional parameter to clear the events instead of sending them.)

Input.use_accumulated_input does not change the end result, only the timing of when the events happen. With default true it is as I described originally, all events are fired AFTER the “fake focus”, but changing to false fires each event when it really happens. But since the App is in “fake focus” mode the App does not execute any of the deferred calls, but also queues them and calls them all at once once the App has real focus again.

I added a workaround in a few key spots in my code, e.g. the scene navigator and the close behaviour of popup dialogs to check for the “event flood” and it helps as a first aid.