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:
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user