/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
mFocusGroupLoopEnabled(false),
mIsWaitingKeyboardFocusChangeCommit(false),
mClearFocusOnTouch(true),
- mEnableDefaultAlgorithm(false)
+ mEnableDefaultAlgorithm(false),
+ mCurrentWindowId(0)
{
// TODO: Get FocusIndicatorEnable constant from stylesheet to set mIsFocusIndicatorShown.
Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
if(styleManager)
{
- const Property::Map& config = Toolkit::DevelStyleManager::GetConfigurations(styleManager);
- const auto alwaysShowFocusValue = config.Find("alwaysShowFocus", Property::Type::BOOLEAN);
+ const auto alwaysShowFocusValue = Toolkit::DevelStyleManager::GetConfigurations(styleManager).Find("alwaysShowFocus", Property::Type::BOOLEAN);
mAlwaysShowIndicator = (alwaysShowFocusValue && alwaysShowFocusValue->Get<bool>()) ? ALWAYS_SHOW : NONE;
mIsFocusIndicatorShown = (mAlwaysShowIndicator == ALWAYS_SHOW) ? SHOW : HIDE;
bool KeyboardFocusManager::DoSetCurrentFocusActor(Actor actor)
{
- bool success = false;
+ bool success = false;
+ Integration::SceneHolder currentWindow;
// Check whether the actor is in the stage and is keyboard focusable.
if(actor &&
actor.GetProperty<bool>(Actor::Property::KEYBOARD_FOCUSABLE) &&
actor.GetProperty<bool>(DevelActor::Property::USER_INTERACTION_ENABLED) &&
- actor.GetProperty<bool>(Actor::Property::CONNECTED_TO_SCENE))
+ actor.GetProperty<bool>(Actor::Property::CONNECTED_TO_SCENE) &&
+ (currentWindow = Integration::SceneHolder::Get(actor))) ///< Note : SceneHolder might not be valid even if actor is connected to scene.
+ /// (e.g. Adaptor Stopped, SceneHolder removed but Scene is still alive)
{
// If the parent's KEYBOARD_FOCUSABLE_CHILDREN is false, it cannot have focus.
Actor parent = actor.GetParent();
return true;
}
- Integration::SceneHolder currentWindow = Integration::SceneHolder::Get(actor);
if(currentWindow.GetRootLayer() != mCurrentFocusedWindow.GetHandle())
{
Layer rootLayer = currentWindow.GetRootLayer();
mCurrentFocusedWindow = rootLayer;
+ mCurrentWindowId = static_cast<uint32_t>(currentWindow.GetNativeId());
}
if((mIsFocusIndicatorShown == SHOW) && (mEnableFocusIndicator == ENABLE))
actor.Add(GetFocusIndicatorActor());
}
+ actor.OffSceneSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnSceneDisconnection);
+
// Save the current focused actor
mCurrentFocusActor = actor;
}
}
-void KeyboardFocusManager::ClearFocus()
+void KeyboardFocusManager::ClearFocus(Actor actor)
{
- ClearFocusIndicator();
- Actor actor = GetCurrentFocusActor();
if(actor)
{
+ DALI_LOG_RELEASE_INFO("ClearFocus id:(%d)\n", actor.GetProperty<int32_t>(Dali::Actor::Property::ID));
+ actor.OffSceneSignal().Disconnect(mSlotDelegate, &KeyboardFocusManager::OnSceneDisconnection);
// Send notification for the change of focus actor
if(!mFocusChangedSignal.Empty())
{
mCurrentFocusActor.Reset();
}
-void KeyboardFocusManager::ClearFocusIndicator()
+void KeyboardFocusManager::ClearFocusIndicator(Actor actor)
{
- Actor actor = GetCurrentFocusActor();
if(actor)
{
if(mFocusIndicatorActor)
mIsFocusIndicatorShown = (mAlwaysShowIndicator == ALWAYS_SHOW) ? SHOW : HIDE;
}
+void KeyboardFocusManager::ClearFocus()
+{
+ Actor actor = GetCurrentFocusActor();
+ ClearFocusIndicator(actor);
+ ClearFocus(actor);
+}
+
void KeyboardFocusManager::SetFocusGroupLoop(bool enabled)
{
mFocusGroupLoopEnabled = enabled;
return mFocusIndicatorActor;
}
+uint32_t KeyboardFocusManager::GetCurrentWindowId() const
+{
+ return mCurrentWindowId;
+}
+
void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
{
+ if(mCurrentFocusedWindow.GetHandle())
+ {
+ // If it is a key event that occurred in another window, it returns.
+ uint32_t eventWindowId = event.GetWindowId();
+ if(eventWindowId > 0 && GetCurrentWindowId() != eventWindowId)
+ {
+ DALI_LOG_RELEASE_INFO("CurrentFocusedWindow id %d, window ID where key event occurred %d : key event skip\n", GetCurrentWindowId(), eventWindowId);
+ return;
+ }
+ }
+
const std::string& keyName = event.GetKeyName();
const std::string& deviceName = event.GetDeviceName();
// If mClearFocusOnTouch is false, do not clear the focus indicator even if user touch the screen.
if(mClearFocusOnTouch)
{
- ClearFocusIndicator();
+ ClearFocusIndicator(GetCurrentFocusActor());
}
// If KEYBOARD_FOCUSABLE and TOUCH_FOCUSABLE is true, set focus actor
// Change Current Focused Window
Layer rootLayer = window.GetRootLayer();
mCurrentFocusedWindow = rootLayer;
+ mCurrentWindowId = static_cast<uint32_t>(Integration::SceneHolder::Get(rootLayer).GetNativeId());
// Get Current Focused Actor from window
Actor currentFocusedActor = GetFocusActorFromCurrentWindow();
mFocusFinderRootActor.Reset();
}
+void KeyboardFocusManager::OnSceneDisconnection(Dali::Actor actor)
+{
+ if(actor && actor == mCurrentFocusActor.GetHandle())
+ {
+ DALI_LOG_RELEASE_INFO("ClearFocus due to actor id:(%d) removed from scene\n", actor.GetProperty<int32_t>(Dali::Actor::Property::ID));
+ ClearFocusIndicator(actor);
+ ClearFocus(actor);
+ }
+}
+
} // namespace Internal
} // namespace Toolkit