mouse: Move click detection into mouse_get_event()

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().

Series-changes: 2
- Add new patch to move click detection into mouse_get_event()

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass
2025-10-07 05:56:09 -06:00
parent 03c65c2b94
commit 90e109789e
2 changed files with 25 additions and 25 deletions

View File

@@ -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 */
/* Process all available events until we find a click */
while (true) {
if (mouse_get_event(dev, &event))
return -EAGAIN; /* No more events */
/* 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;
/* 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)

View File

@@ -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;