[Concept,v2,07/20] mouse: Move click detection into mouse_get_event()

Message ID 20251007170549.541981-8-sjg@u-boot.org
State New
Headers
Series expo: Complete mouse operation in the EFI app |

Commit Message

Simon Glass Oct. 7, 2025, 5:05 p.m. UTC
  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(-)
  

Patch

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;