Changeset 287070 in webkit
- Timestamp:
- Dec 15, 2021, 5:48:20 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 10 edited
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/accessibility/atspi/AccessibilityAtspi.cpp (modified) (10 diffs)
-
Source/WebCore/accessibility/atspi/AccessibilityAtspi.h (modified) (5 diffs)
-
Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.cpp (modified) (3 diffs)
-
Source/WebCore/accessibility/atspi/AccessibilityObjectSelectionAtspi.cpp (modified) (1 diff)
-
Source/WebCore/accessibility/atspi/AccessibilityObjectTextAtspi.cpp (modified) (4 diffs)
-
Source/WebCore/accessibility/atspi/AccessibilityObjectValueAtspi.cpp (modified) (1 diff)
-
Source/WebCore/accessibility/atspi/AccessibilityRootAtspi.cpp (modified) (1 diff)
-
Tools/ChangeLog (modified) (1 diff)
-
Tools/TestWebKitAPI/Tests/WebKitGtk/TestWebKitAccessibility.cpp (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r287067 r287070 1 2021-12-15 Carlos Garcia Campos <cgarcia@igalia.com> 2 3 [GTK][a11y] Register the wrappers tree when there's an event listener registered 4 https://bugs.webkit.org/show_bug.cgi?id=234338 5 6 Reviewed by Joanmarie Diggs. 7 8 Connect to the atspi registry to get the list of registered event listeners. If there's any listener, we register 9 the tree to ensure we can emit signals, but we only emit the signals for which there's a listener registered, 10 except for the ones required by the atspi cache. 11 12 * accessibility/atspi/AccessibilityAtspi.cpp: 13 (WebCore::AccessibilityAtspi::AccessibilityAtspi): Connect to the registry. 14 (WebCore::AccessibilityAtspi::~AccessibilityAtspi): Disconnect registry signals. 15 (WebCore::AccessibilityAtspi::registerTrees const): Register the trees of all root objects. 16 (WebCore::AccessibilityAtspi::initializeRegistry): Get the list of listeners registered and connect to 17 EventListenerRegistered signal. 18 (WebCore::AccessibilityAtspi::addEventListener): Add an event listener to the list converting the detail to non 19 camel case to be abel to compare it later on signal emission. 20 (WebCore::eventIsSubtype): Helper to check if event type is subtype of another. 21 (WebCore::AccessibilityAtspi::removeEventListener): Remove and events listener from the list. 22 (WebCore::AccessibilityAtspi::shouldEmitSignal): Return whether the given signal should be emitted, checking the 23 registered event listeners. 24 (WebCore::AccessibilityAtspi::parentChanged): Do not emit the signal if the object hasn't been registered yet to 25 avoid flooding during tree creation. We just register the object the object in that case which will update the 26 cache because addAccessible is always called. 27 (WebCore::AccessibilityAtspi::stateChanged): Return early if signal should not be emitted. 28 (WebCore::AccessibilityAtspi::textChanged): Ditto. 29 (WebCore::AccessibilityAtspi::textAttributesChanged): Ditto. 30 (WebCore::AccessibilityAtspi::textCaretMoved): Ditto. 31 (WebCore::AccessibilityAtspi::textSelectionChanged): Ditto. 32 (WebCore::AccessibilityAtspi::valueChanged): Ditto. 33 (WebCore::AccessibilityAtspi::selectionChanged): Ditto. 34 * accessibility/atspi/AccessibilityAtspi.h: 35 (WebCore::AccessibilityAtspi::hasEventListeners const): 36 * accessibility/atspi/AccessibilityObjectAtspi.cpp: 37 (WebCore::AccessibilityObjectAtspi::childAdded): Return early if object is already detached or ignored. 38 (WebCore::AccessibilityObjectAtspi::childRemoved): Ditto. 39 (WebCore::AccessibilityObjectAtspi::stateChanged): Do not return early if the object is not registered because 40 we might end up emitting the signal. 41 * accessibility/atspi/AccessibilityObjectSelectionAtspi.cpp: 42 (WebCore::AccessibilityObjectAtspi::selectionChanged): Ditto. 43 * accessibility/atspi/AccessibilityObjectTextAtspi.cpp: 44 (WebCore::AccessibilityObjectAtspi::textInserted): Ditto. 45 (WebCore::AccessibilityObjectAtspi::textDeleted): Ditto. 46 (WebCore::AccessibilityObjectAtspi::selectionChanged): Ditto. 47 (WebCore::AccessibilityObjectAtspi::textAttributesChanged): Ditto. 48 * accessibility/atspi/AccessibilityObjectValueAtspi.cpp: 49 (WebCore::AccessibilityObjectAtspi::valueChanged): Ditto. 50 * accessibility/atspi/AccessibilityRootAtspi.cpp: 51 (WebCore::AccessibilityRootAtspi::embedded): Register the tree if there are event listeners registered. 52 1 53 2021-12-15 Youenn Fablet <youenn@apple.com> 2 54 -
trunk/Source/WebCore/accessibility/atspi/AccessibilityAtspi.cpp
r287020 r287070 30 30 #include <wtf/SortedArrayMap.h> 31 31 #include <wtf/UUID.h> 32 #include <wtf/glib/GUniquePtr.h>33 32 34 33 namespace WebCore { … … 45 44 static_cast<GDBusConnectionFlags>(G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION), 46 45 nullptr, nullptr, &error.outPtr())); 47 if (!m_connection) 46 47 if (m_connection) 48 initializeRegistry(); 49 else 48 50 g_warning("Can't connect to a11y bus: %s", error->message); 49 51 }); 52 } 53 54 AccessibilityAtspi::~AccessibilityAtspi() 55 { 56 if (m_registry) 57 g_signal_handlers_disconnect_by_data(m_registry.get(), this); 58 } 59 60 void AccessibilityAtspi::registerTrees() const 61 { 62 RELEASE_ASSERT(!isMainThread()); 63 for (auto* rootObject : m_rootObjects.keys()) { 64 if (!rootObject->isTreeRegistered()) 65 rootObject->registerTree(); 66 } 67 } 68 69 void AccessibilityAtspi::initializeRegistry() 70 { 71 RELEASE_ASSERT(!isMainThread()); 72 RELEASE_ASSERT(m_connection); 73 GUniqueOutPtr<GError> error; 74 m_registry = adoptGRef(g_dbus_proxy_new_sync(m_connection.get(), G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, nullptr, 75 "org.a11y.atspi.Registry", "/org/a11y/atspi/registry", "org.a11y.atspi.Registry", nullptr, &error.outPtr())); 76 if (!m_registry) { 77 g_warning("Failed to connect to atspi registry: %s\n", error->message); 78 return; 79 } 80 81 g_signal_connect(m_registry.get(), "g-signal", G_CALLBACK(+[](GDBusProxy*, char*, char* signal, GVariant* parameters, AccessibilityAtspi* atspi) { 82 const char* dbusName; 83 const char* eventName; 84 if (!g_strcmp0(signal, "EventListenerRegistered")) { 85 g_variant_get(parameters, "(&s&s@as)", &dbusName, &eventName, nullptr); 86 atspi->addEventListener(dbusName, eventName); 87 atspi->registerTrees(); 88 } else if (!g_strcmp0(signal, "EventListenerDeregistered")) { 89 g_variant_get(parameters, "(&s&s)", &dbusName, &eventName); 90 atspi->removeEventListener(dbusName, eventName); 91 } 92 }), this); 93 94 GRefPtr<GVariant> result = adoptGRef(g_dbus_proxy_call_sync(m_registry.get(), "GetRegisteredEvents", nullptr, G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &error.outPtr())); 95 if (!result) { 96 g_warning("Failed to get atspi registered event listeners: %s\n", error->message); 97 return; 98 } 99 100 GRefPtr<GVariant> events; 101 g_variant_get(result.get(), "(@a(ss))", &events.outPtr()); 102 GVariantIter iter; 103 auto eventCount = g_variant_iter_init(&iter, events.get()); 104 const char* dbusName; 105 const char* eventName; 106 while (g_variant_iter_loop(&iter, "(&s&s)", &dbusName, &eventName)) 107 addEventListener(dbusName, eventName); 108 109 if (eventCount) 110 registerTrees(); 111 } 112 113 static GUniquePtr<char*> eventConvertingDetailToNonCamelCase(const char* eventName) 114 { 115 GUniquePtr<char*> event(g_strsplit(eventName, ":", 3)); 116 if (!event.get()[0] || !event.get()[1] || !event.get()[2] || !*event.get()[2]) 117 return event; 118 119 char* converted = static_cast<char*>(g_malloc(strlen(event.get()[2]) * 2 + 1)); 120 char* convertedPtr = converted; 121 char* detailPtr = event.get()[2]; 122 123 while (*detailPtr) { 124 if (isASCIIUpper(*detailPtr)) { 125 if (convertedPtr > converted) 126 *convertedPtr++ = '-'; 127 *convertedPtr++ = toASCIILower(*detailPtr++); 128 } else 129 *convertedPtr++ = *detailPtr++; 130 } 131 *convertedPtr = '\0'; 132 133 g_free(event.get()[2]); 134 event.get()[2] = converted; 135 136 return event; 137 } 138 139 void AccessibilityAtspi::addEventListener(const char* dbusName, const char* eventName) 140 { 141 RELEASE_ASSERT(!isMainThread()); 142 auto& listeners = m_eventListeners.ensure(dbusName, [] { 143 return Vector<GUniquePtr<char*>> { }; 144 }).iterator->value; 145 listeners.append(eventConvertingDetailToNonCamelCase(eventName)); 146 } 147 148 static bool eventIsSubtype(char** needle, char** haystack) 149 { 150 while (*haystack && **haystack) { 151 if (g_strcmp0(*needle, *haystack)) 152 return false; 153 needle++; 154 haystack++; 155 } 156 157 return true; 158 } 159 160 void AccessibilityAtspi::removeEventListener(const char* dbusName, const char* eventName) 161 { 162 RELEASE_ASSERT(!isMainThread()); 163 if (!eventName || !*eventName) { 164 m_eventListeners.remove(dbusName); 165 return; 166 } 167 168 auto it = m_eventListeners.find(dbusName); 169 if (it == m_eventListeners.end()) 170 return; 171 172 auto needle = eventConvertingDetailToNonCamelCase(eventName); 173 it->value.removeAllMatching([&](const GUniquePtr<char*>& event) { 174 return eventIsSubtype(needle.get(), event.get()); 175 }); 176 177 if (it->value.isEmpty()) 178 m_eventListeners.remove(it); 179 } 180 181 bool AccessibilityAtspi::shouldEmitSignal(const char* interface, const char* name, const char* detail) 182 { 183 RELEASE_ASSERT(!isMainThread()); 184 185 // Always emit signals if we couldn't connect to the registry. 186 if (!m_registry) 187 return true; 188 189 if (m_eventListeners.isEmpty()) 190 return false; 191 192 const char* needle[4] = { interface, name, detail, nullptr }; 193 for (const auto& listeners : m_eventListeners.values()) { 194 auto result = listeners.findMatching([&](const GUniquePtr<char*>& event) { 195 return eventIsSubtype(const_cast<char**>(needle), event.get()); 196 }); 197 if (result != notFound) 198 return true; 199 } 200 201 return false; 50 202 } 51 203 … … 181 333 return; 182 334 183 // We call path here to ensure it happens before parentReference() in case objects are not registered yet. 184 auto path = atspiObject->path(); 185 g_dbus_connection_emit_signal(m_connection.get(), nullptr, path.utf8().data(), "org.a11y.atspi.Event.Object", "PropertyChange", 335 // Emit parentChanged only if the object is already registered, otherwise register the object, 336 // without emitting the signal, because org.a11y.atspi.Cache.AddAccessible() will update the cache. 337 if (atspiObject->registerObject()) 338 return; 339 340 g_dbus_connection_emit_signal(m_connection.get(), nullptr, atspiObject->path().utf8().data(), "org.a11y.atspi.Event.Object", "PropertyChange", 186 341 g_variant_new("(siiva{sv})", "accessible-parent", 0, 0, atspiObject->parentReference(), nullptr), nullptr); 187 342 }); … … 212 367 return; 213 368 369 if (!shouldEmitSignal("Object", "StateChanged", name.data())) 370 return; 371 214 372 g_dbus_connection_emit_signal(m_connection.get(), nullptr, atspiObject->path().utf8().data(), "org.a11y.atspi.Event.Object", "StateChanged", 215 373 g_variant_new("(siiva{sv})", name.data(), value, 0, g_variant_new_string("0"), nullptr), nullptr); … … 224 382 return; 225 383 384 if (!shouldEmitSignal("Object", "TextChanged", changeType.data())) 385 return; 386 226 387 g_dbus_connection_emit_signal(m_connection.get(), nullptr, atspiObject->path().utf8().data(), "org.a11y.atspi.Event.Object", "TextChanged", 227 388 g_variant_new("(siiva{sv})", changeType.data(), offset, length, g_variant_new_string(text.data()), nullptr), nullptr); … … 236 397 return; 237 398 399 if (!shouldEmitSignal("Object", "TextAttributesChanged")) 400 return; 401 238 402 g_dbus_connection_emit_signal(m_connection.get(), nullptr, atspiObject->path().utf8().data(), "org.a11y.atspi.Event.Object", "TextAttributesChanged", 239 403 g_variant_new("(siiva{sv})", "", 0, 0, g_variant_new_string(""), nullptr), nullptr); … … 248 412 return; 249 413 414 if (!shouldEmitSignal("Object", "TextCaretMoved")) 415 return; 416 250 417 g_dbus_connection_emit_signal(m_connection.get(), nullptr, atspiObject->path().utf8().data(), "org.a11y.atspi.Event.Object", "TextCaretMoved", 251 418 g_variant_new("(siiva{sv})", "", caretOffset, 0, g_variant_new_string(""), nullptr), nullptr); … … 260 427 return; 261 428 429 if (!shouldEmitSignal("Object", "TextSelectionChanged")) 430 return; 431 262 432 g_dbus_connection_emit_signal(m_connection.get(), nullptr, atspiObject->path().utf8().data(), "org.a11y.atspi.Event.Object", "TextSelectionChanged", 263 433 g_variant_new("(siiva{sv})", "", 0, 0, g_variant_new_string(""), nullptr), nullptr); … … 272 442 return; 273 443 444 if (!shouldEmitSignal("Object", "PropertyChange", "accessible-value")) 445 return; 446 274 447 g_dbus_connection_emit_signal(m_connection.get(), nullptr, atspiObject->path().utf8().data(), "org.a11y.atspi.Event.Object", "PropertyChange", 275 448 g_variant_new("(siiva{sv})", "accessible-value", 0, 0, g_variant_new_double(value), nullptr), nullptr); … … 282 455 m_queue->dispatch([this, atspiObject = Ref { atspiObject }] { 283 456 if (!m_connection) 457 return; 458 459 if (!shouldEmitSignal("Object", "SelectionChanged")) 284 460 return; 285 461 -
trunk/Source/WebCore/accessibility/atspi/AccessibilityAtspi.h
r287020 r287070 27 27 #include <wtf/WorkQueue.h> 28 28 #include <wtf/glib/GRefPtr.h> 29 #include <wtf/glib/GUniquePtr.h> 29 30 30 31 typedef struct _GDBusConnection GDBusConnection; 31 32 typedef struct _GDBusInterfaceInfo GDBusInterfaceInfo; 32 33 typedef struct _GDBusInterfaceVTable GDBusInterfaceVTable; 34 typedef struct _GDBusProxy GDBusProxy; 33 35 typedef struct _GVariant GVariant; 34 36 … … 42 44 public: 43 45 AccessibilityAtspi(const String&); 44 ~AccessibilityAtspi() = default;46 ~AccessibilityAtspi(); 45 47 46 48 WEBCORE_EXPORT RunLoop& runLoop() const; … … 48 50 const char* uniqueName() const; 49 51 GVariant* nullReference() const; 52 bool hasEventListeners() const { return !m_eventListeners.isEmpty(); } 50 53 51 54 void registerRoot(AccessibilityRootAtspi&, Vector<std::pair<GDBusInterfaceInfo*, GDBusInterfaceVTable*>>&&, CompletionHandler<void(const String&)>&&); … … 75 78 76 79 private: 80 void registerTrees() const; 81 void initializeRegistry(); 82 void addEventListener(const char* dbusName, const char* eventName); 83 void removeEventListener(const char* dbusName, const char* eventName); 84 77 85 void ensureCache(); 78 86 void removeAccessible(AccessibilityObjectAtspi&); 87 88 bool shouldEmitSignal(const char* interface, const char* name, const char* detail = ""); 79 89 80 90 static GDBusInterfaceVTable s_cacheFunctions; … … 82 92 Ref<WorkQueue> m_queue; 83 93 GRefPtr<GDBusConnection> m_connection; 94 GRefPtr<GDBusProxy> m_registry; 95 HashMap<CString, Vector<GUniquePtr<char*>>> m_eventListeners; 84 96 HashMap<AccessibilityRootAtspi*, Vector<unsigned, 2>> m_rootObjects; 85 97 HashMap<AccessibilityObjectAtspi*, Vector<unsigned, 20>> m_atspiObjects; -
trunk/Source/WebCore/accessibility/atspi/AccessibilityObjectAtspi.cpp
r287020 r287070 1214 1214 return; 1215 1215 1216 if (!m_coreObject || m_coreObject->accessibilityIsIgnored()) 1217 return; 1218 1216 1219 m_root.atspi().childrenChanged(*this, child, AccessibilityAtspi::ChildrenChanged::Added); 1217 1220 } … … 1223 1226 return; 1224 1227 1228 if (!m_coreObject || m_coreObject->accessibilityIsIgnored()) 1229 return; 1230 1225 1231 m_root.atspi().childrenChanged(*this, child, AccessibilityAtspi::ChildrenChanged::Removed); 1226 1232 } … … 1229 1235 { 1230 1236 RELEASE_ASSERT(isMainThread()); 1231 if (!m_isRegistered.load())1232 return;1233 1234 1237 m_root.atspi().stateChanged(*this, name, value); 1235 1238 } -
trunk/Source/WebCore/accessibility/atspi/AccessibilityObjectSelectionAtspi.cpp
r286767 r287070 225 225 { 226 226 RELEASE_ASSERT(isMainThread()); 227 if (!m_isRegistered.load())228 return;229 230 227 m_root.atspi().selectionChanged(*this); 231 228 } -
trunk/Source/WebCore/accessibility/atspi/AccessibilityObjectTextAtspi.cpp
r286767 r287070 349 349 { 350 350 RELEASE_ASSERT(isMainThread()); 351 if (!m_isRegistered.load())352 return;353 354 351 if (!m_interfaces.contains(Interface::Text)) 355 352 return; … … 368 365 { 369 366 RELEASE_ASSERT(isMainThread()); 370 if (!m_isRegistered.load())371 return;372 373 367 if (!m_interfaces.contains(Interface::Text)) 374 368 return; … … 752 746 { 753 747 RELEASE_ASSERT(isMainThread()); 754 if (!m_isRegistered.load())755 return;756 757 748 if (!m_interfaces.contains(Interface::Text)) 758 749 return; … … 944 935 { 945 936 RELEASE_ASSERT(isMainThread()); 946 if (!m_isRegistered.load())947 return;948 949 937 if (!m_interfaces.contains(Interface::Text)) 950 938 return; -
trunk/Source/WebCore/accessibility/atspi/AccessibilityObjectValueAtspi.cpp
r286767 r287070 135 135 { 136 136 RELEASE_ASSERT(isMainThread()); 137 if (!m_isRegistered.load())138 return;139 140 137 m_root.atspi().valueChanged(*this, value); 141 138 } -
trunk/Source/WebCore/accessibility/atspi/AccessibilityRootAtspi.cpp
r287020 r287070 224 224 m_parentUniqueName = parentUniqueName; 225 225 m_parentPath = parentPath; 226 if (!m_isTreeRegistered.load() && m_atspi.hasEventListeners()) 227 registerTree(); 226 228 } 227 229 -
trunk/Tools/ChangeLog
r287060 r287070 1 2021-12-15 Carlos Garcia Campos <cgarcia@igalia.com> 2 3 [GTK][a11y] Register the wrappers tree when there's an event listener registered 4 https://bugs.webkit.org/show_bug.cgi?id=234338 5 6 Reviewed by Joanmarie Diggs. 7 8 Add unit test to check the tree is created when there's a listener connected. 9 10 * TestWebKitAPI/Tests/WebKitGtk/TestWebKitAccessibility.cpp: 11 (AccessibilityTest::findTestApplication): Iterate the applications list backwards since the test program is 12 usually the last one in the list. 13 (AccessibilityTest::accessibleApplicationIsTestProgram): Helper to check if a given accessible belongs to the 14 test program. 15 (AccessibilityTest::startEventMonitor): Support for listening to events associated to the test program, not to a 16 particular accessible. 17 (testAccessibleEventListener): 18 (beforeAll): 19 1 20 2021-12-14 Don Olmstead <don.olmstead@sony.com> 2 21 -
trunk/Tools/TestWebKitAPI/Tests/WebKitGtk/TestWebKitAccessibility.cpp
r286416 r287070 58 58 int childCount = atspi_accessible_get_child_count(desktop.get(), nullptr); 59 59 Test::addLogFatalFlag(G_LOG_LEVEL_WARNING); 60 for (int i = 0; i < childCount; ++i){60 for (int i = childCount - 1; i >= 0; --i) { 61 61 GRefPtr<AtspiAccessible> current = adoptGRef(atspi_accessible_get_child_at_index(desktop.get(), i, nullptr)); 62 if (!g_strcmp0(atspi_accessible_get_name(current.get(), nullptr), "TestWebKitAccessibility")) 62 GUniquePtr<char> name(atspi_accessible_get_name(current.get(), nullptr)); 63 if (!g_strcmp0(name.get(), "TestWebKitAccessibility")) 63 64 return current; 64 65 } … … 107 108 } 108 109 110 static bool accessibleApplicationIsTestProgram(AtspiAccessible* accessible) 111 { 112 GRefPtr<AtspiAccessible> application = adoptGRef(atspi_accessible_get_application(accessible, nullptr)); 113 GUniquePtr<char> applicationName(atspi_accessible_get_name(application.get(), nullptr)); 114 return !g_strcmp0(applicationName.get(), "TestWebKitAccessibility"); 115 } 116 109 117 void startEventMonitor(AtspiAccessible* source, Vector<CString>&& events) 110 118 { … … 113 121 m_eventMonitor.listener = adoptGRef(atspi_event_listener_new([](AtspiEvent* event, gpointer userData) { 114 122 auto* test = static_cast<AccessibilityTest*>(userData); 115 if (event->source == test->m_eventMonitor.source) 123 if ((test->m_eventMonitor.source && event->source == test->m_eventMonitor.source) 124 || (!test->m_eventMonitor.source && accessibleApplicationIsTestProgram(event->source))) { 116 125 test->m_eventMonitor.events.append(static_cast<AtspiEvent*>(g_boxed_copy(ATSPI_TYPE_EVENT, event))); 126 } 117 127 }, this, nullptr)); 118 128 … … 810 820 g_assert_false(AccessibilityTest::isSelected(option2.get())); 811 821 #endif 822 } 823 824 static void testAccessibleEventListener(AccessibilityTest* test, gconstpointer) 825 { 826 test->startEventMonitor(nullptr, { "object:state-changed:focused" }); 827 test->showInWindow(); 828 test->loadHtml( 829 "<html>" 830 " <body>" 831 " <input id='entry' type='text'/>" 832 " </body>" 833 "</html>", 834 nullptr); 835 test->waitUntilLoadFinished(); 836 837 test->runJavaScriptAndWaitUntilFinished("document.getElementById('entry').focus();", nullptr); 838 839 auto events = test->stopEventMonitor(1); 840 g_assert_cmpuint(events.size(), ==, 1); 841 g_assert_cmpstr(events[0]->type, ==, "object:state-changed:focused"); 842 auto* entry = events[0]->source; 843 g_assert_true(ATSPI_IS_ACCESSIBLE(entry)); 844 g_assert_cmpint(atspi_accessible_get_role(entry, nullptr), ==, ATSPI_ROLE_ENTRY); 845 846 auto panel = adoptGRef(atspi_accessible_get_parent(entry, nullptr)); 847 g_assert_true(ATSPI_IS_ACCESSIBLE(panel.get())); 848 g_assert_cmpint(atspi_accessible_get_role(panel.get(), nullptr), ==, ATSPI_ROLE_PANEL); 849 850 auto documentWeb = adoptGRef(atspi_accessible_get_parent(panel.get(), nullptr)); 851 g_assert_true(ATSPI_IS_ACCESSIBLE(documentWeb.get())); 852 g_assert_cmpint(atspi_accessible_get_role(documentWeb.get(), nullptr), ==, ATSPI_ROLE_DOCUMENT_WEB); 853 854 auto scrollView = adoptGRef(atspi_accessible_get_parent(documentWeb.get(), nullptr)); 855 g_assert_true(ATSPI_IS_ACCESSIBLE(scrollView.get())); 856 g_assert_cmpint(atspi_accessible_get_role(scrollView.get(), nullptr), ==, ATSPI_ROLE_SCROLL_PANE); 857 858 auto rootObject = adoptGRef(atspi_accessible_get_parent(scrollView.get(), nullptr)); 859 g_assert_true(ATSPI_IS_ACCESSIBLE(rootObject.get())); 860 g_assert_cmpint(atspi_accessible_get_role(rootObject.get(), nullptr), ==, ATSPI_ROLE_FILLER); 812 861 } 813 862 … … 2753 2802 AccessibilityTest::add("WebKitAccessibility", "accessible/state", testAccessibleState); 2754 2803 AccessibilityTest::add("WebKitAccessibility", "accessible/state-changed", testAccessibleStateChanged); 2804 AccessibilityTest::add("WebKitAccessibility", "accessible/event-listener", testAccessibleEventListener); 2755 2805 AccessibilityTest::add("WebKitAccessibility", "component/hit-test", testComponentHitTest); 2756 2806 #ifdef ATSPI_SCROLLTYPE_COUNT
Note:
See TracChangeset
for help on using the changeset viewer.