(menu) Fix stray pointer input when pointer devices are toggled

Third instance of the same class as c09a057 and 8ab71e9.

menu_input_post_iterate() maintains four pointer edge detectors:

   last_select_pressed = (pointer_hw_state->flags & ..._PRESS_SELECT) > 0;
   last_cancel_pressed = ...
   last_left_pressed   = ...
   last_right_pressed  = ...

These are written only at the function's single exit. The caller in
menu_driver_iterate() skips the call entirely when pointer input is
disabled:

   if (menu_input->pointer.type == MENU_POINTER_DISABLED)
      ret = 0;
   else
      ret = menu_input_post_iterate(...);

so the detectors stop being updated, while the hardware press flags
they shadow are left untouched. Neither the disabled branch nor
anything it reaches clears pointer_hw_state; the only two memsets are
menu init and menu deinit.

pointer.type is recomputed every frame in menu_event() from
menu_mouse_enable/menu_pointer_enable, and under HAVE_COCOATOUCH from
MENU_ST_FLAG_INP_DLG_KB_DISPLAY, so this is not a static build-time
condition. Toggling mouse or touch support in Settings -> Input flips
it live, and on iOS every keyboard dialog flips it for the duration of
the dialog.

A press held across the transition therefore leaves the flag and its
shadow captured at different times. Once pointer input is re-enabled
the stale pair yields a rising edge with no corresponding press, which
the select path acts on against whatever entry is selected by then.

Clear the four press flags while pointer input is disabled so the
detectors always resynchronise against a known-unpressed state.
This commit is contained in:
libretroadmin committed 2026-07-20 09:35:07 +02:00
1 parent 8ab71e91ca
commit 46288b2a65
1 file changed
+13
+13
View File
@@ -7615,7 +7615,20 @@ static int generic_menu_iterate(
/* If pointer devices are disabled, just ensure mouse
* cursor is hidden */
if (menu_input->pointer.type == MENU_POINTER_DISABLED)
{
/* menu_input_post_iterate() is skipped here, so its
* 'last_*_pressed' edge detectors stop being updated
* while the hardware press flags are left untouched.
* Clear the flags so that the two cannot desynchronise
* and emit a phantom press/release once pointer input
* is re-enabled */
menu_st->input_pointer_hw_state.flags &=
~(MENU_INP_PTR_FLG_PRESS_SELECT
| MENU_INP_PTR_FLG_PRESS_CANCEL
| MENU_INP_PTR_FLG_PRESS_LEFT
| MENU_INP_PTR_FLG_PRESS_RIGHT);
ret = 0;
}
else
ret = menu_input_post_iterate(p_disp, menu_st, action,
current_time);