From: Simon Glass <sjg@chromium.org> Currently mouse_get_click() processes events by calling mouse_get_event() and tracking the press->release transition. But if other code calls mouse_get_event() directly, those button events are consumed and mouse_get_click() never sees them. Fix this by moving the click detection logic into mouse_get_event() itself. Add a click_pending flag to track when a click has been detected, and simplify mouse_get_click() to just check and clear this flag. This ensures clicks are properly registered regardless of whether callers use mouse_get_event() or mouse_get_click(). Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <sjg@chromium.org> --- Changes in v2: - Add new patch to move click detection into mouse_get_event() drivers/input/mouse-uclass.c | 48 +++++++++++++++++------------------- include/mouse.h | 2 ++ 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/drivers/input/mouse-uclass.c b/drivers/input/mouse-uclass.c index 6bfce915e2b..7cbe961af35 100644 --- a/drivers/input/mouse-uclass.c +++ b/drivers/input/mouse-uclass.c @@ -28,10 +28,23 @@ int mouse_get_event(struct udevice *dev, struct mouse_event *evt) uc_priv->last_pos.y = evt->motion.y; } - /* Update last position for button events */ + /* Update last position for button events and detect clicks */ if (evt->type == MOUSE_EV_BUTTON) { uc_priv->last_pos.x = evt->button.x; uc_priv->last_pos.y = evt->button.y; + + /* Process left-button clicks */ + if (evt->button.button == BUTTON_LEFT) { + /* Detect press->release transition (click) */ + if (uc_priv->left_pressed && !evt->button.pressed) { + uc_priv->click_pending = true; + uc_priv->click_pos.x = evt->button.x; + uc_priv->click_pos.y = evt->button.y; + } + + /* Update button state */ + uc_priv->left_pressed = evt->button.pressed; + } } return 0; @@ -41,36 +54,21 @@ int mouse_get_click(struct udevice *dev, struct vid_pos *pos) { struct mouse_uc_priv *uc_priv = dev_get_uclass_priv(dev); struct mouse_event event; - int ret; - /* Get one mouse event */ - ret = mouse_get_event(dev, &event); - if (ret) - return -EAGAIN; /* No event available */ - - /* Only process button events for left button */ - if (event.type == MOUSE_EV_BUTTON && - event.button.button == BUTTON_LEFT) { - bool pending = false; - - /* Detect press->release transition (click) */ - if (uc_priv->left_pressed && !event.button.pressed) { - pending = true; - uc_priv->click_pos.x = event.button.x; - uc_priv->click_pos.y = event.button.y; - } - - /* Update button state */ - uc_priv->left_pressed = event.button.pressed; + /* Process all available events until we find a click */ + while (true) { + if (mouse_get_event(dev, &event)) + return -EAGAIN; /* No more events */ - /* If we just detected a click, return it */ - if (pending) { + /* Check if this event resulted in a click */ + if (uc_priv->click_pending) { *pos = uc_priv->click_pos; - return 0; + uc_priv->click_pending = false; + break; } } - return -EAGAIN; + return 0; } int mouse_get_pos(struct udevice *dev, struct vid_pos *pos) diff --git a/include/mouse.h b/include/mouse.h index 62cabf24769..1a3a93801e2 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -31,6 +31,7 @@ enum mouse_state_t { * struct mouse_uc_priv - pre-device private data for mouse uclass * * @left_pressed: True if left button is currently pressed + * @click_pending: True if a click has occurred but not yet retrieved * @click_pos: Position where the click occurred * @last_pos: Last position received from mouse * @video_dev: Video device for coordinate scaling @@ -39,6 +40,7 @@ enum mouse_state_t { */ struct mouse_uc_priv { bool left_pressed; + bool click_pending; struct vid_pos click_pos; struct vid_pos last_pos; struct udevice *video_dev; -- 2.43.0