If DISPATCH_KEY_EVENTS property is false, the KeyEvent is not received. 69/263769/9
authorjoogab.yun <joogab.yun@samsung.com>
Fri, 10 Sep 2021 00:57:46 +0000 (09:57 +0900)
committerjoogab.yun <joogab.yun@samsung.com>
Mon, 27 Sep 2021 05:14:00 +0000 (14:14 +0900)
Change-Id: I62bc51eac1af88596635ef27a021c6bf10edc7d8

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

index 5a0cf3324c4785304f42f7e32e26db54e8f200b6..18345a3bdfb0ecb79f0b1ef059cf652b1085df16 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 51cf1cc198870a99aa61902cedf077b1d9f6f73a..36b83f9b7a22825d82df5c148fb2656fd7e615d5 100644 (file)
@@ -184,7 +184,14 @@ enum
    * @brief Set of accessibility attributes describing object in accessibility hierarchy
    * @details Name "accessibilityAttributes", type Property::MAP
    */
-  ACCESSIBILITY_ATTRIBUTES
+  ACCESSIBILITY_ATTRIBUTES,
+
+  /**
+   * @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 ced845ae5b5d2324cdb4e8eb220d89cecf56a88e..f9f437633614915ca3d3bb06c68d01d050bf4e8e 100644 (file)
@@ -467,6 +467,8 @@ const PropertyRegistration Control::Impl::PROPERTY_18(typeRegistration, "accessi
 const PropertyRegistration Control::Impl::PROPERTY_19(typeRegistration, "accessibilityRole",              Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE,               Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
 const PropertyRegistration Control::Impl::PROPERTY_20(typeRegistration, "accessibilityHighlightable",     Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE,      Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
 const PropertyRegistration Control::Impl::PROPERTY_21(typeRegistration, "accessibilityAttributes",        Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES,         Property::MAP,     &Control::Impl::SetProperty, &Control::Impl::GetProperty);
+const PropertyRegistration Control::Impl::PROPERTY_22(typeRegistration, "dispatchKeyEvents",              Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS,               Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
+
 // clang-format on
 
 Control::Impl::Impl(Control& controlImpl)
@@ -501,7 +503,8 @@ Control::Impl::Impl(Control& controlImpl)
   mIsKeyboardNavigationSupported(false),
   mIsKeyboardFocusGroup(false),
   mIsEmittingResourceReadySignal(false),
-  mNeedToEmitResourceReady(false)
+  mNeedToEmitResourceReady(false),
+  mDispatchKeyEvents(true)
 {
   Dali::Accessibility::Accessible::RegisterControlAccessibilityGetter(
     [](Dali::Actor actor) -> Dali::Accessibility::Accessible* {
@@ -1362,6 +1365,16 @@ void Control::Impl::SetProperty(BaseObject* object, Property::Index index, const
         }
         break;
       }
+
+      case Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS:
+      {
+        bool dispatch;
+        if(value.Get(dispatch))
+        {
+          controlImpl.mImpl->mDispatchKeyEvents = dispatch;
+        }
+        break;
+      }
     }
   }
 }
@@ -1522,6 +1535,11 @@ Property::Value Control::Impl::GetProperty(BaseObject* object, Property::Index i
         value = controlImpl.mImpl->mAccessibilityAttributes;
         break;
       }
+      case Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS:
+      {
+        value = controlImpl.mImpl->mDispatchKeyEvents;
+        break;
+      }
     }
   }
 
index 73b12e020c40444c078e042a07c58a70baf7ef29..94da0fc1484d7ccced39ae4ca309e7e9484c9b55 100644 (file)
@@ -551,6 +551,7 @@ public:
   bool             mIsKeyboardFocusGroup : 1;             ///< Stores whether the control is a focus group.
   bool             mIsEmittingResourceReadySignal : 1;    ///< True during ResourceReady().
   bool             mNeedToEmitResourceReady : 1;          ///< True if need to emit the resource ready signal again.
+  bool             mDispatchKeyEvents : 1;                ///< Whether the actor emits key event signals
 
   RegisteredVisualContainer mRemoveVisuals; ///< List of visuals that are being replaced by another visual once ready
 
index ad87ac3f07b13c6352570a83babc58608059c113..ebdb214fb84ba5997afcb1bc29b102b1bde6c093 100644 (file)
@@ -26,6 +26,9 @@
 #include <dali/public-api/actors/layer.h>
 #include <cstring> // for strcmp
 
+// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/controls/control-devel.h>
+
 namespace Dali
 {
 namespace Toolkit
@@ -130,6 +133,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);
   }