[Concept,v2,07/20] mouse: Move click detection into mouse_get_event()
Commit Message
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(-)
@@ -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)
@@ -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;