From 12f7849f1c15319a7d877ba5bf16752a375cfcb6 Mon Sep 17 00:00:00 2001 From: "joogab.yun" Date: Thu, 19 Aug 2021 17:20:24 +0900 Subject: [PATCH] [Tizen] 1. Add KEYBOARD_FOCUSABLE_CHILDREN property. Whether the children of this actor can be focusable by keyboard navigation. 2. If DISPATCH_KEY_EVENTS property is false, the KeyEvent is not received. Change-Id: I58c07ac04b90ce41c7b944c49a672a81be5bb574 --- .../dali-toolkit/utc-Dali-KeyInputFocusManager.cpp | 48 ++++++++ .../dali-toolkit/utc-Dali-KeyboardFocusManager.cpp | 135 +++++++++++++++++++++ dali-toolkit/devel-api/controls/control-devel.h | 9 +- .../devel-api/focus-manager/focus-finder.cpp | 2 +- .../controls/control/control-data-impl.cpp | 56 ++++++--- .../internal/controls/control/control-data-impl.h | 2 + .../focus-manager/keyboard-focus-manager-impl.cpp | 18 ++- .../focus-manager/keyinput-focus-manager-impl.cpp | 15 +++ .../focus-manager/keyboard-focus-manager.h | 1 + 9 files changed, 265 insertions(+), 21 deletions(-) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-KeyInputFocusManager.cpp b/automated-tests/src/dali-toolkit/utc-Dali-KeyInputFocusManager.cpp index 5a0cf33..18345a3 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-KeyInputFocusManager.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-KeyInputFocusManager.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -305,6 +306,53 @@ int UtcDaliKeyInputFocusManagerKeyEventPropagation02(void) END_TEST; } +int UtcDaliKeyInputFocusManagerDispatchKeyEvents(void) +{ + + ToolkitTestApplication application; + Integration::Scene stage = application.GetScene(); + + tet_infoline("Test KeyEvents propagation. If DISPATCH_KEY_EVENTS property is false, the KeyEvent is also not received."); + + KeyInputFocusManager manager = KeyInputFocusManager::Get(); + DALI_TEST_CHECK(manager); + + DummyControl dummy1 = DummyControl::New(true); + dummy1.SetProperty( Actor::Property::SIZE, Vector2(100.0f, 100.0f) ); + KeyEventCallback callback1( false ); + dummy1.KeyEventSignal().Connect( &callback1, &KeyEventCallback::Callback ); + stage.Add( dummy1 ); + + DummyControl dummy2 = DummyControl::New(true); + dummy2.SetProperty( Actor::Property::SIZE, Vector2(100.0f, 100.0f) ); + KeyEventCallback callback2( false ); + dummy2.KeyEventSignal().Connect( &callback2, &KeyEventCallback::Callback ); + // dummy2 set DISPATCH_KEY_EVENTS property to false. + dummy2.SetProperty( Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS, false); + dummy1.Add( dummy2 ); + + DummyControl dummy3 = DummyControl::New(true); + Impl::DummyControl& dummy3Impl = static_cast(dummy3.GetImplementation()); + dummy3.SetProperty( Actor::Property::SIZE, Vector2(100.0f, 100.0f) ); + KeyEventCallback callback3( false ); + dummy3.KeyEventSignal().Connect( &callback3, &KeyEventCallback::Callback ); + dummy2.Add( dummy3 ); + DALI_TEST_CHECK( ! dummy3Impl.keyInputFocusGained ); + DALI_TEST_CHECK( ! dummy3Impl.keyInputFocusLost ); + + manager.SetFocus( dummy3 ); + DALI_TEST_CHECK( dummy3Impl.keyInputFocusGained ); + + Integration::KeyEvent event( "a", "", "a", 0, 0, 0, Integration::KeyEvent::UP, "", "", Device::Class::TOUCH, Device::Subclass::NONE ); + application.ProcessEvent(event); + + DALI_TEST_CHECK( !callback1.mIsCalled ); + DALI_TEST_CHECK( !callback2.mIsCalled ); + DALI_TEST_CHECK( !callback3.mIsCalled ); + + END_TEST; +} + int UtcDaliKeyInputFocusManagerGetCurrentFocusControl(void) { ToolkitTestApplication application; diff --git a/automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp b/automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp index af21d93..6d0e8af 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp @@ -1901,4 +1901,139 @@ int UtcDaliKeyboardFocusManagerSetAndGetCurrentFocusActorInTouchMode(void) DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second); END_TEST; +} + +int UtcDaliKeyboardFocusManagerEnableDefaultAlgorithm(void) +{ + ToolkitTestApplication application; + + tet_infoline(" UtcDaliKeyboardFocusManagerEnableDefaultAlgorithm"); + + // Register Type + TypeInfo type; + type = TypeRegistry::Get().GetTypeInfo( "KeyboardFocusManager" ); + DALI_TEST_CHECK( type ); + BaseHandle handle = type.CreateInstance(); + DALI_TEST_CHECK( handle ); + + KeyboardFocusManager manager = KeyboardFocusManager::Get(); + DALI_TEST_CHECK(manager); + + bool focusChangedSignalVerified = false; + FocusChangedCallback focusChangedCallback(focusChangedSignalVerified); + manager.FocusChangedSignal().Connect( &focusChangedCallback, &FocusChangedCallback::Callback ); + + PushButton button1 = PushButton::New(); + PushButton button2 = PushButton::New(); + + button1.SetProperty(Actor::Property::SIZE, Vector2(50, 50)); + button2.SetProperty(Actor::Property::SIZE, Vector2(50, 50)); + + button1.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE,true); + button2.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE,true); + + application.GetScene().Add(button1); + application.GetScene().Add(button2); + + // set position + // button1 -- button2 + button1.SetProperty(Actor::Property::POSITION, Vector2(0.0f, 0.0f)); + button2.SetProperty(Actor::Property::POSITION, Vector2(100.0f, 0.0f)); + + // flush the queue and render once + application.SendNotification(); + application.Render(); + + // Set the focus to the button1 + // [button1] -- button2 + DALI_TEST_CHECK(manager.SetCurrentFocusActor(button1) == true); + DALI_TEST_CHECK(manager.GetCurrentFocusActor() == button1); + DALI_TEST_CHECK(focusChangedCallback.mSignalVerified); + DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == Actor()); + DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == button1); + focusChangedCallback.Reset(); + + // without set the navigation properties, but we can focus move + // enable the default algorithm + Dali::Toolkit::DevelKeyboardFocusManager::EnableDefaultAlgorithm(manager, true); + DALI_TEST_CHECK( Dali::Toolkit::DevelKeyboardFocusManager::IsDefaultAlgorithmEnabled(manager) ); + + // Move the focus towards right + // button1 -- [button2] + DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::RIGHT) == true); + + // Confirm whether focus is moved to button2 + DALI_TEST_EQUALS(button2.GetProperty(DevelControl::Property::STATE), (int)DevelControl::FOCUSED, TEST_LOCATION); + DALI_TEST_CHECK(focusChangedCallback.mSignalVerified); + DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == button1); + DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == button2); + focusChangedCallback.Reset(); + + // disable the default algorithm + Dali::Toolkit::DevelKeyboardFocusManager::EnableDefaultAlgorithm(manager, false); + DALI_TEST_CHECK( !Dali::Toolkit::DevelKeyboardFocusManager::IsDefaultAlgorithmEnabled(manager) ); + + // Move the focus towards left, The focus move will fail because the default algorithm is disabled. + DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::LEFT) == false); + + // enable the default algorithm + Dali::Toolkit::DevelKeyboardFocusManager::EnableDefaultAlgorithm(manager, true); + DALI_TEST_CHECK( Dali::Toolkit::DevelKeyboardFocusManager::IsDefaultAlgorithmEnabled(manager) ); + + // Move the focus towards left, The focus move will success because the default algorithm is enabled. + // [button1] -- button2 + DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::LEFT) == true); + // Confirm whether focus is moved to button2 + DALI_TEST_EQUALS(button1.GetProperty(DevelControl::Property::STATE), (int)DevelControl::FOCUSED, TEST_LOCATION); + DALI_TEST_CHECK(focusChangedCallback.mSignalVerified); + DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == button2); + DALI_TEST_CHECK(focusChangedCallback.mCurrentFocusedActor == button1); + focusChangedCallback.Reset(); + + + END_TEST; +} + + +int UtcDaliKeyboardFocusManagerWithKeyboardFocusableChildren(void) +{ + ToolkitTestApplication application; + + tet_infoline(" UtcDaliKeyboardFocusManagerWithKeyboardFocusableChildren"); + + KeyboardFocusManager manager = KeyboardFocusManager::Get(); + DALI_TEST_CHECK(manager); + + // Create the first actor and add it to the stage + Actor first = Actor::New(); + first.SetProperty( Actor::Property::KEYBOARD_FOCUSABLE, true); + application.GetScene().Add(first); + + // Create the second actor and add it to the first actor. + Actor second = Actor::New(); + second.SetProperty( Actor::Property::KEYBOARD_FOCUSABLE, true); + first.Add(second); + + // Check that no actor is being focused yet. + DALI_TEST_CHECK(manager.GetCurrentFocusActor() == Actor()); + + // Check that the focus is set on the first actor + DALI_TEST_CHECK(manager.SetCurrentFocusActor(first) == true); + DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first); + + // Set KeyboardFocusableChildren false. + first.SetProperty( DevelActor::Property::KEYBOARD_FOCUSABLE_CHILDREN, false); + + // Check that it will fail to set focus on the second actor as it's not focusable + DALI_TEST_CHECK(manager.SetCurrentFocusActor(second) == false); + DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first); + + // Set KeyboardFocusableChildren true. + first.SetProperty( DevelActor::Property::KEYBOARD_FOCUSABLE_CHILDREN, true); + + // Check that the focus is set on the second actor + DALI_TEST_CHECK(manager.SetCurrentFocusActor(second) == true); + DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second); + + END_TEST; } \ No newline at end of file diff --git a/dali-toolkit/devel-api/controls/control-devel.h b/dali-toolkit/devel-api/controls/control-devel.h index da4b730..909806d 100644 --- a/dali-toolkit/devel-api/controls/control-devel.h +++ b/dali-toolkit/devel-api/controls/control-devel.h @@ -115,7 +115,14 @@ enum * @brief The shadow of the control. * @details Name "shadow", type Property::MAP. */ - SHADOW = PADDING + 8 + SHADOW = PADDING + 8, + + /** + * @brief Whether a Control and its descendants can emit key signals. + * @details Name "dispatchKeyEvents", type Property::BOOLEAN + * @note If a control's dispatchKeyEvents is set to false, then it's children will not emit a key event signal either. + */ + DISPATCH_KEY_EVENTS, }; } // namespace Property diff --git a/dali-toolkit/devel-api/focus-manager/focus-finder.cpp b/dali-toolkit/devel-api/focus-manager/focus-finder.cpp index 2679dda..ddd0360 100644 --- a/dali-toolkit/devel-api/focus-manager/focus-finder.cpp +++ b/dali-toolkit/devel-api/focus-manager/focus-finder.cpp @@ -350,7 +350,7 @@ bool IsFocusable(Actor& actor) Actor FindNextFocus(Actor& actor, Actor& focusedActor, Rect& focusedRect, Rect& bestCandidateRect, Toolkit::Control::KeyboardFocus::Direction direction) { Actor nearestActor; - if(actor && actor.GetProperty(Actor::Property::VISIBLE)) + if(actor && actor.GetProperty(Actor::Property::VISIBLE) && actor.GetProperty(DevelActor::Property::KEYBOARD_FOCUSABLE_CHILDREN)) { // Recursively children const auto childCount = actor.GetChildCount(); diff --git a/dali-toolkit/internal/controls/control/control-data-impl.cpp b/dali-toolkit/internal/controls/control/control-data-impl.cpp index f74344d..e7324e5 100755 --- a/dali-toolkit/internal/controls/control/control-data-impl.cpp +++ b/dali-toolkit/internal/controls/control/control-data-impl.cpp @@ -298,23 +298,26 @@ void SetVisualsOffScene( const RegisteredVisualContainer& container, Actor paren // Properties registered without macro to use specific member variables. -const PropertyRegistration Control::Impl::PROPERTY_1( typeRegistration, "styleName", Toolkit::Control::Property::STYLE_NAME, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); -const PropertyRegistration Control::Impl::PROPERTY_4( typeRegistration, "keyInputFocus", Toolkit::Control::Property::KEY_INPUT_FOCUS, Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); -const PropertyRegistration Control::Impl::PROPERTY_5( typeRegistration, "background", Toolkit::Control::Property::BACKGROUND, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); -const PropertyRegistration Control::Impl::PROPERTY_6( typeRegistration, "margin", Toolkit::Control::Property::MARGIN, Property::EXTENTS, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); -const PropertyRegistration Control::Impl::PROPERTY_7( typeRegistration, "padding", Toolkit::Control::Property::PADDING, Property::EXTENTS, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); -const PropertyRegistration Control::Impl::PROPERTY_8( typeRegistration, "tooltip", Toolkit::DevelControl::Property::TOOLTIP, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); -const PropertyRegistration Control::Impl::PROPERTY_9( typeRegistration, "state", Toolkit::DevelControl::Property::STATE, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); -const PropertyRegistration Control::Impl::PROPERTY_10( typeRegistration, "subState", Toolkit::DevelControl::Property::SUB_STATE, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); -const PropertyRegistration Control::Impl::PROPERTY_11( typeRegistration, "leftFocusableActorId", Toolkit::DevelControl::Property::LEFT_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); -const PropertyRegistration Control::Impl::PROPERTY_12( typeRegistration, "rightFocusableActorId", Toolkit::DevelControl::Property::RIGHT_FOCUSABLE_ACTOR_ID,Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); -const PropertyRegistration Control::Impl::PROPERTY_13( typeRegistration, "upFocusableActorId", Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); -const PropertyRegistration Control::Impl::PROPERTY_14( typeRegistration, "downFocusableActorId", Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); -const PropertyRegistration Control::Impl::PROPERTY_15( typeRegistration, "shadow", Toolkit::DevelControl::Property::SHADOW, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); - -Control::Impl::Impl( Control& controlImpl ) -: mControlImpl( controlImpl ), - mState( Toolkit::DevelControl::NORMAL ), +const PropertyRegistration Control::Impl::PROPERTY_1(typeRegistration, "styleName", Toolkit::Control::Property::STYLE_NAME, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty); +const PropertyRegistration Control::Impl::PROPERTY_4(typeRegistration, "keyInputFocus", Toolkit::Control::Property::KEY_INPUT_FOCUS, Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty); +const PropertyRegistration Control::Impl::PROPERTY_5(typeRegistration, "background", Toolkit::Control::Property::BACKGROUND, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty); +const PropertyRegistration Control::Impl::PROPERTY_6(typeRegistration, "margin", Toolkit::Control::Property::MARGIN, Property::EXTENTS, &Control::Impl::SetProperty, &Control::Impl::GetProperty); +const PropertyRegistration Control::Impl::PROPERTY_7(typeRegistration, "padding", Toolkit::Control::Property::PADDING, Property::EXTENTS, &Control::Impl::SetProperty, &Control::Impl::GetProperty); +const PropertyRegistration Control::Impl::PROPERTY_8(typeRegistration, "tooltip", Toolkit::DevelControl::Property::TOOLTIP, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty); +const PropertyRegistration Control::Impl::PROPERTY_9(typeRegistration, "state", Toolkit::DevelControl::Property::STATE, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty); +const PropertyRegistration Control::Impl::PROPERTY_10(typeRegistration, "subState", Toolkit::DevelControl::Property::SUB_STATE, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty); +const PropertyRegistration Control::Impl::PROPERTY_11(typeRegistration, "leftFocusableActorId", Toolkit::DevelControl::Property::LEFT_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty); +const PropertyRegistration Control::Impl::PROPERTY_12(typeRegistration, "rightFocusableActorId", Toolkit::DevelControl::Property::RIGHT_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty); +const PropertyRegistration Control::Impl::PROPERTY_13(typeRegistration, "upFocusableActorId", Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty); +const PropertyRegistration Control::Impl::PROPERTY_14(typeRegistration, "downFocusableActorId", Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty); +const PropertyRegistration Control::Impl::PROPERTY_15(typeRegistration, "shadow", Toolkit::DevelControl::Property::SHADOW, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty); +const PropertyRegistration Control::Impl::PROPERTY_16(typeRegistration, "dispatchKeyEvents", Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS, Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty); + +// clang-format on + +Control::Impl::Impl(Control& controlImpl) +: mControlImpl(controlImpl), + mState(Toolkit::DevelControl::NORMAL), mSubStateName(""), mLeftFocusableActorId( -1 ), mRightFocusableActorId( -1 ), @@ -344,7 +347,8 @@ Control::Impl::Impl( Control& controlImpl ) mIsKeyboardFocusGroup( false ), mIsEmittingResourceReadySignal(false), mNeedToEmitResourceReady(false), - mIsAutofillEnabled( false ) + mIsAutofillEnabled( false ), + mDispatchKeyEvents(true) { } @@ -1021,6 +1025,16 @@ void Control::Impl::SetProperty( BaseObject* object, Property::Index index, cons break; } + case Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS: + { + bool dispatch; + if(value.Get(dispatch)) + { + controlImpl.mImpl->mDispatchKeyEvents = dispatch; + } + break; + } + } } } @@ -1133,6 +1147,12 @@ Property::Value Control::Impl::GetProperty( BaseObject* object, Property::Index value = map; break; } + + case Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS: + { + value = controlImpl.mImpl->mDispatchKeyEvents; + break; + } } } diff --git a/dali-toolkit/internal/controls/control/control-data-impl.h b/dali-toolkit/internal/controls/control/control-data-impl.h index fbef8b6..ba53193 100755 --- a/dali-toolkit/internal/controls/control/control-data-impl.h +++ b/dali-toolkit/internal/controls/control/control-data-impl.h @@ -478,6 +478,7 @@ public: bool mIsEmittingResourceReadySignal :1; ///< True during ResourceReady(). bool mNeedToEmitResourceReady :1; ///< True if need to emit the resource ready signal again. bool mIsAutofillEnabled : 1; ///< Stroes whether the Autofill functionality is enabled. + bool mDispatchKeyEvents : 1; ///< Whether the actor emits key event signals RegisteredVisualContainer mRemoveVisuals; ///< List of visuals that are being replaced by another visual once ready @@ -498,6 +499,7 @@ public: static const PropertyRegistration PROPERTY_13; static const PropertyRegistration PROPERTY_14; static const PropertyRegistration PROPERTY_15; + static const PropertyRegistration PROPERTY_16; }; diff --git a/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp b/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp index 4f9bb84..f974299 100644 --- a/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp +++ b/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp @@ -204,7 +204,23 @@ bool KeyboardFocusManager::SetCurrentFocusActor( Actor actor ) bool KeyboardFocusManager::DoSetCurrentFocusActor( Actor actor ) { bool success = false; - if( actor && actor.GetProperty< bool >( Actor::Property::KEYBOARD_FOCUSABLE ) && actor.GetProperty< bool >( Actor::Property::CONNECTED_TO_SCENE ) ) + + // If the parent's KEYBOARD_FOCUSABLE_CHILDREN is false, it cannot have focus. + if(actor) + { + Actor parent = actor.GetParent(); + while(parent) + { + if(!parent.GetProperty(DevelActor::Property::KEYBOARD_FOCUSABLE_CHILDREN)) + { + DALI_LOG_INFO(gLogFilter, Debug::General, "[%s:%d] Parent Actor has KEYBOARD_FOCUSABLE_CHILDREN false,\n", __FUNCTION__, __LINE__); + return false; + } + parent = parent.GetParent(); + } + } + + if(actor && actor.GetProperty(Actor::Property::KEYBOARD_FOCUSABLE) && actor.GetProperty(Actor::Property::CONNECTED_TO_SCENE)) { Integration::SceneHolder currentWindow = Integration::SceneHolder::Get( actor ); diff --git a/dali-toolkit/internal/focus-manager/keyinput-focus-manager-impl.cpp b/dali-toolkit/internal/focus-manager/keyinput-focus-manager-impl.cpp index 2549e52..83e6018 100644 --- a/dali-toolkit/internal/focus-manager/keyinput-focus-manager-impl.cpp +++ b/dali-toolkit/internal/focus-manager/keyinput-focus-manager-impl.cpp @@ -26,6 +26,9 @@ #include #include +// INTERNAL INCLUDES +#include + namespace Dali { @@ -134,6 +137,18 @@ bool KeyInputFocusManager::OnKeyEvent( const KeyEvent& event ) Toolkit::Control control = GetCurrentFocusControl(); if( control ) { + Dali::Actor dispatch = control; + while(dispatch) + { + // If the DISPATCH_KEY_EVENTS is false, it cannot emit key event. + Toolkit::Control dispatchControl = Toolkit::Control::DownCast(dispatch); + if(dispatchControl && !dispatchControl.GetProperty(Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS)) + { + return true; + } + dispatch = dispatch.GetParent(); + } + // Notify the control about the key event consumed = EmitKeyEventSignal( control, event ); } diff --git a/dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h b/dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h index d99844e..df934f1 100644 --- a/dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h +++ b/dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h @@ -102,6 +102,7 @@ public: * @return Whether the focus is successful or not * @pre The KeyboardFocusManager has been initialized. * @pre The Actor has been initialized. + * @note If the parent of this actor has the KEYBOARD FOCUSABLE CHILDREN property set to false, it will not be focused. */ bool SetCurrentFocusActor(Actor actor); -- 2.7.4