(menu_event) Fix stray menu input after MENU_ST_FLAG_BLOCK_ALL_INPUT

menu_event() returns early when MENU_ST_FLAG_BLOCK_ALL_INPUT is set,
but does so before the 'ok_old' static is updated. 'ok_old' holds the
previous frame's OK button state and is used to derive the edges:

   ok_trigger         = ok_current & ~ok_old;
   ok_trigger_release = !ok_current && ok_old;

Because the write is skipped, 'ok_old' freezes at its last unblocked
value while the physical button continues to change state. When input
is unblocked, a phantom edge is produced:

 - OK held when the block begins and released during it leaves
   ok_old = 1, so the first unblocked frame yields a spurious
   ok_trigger_release.
 - OK released before the block and pressed during it leaves
   ok_old = 0, so the first unblocked frame yields a spurious
   ok_trigger.

The release case is the more damaging of the two, since 'ok_enum_idx'
also still holds the entry enum from before the block. The release
handling paths (RESUME_CONTENT, LOAD_STATE/SAVE_STATE with
menu_savestate_resume, single-click playlist entries, disk insert)
compare against it and can therefore self-activate against an entry
the user never pressed OK on.

Update 'ok_old' before returning so the blocked interval is absorbed
into the edge detector rather than skipped over. The screensaver early
return further down is unaffected, as it already sits after the
'ok_old' write and annuls state via select_inhibit/cancel_inhibit.
This commit is contained in:
libretroadmin committed 2026-07-19 01:52:28 +02:00
1 parent 0a16d7d578
commit c09a057ee9
1 file changed
+8 -1
+8 -1
View File
@@ -5199,9 +5199,16 @@ unsigned menu_event(
RETRO_DEVICE_ID_JOYPAD_Y
};
/* Check if all menu input is blocked */
/* Check if all menu input is blocked
* > 'ok_old' must be updated before returning, otherwise the
* button state is frozen for the duration of the block and a
* phantom trigger/release edge is generated against a stale
* 'ok_enum_idx' once input is unblocked */
if (menu_st->flags & MENU_ST_FLAG_BLOCK_ALL_INPUT)
{
ok_old = ok_current;
return MENU_ACTION_NOOP;
}
/* Clear OK if dragged */
if (menu_input->pointer.flags & MENU_INP_PTR_FLG_DRAGGED)