Fix an issue where TapGesture Events are not being received. 23/277923/2
authorjoogab.yun <joogab.yun@samsung.com>
Fri, 15 Jul 2022 05:01:19 +0000 (14:01 +0900)
committerjoogab.yun <joogab.yun@samsung.com>
Fri, 15 Jul 2022 05:57:04 +0000 (14:57 +0900)
If MaximumTapsRequired is greater than 1, TapEvent may not be received when mMaximumAllowedTime is checked in touch-up.

So, move the mMaximumAllowedTime check code to Touchdown.

And in touch-up, the time between previous touch-down and touch-up is checked.

Change-Id: Iec05c9c902fda5c04a8ddde54bec1d887224d5fe

automated-tests/src/dali/utc-Dali-TapGestureRecognizer.cpp
dali/internal/event/events/tap-gesture/tap-gesture-recognizer.cpp
dali/internal/event/events/tap-gesture/tap-gesture-recognizer.h

index e33a21c..165fbc4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -428,21 +428,29 @@ int UtcDaliTapGestureRecognizerDoubleTapWaitTooLong(void)
 
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
 
-  application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 650));
+  application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 750));
 
-  application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 750));
+  application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 850));
 
   application.SendNotification();
 
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
 
-  application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 950));
+  application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 900));
 
-  application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 1000));
+  application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 1450));
 
-  application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 1050));
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 1500));
 
-  application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 1000));
+  application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 1550));
+
+  application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 1600));
+
+  application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 1650));
 
   application.SendNotification();
 
@@ -606,9 +614,9 @@ int UtcDaliTapGestureSetMaximumAllowedTime(void)
 
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
 
-  application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 250));
+  application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 300));
 
-  application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 300));
+  application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 350));
 
   application.SendNotification();
 
index 7d33bb4..05bbf94 100644 (file)
@@ -49,6 +49,7 @@ TapGestureRecognizer::TapGestureRecognizer(Observer& observer, Vector2 screenSiz
   mTouchPosition(),
   mTouchTime(0u),
   mLastTapTime(0u),
+  mLastTouchTime(0u),
   mGestureSourceType(GestureSourceType::INVALID),
   mMaximumAllowedTime(maximumAllowedTime)
 {
@@ -102,6 +103,7 @@ void TapGestureRecognizer::SendEvent(const Integration::TouchEvent& event)
         if(pointState == PointState::DOWN)
         {
           SetupForTouchDown(event, point);
+          mLastTouchTime = event.time;
         }
         break;
       }
@@ -114,7 +116,7 @@ void TapGestureRecognizer::SendEvent(const Integration::TouchEvent& event)
         {
           if(deltaBetweenTouchDownTouchUp < mMaximumAllowedTime)
           {
-            mLastTapTime = mTouchTime;
+            mLastTapTime = event.time;
             EmitSingleTap(event.time, point);
             mState = REGISTERED;
           }
@@ -134,24 +136,17 @@ void TapGestureRecognizer::SendEvent(const Integration::TouchEvent& event)
       {
         if(pointState == PointState::UP)
         {
-          // This is a possible multiple tap, so has it been quick enough?
-          uint32_t timeDelta                    = event.time - mLastTapTime;
-          uint32_t deltaBetweenTouchDownTouchUp = event.time - mTouchTime;
-          if(timeDelta > mMaximumAllowedTime || // If exceeded time between taps then just a single tap
-             mMaximumTapsRequired == 1u)        // If MaximumTapsRequired is 1, it is not waiting for a multi-tap, so a Tap gesture send a single tap.
+          uint32_t deltaBetweenLastTouchDownTouchUp = event.time - mLastTouchTime;
+          // Clear if the time between touch down and touch up is long.
+          if(deltaBetweenLastTouchDownTouchUp > mMaximumAllowedTime)
           {
-            mLastTapTime = event.time;
-            EmitSingleTap(event.time, point);
+            mState = CLEAR;
           }
-          else if(deltaBetweenTouchDownTouchUp < mMaximumAllowedTime)
+          else
           {
-            ++mTapsRegistered;
+            mLastTapTime = event.time;
             EmitGesture(GestureState::STARTED, event.time);
           }
-          else // Delta between touch down and touch up too long to be considered a TAP event
-          {
-            mState = CLEAR;
-          }
         }
         else if(pointState == PointState::DOWN)
         {
@@ -159,11 +154,16 @@ void TapGestureRecognizer::SendEvent(const Integration::TouchEvent& event)
           Vector2        distanceDelta(std::abs(mTouchPosition.x - screen.x),
                                 std::abs(mTouchPosition.y - screen.y));
 
-          uint32_t timeDelta = event.time - mLastTapTime;
+          uint32_t deltaBetweenInitTouchDownCurrentTouchDown = event.time - mTouchTime;
+          uint32_t timeDelta                                 = event.time - mLastTapTime;
+          mLastTouchTime                                     = event.time;
+          ++mTapsRegistered;
 
           if(distanceDelta.x > MAXIMUM_MOTION_ALLOWED ||
              distanceDelta.y > MAXIMUM_MOTION_ALLOWED ||
-             timeDelta > mMaximumAllowedTime)
+             timeDelta > mMaximumAllowedTime ||                                 // If the time between tabs is long, it starts over from SetupForTouchDown.
+             deltaBetweenInitTouchDownCurrentTouchDown > mMaximumAllowedTime || // If it times out compared to the first touchdown time, it starts over from SetupForTouchDown.
+             mTapsRegistered > mMaximumTapsRequired)                            // If it is greater than MaximumTapsRequired, it starts over from SetupForTouchDown.
           {
             SetupForTouchDown(event, point);
           }
index b4fbda9..d6e39c1 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_EVENT_EVENTS_TAP_GESTURE_RECOGNIZER_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -149,6 +149,7 @@ private:
   Vector2  mTouchPosition; ///< The initial touch down position.
   uint32_t mTouchTime;     ///< The initial touch down time.
   uint32_t mLastTapTime;   ///< Time last tap gesture was registered
+  uint32_t mLastTouchTime; ///< The last touch down time.
 
   GestureSourceType mGestureSourceType;  /// < Gesture input source type value.
   uint32_t          mMaximumAllowedTime; ///< The maximum allowed time required to be recognized as a multi tap gesture (millisecond)