Title: [287020] trunk/Source/WebCore
Revision
287020
Author
[email protected]
Date
2021-12-14 02:43:09 -0800 (Tue, 14 Dec 2021)

Log Message

[GTK][a11y] Register the wrappers tree when org.a11y.atspi.Cache.GetItems() is called
https://bugs.webkit.org/show_bug.cgi?id=234292

Reviewed by Joanmarie Diggs.

This ensures wrappers always have a reference before being added to the cache.

* accessibility/AXObjectCache.h:
* accessibility/atspi/AXObjectCacheAtspi.cpp:
(WebCore::AXObjectCache::attachWrapper): Defer the set parent call to next cache update.
(WebCore::AXObjectCache::platformPerformDeferredCacheUpdate): Do the set parent call here.
* accessibility/atspi/AccessibilityAtspi.cpp:
(WebCore::AccessibilityAtspi::registerObject): Do not call addAccessible from here, since it needs the path,
it's now called from the caller of registerObject().
(WebCore::AccessibilityAtspi::parentChanged): Notify about parent property change.
(WebCore::AccessibilityAtspi::childrenChanged): Always emit ChildrenChanged when the tree is registered because
the atspi cache always consumes it.
(WebCore::AccessibilityAtspi::addAccessible): We no longer need to dispath addAccessible in the next run loop iteration.
* accessibility/atspi/AccessibilityAtspi.h:
* accessibility/atspi/AccessibilityObjectAtspi.cpp:
(WebCore::AccessibilityObjectAtspi::registerObject): Helper to register the object when path is not needed. Also
ensure the isolated tree is created before registering the object.
(WebCore::AccessibilityObjectAtspi::path): Call registerObject().
(WebCore::AccessibilityObjectAtspi::hyperlinkReference): Use registerObject() instead of path().
(WebCore::AccessibilityObjectAtspi::setParent): Call AccessibilityAtspi::parentChanged() if the wrapper is still
and attached and not ignored.
(WebCore::AccessibilityObjectAtspi::parentReference const): Use the parent member instead of asking the main
thread again.
(WebCore::AccessibilityObjectAtspi::isDefunct const): Return true if wrapper has been detached.
(WebCore::AccessibilityObjectAtspi::childAdded): We no longer need to dispatch childrenChanged in next run loop iteration.
* accessibility/atspi/AccessibilityObjectAtspi.h:
* accessibility/atspi/AccessibilityRootAtspi.cpp:
(WebCore::registerSubtree): Helper to register the wrappers tree recursively.
(WebCore::AccessibilityRootAtspi::registerTree): Register the wrappers tree.
* accessibility/atspi/AccessibilityRootAtspi.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (287019 => 287020)


--- trunk/Source/WebCore/ChangeLog	2021-12-14 10:29:29 UTC (rev 287019)
+++ trunk/Source/WebCore/ChangeLog	2021-12-14 10:43:09 UTC (rev 287020)
@@ -1,3 +1,41 @@
+2021-12-14  Carlos Garcia Campos  <[email protected]>
+
+        [GTK][a11y] Register the wrappers tree when org.a11y.atspi.Cache.GetItems() is called
+        https://bugs.webkit.org/show_bug.cgi?id=234292
+
+        Reviewed by Joanmarie Diggs.
+
+        This ensures wrappers always have a reference before being added to the cache.
+
+        * accessibility/AXObjectCache.h:
+        * accessibility/atspi/AXObjectCacheAtspi.cpp:
+        (WebCore::AXObjectCache::attachWrapper): Defer the set parent call to next cache update.
+        (WebCore::AXObjectCache::platformPerformDeferredCacheUpdate): Do the set parent call here.
+        * accessibility/atspi/AccessibilityAtspi.cpp:
+        (WebCore::AccessibilityAtspi::registerObject): Do not call addAccessible from here, since it needs the path,
+        it's now called from the caller of registerObject().
+        (WebCore::AccessibilityAtspi::parentChanged): Notify about parent property change.
+        (WebCore::AccessibilityAtspi::childrenChanged): Always emit ChildrenChanged when the tree is registered because
+        the atspi cache always consumes it.
+        (WebCore::AccessibilityAtspi::addAccessible): We no longer need to dispath addAccessible in the next run loop iteration.
+        * accessibility/atspi/AccessibilityAtspi.h:
+        * accessibility/atspi/AccessibilityObjectAtspi.cpp:
+        (WebCore::AccessibilityObjectAtspi::registerObject): Helper to register the object when path is not needed. Also
+        ensure the isolated tree is created before registering the object.
+        (WebCore::AccessibilityObjectAtspi::path): Call registerObject().
+        (WebCore::AccessibilityObjectAtspi::hyperlinkReference): Use registerObject() instead of path().
+        (WebCore::AccessibilityObjectAtspi::setParent): Call AccessibilityAtspi::parentChanged() if the wrapper is still
+        and attached and not ignored.
+        (WebCore::AccessibilityObjectAtspi::parentReference const): Use the parent member instead of asking the main
+        thread again.
+        (WebCore::AccessibilityObjectAtspi::isDefunct const): Return true if wrapper has been detached.
+        (WebCore::AccessibilityObjectAtspi::childAdded): We no longer need to dispatch childrenChanged in next run loop iteration.
+        * accessibility/atspi/AccessibilityObjectAtspi.h:
+        * accessibility/atspi/AccessibilityRootAtspi.cpp:
+        (WebCore::registerSubtree): Helper to register the wrappers tree recursively.
+        (WebCore::AccessibilityRootAtspi::registerTree): Register the wrappers tree.
+        * accessibility/atspi/AccessibilityRootAtspi.h:
+
 2021-12-14  Darin Adler  <[email protected]>
 
         Automatically generate event handler content attribute maps so they are easier to maintain

Modified: trunk/Source/WebCore/accessibility/AXObjectCache.h (287019 => 287020)


--- trunk/Source/WebCore/accessibility/AXObjectCache.h	2021-12-14 10:29:29 UTC (rev 287019)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.h	2021-12-14 10:43:09 UTC (rev 287020)
@@ -528,6 +528,9 @@
     ListHashSet<RefPtr<AccessibilityObject>> m_deferredAttachedWrapperObjectList;
     ListHashSet<GRefPtr<AccessibilityObjectWrapper>> m_deferredDetachedWrapperList;
 #endif
+#if USE(ATSPI)
+    ListHashSet<RefPtr<AXCoreObject>> m_deferredParentChangedList;
+#endif
 };
 
 class AXAttributeCacheEnabler

Modified: trunk/Source/WebCore/accessibility/atspi/AXObjectCacheAtspi.cpp (287019 => 287020)


--- trunk/Source/WebCore/accessibility/atspi/AXObjectCacheAtspi.cpp	2021-12-14 10:29:29 UTC (rev 287019)
+++ trunk/Source/WebCore/accessibility/atspi/AXObjectCacheAtspi.cpp	2021-12-14 10:43:09 UTC (rev 287020)
@@ -42,22 +42,30 @@
     auto wrapper = AccessibilityObjectAtspi::create(axObject, *rootWrapper);
     axObject->setWrapper(wrapper.ptr());
 
-    auto* axParent = axObject->parentObjectUnignored();
-    if (!axParent) {
-        if (axObject->isScrollView() && axObject->scrollView() == document().view())
-            wrapper->setParent(nullptr); // nullptr parent means root.
-        return;
-    }
-
-    auto* axParentWrapper = axParent->wrapper();
-    if (!axParentWrapper)
-        return;
-
-    wrapper->setParent(axParentWrapper);
+    m_deferredParentChangedList.add(axObject);
 }
 
 void AXObjectCache::platformPerformDeferredCacheUpdate()
 {
+    auto handleParentChanged = [&](const AXCoreObject& axObject) {
+        auto* wrapper = axObject.wrapper();
+        if (!wrapper)
+            return;
+
+        auto* axParent = axObject.parentObjectUnignored();
+        if (!axParent) {
+            if (axObject.isScrollView() && axObject.scrollView() == document().view())
+                wrapper->setParent(nullptr); // nullptr parent means root.
+            return;
+        }
+
+        if (auto* axParentWrapper = axParent->wrapper())
+            wrapper->setParent(axParentWrapper);
+    };
+
+    for (const auto& axObject : m_deferredParentChangedList)
+        handleParentChanged(*axObject);
+    m_deferredParentChangedList.clear();
 }
 
 bool AXObjectCache::isIsolatedTreeEnabled()

Modified: trunk/Source/WebCore/accessibility/atspi/AccessibilityAtspi.cpp (287019 => 287020)


--- trunk/Source/WebCore/accessibility/atspi/AccessibilityAtspi.cpp	2021-12-14 10:29:29 UTC (rev 287019)
+++ trunk/Source/WebCore/accessibility/atspi/AccessibilityAtspi.cpp	2021-12-14 10:43:09 UTC (rev 287020)
@@ -26,6 +26,7 @@
 #include <gio/gio.h>
 #include <glib/gi18n-lib.h>
 #include <wtf/MainThread.h>
+#include <wtf/SetForScope.h>
 #include <wtf/SortedArrayMap.h>
 #include <wtf/UUID.h>
 #include <wtf/glib/GUniquePtr.h>
@@ -123,8 +124,6 @@
     }
     m_atspiObjects.add(&atspiObject, WTFMove(registeredObjects));
 
-    addAccessible(atspiObject, path);
-
     return path;
 }
 
@@ -170,6 +169,24 @@
     return path;
 }
 
+void AccessibilityAtspi::parentChanged(AccessibilityObjectAtspi& atspiObject)
+{
+    RELEASE_ASSERT(isMainThread());
+    m_queue->dispatch([this, atspiObject = Ref { atspiObject }] {
+        if (!m_connection)
+            return;
+
+        // Always emit parentChanged when the tree is registered because the atspi cache always consumes it.
+        if (!atspiObject->root().isTreeRegistered())
+            return;
+
+        // We call path here to ensure it happens before parentReference() in case objects are not registered yet.
+        auto path = atspiObject->path();
+        g_dbus_connection_emit_signal(m_connection.get(), nullptr, path.utf8().data(), "org.a11y.atspi.Event.Object", "PropertyChange",
+            g_variant_new("(siiva{sv})", "accessible-parent", 0, 0, atspiObject->parentReference(), nullptr), nullptr);
+    });
+}
+
 void AccessibilityAtspi::childrenChanged(AccessibilityObjectAtspi& atspiObject, AccessibilityObjectAtspi& child, ChildrenChanged change)
 {
     RELEASE_ASSERT(isMainThread());
@@ -177,6 +194,10 @@
         if (!m_connection)
             return;
 
+        // Always emit ChildrenChanged when the tree is registered because the atspi cache always consumes it.
+        if (!atspiObject->root().isTreeRegistered())
+            return;
+
         g_dbus_connection_emit_signal(m_connection.get(), nullptr, atspiObject->path().utf8().data(), "org.a11y.atspi.Event.Object", "ChildrenChanged",
             g_variant_new("(siiv(so))", change == ChildrenChanged::Added ? "add" : "remove", child->indexInParentForChildrenChanged(change),
             0, g_variant_new("(so)", uniqueName(), child->path().utf8().data()), uniqueName(), atspiObject->path().utf8().data()), nullptr);
@@ -415,10 +436,12 @@
         RELEASE_ASSERT(!isMainThread());
         if (!g_strcmp0(methodName, "GetItems")) {
             auto& atspi = *static_cast<AccessibilityAtspi*>(userData);
+            SetForScope<bool> inGetItems(atspi.m_inGetItems, true);
             GVariantBuilder builder = G_VARIANT_BUILDER_INIT(G_VARIANT_TYPE("(" GET_ITEMS_SIGNATURE ")"));
             g_variant_builder_open(&builder, G_VARIANT_TYPE(GET_ITEMS_SIGNATURE));
-            for (const auto* rootObject : atspi.m_rootObjects.keys()) {
+            for (auto* rootObject : atspi.m_rootObjects.keys()) {
                 g_variant_builder_open(&builder, G_VARIANT_TYPE("(" ITEM_SIGNATURE ")"));
+                rootObject->registerTree();
                 rootObject->serialize(&builder);
                 g_variant_builder_close(&builder);
             }
@@ -429,7 +452,7 @@
             for (const auto& path : paths) {
                 auto wrapper = atspi.m_cache.get(path);
                 wrapper->updateBackingStore();
-                if (!atspi.m_cache.contains(path))
+                if (!atspi.m_cache.contains(path) || wrapper->isDefunct())
                     continue;
                 g_variant_builder_open(&builder, G_VARIANT_TYPE("(" ITEM_SIGNATURE ")"));
                 wrapper->serialize(&builder);
@@ -459,27 +482,23 @@
     m_cacheID = g_dbus_connection_register_object(m_connection.get(), "/org/a11y/atspi/cache", const_cast<GDBusInterfaceInfo*>(&webkit_cache_interface), &s_cacheFunctions, this, nullptr, nullptr);
 }
 
-void AccessibilityAtspi::addAccessible(AccessibilityObjectAtspi& atspiObject, const String& path)
+void AccessibilityAtspi::addAccessible(AccessibilityObjectAtspi& atspiObject)
 {
     RELEASE_ASSERT(!isMainThread());
     if (!m_connection)
         return;
 
-    auto addResult = m_cache.add(path, &atspiObject);
+    auto addResult = m_cache.add(atspiObject.path(), &atspiObject);
     if (!addResult.isNewEntry)
         return;
 
-    // AddAccessible needs to be emitted after ChildrenChanged.
-    RunLoop::current().dispatch([this, atspiObject = Ref { atspiObject }, path = path.isolatedCopy()] {
-        atspiObject->updateBackingStore();
-        if (!m_cache.contains(path))
-            return;
+    if (m_inGetItems)
+        return;
 
-        GVariantBuilder builder = G_VARIANT_BUILDER_INIT(G_VARIANT_TYPE("(" ITEM_SIGNATURE ")"));
-        atspiObject->serialize(&builder);
-        g_dbus_connection_emit_signal(m_connection.get(), nullptr, "/org/a11y/atspi/cache", "org.a11y.atspi.Cache", "AddAccessible",
-            g_variant_new("(@(" ITEM_SIGNATURE "))", g_variant_builder_end(&builder)), nullptr);
-    });
+    GVariantBuilder builder = G_VARIANT_BUILDER_INIT(G_VARIANT_TYPE("(" ITEM_SIGNATURE ")"));
+    atspiObject.serialize(&builder);
+    g_dbus_connection_emit_signal(m_connection.get(), nullptr, "/org/a11y/atspi/cache", "org.a11y.atspi.Cache", "AddAccessible",
+        g_variant_new("(@(" ITEM_SIGNATURE "))", g_variant_builder_end(&builder)), nullptr);
 }
 
 void AccessibilityAtspi::removeAccessible(AccessibilityObjectAtspi& atspiObject)

Modified: trunk/Source/WebCore/accessibility/atspi/AccessibilityAtspi.h (287019 => 287020)


--- trunk/Source/WebCore/accessibility/atspi/AccessibilityAtspi.h	2021-12-14 10:29:29 UTC (rev 287019)
+++ trunk/Source/WebCore/accessibility/atspi/AccessibilityAtspi.h	2021-12-14 10:43:09 UTC (rev 287020)
@@ -54,6 +54,7 @@
     void unregisterObject(AccessibilityObjectAtspi&);
     String registerHyperlink(AccessibilityObjectAtspi&, Vector<std::pair<GDBusInterfaceInfo*, GDBusInterfaceVTable*>>&&);
 
+    void parentChanged(AccessibilityObjectAtspi&);
     enum class ChildrenChanged { Added, Removed };
     void childrenChanged(AccessibilityObjectAtspi&, AccessibilityObjectAtspi&, ChildrenChanged);
 
@@ -70,9 +71,10 @@
 
     static const char* localizedRoleName(AccessibilityRole);
 
+    void addAccessible(AccessibilityObjectAtspi&);
+
 private:
     void ensureCache();
-    void addAccessible(AccessibilityObjectAtspi&, const String&);
     void removeAccessible(AccessibilityObjectAtspi&);
 
     static GDBusInterfaceVTable s_cacheFunctions;
@@ -84,6 +86,7 @@
     HashMap<AccessibilityObjectAtspi*, Vector<unsigned, 20>> m_atspiHyperlinks;
     unsigned m_cacheID { 0 };
     HashMap<String, AccessibilityObjectAtspi*> m_cache;
+    bool m_inGetItems { false };
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.cpp (287019 => 287020)


--- trunk/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.cpp	2021-12-14 10:29:29 UTC (rev 287019)
+++ trunk/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.cpp	2021-12-14 10:43:09 UTC (rev 287020)
@@ -481,40 +481,55 @@
     nullptr
 };
 
-const String& AccessibilityObjectAtspi::path()
+bool AccessibilityObjectAtspi::registerObject()
 {
     RELEASE_ASSERT(!isMainThread());
-    if (m_path.isNull()) {
-        m_isRegistered.store(true);
+    if (!m_path.isNull())
+        return false;
 
-        Vector<std::pair<GDBusInterfaceInfo*, GDBusInterfaceVTable*>> interfaces;
-        if (m_interfaces.contains(Interface::Accessible))
-            interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_accessible_interface), &s_accessibleFunctions });
-        if (m_interfaces.contains(Interface::Component))
-            interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_component_interface), &s_componentFunctions });
-        if (m_interfaces.contains(Interface::Text))
-            interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_text_interface), &s_textFunctions });
-        if (m_interfaces.contains(Interface::Value))
-            interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_value_interface), &s_valueFunctions });
-        if (m_interfaces.contains(Interface::Hyperlink))
-            interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_hyperlink_interface), &s_hyperlinkFunctions });
-        if (m_interfaces.contains(Interface::Hypertext))
-            interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_hypertext_interface), &s_hypertextFunctions });
-        if (m_interfaces.contains(Interface::Action))
-            interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_action_interface), &s_actionFunctions });
-        if (m_interfaces.contains(Interface::Document))
-            interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_document_interface), &s_documentFunctions });
-        if (m_interfaces.contains(Interface::Image))
-            interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_image_interface), &s_imageFunctions });
-        if (m_interfaces.contains(Interface::Selection))
-            interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_selection_interface), &s_selectionFunctions });
-        if (m_interfaces.contains(Interface::Table))
-            interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_table_interface), &s_tableFunctions });
-        if (m_interfaces.contains(Interface::TableCell))
-            interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_table_cell_interface), &s_tableCellFunctions });
-        m_path = m_root.atspi().registerObject(*this, WTFMove(interfaces));
+    m_isRegistered.store(true);
+    Vector<std::pair<GDBusInterfaceInfo*, GDBusInterfaceVTable*>> interfaces;
+    if (m_interfaces.contains(Interface::Accessible))
+        interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_accessible_interface), &s_accessibleFunctions });
+    if (m_interfaces.contains(Interface::Component))
+        interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_component_interface), &s_componentFunctions });
+    if (m_interfaces.contains(Interface::Text))
+        interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_text_interface), &s_textFunctions });
+    if (m_interfaces.contains(Interface::Value))
+        interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_value_interface), &s_valueFunctions });
+    if (m_interfaces.contains(Interface::Hyperlink))
+        interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_hyperlink_interface), &s_hyperlinkFunctions });
+    if (m_interfaces.contains(Interface::Hypertext))
+        interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_hypertext_interface), &s_hypertextFunctions });
+    if (m_interfaces.contains(Interface::Action))
+        interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_action_interface), &s_actionFunctions });
+    if (m_interfaces.contains(Interface::Document))
+        interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_document_interface), &s_documentFunctions });
+    if (m_interfaces.contains(Interface::Image))
+        interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_image_interface), &s_imageFunctions });
+    if (m_interfaces.contains(Interface::Selection))
+        interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_selection_interface), &s_selectionFunctions });
+    if (m_interfaces.contains(Interface::Table))
+        interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_table_interface), &s_tableFunctions });
+    if (m_interfaces.contains(Interface::TableCell))
+        interfaces.append({ const_cast<GDBusInterfaceInfo*>(&webkit_table_cell_interface), &s_tableCellFunctions });
+    if (!m_axObject) {
+        // Isolated tree hasn't been created yet, call AccessibilityRootAtspi::child()
+        // to create it before registering the object.
+        Accessibility::performFunctionOnMainThread([this] {
+            m_root.child();
+        });
     }
+    m_path = m_root.atspi().registerObject(*this, WTFMove(interfaces));
+    m_root.atspi().addAccessible(*this);
 
+    return true;
+}
+
+const String& AccessibilityObjectAtspi::path()
+{
+    RELEASE_ASSERT(!isMainThread());
+    registerObject();
     return m_path;
 }
 
@@ -528,7 +543,7 @@
 {
     RELEASE_ASSERT(!isMainThread());
     if (m_hyperlinkPath.isNull()) {
-        path();
+        registerObject();
         m_hyperlinkPath = m_root.atspi().registerHyperlink(*this, { { const_cast<GDBusInterfaceInfo*>(&webkit_hyperlink_interface), &s_hyperlinkFunctions } });
     }
 
@@ -542,6 +557,10 @@
         return;
 
     m_parent = atspiParent;
+    if (!m_coreObject || m_coreObject->accessibilityIsIgnored())
+        return;
+
+    m_root.atspi().parentChanged(*this);
     if (m_parent && *m_parent)
         m_parent.value()->childAdded(*this);
 }
@@ -564,14 +583,13 @@
 
 GVariant* AccessibilityObjectAtspi::parentReference() const
 {
-    auto parentAtspi = parent();
-    if (!parentAtspi)
+    if (!m_parent)
         return m_root.atspi().nullReference();
 
-    if (!parentAtspi.value())
+    if (!m_parent.value())
         return m_root.reference();
 
-    return parentAtspi.value()->reference();
+    return m_parent.value()->reference();
 }
 
 unsigned AccessibilityObjectAtspi::childCount() const
@@ -849,6 +867,13 @@
     });
 }
 
+bool AccessibilityObjectAtspi::isDefunct() const
+{
+    return Accessibility::retrieveValueFromMainThread<bool>([this]() -> bool {
+        return !m_coreObject;
+    });
+}
+
 String AccessibilityObjectAtspi::id() const
 {
     RELEASE_ASSERT(isMainThread());
@@ -1188,11 +1213,7 @@
     if (!m_isRegistered.load())
         return;
 
-    RunLoop::main().dispatch([this, protectedThis = Ref { *this }, child = Ref { child }] {
-        if (!m_coreObject)
-            return;
-        m_root.atspi().childrenChanged(*this, child, AccessibilityAtspi::ChildrenChanged::Added);
-    });
+    m_root.atspi().childrenChanged(*this, child, AccessibilityAtspi::ChildrenChanged::Added);
 }
 
 void AccessibilityObjectAtspi::childRemoved(AccessibilityObjectAtspi& child)

Modified: trunk/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.h (287019 => 287020)


--- trunk/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.h	2021-12-14 10:29:29 UTC (rev 287019)
+++ trunk/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.h	2021-12-14 10:43:09 UTC (rev 287020)
@@ -41,6 +41,8 @@
     static Ref<AccessibilityObjectAtspi> create(AXCoreObject*, AccessibilityRootAtspi&);
     ~AccessibilityObjectAtspi() = default;
 
+    bool registerObject();
+
     enum class Interface : uint16_t {
         Accessible = 1 << 0,
         Component = 1 << 1,
@@ -60,6 +62,7 @@
     const AccessibilityRootAtspi& root() const { return m_root; }
     void setParent(std::optional<AccessibilityObjectAtspi*>);
     WEBCORE_EXPORT std::optional<AccessibilityObjectAtspi*> parent() const;
+    GVariant* parentReference() const;
     WEBCORE_EXPORT void updateBackingStore();
 
     void attach(AXCoreObject*);
@@ -83,6 +86,7 @@
     WEBCORE_EXPORT Vector<RefPtr<AccessibilityObjectAtspi>> children() const;
     WEBCORE_EXPORT AccessibilityObjectAtspi* childAt(unsigned) const;
     WEBCORE_EXPORT uint64_t state() const;
+    bool isDefunct() const;
     void stateChanged(const char*, bool);
     WEBCORE_EXPORT HashMap<String, String> attributes() const;
     WEBCORE_EXPORT HashMap<uint32_t, Vector<RefPtr<AccessibilityObjectAtspi>>> relationMap() const;
@@ -157,7 +161,6 @@
 
     Vector<RefPtr<AccessibilityObjectAtspi>> wrapperVector(const Vector<RefPtr<AXCoreObject>>&) const;
     int indexInParent() const;
-    GVariant* parentReference() const;
     void childAdded(AccessibilityObjectAtspi&);
     void childRemoved(AccessibilityObjectAtspi&);
 

Modified: trunk/Source/WebCore/accessibility/atspi/AccessibilityRootAtspi.cpp (287019 => 287020)


--- trunk/Source/WebCore/accessibility/atspi/AccessibilityRootAtspi.cpp	2021-12-14 10:29:29 UTC (rev 287019)
+++ trunk/Source/WebCore/accessibility/atspi/AccessibilityRootAtspi.cpp	2021-12-14 10:43:09 UTC (rev 287020)
@@ -187,6 +187,31 @@
         m_page->setAccessibilityRootObject(nullptr);
 }
 
+static void registerSubtree(AccessibilityObjectAtspi* atspiObject)
+{
+    if (!atspiObject)
+        return;
+
+    if (!atspiObject->registerObject())
+        return;
+
+    atspiObject->updateBackingStore();
+    for (auto& child : atspiObject->children())
+        registerSubtree(child.get());
+}
+
+void AccessibilityRootAtspi::registerTree()
+{
+    RELEASE_ASSERT(!isMainThread());
+    if (m_parentUniqueName.isNull())
+        return;
+
+    registerSubtree(Accessibility::retrieveValueFromMainThread<AccessibilityObjectAtspi*>([this]() -> AccessibilityObjectAtspi* {
+        return child();
+    }));
+    m_isTreeRegistered.store(true);
+}
+
 void AccessibilityRootAtspi::setPath(String&& path)
 {
     RELEASE_ASSERT(!isMainThread());

Modified: trunk/Source/WebCore/accessibility/atspi/AccessibilityRootAtspi.h (287019 => 287020)


--- trunk/Source/WebCore/accessibility/atspi/AccessibilityRootAtspi.h	2021-12-14 10:29:29 UTC (rev 287019)
+++ trunk/Source/WebCore/accessibility/atspi/AccessibilityRootAtspi.h	2021-12-14 10:43:09 UTC (rev 287020)
@@ -22,6 +22,7 @@
 #if ENABLE(ACCESSIBILITY) && USE(ATSPI)
 #include "AccessibilityAtspi.h"
 #include "IntRect.h"
+#include <wtf/Atomics.h>
 #include <wtf/FastMalloc.h>
 #include <wtf/ThreadSafeRefCounted.h>
 #include <wtf/WeakPtr.h>
@@ -40,6 +41,8 @@
 
     void registerObject(CompletionHandler<void(const String&)>&&);
     void unregisterObject();
+    void registerTree();
+    bool isTreeRegistered() const { return m_isTreeRegistered.load(); }
     void setPath(String&&);
 
     const String& path() const { return m_path; }
@@ -66,6 +69,7 @@
     String m_path;
     String m_parentUniqueName;
     String m_parentPath;
+    Atomic<bool> m_isTreeRegistered { false };
 };
 
 } // namespace WebCore
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to