[Tizen] 1. Add KEYBOARD_FOCUSABLE_CHILDREN property. 53/267653/1
authorjoogab.yun <joogab.yun@samsung.com>
Thu, 19 Aug 2021 08:20:24 +0000 (17:20 +0900)
committerjoogab.yun <joogab.yun@samsung.com>
Wed, 8 Dec 2021 07:28:39 +0000 (16:28 +0900)
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

automated-tests/src/dali-toolkit/utc-Dali-KeyInputFocusManager.cpp
automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp
dali-toolkit/devel-api/controls/control-devel.h
dali-toolkit/devel-api/focus-manager/focus-finder.cpp
dali-toolkit/internal/controls/control/control-data-impl.cpp
dali-toolkit/internal/controls/control/control-data-impl.h
dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp
dali-toolkit/internal/focus-manager/keyinput-focus-manager-impl.cpp
dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h

index 5a0cf33..18345a3 100644 (file)
@@ -20,6 +20,7 @@
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali-toolkit/dali-toolkit.h>
 #include <dali/integration-api/events/key-event-integ.h>
+#include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
 #include <dali/devel-api/common/stage-devel.h>
 
@@ -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<Impl::DummyControl&>(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;
index af21d93..6d0e8af 100644 (file)
@@ -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<int>(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<int>(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
index da4b730..909806d 100644 (file)
@@ -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
index 2679dda..ddd0360 100644 (file)
@@ -350,7 +350,7 @@ bool IsFocusable(Actor& actor)
 Actor FindNextFocus(Actor& actor, Actor& focusedActor, Rect<float>& focusedRect, Rect<float>& bestCandidateRect, Toolkit::Control::KeyboardFocus::Direction direction)\r
 {\r
   Actor nearestActor;\r
-  if(actor && actor.GetProperty<bool>(Actor::Property::VISIBLE))\r
+  if(actor && actor.GetProperty<bool>(Actor::Property::VISIBLE) && actor.GetProperty<bool>(DevelActor::Property::KEYBOARD_FOCUSABLE_CHILDREN))\r
   {\r
     // Recursively children\r
     const auto childCount = actor.GetChildCount();\r
index f74344d..e7324e5 100755 (executable)
@@ -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;
+      }
     }
   }
 
index fbef8b6..ba53193 100755 (executable)
@@ -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;
 };
 
 
index 4f9bb84..f974299 100644 (file)
@@ -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<bool>(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<bool>(Actor::Property::KEYBOARD_FOCUSABLE) && actor.GetProperty<bool>(Actor::Property::CONNECTED_TO_SCENE))
   {
     Integration::SceneHolder currentWindow = Integration::SceneHolder::Get( actor );
 
index 2549e52..83e6018 100644 (file)
@@ -26,6 +26,9 @@
 #include <dali/integration-api/adaptor-framework/adaptor.h>
 #include <dali/integration-api/adaptor-framework/scene-holder.h>
 
+// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/controls/control-devel.h>
+
 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<bool>(Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS))
+      {
+        return true;
+      }
+      dispatch = dispatch.GetParent();
+    }
+
     // Notify the control about the key event
     consumed = EmitKeyEventSignal( control, event );
   }
index d99844e..df934f1 100644 (file)
@@ -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);