[ATSPI] Blocking unwanted emission of "MoveOuted" signal 38/261238/10
authorLukasz Oleksak <l.oleksak@samsung.com>
Tue, 13 Jul 2021 16:31:24 +0000 (18:31 +0200)
committerLukasz Oleksak <l.oleksak@samsung.com>
Mon, 26 Jul 2021 12:17:29 +0000 (14:17 +0200)
This patch is blocking unwanted emission of "MoveOuted" signal to dbus
when auto-scroll feature moves highlighted object into the screen.

This patch requires following dali-adaptor patch:
https://review.tizen.org/gerrit/#/c/platform/core/uifw/dali-adaptor/+/261237/

Change-Id: I43115faf0e9a061436d6751069ca1541ff0d4017

automated-tests/src/dali-toolkit-internal/utc-Dali-Accessibility-Controls-BridgeUp.cpp
dali-toolkit/internal/controls/control/control-data-impl.cpp
dali-toolkit/internal/controls/control/control-data-impl.h

index 6d47f06..5720b4e 100644 (file)
@@ -1081,12 +1081,13 @@ int UtcDaliAccessibilityCheckHighlight(void)
   parentButton.Add(buttonB);
   Wait(application);
 
   parentButton.Add(buttonB);
   Wait(application);
 
-  // Move second child out of parent area
+  // Set highlight to first child (A) to enable movement tracking
   auto* accessible = dynamic_cast<DevelControl::AccessibleImpl*>(Dali::Accessibility::Accessible::Get(buttonA));
   DALI_TEST_CHECK(accessible);
   accessible->GrabHighlight();
   Wait(application);
 
   auto* accessible = dynamic_cast<DevelControl::AccessibleImpl*>(Dali::Accessibility::Accessible::Get(buttonA));
   DALI_TEST_CHECK(accessible);
   accessible->GrabHighlight();
   Wait(application);
 
+  // Move first child (A) out of parent area through the parent's area top edge - single move outed event expected for A object and OUTGOING_TOP_LEFT direction
   buttonA.SetProperty( Dali::Actor::Property::POSITION, Dali::Vector2(0.0f, -200.0f) );
   Wait(application);
   // Need one more seding notificaiton to get correct updated position
   buttonA.SetProperty( Dali::Actor::Property::POSITION, Dali::Vector2(0.0f, -200.0f) );
   Wait(application);
   // Need one more seding notificaiton to get correct updated position
@@ -1096,18 +1097,68 @@ int UtcDaliAccessibilityCheckHighlight(void)
   // Reset verdict data
   Dali::Accessibility::TestResetMoveOutedCalled();
 
   // Reset verdict data
   Dali::Accessibility::TestResetMoveOutedCalled();
 
-  // Move second child out of parent area
+  // Move first child (A) outside of parent area (both start and end position are outside of parent area) - no move outed event expected for A object
+  buttonA.SetProperty( Dali::Actor::Property::POSITION, Dali::Vector2(0.0f, -300.0f) );
+  Wait(application);
+  // Need one more seding notificaiton to get correct updated position
+  application.SendNotification();
+  DALI_TEST_EQUALS( false, Dali::Accessibility::TestGetMoveOutedCalled(), TEST_LOCATION );
+
+  // Reset verdict data
+  Dali::Accessibility::TestResetMoveOutedCalled();
+
+  // Set highlight to second child (B) to enable movement tracking
   accessible = dynamic_cast<DevelControl::AccessibleImpl*>(Dali::Accessibility::Accessible::Get(buttonB));
   DALI_TEST_CHECK(accessible);
   accessible->GrabHighlight();
   Wait(application);
 
   accessible = dynamic_cast<DevelControl::AccessibleImpl*>(Dali::Accessibility::Accessible::Get(buttonB));
   DALI_TEST_CHECK(accessible);
   accessible->GrabHighlight();
   Wait(application);
 
+  // Move second child (B) inside of parent area (both start and end position are inside of parent area) - no move outed event expected for B object
+  // B: (0,100) --> (0, 50)
+  buttonB.SetProperty( Dali::Actor::Property::POSITION, Dali::Vector2(0.0f, 50.0f) );
+  Wait(application);
+  // Need one more seding notificaiton to get correct updated position
+  application.SendNotification();
+  DALI_TEST_EQUALS( false, Dali::Accessibility::TestGetMoveOutedCalled(), TEST_LOCATION );
+
+  // Reset verdict data
+  Dali::Accessibility::TestResetMoveOutedCalled();
+
+  // Move second child (B) out of parent area through the parent's area right edge - single move outed event expected for B object and OUTGOING_BOTTOM_RIGHT direction
   buttonB.SetProperty( Dali::Actor::Property::POSITION, Dali::Vector2(300.0f, 100.0f) );
   Wait(application);
   // Need one more seding notificaiton to get correct updated position
   application.SendNotification();
   DALI_TEST_EQUALS( true, Dali::Accessibility::TestGetMoveOutedCalled(), TEST_LOCATION );
 
   buttonB.SetProperty( Dali::Actor::Property::POSITION, Dali::Vector2(300.0f, 100.0f) );
   Wait(application);
   // Need one more seding notificaiton to get correct updated position
   application.SendNotification();
   DALI_TEST_EQUALS( true, Dali::Accessibility::TestGetMoveOutedCalled(), TEST_LOCATION );
 
+  // Reset verdict data
+  Dali::Accessibility::TestResetMoveOutedCalled();
+
+  // Move second child (B) back into parent area (start position is outside but end position is inside of parent area) - no move outed event expected for B object
+  // B: (300,100) --> (0, 100)
+  buttonB.SetProperty( Dali::Actor::Property::POSITION, Dali::Vector2(0.0f, 100.0f) );
+  Wait(application);
+  // Need one more seding notificaiton to get correct updated position
+  application.SendNotification();
+  DALI_TEST_EQUALS( false, Dali::Accessibility::TestGetMoveOutedCalled(), TEST_LOCATION );
+
+  // Reset verdict data
+  Dali::Accessibility::TestResetMoveOutedCalled();
+
+  // Disable movement tracking on B by giving highlight to A
+  accessible = dynamic_cast<DevelControl::AccessibleImpl*>(Dali::Accessibility::Accessible::Get(buttonA));
+  DALI_TEST_CHECK(accessible);
+  accessible->GrabHighlight();
+  Wait(application);
+
+  // Move B (untracked) out of parent area through the parent's area right edge - no move outed event expected for B object
+  // B: (0,100) --> (300, 100)
+  buttonB.SetProperty( Dali::Actor::Property::POSITION, Dali::Vector2(300.0f, 100.0f) );
+  Wait(application);
+  // Need one more seding notificaiton to get correct updated position
+  application.SendNotification();
+  DALI_TEST_EQUALS( false, Dali::Accessibility::TestGetMoveOutedCalled(), TEST_LOCATION );
+
   Dali::Accessibility::TestEnableSC( false );
   END_TEST;
 }
   Dali::Accessibility::TestEnableSC( false );
   END_TEST;
 }
index 0b41d3f..ced845a 100644 (file)
@@ -439,6 +439,11 @@ Dali::Rect<> GetShowingGeometry(Dali::Rect<> rect, Dali::Toolkit::DevelControl::
   return rect;
 }
 
   return rect;
 }
 
+static bool IsShowingGeometryOnScreen(Dali::Rect<> rect)
+{
+  return rect.width > 0 && rect.height > 0;
+}
+
 } // unnamed namespace
 
 // clang-format off
 } // unnamed namespace
 
 // clang-format off
@@ -547,7 +552,7 @@ const Control::Impl& Control::Impl::Get(const Internal::Control& internalControl
   return *internalControl.mImpl;
 }
 
   return *internalControl.mImpl;
 }
 
-void Control::Impl::CheckHighlightedObjectGeometry(PropertyNotification& propertyNotification)
+void Control::Impl::CheckHighlightedObjectGeometry()
 {
   auto accessibleImpl = dynamic_cast<Dali::Toolkit::DevelControl::AccessibleImpl*>(mAccessibilityObject.get());
   if(!accessibleImpl)
 {
   auto accessibleImpl = dynamic_cast<Dali::Toolkit::DevelControl::AccessibleImpl*>(mAccessibilityObject.get());
   if(!accessibleImpl)
@@ -558,40 +563,52 @@ void Control::Impl::CheckHighlightedObjectGeometry(PropertyNotification& propert
 
   auto lastPosition   = accessibleImpl->GetLastPosition();
   auto accessibleRect = accessibleImpl->GetExtents(Dali::Accessibility::CoordinateType::WINDOW);
 
   auto lastPosition   = accessibleImpl->GetLastPosition();
   auto accessibleRect = accessibleImpl->GetExtents(Dali::Accessibility::CoordinateType::WINDOW);
-
-  if(lastPosition.x == accessibleRect.x && lastPosition.y == accessibleRect.y)
-  {
-    return;
-  }
-
   auto rect = GetShowingGeometry(accessibleRect, accessibleImpl);
 
   auto rect = GetShowingGeometry(accessibleRect, accessibleImpl);
 
-  // MoveOuted is sent already, no need to send it again
-  if(mAccessibilityMovedOutOfScreenDirection != Dali::Accessibility::MovedOutOfScreenType::NONE)
+  switch(mAccessibilityLastScreenRelativeMoveType)
   {
   {
-    if(rect.width > 0 && rect.height > 0)
+    case Dali::Accessibility::ScreenRelativeMoveType::OUTSIDE:
     {
     {
-      // flick next does not use MoveOuted - ScrollToSelf makes object show, so reset for sending MoveOuted next
-      mAccessibilityMovedOutOfScreenDirection = Dali::Accessibility::MovedOutOfScreenType::NONE;
+      if(IsShowingGeometryOnScreen(rect))
+      {
+        mAccessibilityLastScreenRelativeMoveType = Dali::Accessibility::ScreenRelativeMoveType::INSIDE;
+      }
+      break;
+    }
+    case Dali::Accessibility::ScreenRelativeMoveType::INSIDE:
+    {
+      if(rect.width < 0 && accessibleRect.x != lastPosition.x)
+      {
+        mAccessibilityLastScreenRelativeMoveType = (accessibleRect.x < lastPosition.x) ? Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_TOP_LEFT : Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_BOTTOM_RIGHT;
+      }
+      if(rect.height < 0 && accessibleRect.y != lastPosition.y)
+      {
+        mAccessibilityLastScreenRelativeMoveType = (accessibleRect.y < lastPosition.y) ? Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_TOP_LEFT : Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_BOTTOM_RIGHT;
+      }
+      // notify AT-clients on outgoing moves only
+      if(mAccessibilityLastScreenRelativeMoveType != Dali::Accessibility::ScreenRelativeMoveType::INSIDE)
+      {
+        mAccessibilityObject.get()->EmitMovedOutOfScreen(mAccessibilityLastScreenRelativeMoveType);
+      }
+      break;
+    }
+    case Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_TOP_LEFT:
+    case Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_BOTTOM_RIGHT:
+    {
+      if(IsShowingGeometryOnScreen(rect))
+      {
+        mAccessibilityLastScreenRelativeMoveType = Dali::Accessibility::ScreenRelativeMoveType::INSIDE;
+      }
+      else
+      {
+        mAccessibilityLastScreenRelativeMoveType = Dali::Accessibility::ScreenRelativeMoveType::OUTSIDE;
+      }
+      break;
+    }
+    default:
+    {
+      break;
     }
     }
-    return;
-  }
-
-  if(rect.width < 0)
-  {
-    mAccessibilityMovedOutOfScreenDirection = (accessibleRect.x < lastPosition.x) ? Dali::Accessibility::MovedOutOfScreenType::TOP_LEFT : Dali::Accessibility::MovedOutOfScreenType::BOTTOM_RIGHT;
-  }
-
-  if(rect.height < 0)
-  {
-    mAccessibilityMovedOutOfScreenDirection = (accessibleRect.y < lastPosition.y) ? Dali::Accessibility::MovedOutOfScreenType::TOP_LEFT : Dali::Accessibility::MovedOutOfScreenType::BOTTOM_RIGHT;
-  }
-
-  if(mAccessibilityMovedOutOfScreenDirection != Dali::Accessibility::MovedOutOfScreenType::NONE)
-  {
-    mAccessibilityObject.get()->EmitMovedOutOfScreen(mAccessibilityMovedOutOfScreenDirection);
-    accessibleImpl->SetLastPosition(Vector2(0.0f, 0.0f));
-    return;
   }
 
   accessibleImpl->SetLastPosition(Vector2(accessibleRect.x, accessibleRect.y));
   }
 
   accessibleImpl->SetLastPosition(Vector2(accessibleRect.x, accessibleRect.y));
@@ -603,11 +620,13 @@ void Control::Impl::RegisterAccessibilityPositionPropertyNotification()
   {
     return;
   }
   {
     return;
   }
-
-  mAccessibilityMovedOutOfScreenDirection = Dali::Accessibility::MovedOutOfScreenType::NONE;
-  mAccessibilityPositionNotification      = mControlImpl.Self().AddPropertyNotification(Actor::Property::WORLD_POSITION, StepCondition(1.0f, 1.0f));
+  // set default value until first move of object is detected
+  mAccessibilityLastScreenRelativeMoveType = Dali::Accessibility::ScreenRelativeMoveType::OUTSIDE;
+  // recalculate mAccessibilityLastScreenRelativeMoveType accordingly to the initial position
+  CheckHighlightedObjectGeometry();
+  mAccessibilityPositionNotification       = mControlImpl.Self().AddPropertyNotification(Actor::Property::WORLD_POSITION, StepCondition(1.0f, 1.0f));
   mAccessibilityPositionNotification.SetNotifyMode(PropertyNotification::NOTIFY_ON_CHANGED);
   mAccessibilityPositionNotification.SetNotifyMode(PropertyNotification::NOTIFY_ON_CHANGED);
-  mAccessibilityPositionNotification.NotifySignal().Connect(this, &Control::Impl::CheckHighlightedObjectGeometry);
+  mAccessibilityPositionNotification.NotifySignal().Connect(this, [this](PropertyNotification&){ CheckHighlightedObjectGeometry(); });
   mIsAccessibilityPositionPropertyNotificationSet = true;
 }
 
   mIsAccessibilityPositionPropertyNotificationSet = true;
 }
 
index c31ed81..aa590c5 100644 (file)
@@ -470,9 +470,8 @@ private:
 
   /**
    * @brief Checks highlighted object geometry if it is showing or not
 
   /**
    * @brief Checks highlighted object geometry if it is showing or not
-   * @param[in] propertyNotification PropertyNotification
    */
    */
-  void CheckHighlightedObjectGeometry(Dali::PropertyNotification& propertyNotification);
+  void CheckHighlightedObjectGeometry();
 
   /**
    * @brief Register property notification to check highlighted object position
 
   /**
    * @brief Register property notification to check highlighted object position
@@ -583,7 +582,7 @@ private:
   // Accessibility - notification for highlighted object to check if it is showing.
   bool                                      mIsAccessibilityPositionPropertyNotificationSet{false};
   Dali::PropertyNotification                mAccessibilityPositionNotification;
   // Accessibility - notification for highlighted object to check if it is showing.
   bool                                      mIsAccessibilityPositionPropertyNotificationSet{false};
   Dali::PropertyNotification                mAccessibilityPositionNotification;
-  Dali::Accessibility::MovedOutOfScreenType mAccessibilityMovedOutOfScreenDirection{Accessibility::MovedOutOfScreenType::NONE};
+  Dali::Accessibility::ScreenRelativeMoveType mAccessibilityLastScreenRelativeMoveType;
 };
 
 } // namespace Internal
 };
 
 } // namespace Internal