If IsDispatchHoverMotion is false, the move event was not dispatched. So consumedActo... 04/321004/4
authorjoogab.yun <joogab.yun@samsung.com>
Thu, 13 Mar 2025 00:28:41 +0000 (09:28 +0900)
committerjoogab.yun <joogab.yun@samsung.com>
Thu, 13 Mar 2025 06:24:41 +0000 (15:24 +0900)
Change-Id: Ifbadde1b21abfca728c9e91be81a8f57c4650a6e

automated-tests/src/dali/utc-Dali-HoverProcessing.cpp
dali/internal/event/events/hover-event-processor.cpp

index df7e04fcf62ecded0f54cacb5db3aefe23a86687..76db78654e9cb66da1855b72e61b8f8e13006470 100644 (file)
@@ -673,6 +673,82 @@ int UtcDaliHoverLeaveParentConsumer(void)
   END_TEST;
 }
 
+int UtcDaliHoverLeaveWithDispatchMotion(void)
+{
+  TestApplication application;
+  Actor           rootActor(application.GetScene().GetRootLayer());
+
+  Actor actor = Actor::New();
+  actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+  actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  application.GetScene().Add(actor);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Connect to actor's hovered signal
+  SignalData        data;
+  HoverEventFunctor functor(data, false);
+  actor.HoveredSignal().Connect(&application, functor);
+
+  // Connect to root actor's hovered signal
+  SignalData        rootData;
+  HoverEventFunctor rootFunctor(rootData); // Consumes signal
+  rootActor.HoveredSignal().Connect(&application, rootFunctor);
+
+  // Set actor to require leave events
+  actor.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
+  rootActor.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
+
+  // Sets the dispatch hover motion property to false. This means that hover motion events are not recived
+  actor.SetProperty(DevelActor::Property::DISPATCH_HOVER_MOTION, false);
+  rootActor.SetProperty(DevelActor::Property::DISPATCH_HOVER_MOTION, false);
+
+  // Emit a started signal
+  application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(PointState::STARTED, data.hoverEvent.GetState(0), TEST_LOCATION);
+  DALI_TEST_EQUALS(PointState::STARTED, rootData.hoverEvent.GetState(0), TEST_LOCATION);
+  DALI_TEST_CHECK(actor == data.hoverEvent.GetHitActor(0));
+  DALI_TEST_CHECK(actor == rootData.hoverEvent.GetHitActor(0));
+  data.Reset();
+  rootData.Reset();
+
+  // Emit a motion signal outside of actor, should be signalled with a Leave
+  application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(200.0f, 200.0f)));
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(PointState::LEAVE, data.hoverEvent.GetState(0), TEST_LOCATION);
+  // rootActor receives "started" state because a new hover event entered in rootActor area.
+  DALI_TEST_EQUALS(PointState::STARTED, rootData.hoverEvent.GetState(0), TEST_LOCATION);
+  DALI_TEST_CHECK(actor == data.hoverEvent.GetHitActor(0));
+  DALI_TEST_CHECK(rootActor == rootData.hoverEvent.GetHitActor(0));
+  data.Reset();
+  rootData.Reset();
+
+  // Another motion event inside actor, signalled with start. This is because a new hover event was started on that actor.
+  application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(50.0f, 50.0f)));
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(PointState::STARTED, data.hoverEvent.GetState(0), TEST_LOCATION);
+  DALI_TEST_EQUALS(PointState::STARTED, rootData.hoverEvent.GetState(0), TEST_LOCATION);
+  DALI_TEST_CHECK(actor == data.hoverEvent.GetHitActor(0));
+  DALI_TEST_CHECK(actor == rootData.hoverEvent.GetHitActor(0));
+  data.Reset();
+  rootData.Reset();
+
+  // Another motion event inside actor, Since DispatchHoverMotion is false, no signal is received.
+  application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(10.0f, 10.0f)));
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(false, rootData.functorCalled, TEST_LOCATION);
+  data.Reset();
+  rootData.Reset();
+
+  END_TEST;
+}
+
 int UtcDaliHoverActorBecomesInsensitive(void)
 {
   TestApplication application;
index 220934fcd5f63ff4b92b27ca1f410016e0155457..ca2925a90e1688f51c5fec7bee05352dcc44eadd 100644 (file)
@@ -420,6 +420,11 @@ struct HoverEventProcessor::Impl
         else
         {
           localVars.consumedActor = EmitHoverSignals(hitActor, localVars.hoverEventHandle);
+          // If IsDispatchHoverMotion is false, the move event was not dispatched. So consumedActor should keep the previous LastConsumedActor value.
+          if(!localVars.consumedActor && localVars.primaryPointState == PointState::MOTION && !GetImplementation(hitActor).IsDispatchHoverMotion())
+          {
+            localVars.consumedActor = Dali::Actor(processor.mLastConsumedActor.GetActor());
+          }
         }
       }