summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeoyeon Kim <seoyeon2.kim@samsung.com>2024-03-12 02:58:43 +0000
committerGerrit Code Review <gerrit@review>2024-03-12 02:58:43 +0000
commit818595f5b37031fb09cb5f4bd0efd1dceffe3751 (patch)
treeaeda3afe1ddc2cbef827b1574ddbb63baeef9b0e
parent178139049e8b853b9df7fbb3ecd5b0916a067c3e (diff)
parent6f1168bbac355dbd3c082d76559d68f522469172 (diff)
downloaddali-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.cpp75
-rw-r--r--dali/internal/accessibility/bridge/bridge-base.h24
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();