X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;ds=sidebyside;f=dali-toolkit%2Finternal%2Ffocus-manager%2Fkeyboard-focus-manager-impl.cpp;h=8c737d2f000447261ef0df6701b73ea1c4ed7a05;hb=HEAD;hp=a64690e053ecb3f9e79be9045662bf2396e2e026;hpb=a5167c61104580ae0ab724f904537a3a01ea3061;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git 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 a64690e..e8a990f 100644 --- a/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp +++ b/dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 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. @@ -119,6 +119,7 @@ KeyboardFocusManager::KeyboardFocusManager() mFocusedActorEnterKeySignal(), mCurrentFocusActor(), mFocusIndicatorActor(), + mFocusFinderRootActor(), mFocusHistory(), mSlotDelegate(this), mCustomAlgorithmInterface(NULL), @@ -129,7 +130,8 @@ KeyboardFocusManager::KeyboardFocusManager() mFocusGroupLoopEnabled(false), mIsWaitingKeyboardFocusChangeCommit(false), mClearFocusOnTouch(true), - mEnableDefaultAlgorithm(false) + mEnableDefaultAlgorithm(false), + mCurrentWindowId(0) { // TODO: Get FocusIndicatorEnable constant from stylesheet to set mIsFocusIndicatorShown. @@ -148,7 +150,7 @@ void KeyboardFocusManager::OnAdaptorInit() (*iter).TouchedSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnTouch); (*iter).WheelEventGeneratedSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnCustomWheelEvent); (*iter).WheelEventSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnWheelEvent); - Dali::Window window = DevelWindow::DownCast(*iter); + Window window = Window::DownCast(*iter); if(window) { window.FocusChangeSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnWindowFocusChanged); @@ -166,7 +168,7 @@ void KeyboardFocusManager::OnSceneHolderCreated(Dali::Integration::SceneHolder& sceneHolder.TouchedSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnTouch); sceneHolder.WheelEventGeneratedSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnCustomWheelEvent); sceneHolder.WheelEventSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnWheelEvent); - Dali::Window window = DevelWindow::DownCast(sceneHolder); + Window window = Window::DownCast(sceneHolder); if(window) { window.FocusChangeSignal().Connect(mSlotDelegate, &KeyboardFocusManager::OnWindowFocusChanged); @@ -182,8 +184,9 @@ void KeyboardFocusManager::GetConfigurationFromStyleManger() Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get(); if(styleManager) { - Property::Map config = Toolkit::DevelStyleManager::GetConfigurations(styleManager); - mAlwaysShowIndicator = config["alwaysShowFocus"].Get() ? ALWAYS_SHOW : NONE; + const auto alwaysShowFocusValue = Toolkit::DevelStyleManager::GetConfigurations(styleManager).Find("alwaysShowFocus", Property::Type::BOOLEAN); + + mAlwaysShowIndicator = (alwaysShowFocusValue && alwaysShowFocusValue->Get()) ? ALWAYS_SHOW : NONE; mIsFocusIndicatorShown = (mAlwaysShowIndicator == ALWAYS_SHOW) ? SHOW : HIDE; mClearFocusOnTouch = (mIsFocusIndicatorShown == SHOW) ? false : true; } @@ -205,61 +208,45 @@ bool KeyboardFocusManager::DoSetCurrentFocusActor(Actor actor) { bool success = false; - // If the parent's KEYBOARD_FOCUSABLE_CHILDREN is false, it cannot have focus. - if(actor) + // Check whether the actor is in the stage and is keyboard focusable. + if(actor && + actor.GetProperty(Actor::Property::KEYBOARD_FOCUSABLE) && + actor.GetProperty(DevelActor::Property::USER_INTERACTION_ENABLED) && + actor.GetProperty(Actor::Property::CONNECTED_TO_SCENE)) { + // If the parent's KEYBOARD_FOCUSABLE_CHILDREN is false, it cannot have focus. 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__); + DALI_LOG_DEBUG_INFO("Parent Actor has KEYBOARD_FOCUSABLE_CHILDREN false\n"); return false; } parent = parent.GetParent(); } - } - if(actor && actor.GetProperty(Actor::Property::KEYBOARD_FOCUSABLE) && actor.GetProperty(DevelActor::Property::USER_INTERACTION_ENABLED) && actor.GetProperty(Actor::Property::CONNECTED_TO_SCENE)) - { - Integration::SceneHolder currentWindow = Integration::SceneHolder::Get(actor); + // If developer set focus on same actor, doing nothing + Actor currentFocusedActor = GetCurrentFocusActor(); + DALI_LOG_DEBUG_INFO("current focused actor : [%p] new focused actor : [%p]\n", currentFocusedActor.GetObjectPtr(), actor.GetObjectPtr()); + if(actor == currentFocusedActor) + { + return true; + } + Integration::SceneHolder currentWindow = Integration::SceneHolder::Get(actor); if(currentWindow.GetRootLayer() != mCurrentFocusedWindow.GetHandle()) { Layer rootLayer = currentWindow.GetRootLayer(); mCurrentFocusedWindow = rootLayer; + mCurrentWindowId = static_cast(currentWindow.GetNativeId()); } - } - - Actor currentFocusedActor = GetCurrentFocusActor(); - // If developer set focus on same actor, doing nothing - if(actor == currentFocusedActor) - { - if(!actor) - { - return false; - } - return true; - } - - // Check whether the actor is in the stage and is keyboard focusable. - if(actor && actor.GetProperty(Actor::Property::KEYBOARD_FOCUSABLE) && actor.GetProperty(DevelActor::Property::USER_INTERACTION_ENABLED) && actor.GetProperty(Actor::Property::CONNECTED_TO_SCENE)) - { if((mIsFocusIndicatorShown == SHOW) && (mEnableFocusIndicator == ENABLE)) { actor.Add(GetFocusIndicatorActor()); } - - Toolkit::Control currentlyFocusedControl = Toolkit::Control::DownCast(currentFocusedActor); - if(currentlyFocusedControl) - { - // Do we need it to remember if it was previously DISABLED? - currentlyFocusedControl.SetProperty(DevelControl::Property::STATE, DevelControl::NORMAL); - currentlyFocusedControl.ClearKeyInputFocus(); - } - // Save the current focused actor mCurrentFocusActor = actor; @@ -279,6 +266,20 @@ bool KeyboardFocusManager::DoSetCurrentFocusActor(Actor actor) mCurrentFocusActors.push_back(std::pair, WeakHandle >(mCurrentFocusedWindow, actor)); } + // Send notification for the change of focus actor + if(!mFocusChangedSignal.Empty()) + { + mFocusChangedSignal.Emit(currentFocusedActor, actor); + } + + Toolkit::Control currentlyFocusedControl = Toolkit::Control::DownCast(currentFocusedActor); + if(currentlyFocusedControl) + { + // Do we need it to remember if it was previously DISABLED? + currentlyFocusedControl.SetProperty(DevelControl::Property::STATE, DevelControl::NORMAL); + currentlyFocusedControl.ClearKeyInputFocus(); + } + Toolkit::Control newlyFocusedControl = Toolkit::Control::DownCast(actor); if(newlyFocusedControl) { @@ -296,11 +297,6 @@ bool KeyboardFocusManager::DoSetCurrentFocusActor(Actor actor) mFocusHistory.erase(beginPos); } - // Send notification for the change of focus actor - if(!mFocusChangedSignal.Empty()) - { - mFocusChangedSignal.Emit(currentFocusedActor, actor); - } DALI_LOG_INFO(gLogFilter, Debug::General, "[%s:%d] SUCCEED\n", __FUNCTION__, __LINE__); success = true; } @@ -428,11 +424,11 @@ bool KeyboardFocusManager::MoveFocus(Toolkit::Control::KeyboardFocus::Direction bool succeed = false; // Go through the actor's hierarchy until we find a layout control that knows how to move the focus - Toolkit::Control parentLayoutControl = GetParentLayoutControl(currentFocusActor); - while(parentLayoutControl && !succeed) + Toolkit::Control layoutControl = IsLayoutControl(currentFocusActor) ? Toolkit::Control::DownCast(currentFocusActor) : GetParentLayoutControl(currentFocusActor); + while(layoutControl && !succeed) { - succeed = DoMoveFocusWithinLayoutControl(parentLayoutControl, currentFocusActor, direction); - parentLayoutControl = GetParentLayoutControl(parentLayoutControl); + succeed = DoMoveFocusWithinLayoutControl(layoutControl, currentFocusActor, direction); + layoutControl = GetParentLayoutControl(layoutControl); } if(!succeed) @@ -527,27 +523,30 @@ bool KeyboardFocusManager::MoveFocus(Toolkit::Control::KeyboardFocus::Direction nextFocusableActor = mPreFocusChangeSignal.Emit(currentFocusActor, Actor(), direction); mIsWaitingKeyboardFocusChangeCommit = false; } - else if (mEnableDefaultAlgorithm) + else if(mEnableDefaultAlgorithm) { - Layer rootLayer; - if (currentFocusActor) + Actor rootActor = mFocusFinderRootActor.GetHandle(); + if(!rootActor) { - // Find the window of the focused actor. - Integration::SceneHolder window = Integration::SceneHolder::Get(currentFocusActor); - if (window) + if(currentFocusActor) { - rootLayer = window.GetRootLayer(); + // Find the window of the focused actor. + Integration::SceneHolder window = Integration::SceneHolder::Get(currentFocusActor); + if(window) + { + rootActor = window.GetRootLayer(); + } + } + else + { + // Searches from the currently focused window. + rootActor = mCurrentFocusedWindow.GetHandle(); } } - else - { - // Searches from the currently focused window. - rootLayer = mCurrentFocusedWindow.GetHandle(); - } - if (rootLayer) + if(rootActor) { // We should find it among the actors nearby. - nextFocusableActor = Toolkit::FocusFinder::GetNearestFocusableActor(rootLayer, currentFocusActor, direction); + nextFocusableActor = Toolkit::FocusFinder::GetNearestFocusableActor(rootActor, currentFocusActor, direction); } } } @@ -561,9 +560,9 @@ bool KeyboardFocusManager::MoveFocus(Toolkit::Control::KeyboardFocus::Direction Toolkit::Control layoutControl = Toolkit::Control::DownCast(nextFocusableActor); succeed = DoMoveFocusWithinLayoutControl(layoutControl, currentFocusActor, direction); } - else + if(!succeed) { - // Otherwise, just set focus to the next focusable actor + // Just set focus to the next focusable actor succeed = SetCurrentFocusActor(nextFocusableActor); } } @@ -600,7 +599,7 @@ bool KeyboardFocusManager::DoMoveFocusWithinLayoutControl(Toolkit::Control contr if(committedFocusActor && committedFocusActor.GetProperty(Actor::Property::KEYBOARD_FOCUSABLE) && committedFocusActor.GetProperty(DevelActor::Property::USER_INTERACTION_ENABLED)) { // Whether the commited focusable actor is a layout control - if(IsLayoutControl(committedFocusActor)) + if(IsLayoutControl(committedFocusActor) && committedFocusActor != control) { // If so, move the focus inside it. Toolkit::Control layoutControl = Toolkit::Control::DownCast(committedFocusActor); @@ -683,6 +682,7 @@ void KeyboardFocusManager::ClearFocus() Actor actor = GetCurrentFocusActor(); if(actor) { + DALI_LOG_RELEASE_INFO("ClearFocus id:(%d)\n", actor.GetProperty(Dali::Actor::Property::ID)); // Send notification for the change of focus actor if(!mFocusChangedSignal.Empty()) { @@ -801,9 +801,25 @@ Actor KeyboardFocusManager::GetFocusIndicatorActor() return mFocusIndicatorActor; } +uint32_t KeyboardFocusManager::GetCurrentWindowId() const +{ + return mCurrentWindowId; +} + void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event) { - const std::string& keyName = event.GetKeyName(); + 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(mIsFocusIndicatorShown == UNKNOWN) @@ -988,7 +1004,7 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event) actor.Add(GetFocusIndicatorActor()); } } - else + else if(!mEnableDefaultAlgorithm) { // No actor is focused but keyboard focus is activated by the key press // Let's try to move the initial focus @@ -1016,24 +1032,17 @@ void KeyboardFocusManager::OnTouch(const TouchEvent& touch) { return; } + // If mClearFocusOnTouch is false, do not clear the focus indicator even if user touch the screen. + if(mClearFocusOnTouch) + { + ClearFocusIndicator(); + } + // If KEYBOARD_FOCUSABLE and TOUCH_FOCUSABLE is true, set focus actor if(hitActor && hitActor.GetProperty(Actor::Property::KEYBOARD_FOCUSABLE) && hitActor.GetProperty(DevelActor::Property::TOUCH_FOCUSABLE)) { - // If mClearFocusOnTouch is false, do not clear the focus - if(mClearFocusOnTouch) - { - ClearFocus(); - } SetCurrentFocusActor(hitActor); } - else - { - // If mClearFocusOnTouch is false, do not clear the focus indicator even if user touch the screen. - if(mClearFocusOnTouch) - { - ClearFocusIndicator(); - } - } } } @@ -1049,8 +1058,8 @@ void KeyboardFocusManager::OnWheelEvent(const WheelEvent& event) bool KeyboardFocusManager::OnCustomWheelEvent(const WheelEvent& event) { - bool consumed = false; - Actor actor = GetCurrentFocusActor(); + bool consumed = false; + Actor actor = GetCurrentFocusActor(); if(actor) { // Notify the actor about the wheel event @@ -1097,16 +1106,20 @@ void KeyboardFocusManager::OnWindowFocusChanged(Window window, bool focusIn) // Change Current Focused Window Layer rootLayer = window.GetRootLayer(); mCurrentFocusedWindow = rootLayer; + mCurrentWindowId = static_cast(Integration::SceneHolder::Get(rootLayer).GetNativeId()); // Get Current Focused Actor from window Actor currentFocusedActor = GetFocusActorFromCurrentWindow(); - SetCurrentFocusActor(currentFocusedActor); - - if(currentFocusedActor && (mEnableFocusIndicator == ENABLE)) + if(currentFocusedActor) { - // Make sure the focused actor is highlighted - currentFocusedActor.Add(GetFocusIndicatorActor()); - mIsFocusIndicatorShown = SHOW; + SetCurrentFocusActor(currentFocusedActor); + + if(mEnableFocusIndicator == ENABLE) + { + // Make sure the focused actor is highlighted + currentFocusedActor.Add(GetFocusIndicatorActor()); + mIsFocusIndicatorShown = SHOW; + } } } } @@ -1193,6 +1206,16 @@ bool KeyboardFocusManager::IsDefaultAlgorithmEnabled() const return mEnableDefaultAlgorithm; } +void KeyboardFocusManager::SetFocusFinderRootActor(Actor actor) +{ + mFocusFinderRootActor = actor; +} + +void KeyboardFocusManager::ResetFocusFinderRootActor() +{ + mFocusFinderRootActor.Reset(); +} + } // namespace Internal } // namespace Toolkit