From b602a2e95937dee2e0b842636b8b320fea27aa0b Mon Sep 17 00:00:00 2001 From: Lukasz Oleksak Date: Tue, 13 Jul 2021 18:31:24 +0200 Subject: [PATCH] [ATSPI] Blocking unwanted emission of "MoveOuted" signal 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 --- .../utc-Dali-Accessibility-Controls-BridgeUp.cpp | 55 +++++++++++++- .../controls/control/control-data-impl.cpp | 87 +++++++++++++--------- .../internal/controls/control/control-data-impl.h | 5 +- 3 files changed, 108 insertions(+), 39 deletions(-) diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-Accessibility-Controls-BridgeUp.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-Accessibility-Controls-BridgeUp.cpp index 6d47f06..5720b4e 100644 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-Accessibility-Controls-BridgeUp.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-Accessibility-Controls-BridgeUp.cpp @@ -1081,12 +1081,13 @@ int UtcDaliAccessibilityCheckHighlight(void) 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(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 @@ -1096,18 +1097,68 @@ int UtcDaliAccessibilityCheckHighlight(void) // 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(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 ); + // 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(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; } diff --git a/dali-toolkit/internal/controls/control/control-data-impl.cpp b/dali-toolkit/internal/controls/control/control-data-impl.cpp index 0b41d3f..ced845a 100644 --- a/dali-toolkit/internal/controls/control/control-data-impl.cpp +++ b/dali-toolkit/internal/controls/control/control-data-impl.cpp @@ -439,6 +439,11 @@ Dali::Rect<> GetShowingGeometry(Dali::Rect<> rect, Dali::Toolkit::DevelControl:: return rect; } +static bool IsShowingGeometryOnScreen(Dali::Rect<> rect) +{ + return rect.width > 0 && rect.height > 0; +} + } // unnamed namespace // clang-format off @@ -547,7 +552,7 @@ const Control::Impl& Control::Impl::Get(const Internal::Control& internalControl return *internalControl.mImpl; } -void Control::Impl::CheckHighlightedObjectGeometry(PropertyNotification& propertyNotification) +void Control::Impl::CheckHighlightedObjectGeometry() { auto accessibleImpl = dynamic_cast(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); - - if(lastPosition.x == accessibleRect.x && lastPosition.y == accessibleRect.y) - { - return; - } - 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)); @@ -603,11 +620,13 @@ void Control::Impl::RegisterAccessibilityPositionPropertyNotification() { 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.NotifySignal().Connect(this, &Control::Impl::CheckHighlightedObjectGeometry); + mAccessibilityPositionNotification.NotifySignal().Connect(this, [this](PropertyNotification&){ CheckHighlightedObjectGeometry(); }); mIsAccessibilityPositionPropertyNotificationSet = true; } diff --git a/dali-toolkit/internal/controls/control/control-data-impl.h b/dali-toolkit/internal/controls/control/control-data-impl.h index c31ed81..aa590c5 100644 --- a/dali-toolkit/internal/controls/control/control-data-impl.h +++ b/dali-toolkit/internal/controls/control/control-data-impl.h @@ -470,9 +470,8 @@ private: /** * @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 @@ -583,7 +582,7 @@ private: // 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 -- 2.7.4