#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>
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;
* @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
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)
mIsKeyboardNavigationSupported(false),
mIsKeyboardFocusGroup(false),
mIsEmittingResourceReadySignal(false),
- mNeedToEmitResourceReady(false)
+ mNeedToEmitResourceReady(false),
+ mDispatchKeyEvents(true)
{
Dali::Accessibility::Accessible::RegisterControlAccessibilityGetter(
[](Dali::Actor actor) -> Dali::Accessibility::Accessible* {
}
break;
}
+
+ case Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS:
+ {
+ bool dispatch;
+ if(value.Get(dispatch))
+ {
+ controlImpl.mImpl->mDispatchKeyEvents = dispatch;
+ }
+ break;
+ }
}
}
}
value = controlImpl.mImpl->mAccessibilityAttributes;
break;
}
+ case Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS:
+ {
+ value = controlImpl.mImpl->mDispatchKeyEvents;
+ break;
+ }
}
}
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
#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
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);
}