diff options
author | Seoyeon Kim <seoyeon2.kim@samsung.com> | 2024-03-12 02:58:43 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@review> | 2024-03-12 02:58:43 +0000 |
commit | 818595f5b37031fb09cb5f4bd0efd1dceffe3751 (patch) | |
tree | aeda3afe1ddc2cbef827b1574ddbb63baeef9b0e | |
parent | 178139049e8b853b9df7fbb3ecd5b0916a067c3e (diff) | |
parent | 6f1168bbac355dbd3c082d76559d68f522469172 (diff) | |
download | dali-adaptor-818595f5b37031fb09cb5f4bd0efd1dceffe3751.tar.gz dali-adaptor-818595f5b37031fb09cb5f4bd0efd1dceffe3751.tar.bz2 dali-adaptor-818595f5b37031fb09cb5f4bd0efd1dceffe3751.zip |
Merge "[AT-SPI] Associate default labels with windows" into devel/master
-rw-r--r-- | dali/internal/accessibility/bridge/bridge-base.cpp | 75 | ||||
-rw-r--r-- | dali/internal/accessibility/bridge/bridge-base.h | 24 |
2 files changed, 86 insertions, 13 deletions
diff --git a/dali/internal/accessibility/bridge/bridge-base.cpp b/dali/internal/accessibility/bridge/bridge-base.cpp index 450969424..a819f259a 100644 --- a/dali/internal/accessibility/bridge/bridge-base.cpp +++ b/dali/internal/accessibility/bridge/bridge-base.cpp @@ -25,6 +25,7 @@ #include <memory> // INTERNAL INCLUDES +#include <dali/devel-api/adaptor-framework/window-devel.h> #include <dali/public-api/adaptor-framework/timer.h> using namespace Dali::Accessibility; @@ -227,28 +228,68 @@ void BridgeBase::RemoveTopLevelWindow(Accessible* windowAccessible) } } +void BridgeBase::CompressDefaultLabels() +{ + // Remove entries for objects which no longer exist + mDefaultLabels.remove_if([](const DefaultLabelType& label) { + return !label.first.GetBaseHandle(); // Check window's weak handle + // TODO: Once Accessible becomes a handle type, check its weak handle here as well + }); +} + void BridgeBase::RegisterDefaultLabel(Accessible* object) { - if(std::find(mDefaultLabels.begin(), mDefaultLabels.end(), object) == mDefaultLabels.end()) + CompressDefaultLabels(); + + Dali::WeakHandle<Dali::Window> window = GetWindow(object); + if(!window.GetBaseHandle()) // true also if `object` is null + { + DALI_LOG_ERROR("Cannot register default label: object does not belong to any window"); + return; + } + + auto it = std::find_if(mDefaultLabels.begin(), mDefaultLabels.end(), [object](const DefaultLabelType& label) { + return object == label.second; + }); + + if(it == mDefaultLabels.end()) + { + mDefaultLabels.push_back({window, object}); + } + else if(it->first != window) + { + // TODO: Tentative implementation. It is yet to be specified what should happen + // when the same object is re-registered as a default label for another window. + *it = {window, object}; + } + else // it->first == window && it->second == object { - mDefaultLabels.push_back(object); + // Nothing to do } } void BridgeBase::UnregisterDefaultLabel(Accessible* object) { - auto it = std::find(mDefaultLabels.begin(), mDefaultLabels.end(), object); - if(it != mDefaultLabels.end()) - { - mDefaultLabels.erase(it); - } + CompressDefaultLabels(); + + mDefaultLabels.remove_if([object](const DefaultLabelType& label) { + return object == label.second; + }); } Accessible* BridgeBase::GetDefaultLabel(Accessible* root) const { - // TODO (multi-window support): Change mDefaultLabels to a collection of vectors - // (one per window) and select the right one based on the window that 'root' belongs to. - return mDefaultLabels.empty() ? root : mDefaultLabels.back(); + Dali::WeakHandle<Dali::Window> window = GetWindow(root); + if(!window.GetBaseHandle()) + { + return root; + } + + auto it = std::find_if(mDefaultLabels.rbegin(), mDefaultLabels.rend(), [&window](const DefaultLabelType& label) { + return window == label.first; + }); + + return (it == mDefaultLabels.rend()) ? root : it->second; } std::string BridgeBase::StripPrefix(const std::string& path) @@ -360,3 +401,17 @@ auto BridgeBase::CreateCacheElement(Accessible* item) -> CacheElementType item->GetDescription(), item->GetStates().GetRawData()); } + +Dali::WeakHandle<Dali::Window> BridgeBase::GetWindow(Dali::Accessibility::Accessible* accessible) +{ + Dali::WeakHandle<Dali::Window> windowHandle; + Dali::Actor actor = accessible ? accessible->GetInternalActor() : Dali::Actor(); + + if(actor) + { + Dali::Window window = Dali::DevelWindow::Get(actor); + windowHandle = {window}; + } + + return windowHandle; +} diff --git a/dali/internal/accessibility/bridge/bridge-base.h b/dali/internal/accessibility/bridge/bridge-base.h index 81a6dfb03..ab797232c 100644 --- a/dali/internal/accessibility/bridge/bridge-base.h +++ b/dali/internal/accessibility/bridge/bridge-base.h @@ -21,6 +21,7 @@ // EXTERNAL INCLUDES #include <dali/public-api/actors/layer.h> #include <dali/public-api/dali-adaptor-version.h> +#include <dali/public-api/object/weak-handle.h> #include <dali/public-api/signals/connection-tracker.h> #include <memory> #include <tuple> @@ -612,9 +613,13 @@ public: } protected: - mutable ApplicationAccessible mApplication; - std::vector<Dali::Accessibility::Accessible*> mDefaultLabels; - bool mIsScreenReaderSuppressed = false; + // We use a weak handle in order not to keep a window alive forever if someone forgets to UnregisterDefaultLabel() + using DefaultLabelType = std::pair<Dali::WeakHandle<Dali::Window>, Dali::Accessibility::Accessible*>; + using DefaultLabelsType = std::list<DefaultLabelType>; + + mutable ApplicationAccessible mApplication; + DefaultLabelsType mDefaultLabels; + bool mIsScreenReaderSuppressed = false; private: /** @@ -664,6 +669,19 @@ private: */ CacheElementType CreateCacheElement(Dali::Accessibility::Accessible* item); + /** + * @brief Removes expired elements from the default label collection. + */ + void CompressDefaultLabels(); + + /** + * @brief Gets the window to which this accessible belongs (or an empty handle). + * + * @param accessible The accessible + * @return The window + */ + static Dali::WeakHandle<Dali::Window> GetWindow(Dali::Accessibility::Accessible* accessible); + protected: BridgeBase(); virtual ~BridgeBase(); |