You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1084 lines
44 KiB
1084 lines
44 KiB
diff -up chromium-129.0.6668.58/content/browser/accessibility/accessibility_auralinux_browsertest.cc.me chromium-129.0.6668.58/content/browser/accessibility/accessibility_auralinux_browsertest.cc
|
|
--- chromium-129.0.6668.58/content/browser/accessibility/accessibility_auralinux_browsertest.cc.me 2024-09-18 19:26:40.951100740 +0200
|
|
+++ chromium-129.0.6668.58/content/browser/accessibility/accessibility_auralinux_browsertest.cc 2024-09-18 19:28:06.219700474 +0200
|
|
@@ -3,6 +3,7 @@
|
|
// found in the LICENSE file.
|
|
|
|
#include <atk/atk.h>
|
|
+#include <dlfcn.h>
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
@@ -547,6 +548,10 @@ IN_PROC_BROWSER_TEST_F(AccessibilityAura
|
|
g_object_unref(div_element);
|
|
}
|
|
|
|
+#if defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 30, 0)
|
|
+#define ATK_230
|
|
+#endif
|
|
+
|
|
IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
|
|
TestCharacterExtentsWithInvalidArguments) {
|
|
AtkText* atk_text = SetUpSampleParagraph();
|
|
@@ -569,12 +574,14 @@ IN_PROC_BROWSER_TEST_F(AccessibilityAura
|
|
EXPECT_EQ(expect, width);
|
|
EXPECT_EQ(expect, height);
|
|
|
|
+#ifdef ATK_230
|
|
atk_text_get_character_extents(atk_text, invalid_offset, &x, &y, &width,
|
|
&height, ATK_XY_PARENT);
|
|
EXPECT_EQ(expect, x);
|
|
EXPECT_EQ(expect, y);
|
|
EXPECT_EQ(expect, width);
|
|
EXPECT_EQ(expect, height);
|
|
+#endif // ATK_230
|
|
|
|
atk_text_get_character_extents(atk_text, invalid_offset, &x, &y, &width,
|
|
&height, ATK_XY_WINDOW);
|
|
@@ -593,12 +600,14 @@ IN_PROC_BROWSER_TEST_F(AccessibilityAura
|
|
EXPECT_EQ(expect, width);
|
|
EXPECT_EQ(expect, height);
|
|
|
|
+#ifdef ATK_230
|
|
atk_text_get_character_extents(atk_text, invalid_offset, &x, &y, &width,
|
|
&height, ATK_XY_PARENT);
|
|
EXPECT_EQ(expect, x);
|
|
EXPECT_EQ(expect, y);
|
|
EXPECT_EQ(expect, width);
|
|
EXPECT_EQ(expect, height);
|
|
+#endif // ATK_230
|
|
|
|
atk_text_get_character_extents(atk_text, invalid_offset, &x, &y, &width,
|
|
&height, ATK_XY_WINDOW);
|
|
@@ -613,7 +622,9 @@ IN_PROC_BROWSER_TEST_F(AccessibilityAura
|
|
AtkCoordType kCoordinateTypes[] = {
|
|
ATK_XY_SCREEN,
|
|
ATK_XY_WINDOW,
|
|
+#ifdef ATK_230
|
|
ATK_XY_PARENT,
|
|
+#endif // ATK_230
|
|
};
|
|
|
|
IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
|
|
@@ -872,6 +883,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityAura
|
|
TestCharacterExtentsInScrollableInput();
|
|
}
|
|
|
|
+#if defined(ATK_230)
|
|
typedef bool (*ScrollToPointFunc)(AtkComponent* component,
|
|
AtkCoordType coords,
|
|
gint x,
|
|
@@ -881,6 +893,18 @@ typedef bool (*ScrollToFunc)(AtkComponen
|
|
// TODO(crbug.com/40866728): Enable this test.
|
|
IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
|
|
DISABLED_TestScrollToPoint) {
|
|
+ // There's a chance we may be compiled with a newer version of ATK and then
|
|
+ // run with an older one, so we need to do a runtime check for this method
|
|
+ // that is available in ATK 2.30 instead of linking directly.
|
|
+ ScrollToPointFunc scroll_to_point = reinterpret_cast<ScrollToPointFunc>(
|
|
+ dlsym(RTLD_DEFAULT, "atk_component_scroll_to_point"));
|
|
+ if (!scroll_to_point) {
|
|
+ LOG(WARNING)
|
|
+ << "Skipping AccessibilityAuraLinuxBrowserTest::TestScrollToPoint"
|
|
+ " because ATK version < 2.30 detected.";
|
|
+ return;
|
|
+ }
|
|
+
|
|
LoadSampleParagraphInScrollableDocument();
|
|
AtkText* atk_text = GetSampleParagraph();
|
|
ASSERT_TRUE(ATK_IS_COMPONENT(atk_text));
|
|
@@ -893,7 +917,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityAura
|
|
AccessibilityNotificationWaiter location_changed_waiter(
|
|
shell()->web_contents(), ui::kAXModeComplete,
|
|
ax::mojom::Event::kLocationChanged);
|
|
- atk_component_scroll_to_point(atk_component, ATK_XY_PARENT, 0, 0);
|
|
+ scroll_to_point(atk_component, ATK_XY_PARENT, 0, 0);
|
|
ASSERT_TRUE(location_changed_waiter.WaitForNotification());
|
|
|
|
atk_component_get_extents(atk_component, &x, &y, nullptr, nullptr,
|
|
@@ -902,20 +926,20 @@ IN_PROC_BROWSER_TEST_F(AccessibilityAura
|
|
EXPECT_GT(prev_y, y);
|
|
|
|
constexpr int kScrollToY = 0;
|
|
- atk_component_scroll_to_point(atk_component, ATK_XY_SCREEN, 0, kScrollToY);
|
|
+ scroll_to_point(atk_component, ATK_XY_SCREEN, 0, kScrollToY);
|
|
ASSERT_TRUE(location_changed_waiter.WaitForNotification());
|
|
atk_component_get_extents(atk_component, &x, &y, nullptr, nullptr,
|
|
ATK_XY_SCREEN);
|
|
EXPECT_EQ(kScrollToY, y);
|
|
|
|
constexpr int kScrollToY_2 = 243;
|
|
- atk_component_scroll_to_point(atk_component, ATK_XY_SCREEN, 0, kScrollToY_2);
|
|
+ scroll_to_point(atk_component, ATK_XY_SCREEN, 0, kScrollToY_2);
|
|
ASSERT_TRUE(location_changed_waiter.WaitForNotification());
|
|
atk_component_get_extents(atk_component, nullptr, &y, nullptr, nullptr,
|
|
ATK_XY_SCREEN);
|
|
EXPECT_EQ(kScrollToY_2, y);
|
|
|
|
- atk_component_scroll_to_point(atk_component, ATK_XY_SCREEN, 0, 129);
|
|
+ scroll_to_point(atk_component, ATK_XY_SCREEN, 0, 129);
|
|
ASSERT_TRUE(location_changed_waiter.WaitForNotification());
|
|
atk_component_get_extents(atk_component, nullptr, &y, nullptr, nullptr,
|
|
ATK_XY_SCREEN);
|
|
@@ -932,6 +956,17 @@ IN_PROC_BROWSER_TEST_F(AccessibilityAura
|
|
// TODO(crbug.com/40866728): Enable this test.
|
|
IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
|
|
DISABLED_TestScrollTo) {
|
|
+ // There's a chance we may be compiled with a newer version of ATK and then
|
|
+ // run with an older one, so we need to do a runtime check for this method
|
|
+ // that is available in ATK 2.30 instead of linking directly.
|
|
+ ScrollToFunc scroll_to = reinterpret_cast<ScrollToFunc>(
|
|
+ dlsym(RTLD_DEFAULT, "atk_component_scroll_to"));
|
|
+ if (!scroll_to) {
|
|
+ LOG(WARNING) << "Skipping AccessibilityAuraLinuxBrowserTest::TestScrollTo"
|
|
+ " because ATK version < 2.30 detected.";
|
|
+ return;
|
|
+ }
|
|
+
|
|
LoadInitialAccessibilityTreeFromHtml(
|
|
R"HTML(<!DOCTYPE html>
|
|
<html>
|
|
@@ -973,8 +1008,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityAura
|
|
AccessibilityNotificationWaiter waiter(
|
|
shell()->web_contents(), ui::kAXModeComplete,
|
|
ax::mojom::Event::kScrollPositionChanged);
|
|
- ASSERT_TRUE(
|
|
- atk_component_scroll_to(ATK_COMPONENT(target), ATK_SCROLL_TOP_EDGE));
|
|
+ ASSERT_TRUE(scroll_to(ATK_COMPONENT(target), ATK_SCROLL_TOP_EDGE));
|
|
ASSERT_TRUE(waiter.WaitForNotification());
|
|
int x, y;
|
|
atk_component_get_extents(ATK_COMPONENT(target), &x, &y, nullptr, nullptr,
|
|
@@ -982,40 +1016,35 @@ IN_PROC_BROWSER_TEST_F(AccessibilityAura
|
|
EXPECT_EQ(y, doc_y);
|
|
EXPECT_NE(x, doc_x);
|
|
|
|
- ASSERT_TRUE(
|
|
- atk_component_scroll_to(ATK_COMPONENT(target), ATK_SCROLL_TOP_LEFT));
|
|
+ ASSERT_TRUE(scroll_to(ATK_COMPONENT(target), ATK_SCROLL_TOP_LEFT));
|
|
ASSERT_TRUE(waiter.WaitForNotification());
|
|
atk_component_get_extents(ATK_COMPONENT(target), &x, &y, nullptr, nullptr,
|
|
ATK_XY_SCREEN);
|
|
EXPECT_EQ(y, doc_y);
|
|
EXPECT_EQ(x, doc_x);
|
|
|
|
- ASSERT_TRUE(
|
|
- atk_component_scroll_to(ATK_COMPONENT(target), ATK_SCROLL_BOTTOM_EDGE));
|
|
+ ASSERT_TRUE(scroll_to(ATK_COMPONENT(target), ATK_SCROLL_BOTTOM_EDGE));
|
|
ASSERT_TRUE(waiter.WaitForNotification());
|
|
atk_component_get_extents(ATK_COMPONENT(target), &x, &y, nullptr, nullptr,
|
|
ATK_XY_SCREEN);
|
|
EXPECT_NE(y, doc_y);
|
|
EXPECT_EQ(x, doc_x);
|
|
|
|
- ASSERT_TRUE(
|
|
- atk_component_scroll_to(ATK_COMPONENT(target), ATK_SCROLL_RIGHT_EDGE));
|
|
+ ASSERT_TRUE(scroll_to(ATK_COMPONENT(target), ATK_SCROLL_RIGHT_EDGE));
|
|
ASSERT_TRUE(waiter.WaitForNotification());
|
|
atk_component_get_extents(ATK_COMPONENT(target), &x, &y, nullptr, nullptr,
|
|
ATK_XY_SCREEN);
|
|
EXPECT_NE(y, doc_y);
|
|
EXPECT_NE(x, doc_x);
|
|
|
|
- ASSERT_TRUE(
|
|
- atk_component_scroll_to(ATK_COMPONENT(target2), ATK_SCROLL_LEFT_EDGE));
|
|
+ ASSERT_TRUE(scroll_to(ATK_COMPONENT(target2), ATK_SCROLL_LEFT_EDGE));
|
|
ASSERT_TRUE(waiter.WaitForNotification());
|
|
atk_component_get_extents(ATK_COMPONENT(target2), &x, &y, nullptr, nullptr,
|
|
ATK_XY_SCREEN);
|
|
EXPECT_NE(y, doc_y);
|
|
EXPECT_EQ(x, doc_x);
|
|
|
|
- ASSERT_TRUE(
|
|
- atk_component_scroll_to(ATK_COMPONENT(target2), ATK_SCROLL_TOP_LEFT));
|
|
+ ASSERT_TRUE(scroll_to(ATK_COMPONENT(target2), ATK_SCROLL_TOP_LEFT));
|
|
ASSERT_TRUE(waiter.WaitForNotification());
|
|
atk_component_get_extents(ATK_COMPONENT(target2), &x, &y, nullptr, nullptr,
|
|
ATK_XY_SCREEN);
|
|
@@ -1047,10 +1076,39 @@ IN_PROC_BROWSER_TEST_F(AccessibilityAura
|
|
g_object_unref(target2);
|
|
g_object_unref(target3);
|
|
}
|
|
+#endif // defined(ATK_230)
|
|
+
|
|
+#if defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 32, 0)
|
|
+typedef gboolean (*ScrollSubstringToFunc)(AtkText* text,
|
|
+ gint start_offset,
|
|
+ gint end_offset,
|
|
+ AtkScrollType type);
|
|
+ScrollSubstringToFunc g_scroll_substring_to = nullptr;
|
|
+
|
|
+NO_SANITIZE("cfi-icall")
|
|
+gboolean ScrollSubstringTo(AtkText* text,
|
|
+ gint start_offset,
|
|
+ gint end_offset,
|
|
+ AtkScrollType type) {
|
|
+ EXPECT_NE(g_scroll_substring_to, nullptr);
|
|
+ return g_scroll_substring_to(text, start_offset, end_offset, type);
|
|
+}
|
|
|
|
// TODO(crbug.com/40866728): Enable this test.
|
|
IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
|
|
DISABLED_TestScrollSubstringTo) {
|
|
+ // There's a chance we may be compiled with a newer version of ATK and then
|
|
+ // run with an older one, so we need to do a runtime check for this method
|
|
+ // that is available in ATK 2.32 instead of linking directly.
|
|
+ g_scroll_substring_to = reinterpret_cast<ScrollSubstringToFunc>(
|
|
+ dlsym(RTLD_DEFAULT, "atk_text_scroll_substring_to"));
|
|
+ if (!g_scroll_substring_to) {
|
|
+ LOG(WARNING) << "Skipping "
|
|
+ "AccessibilityAuraLinuxBrowserTest::TestSubstringScrollTo"
|
|
+ " because ATK version < 2.32 detected.";
|
|
+ return;
|
|
+ }
|
|
+
|
|
LoadInitialAccessibilityTreeFromHtml(
|
|
R"HTML(<!DOCTYPE html>
|
|
<html>
|
|
@@ -1084,8 +1142,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityAura
|
|
AccessibilityNotificationWaiter waiter(
|
|
shell()->web_contents(), ui::kAXModeComplete,
|
|
ax::mojom::Event::kScrollPositionChanged);
|
|
- ASSERT_TRUE(atk_text_scroll_substring_to(ATK_TEXT(target1), 1, 2,
|
|
- ATK_SCROLL_TOP_EDGE));
|
|
+ ASSERT_TRUE(ScrollSubstringTo(ATK_TEXT(target1), 1, 2, ATK_SCROLL_TOP_EDGE));
|
|
ASSERT_TRUE(waiter.WaitForNotification());
|
|
int x, y;
|
|
atk_text_get_character_extents(ATK_TEXT(target1), 1, &x, &y, nullptr, nullptr,
|
|
@@ -1093,40 +1150,37 @@ IN_PROC_BROWSER_TEST_F(AccessibilityAura
|
|
EXPECT_EQ(y, doc_y);
|
|
EXPECT_NE(x, doc_x);
|
|
|
|
- ASSERT_TRUE(atk_text_scroll_substring_to(ATK_TEXT(target1), 1, 2,
|
|
- ATK_SCROLL_TOP_LEFT));
|
|
+ ASSERT_TRUE(ScrollSubstringTo(ATK_TEXT(target1), 1, 2, ATK_SCROLL_TOP_LEFT));
|
|
ASSERT_TRUE(waiter.WaitForNotification());
|
|
atk_text_get_character_extents(ATK_TEXT(target1), 1, &x, &y, nullptr, nullptr,
|
|
ATK_XY_SCREEN);
|
|
EXPECT_EQ(y, doc_y);
|
|
EXPECT_EQ(x, doc_x);
|
|
|
|
- ASSERT_TRUE(atk_text_scroll_substring_to(ATK_TEXT(target1), 1, 2,
|
|
- ATK_SCROLL_BOTTOM_EDGE));
|
|
+ ASSERT_TRUE(
|
|
+ ScrollSubstringTo(ATK_TEXT(target1), 1, 2, ATK_SCROLL_BOTTOM_EDGE));
|
|
ASSERT_TRUE(waiter.WaitForNotification());
|
|
atk_text_get_character_extents(ATK_TEXT(target1), 1, &x, &y, nullptr, nullptr,
|
|
ATK_XY_SCREEN);
|
|
EXPECT_NE(y, doc_y);
|
|
EXPECT_EQ(x, doc_x);
|
|
|
|
- ASSERT_TRUE(atk_text_scroll_substring_to(ATK_TEXT(target1), 1, 2,
|
|
- ATK_SCROLL_RIGHT_EDGE));
|
|
+ ASSERT_TRUE(
|
|
+ ScrollSubstringTo(ATK_TEXT(target1), 1, 2, ATK_SCROLL_RIGHT_EDGE));
|
|
ASSERT_TRUE(waiter.WaitForNotification());
|
|
atk_text_get_character_extents(ATK_TEXT(target1), 1, &x, &y, nullptr, nullptr,
|
|
ATK_XY_SCREEN);
|
|
EXPECT_NE(y, doc_y);
|
|
EXPECT_NE(x, doc_x);
|
|
|
|
- ASSERT_TRUE(atk_text_scroll_substring_to(ATK_TEXT(target1), 1, 2,
|
|
- ATK_SCROLL_LEFT_EDGE));
|
|
+ ASSERT_TRUE(ScrollSubstringTo(ATK_TEXT(target1), 1, 2, ATK_SCROLL_LEFT_EDGE));
|
|
ASSERT_TRUE(waiter.WaitForNotification());
|
|
atk_text_get_character_extents(ATK_TEXT(target1), 1, &x, &y, nullptr, nullptr,
|
|
ATK_XY_SCREEN);
|
|
EXPECT_NE(y, doc_y);
|
|
EXPECT_EQ(x, doc_x);
|
|
|
|
- ASSERT_TRUE(atk_text_scroll_substring_to(ATK_TEXT(target1), 1, 2,
|
|
- ATK_SCROLL_TOP_LEFT));
|
|
+ ASSERT_TRUE(ScrollSubstringTo(ATK_TEXT(target1), 1, 2, ATK_SCROLL_TOP_LEFT));
|
|
ASSERT_TRUE(waiter.WaitForNotification());
|
|
atk_text_get_character_extents(ATK_TEXT(target1), 1, &x, &y, nullptr, nullptr,
|
|
ATK_XY_SCREEN);
|
|
@@ -1136,9 +1190,42 @@ IN_PROC_BROWSER_TEST_F(AccessibilityAura
|
|
g_object_unref(target1);
|
|
}
|
|
|
|
+typedef gboolean (*ScrollSubstringToPointFunc)(AtkText* text,
|
|
+ gint start_offset,
|
|
+ gint end_offset,
|
|
+ AtkCoordType coord_type,
|
|
+ gint x,
|
|
+ gint y);
|
|
+ScrollSubstringToPointFunc g_scroll_substring_to_point = nullptr;
|
|
+
|
|
+NO_SANITIZE("cfi-icall")
|
|
+gboolean ScrollSubstringToPoint(AtkText* text,
|
|
+ gint start_offset,
|
|
+ gint end_offset,
|
|
+ AtkCoordType coord_type,
|
|
+ gint x,
|
|
+ gint y) {
|
|
+ EXPECT_NE(g_scroll_substring_to_point, nullptr);
|
|
+ return g_scroll_substring_to_point(text, start_offset, end_offset, coord_type,
|
|
+ x, y);
|
|
+}
|
|
+
|
|
// TODO(crbug.com/40866728): Enable this test.
|
|
IN_PROC_BROWSER_TEST_F(AccessibilityAuraLinuxBrowserTest,
|
|
DISABLED_TestScrollSubstringToPoint) {
|
|
+ // There's a chance we may be compiled with a newer version of ATK and then
|
|
+ // run with an older one, so we need to do a runtime check for this method
|
|
+ // that is available in ATK 2.30 instead of linking directly.
|
|
+ g_scroll_substring_to_point = reinterpret_cast<ScrollSubstringToPointFunc>(
|
|
+ dlsym(RTLD_DEFAULT, "atk_text_scroll_substring_to_point"));
|
|
+ if (!g_scroll_substring_to_point) {
|
|
+ LOG(WARNING)
|
|
+ << "Skipping "
|
|
+ "AccessibilityAuraLinuxBrowserTest::TestScrollSubstringToPoint"
|
|
+ " because ATK version < 2.30 detected.";
|
|
+ return;
|
|
+ }
|
|
+
|
|
LoadSampleParagraphInScrollableDocument();
|
|
AtkText* atk_text = GetSampleParagraph();
|
|
ASSERT_TRUE(ATK_IS_COMPONENT(atk_text));
|
|
@@ -1151,7 +1238,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityAura
|
|
AccessibilityNotificationWaiter location_changed_waiter(
|
|
shell()->web_contents(), ui::kAXModeComplete,
|
|
ax::mojom::Event::kLocationChanged);
|
|
- atk_text_scroll_substring_to_point(atk_text, 1, 2, ATK_XY_PARENT, 0, 0);
|
|
+ ScrollSubstringToPoint(atk_text, 1, 2, ATK_XY_PARENT, 0, 0);
|
|
ASSERT_TRUE(location_changed_waiter.WaitForNotification());
|
|
|
|
atk_text_get_character_extents(atk_text, 1, &x, &y, nullptr, nullptr,
|
|
@@ -1160,22 +1247,20 @@ IN_PROC_BROWSER_TEST_F(AccessibilityAura
|
|
EXPECT_GT(prev_y, y);
|
|
|
|
constexpr int kScrollToY = 0;
|
|
- atk_text_scroll_substring_to_point(atk_text, 1, 2, ATK_XY_SCREEN, 0,
|
|
- kScrollToY);
|
|
+ ScrollSubstringToPoint(atk_text, 1, 2, ATK_XY_SCREEN, 0, kScrollToY);
|
|
ASSERT_TRUE(location_changed_waiter.WaitForNotification());
|
|
atk_text_get_character_extents(atk_text, 1, &x, &y, nullptr, nullptr,
|
|
ATK_XY_SCREEN);
|
|
EXPECT_EQ(kScrollToY, y);
|
|
|
|
constexpr int kScrollToY_2 = 243;
|
|
- atk_text_scroll_substring_to_point(atk_text, 1, 2, ATK_XY_SCREEN, 0,
|
|
- kScrollToY_2);
|
|
+ ScrollSubstringToPoint(atk_text, 1, 2, ATK_XY_SCREEN, 0, kScrollToY_2);
|
|
ASSERT_TRUE(location_changed_waiter.WaitForNotification());
|
|
atk_text_get_character_extents(atk_text, 1, &x, &y, nullptr, nullptr,
|
|
ATK_XY_SCREEN);
|
|
EXPECT_EQ(kScrollToY_2, y);
|
|
|
|
- atk_text_scroll_substring_to_point(atk_text, 1, 2, ATK_XY_SCREEN, 0, 129);
|
|
+ ScrollSubstringToPoint(atk_text, 1, 2, ATK_XY_SCREEN, 0, 129);
|
|
ASSERT_TRUE(location_changed_waiter.WaitForNotification());
|
|
atk_text_get_character_extents(atk_text, 1, &x, &y, nullptr, nullptr,
|
|
ATK_XY_SCREEN);
|
|
@@ -1191,6 +1276,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityAura
|
|
|
|
g_object_unref(atk_text);
|
|
}
|
|
+#endif // defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 32, 0)
|
|
|
|
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
|
|
// Flaky on crbug.com/1026149
|
|
diff -up chromium-129.0.6668.58/ui/accessibility/platform/ax_platform_node_auralinux.cc.me chromium-129.0.6668.58/ui/accessibility/platform/ax_platform_node_auralinux.cc
|
|
--- chromium-129.0.6668.58/ui/accessibility/platform/ax_platform_node_auralinux.cc.me 2024-09-18 19:26:26.040821017 +0200
|
|
+++ chromium-129.0.6668.58/ui/accessibility/platform/ax_platform_node_auralinux.cc 2024-09-18 19:28:06.220700493 +0200
|
|
@@ -2,7 +2,6 @@
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
-#include "base/version.h"
|
|
#ifdef UNSAFE_BUFFERS_BUILD
|
|
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
|
|
#pragma allow_unsafe_buffers
|
|
@@ -10,6 +9,7 @@
|
|
|
|
#include "ui/accessibility/platform/ax_platform_node_auralinux.h"
|
|
|
|
+#include <dlfcn.h>
|
|
#include <stdint.h>
|
|
|
|
#include <algorithm>
|
|
@@ -47,14 +47,33 @@
|
|
#include "ui/accessibility/platform/child_iterator.h"
|
|
#include "ui/gfx/geometry/rect_conversions.h"
|
|
|
|
-// Function availability can be tested by checking whether its address is not
|
|
-// nullptr.
|
|
-#define WEAK_ATK_FN(x) extern "C" __attribute__((weak)) decltype(x) x
|
|
-
|
|
-// TODO(https://crbug.com/40549424): This may be removed when support for
|
|
-// Ubuntu 18.04 is dropped.
|
|
-WEAK_ATK_FN(atk_component_scroll_to_point);
|
|
-WEAK_ATK_FN(atk_text_scroll_substring_to_point);
|
|
+#if defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 10, 0)
|
|
+#define ATK_210
|
|
+#endif
|
|
+
|
|
+#if defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 12, 0)
|
|
+#define ATK_212
|
|
+#endif
|
|
+
|
|
+#if defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 16, 0)
|
|
+#define ATK_216
|
|
+#endif
|
|
+
|
|
+#if defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 26, 0)
|
|
+#define ATK_226
|
|
+#endif
|
|
+
|
|
+#if defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 30, 0)
|
|
+#define ATK_230
|
|
+#endif
|
|
+
|
|
+#if defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 32, 0)
|
|
+#define ATK_232
|
|
+#endif
|
|
+
|
|
+#if defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 34, 0)
|
|
+#define ATK_234
|
|
+#endif
|
|
|
|
namespace ui {
|
|
|
|
@@ -146,11 +165,29 @@ AtkObject* g_active_top_level_frame = nu
|
|
|
|
AtkObject* g_active_views_dialog = nullptr;
|
|
|
|
+#if defined(ATK_216)
|
|
constexpr AtkRole kStaticRole = ATK_ROLE_STATIC;
|
|
constexpr AtkRole kSubscriptRole = ATK_ROLE_SUBSCRIPT;
|
|
constexpr AtkRole kSuperscriptRole = ATK_ROLE_SUPERSCRIPT;
|
|
+#else
|
|
+constexpr AtkRole kStaticRole = ATK_ROLE_TEXT;
|
|
+constexpr AtkRole kSubscriptRole = ATK_ROLE_TEXT;
|
|
+constexpr AtkRole kSuperscriptRole = ATK_ROLE_TEXT;
|
|
+#endif
|
|
|
|
+#if defined(ATK_226)
|
|
constexpr AtkRole kAtkFootnoteRole = ATK_ROLE_FOOTNOTE;
|
|
+#else
|
|
+constexpr AtkRole kAtkFootnoteRole = ATK_ROLE_LIST_ITEM;
|
|
+#endif
|
|
+
|
|
+#if defined(ATK_234)
|
|
+constexpr AtkRole kAtkRoleContentDeletion = ATK_ROLE_CONTENT_DELETION;
|
|
+constexpr AtkRole kAtkRoleContentInsertion = ATK_ROLE_CONTENT_INSERTION;
|
|
+#else
|
|
+constexpr AtkRole kAtkRoleContentDeletion = ATK_ROLE_SECTION;
|
|
+constexpr AtkRole kAtkRoleContentInsertion = ATK_ROLE_SECTION;
|
|
+#endif
|
|
|
|
using GetTypeFunc = GType (*)();
|
|
using GetColumnHeaderCellsFunc = GPtrArray* (*)(AtkTableCell* cell);
|
|
@@ -161,6 +198,11 @@ using GetRowColumnSpanFunc = bool (*)(At
|
|
gint* row_span,
|
|
gint* col_span);
|
|
|
|
+static GetTypeFunc g_atk_table_cell_get_type;
|
|
+static GetColumnHeaderCellsFunc g_atk_table_cell_get_column_header_cells;
|
|
+static GetRowHeaderCellsFunc g_atk_table_cell_get_row_header_cells;
|
|
+static GetRowColumnSpanFunc g_atk_table_cell_get_row_column_span;
|
|
+
|
|
// The ATK API often requires pointers to be used as out arguments, while
|
|
// allowing for those pointers to be null if the caller is not interested in
|
|
// the value. This function is a simpler helper to avoid continually checking
|
|
@@ -170,35 +212,17 @@ void SetIntPointerValueIfNotNull(int* po
|
|
*pointer = value;
|
|
}
|
|
|
|
-// TODO(https://crbug.com/40549424): This may be removed when support for
|
|
-// Ubuntu 18.04 is dropped.
|
|
+#if defined(ATK_230)
|
|
bool SupportsAtkComponentScrollingInterface() {
|
|
- return atk_component_scroll_to_point;
|
|
+ return dlsym(RTLD_DEFAULT, "atk_component_scroll_to_point");
|
|
}
|
|
+#endif
|
|
|
|
-// TODO(https://crbug.com/40549424): This may be removed when support for
|
|
-// Ubuntu 18.04 is dropped.
|
|
+#if defined(ATK_232)
|
|
bool SupportsAtkTextScrollingInterface() {
|
|
- return atk_text_scroll_substring_to_point;
|
|
-}
|
|
-
|
|
-// TODO(https://crbug.com/40549424): This may be removed when support for
|
|
-// Ubuntu 18.04 is dropped.
|
|
-AtkRole GetAtkRoleContentDeletion() {
|
|
- base::Version atk_version(atk_get_version());
|
|
- return atk_version.CompareTo(base::Version("2.34.0")) >= 0
|
|
- ? ATK_ROLE_CONTENT_DELETION
|
|
- : ATK_ROLE_SECTION;
|
|
-}
|
|
-
|
|
-// TODO(https://crbug.com/40549424): This may be removed when support for
|
|
-// Ubuntu 18.04 is dropped.
|
|
-AtkRole GetAtkRoleContentInsertion() {
|
|
- base::Version atk_version(atk_get_version());
|
|
- return atk_version.CompareTo(base::Version("2.34.0")) >= 0
|
|
- ? ATK_ROLE_CONTENT_INSERTION
|
|
- : ATK_ROLE_SECTION;
|
|
+ return dlsym(RTLD_DEFAULT, "atk_text_scroll_substring_to_point");
|
|
}
|
|
+#endif
|
|
|
|
AtkObject* FindAtkObjectParentFrame(AtkObject* atk_object) {
|
|
AXPlatformNodeAuraLinux* node =
|
|
@@ -297,10 +321,12 @@ AXCoordinateSystem AtkCoordTypeToAXCoord
|
|
return AXCoordinateSystem::kScreenDIPs;
|
|
case ATK_XY_WINDOW:
|
|
return AXCoordinateSystem::kRootFrame;
|
|
+#if defined(ATK_230)
|
|
case ATK_XY_PARENT:
|
|
// AXCoordinateSystem does not support parent coordinates.
|
|
NOTIMPLEMENTED();
|
|
return AXCoordinateSystem::kFrame;
|
|
+#endif
|
|
default:
|
|
return AXCoordinateSystem::kScreenDIPs;
|
|
}
|
|
@@ -513,6 +539,7 @@ gboolean GrabFocus(AtkComponent* atk_com
|
|
return obj->GrabFocus();
|
|
}
|
|
|
|
+#if defined(ATK_230)
|
|
gboolean ScrollTo(AtkComponent* atk_component, AtkScrollType scroll_type) {
|
|
g_return_val_if_fail(ATK_IS_COMPONENT(atk_component), FALSE);
|
|
|
|
@@ -539,6 +566,7 @@ gboolean ScrollToPoint(AtkComponent* atk
|
|
obj->ScrollToPoint(atk_coord_type, x, y);
|
|
return TRUE;
|
|
}
|
|
+#endif
|
|
|
|
void Init(AtkComponentIface* iface) {
|
|
iface->get_extents = GetExtents;
|
|
@@ -546,10 +574,12 @@ void Init(AtkComponentIface* iface) {
|
|
iface->get_size = GetSize;
|
|
iface->ref_accessible_at_point = RefAccesibleAtPoint;
|
|
iface->grab_focus = GrabFocus;
|
|
+#if defined(ATK_230)
|
|
if (SupportsAtkComponentScrollingInterface()) {
|
|
iface->scroll_to = ScrollTo;
|
|
iface->scroll_to_point = ScrollToPoint;
|
|
}
|
|
+#endif
|
|
}
|
|
|
|
const GInterfaceInfo Info = {reinterpret_cast<GInterfaceInitFunc>(Init),
|
|
@@ -1232,6 +1262,7 @@ gboolean AddSelection(AtkText* atk_text,
|
|
return SetSelection(atk_text, 0, start_offset, end_offset);
|
|
}
|
|
|
|
+#if defined(ATK_210)
|
|
char* GetStringAtOffset(AtkText* atk_text,
|
|
int offset,
|
|
AtkTextGranularity atk_granularity,
|
|
@@ -1246,7 +1277,9 @@ char* GetStringAtOffset(AtkText* atk_tex
|
|
return GetTextWithBoundaryType(atk_text, offset, boundary, start_offset,
|
|
end_offset);
|
|
}
|
|
+#endif
|
|
|
|
+#if defined(ATK_230)
|
|
gfx::Rect GetUnclippedParentHypertextRangeBoundsRect(
|
|
AXPlatformNodeDelegate* ax_platform_node_delegate,
|
|
const int start_offset,
|
|
@@ -1270,6 +1303,7 @@ gfx::Rect GetUnclippedParentHypertextRan
|
|
AXClippingBehavior::kClipped)
|
|
.OffsetFromOrigin();
|
|
}
|
|
+#endif
|
|
|
|
void GetCharacterExtents(AtkText* atk_text,
|
|
int offset,
|
|
@@ -1285,10 +1319,12 @@ void GetCharacterExtents(AtkText* atk_te
|
|
AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(atk_text));
|
|
if (obj) {
|
|
switch (coordinate_type) {
|
|
+#if defined(ATK_230)
|
|
case ATK_XY_PARENT:
|
|
rect = GetUnclippedParentHypertextRangeBoundsRect(obj->GetDelegate(),
|
|
offset, offset + 1);
|
|
break;
|
|
+#endif
|
|
default:
|
|
rect = obj->GetDelegate()->GetHypertextRangeBoundsRect(
|
|
obj->UnicodeToUTF16OffsetInText(offset),
|
|
@@ -1324,10 +1360,12 @@ void GetRangeExtents(AtkText* atk_text,
|
|
AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(atk_text));
|
|
if (obj) {
|
|
switch (coordinate_type) {
|
|
+#if defined(ATK_230)
|
|
case ATK_XY_PARENT:
|
|
rect = GetUnclippedParentHypertextRangeBoundsRect(
|
|
obj->GetDelegate(), start_offset, end_offset);
|
|
break;
|
|
+#endif
|
|
default:
|
|
rect = obj->GetDelegate()->GetHypertextRangeBoundsRect(
|
|
obj->UnicodeToUTF16OffsetInText(start_offset),
|
|
@@ -1377,6 +1415,7 @@ AtkAttributeSet* GetDefaultAttributes(At
|
|
return ToAtkAttributeSet(obj->GetDefaultTextAttributes());
|
|
}
|
|
|
|
+#if defined(ATK_232)
|
|
gboolean ScrollSubstringTo(AtkText* atk_text,
|
|
gint start_offset,
|
|
gint end_offset,
|
|
@@ -1407,6 +1446,7 @@ gboolean ScrollSubstringToPoint(AtkText*
|
|
return obj->ScrollSubstringToPoint(start_offset, end_offset, atk_coord_type,
|
|
x, y);
|
|
}
|
|
+#endif // ATK_232
|
|
|
|
void Init(AtkTextIface* iface) {
|
|
iface->get_text = GetText;
|
|
@@ -1429,12 +1469,16 @@ void Init(AtkTextIface* iface) {
|
|
iface->get_run_attributes = GetRunAttributes;
|
|
iface->get_default_attributes = GetDefaultAttributes;
|
|
|
|
+#if defined(ATK_210)
|
|
iface->get_string_at_offset = GetStringAtOffset;
|
|
+#endif
|
|
|
|
+#if defined(ATK_232)
|
|
if (SupportsAtkTextScrollingInterface()) {
|
|
iface->scroll_substring_to = ScrollSubstringTo;
|
|
iface->scroll_substring_to_point = ScrollSubstringToPoint;
|
|
}
|
|
+#endif
|
|
}
|
|
|
|
const GInterfaceInfo Info = {reinterpret_cast<GInterfaceInitFunc>(Init),
|
|
@@ -1837,11 +1881,15 @@ const GInterfaceInfo Info = {reinterpret
|
|
|
|
} // namespace atk_table
|
|
|
|
+// The ATK table cell interface was added in ATK 2.12.
|
|
+#if defined(ATK_212)
|
|
+
|
|
namespace atk_table_cell {
|
|
|
|
gint GetColumnSpan(AtkTableCell* cell) {
|
|
+ DCHECK(g_atk_table_cell_get_type);
|
|
g_return_val_if_fail(
|
|
- G_TYPE_CHECK_INSTANCE_TYPE((cell), atk_table_cell_get_type()), 0);
|
|
+ G_TYPE_CHECK_INSTANCE_TYPE((cell), AtkTableCellInterface::GetType()), 0);
|
|
|
|
if (const AXPlatformNodeBase* obj =
|
|
AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(cell))) {
|
|
@@ -1853,8 +1901,10 @@ gint GetColumnSpan(AtkTableCell* cell) {
|
|
}
|
|
|
|
GPtrArray* GetColumnHeaderCells(AtkTableCell* cell) {
|
|
+ DCHECK(g_atk_table_cell_get_type);
|
|
g_return_val_if_fail(
|
|
- G_TYPE_CHECK_INSTANCE_TYPE((cell), atk_table_cell_get_type()), nullptr);
|
|
+ G_TYPE_CHECK_INSTANCE_TYPE((cell), AtkTableCellInterface::GetType()),
|
|
+ nullptr);
|
|
|
|
GPtrArray* array = g_ptr_array_new_with_free_func(g_object_unref);
|
|
|
|
@@ -1888,8 +1938,10 @@ GPtrArray* GetColumnHeaderCells(AtkTable
|
|
}
|
|
|
|
gboolean GetCellPosition(AtkTableCell* cell, gint* row, gint* column) {
|
|
+ DCHECK(g_atk_table_cell_get_type);
|
|
g_return_val_if_fail(
|
|
- G_TYPE_CHECK_INSTANCE_TYPE((cell), atk_table_cell_get_type()), FALSE);
|
|
+ G_TYPE_CHECK_INSTANCE_TYPE((cell), AtkTableCellInterface::GetType()),
|
|
+ FALSE);
|
|
|
|
if (auto* obj = AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(cell))) {
|
|
std::optional<int> row_index = obj->GetTableRow();
|
|
@@ -1906,8 +1958,9 @@ gboolean GetCellPosition(AtkTableCell* c
|
|
}
|
|
|
|
gint GetRowSpan(AtkTableCell* cell) {
|
|
+ DCHECK(g_atk_table_cell_get_type);
|
|
g_return_val_if_fail(
|
|
- G_TYPE_CHECK_INSTANCE_TYPE((cell), atk_table_cell_get_type()), 0);
|
|
+ G_TYPE_CHECK_INSTANCE_TYPE((cell), AtkTableCellInterface::GetType()), 0);
|
|
|
|
if (auto* obj = AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(cell))) {
|
|
// If the object is not a cell, we return 0.
|
|
@@ -1918,8 +1971,10 @@ gint GetRowSpan(AtkTableCell* cell) {
|
|
}
|
|
|
|
GPtrArray* GetRowHeaderCells(AtkTableCell* cell) {
|
|
+ DCHECK(g_atk_table_cell_get_type);
|
|
g_return_val_if_fail(
|
|
- G_TYPE_CHECK_INSTANCE_TYPE((cell), atk_table_cell_get_type()), nullptr);
|
|
+ G_TYPE_CHECK_INSTANCE_TYPE((cell), AtkTableCellInterface::GetType()),
|
|
+ nullptr);
|
|
|
|
GPtrArray* array = g_ptr_array_new_with_free_func(g_object_unref);
|
|
|
|
@@ -1953,8 +2008,10 @@ GPtrArray* GetRowHeaderCells(AtkTableCel
|
|
}
|
|
|
|
AtkObject* GetTable(AtkTableCell* cell) {
|
|
+ DCHECK(g_atk_table_cell_get_type);
|
|
g_return_val_if_fail(
|
|
- G_TYPE_CHECK_INSTANCE_TYPE((cell), atk_table_cell_get_type()), nullptr);
|
|
+ G_TYPE_CHECK_INSTANCE_TYPE((cell), AtkTableCellInterface::GetType()),
|
|
+ nullptr);
|
|
|
|
if (auto* obj = AXPlatformNodeAuraLinux::FromAtkObject(ATK_OBJECT(cell))) {
|
|
if (auto* table = obj->GetTable())
|
|
@@ -1980,6 +2037,8 @@ const GInterfaceInfo Info = {reinterpret
|
|
|
|
} // namespace atk_table_cell
|
|
|
|
+#endif // ATK_212
|
|
+
|
|
namespace atk_object {
|
|
|
|
gpointer kAXPlatformNodeAuraLinuxParentClass = nullptr;
|
|
@@ -2246,6 +2305,50 @@ void Detach(AXPlatformNodeAuraLinuxObjec
|
|
|
|
} // namespace
|
|
|
|
+// static
|
|
+NO_SANITIZE("cfi-icall")
|
|
+GType AtkTableCellInterface::GetType() {
|
|
+ return g_atk_table_cell_get_type();
|
|
+}
|
|
+
|
|
+// static
|
|
+NO_SANITIZE("cfi-icall")
|
|
+GPtrArray* AtkTableCellInterface::GetColumnHeaderCells(AtkTableCell* cell) {
|
|
+ return g_atk_table_cell_get_column_header_cells(cell);
|
|
+}
|
|
+
|
|
+// static
|
|
+NO_SANITIZE("cfi-icall")
|
|
+GPtrArray* AtkTableCellInterface::GetRowHeaderCells(AtkTableCell* cell) {
|
|
+ return g_atk_table_cell_get_row_header_cells(cell);
|
|
+}
|
|
+
|
|
+// static
|
|
+NO_SANITIZE("cfi-icall")
|
|
+bool AtkTableCellInterface::GetRowColumnSpan(AtkTableCell* cell,
|
|
+ gint* row,
|
|
+ gint* column,
|
|
+ gint* row_span,
|
|
+ gint* col_span) {
|
|
+ return g_atk_table_cell_get_row_column_span(cell, row, column, row_span,
|
|
+ col_span);
|
|
+}
|
|
+
|
|
+// static
|
|
+bool AtkTableCellInterface::Exists() {
|
|
+ g_atk_table_cell_get_type = reinterpret_cast<GetTypeFunc>(
|
|
+ dlsym(RTLD_DEFAULT, "atk_table_cell_get_type"));
|
|
+ g_atk_table_cell_get_column_header_cells =
|
|
+ reinterpret_cast<GetColumnHeaderCellsFunc>(
|
|
+ dlsym(RTLD_DEFAULT, "atk_table_cell_get_column_header_cells"));
|
|
+ g_atk_table_cell_get_row_header_cells =
|
|
+ reinterpret_cast<GetRowHeaderCellsFunc>(
|
|
+ dlsym(RTLD_DEFAULT, "atk_table_cell_get_row_header_cells"));
|
|
+ g_atk_table_cell_get_row_column_span = reinterpret_cast<GetRowColumnSpanFunc>(
|
|
+ dlsym(RTLD_DEFAULT, "atk_table_cell_get_row_column_span"));
|
|
+ return *g_atk_table_cell_get_type;
|
|
+}
|
|
+
|
|
void AXPlatformNodeAuraLinux::EnsureGTypeInit() {
|
|
#if !GLIB_CHECK_VERSION(2, 36, 0)
|
|
static bool first_time = true;
|
|
@@ -2353,8 +2456,11 @@ GType AXPlatformNodeAuraLinux::GetAccess
|
|
g_type_add_interface_static(type, ATK_TYPE_TABLE, &atk_table::Info);
|
|
|
|
if (interface_mask_.Implements(ImplementedAtkInterfaces::Value::kTableCell)) {
|
|
- g_type_add_interface_static(type, atk_table_cell_get_type(),
|
|
- &atk_table_cell::Info);
|
|
+ // Run-time check to ensure AtkTableCell is supported (requires ATK 2.12).
|
|
+ if (AtkTableCellInterface::Exists()) {
|
|
+ g_type_add_interface_static(type, AtkTableCellInterface::GetType(),
|
|
+ &atk_table_cell::Info);
|
|
+ }
|
|
}
|
|
|
|
return type;
|
|
@@ -2584,9 +2690,9 @@ AtkRole AXPlatformNodeAuraLinux::GetAtkR
|
|
case ax::mojom::Role::kComplementary:
|
|
return ATK_ROLE_LANDMARK;
|
|
case ax::mojom::Role::kContentDeletion:
|
|
- return GetAtkRoleContentDeletion();
|
|
+ return kAtkRoleContentDeletion;
|
|
case ax::mojom::Role::kContentInsertion:
|
|
- return GetAtkRoleContentInsertion();
|
|
+ return kAtkRoleContentInsertion;
|
|
case ax::mojom::Role::kContentInfo:
|
|
case ax::mojom::Role::kFooter:
|
|
return ATK_ROLE_LANDMARK;
|
|
@@ -3020,12 +3126,14 @@ void AXPlatformNodeAuraLinux::GetAtkStat
|
|
static_cast<int32_t>(ax::mojom::AriaCurrentState::kFalse)) {
|
|
atk_state_set_add_state(atk_state_set, ATK_STATE_ACTIVE);
|
|
}
|
|
+#if defined(ATK_216)
|
|
// Runtime checks in case we were compiled with a newer version of ATK.
|
|
if (IsPlatformCheckable() && PlatformSupportsState(ATK_STATE_CHECKABLE))
|
|
atk_state_set_add_state(atk_state_set, ATK_STATE_CHECKABLE);
|
|
if (HasIntAttribute(ax::mojom::IntAttribute::kHasPopup) &&
|
|
PlatformSupportsState(ATK_STATE_HAS_POPUP))
|
|
atk_state_set_add_state(atk_state_set, ATK_STATE_HAS_POPUP);
|
|
+#endif
|
|
if (GetBoolAttribute(ax::mojom::BoolAttribute::kBusy))
|
|
atk_state_set_add_state(atk_state_set, ATK_STATE_BUSY);
|
|
if (GetBoolAttribute(ax::mojom::BoolAttribute::kModal))
|
|
@@ -3064,9 +3172,11 @@ void AXPlatformNodeAuraLinux::GetAtkStat
|
|
if (GetData().GetRestriction() != ax::mojom::Restriction::kDisabled) {
|
|
if (GetDelegate()->IsReadOnlySupported() &&
|
|
GetDelegate()->IsReadOnlyOrDisabled()) {
|
|
+#if defined(ATK_216)
|
|
// Runtime check in case we were compiled with a newer version of ATK.
|
|
if (PlatformSupportsState(ATK_STATE_READ_ONLY))
|
|
atk_state_set_add_state(atk_state_set, ATK_STATE_READ_ONLY);
|
|
+#endif
|
|
} else {
|
|
atk_state_set_add_state(atk_state_set, ATK_STATE_ENABLED);
|
|
atk_state_set_add_state(atk_state_set, ATK_STATE_SENSITIVE);
|
|
@@ -3100,12 +3210,16 @@ struct AtkIntListRelation {
|
|
static AtkIntListRelation kIntListRelations[] = {
|
|
{ax::mojom::IntListAttribute::kControlsIds, ATK_RELATION_CONTROLLER_FOR,
|
|
ATK_RELATION_CONTROLLED_BY},
|
|
+#if defined(ATK_226)
|
|
{ax::mojom::IntListAttribute::kDetailsIds, ATK_RELATION_DETAILS,
|
|
ATK_RELATION_DETAILS_FOR},
|
|
+#endif
|
|
{ax::mojom::IntListAttribute::kDescribedbyIds, ATK_RELATION_DESCRIBED_BY,
|
|
ATK_RELATION_DESCRIPTION_FOR},
|
|
+#if defined(ATK_226)
|
|
{ax::mojom::IntListAttribute::kErrormessageIds, ATK_RELATION_ERROR_MESSAGE,
|
|
ATK_RELATION_ERROR_FOR},
|
|
+#endif
|
|
{ax::mojom::IntListAttribute::kFlowtoIds, ATK_RELATION_FLOWS_TO,
|
|
ATK_RELATION_FLOWS_FROM},
|
|
{ax::mojom::IntListAttribute::kLabelledbyIds, ATK_RELATION_LABELLED_BY,
|
|
@@ -3884,6 +3998,7 @@ void AXPlatformNodeAuraLinux::OnReadonly
|
|
if (!obj)
|
|
return;
|
|
|
|
+#if defined(ATK_216)
|
|
// Runtime check in case we were compiled with a newer version of ATK.
|
|
if (!PlatformSupportsState(ATK_STATE_READ_ONLY))
|
|
return;
|
|
@@ -3891,6 +4006,7 @@ void AXPlatformNodeAuraLinux::OnReadonly
|
|
atk_object_notify_state_change(
|
|
obj, ATK_STATE_READ_ONLY,
|
|
GetData().GetRestriction() == ax::mojom::Restriction::kReadOnly);
|
|
+#endif
|
|
}
|
|
|
|
void AXPlatformNodeAuraLinux::OnInvalidStatusChanged() {
|
|
@@ -4217,11 +4333,13 @@ gfx::Rect AXPlatformNodeAuraLinux::GetEx
|
|
extents.Offset(window_origin);
|
|
break;
|
|
}
|
|
+#if defined(ATK_230)
|
|
case ATK_XY_PARENT: {
|
|
gfx::Vector2d parent_origin = -GetParentOriginInScreenCoordinates();
|
|
extents.Offset(parent_origin);
|
|
break;
|
|
}
|
|
+#endif
|
|
}
|
|
|
|
return extents;
|
|
@@ -4651,6 +4769,7 @@ bool AXPlatformNodeAuraLinux::IsInLiveRe
|
|
return HasStringAttribute(ax::mojom::StringAttribute::kContainerLiveStatus);
|
|
}
|
|
|
|
+#if defined(ATK_230)
|
|
void AXPlatformNodeAuraLinux::ScrollToPoint(AtkCoordType atk_coord_type,
|
|
int x,
|
|
int y) {
|
|
@@ -4723,7 +4842,9 @@ void AXPlatformNodeAuraLinux::ScrollNode
|
|
rect -= rect.OffsetFromOrigin();
|
|
ScrollNodeRectIntoView(rect, atk_scroll_type);
|
|
}
|
|
+#endif // defined(ATK_230)
|
|
|
|
+#if defined(ATK_232)
|
|
std::optional<gfx::Rect>
|
|
AXPlatformNodeAuraLinux::GetUnclippedHypertextRangeBoundsRect(int start_offset,
|
|
int end_offset) {
|
|
@@ -4782,6 +4903,7 @@ bool AXPlatformNodeAuraLinux::ScrollSubs
|
|
|
|
return true;
|
|
}
|
|
+#endif // defined(ATK_232)
|
|
|
|
void AXPlatformNodeAuraLinux::ComputeStylesIfNeeded() {
|
|
if (!offset_to_text_attributes_.empty())
|
|
@@ -4964,8 +5086,10 @@ gfx::Point AXPlatformNodeAuraLinux::Conv
|
|
switch (atk_coord_type) {
|
|
case ATK_XY_WINDOW:
|
|
return point + GetParentFrameOriginInScreenCoordinates();
|
|
+#if defined(ATK_230)
|
|
case ATK_XY_PARENT:
|
|
return point + GetParentOriginInScreenCoordinates();
|
|
+#endif
|
|
case ATK_XY_SCREEN:
|
|
default:
|
|
return point;
|
|
diff -up chromium-129.0.6668.58/ui/accessibility/platform/ax_platform_node_auralinux.h.me chromium-129.0.6668.58/ui/accessibility/platform/ax_platform_node_auralinux.h
|
|
--- chromium-129.0.6668.58/ui/accessibility/platform/ax_platform_node_auralinux.h.me 2024-09-18 19:26:54.167348688 +0200
|
|
+++ chromium-129.0.6668.58/ui/accessibility/platform/ax_platform_node_auralinux.h 2024-09-18 19:28:06.220700493 +0200
|
|
@@ -52,6 +52,31 @@ struct FindInPageResultInfo {
|
|
}
|
|
};
|
|
|
|
+// AtkTableCell was introduced in ATK 2.12. Ubuntu Trusty has ATK 2.10.
|
|
+// Compile-time checks are in place for ATK versions that are older than 2.12.
|
|
+// However, we also need runtime checks in case the version we are building
|
|
+// against is newer than the runtime version. To prevent a runtime error, we
|
|
+// check that we have a version of ATK that supports AtkTableCell. If we do,
|
|
+// we dynamically load the symbol; if we don't, the interface is absent from
|
|
+// the accessible object and its methods will not be exposed or callable.
|
|
+// The definitions below ensure we have no missing symbols. Note that in
|
|
+// environments where we have ATK > 2.12, the definitions of AtkTableCell and
|
|
+// AtkTableCellIface below are overridden by the runtime version.
|
|
+// TODO(accessibility) Remove AtkTableCellInterface when 2.12 is the minimum
|
|
+// supported version.
|
|
+struct COMPONENT_EXPORT(AX_PLATFORM) AtkTableCellInterface {
|
|
+ typedef struct _AtkTableCell AtkTableCell;
|
|
+ static GType GetType();
|
|
+ static GPtrArray* GetColumnHeaderCells(AtkTableCell* cell);
|
|
+ static GPtrArray* GetRowHeaderCells(AtkTableCell* cell);
|
|
+ static bool GetRowColumnSpan(AtkTableCell* cell,
|
|
+ gint* row,
|
|
+ gint* column,
|
|
+ gint* row_span,
|
|
+ gint* col_span);
|
|
+ static bool Exists();
|
|
+};
|
|
+
|
|
// This class with an enum is used to generate a bitmask which tracks the ATK
|
|
// interfaces that an AXPlatformNodeAuraLinux's ATKObject implements.
|
|
class ImplementedAtkInterfaces {
|
|
diff -up chromium-129.0.6668.58/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc.me chromium-129.0.6668.58/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc
|
|
--- chromium-129.0.6668.58/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc.me 2024-09-18 19:27:10.728659400 +0200
|
|
+++ chromium-129.0.6668.58/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc 2024-09-18 19:28:06.221700512 +0200
|
|
@@ -8,6 +8,7 @@
|
|
#endif
|
|
|
|
#include <atk/atk.h>
|
|
+#include <dlfcn.h>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
@@ -884,6 +885,17 @@ typedef bool (*ScrollToPointFunc)(AtkCom
|
|
typedef bool (*ScrollToFunc)(AtkComponent* component, AtkScrollType type);
|
|
|
|
TEST_F(AXPlatformNodeAuraLinuxTest, AtkComponentScrollToPoint) {
|
|
+ // There's a chance we may be compiled with a newer version of ATK and then
|
|
+ // run with an older one, so we need to do a runtime check for this method
|
|
+ // that is available in ATK 2.30 instead of linking directly.
|
|
+ ScrollToPointFunc scroll_to_point = reinterpret_cast<ScrollToPointFunc>(
|
|
+ dlsym(RTLD_DEFAULT, "atk_component_scroll_to_point"));
|
|
+ if (!scroll_to_point) {
|
|
+ LOG(WARNING) << "Skipping AtkComponentScrollToPoint"
|
|
+ " because ATK version < 2.30 detected.";
|
|
+ return;
|
|
+ }
|
|
+
|
|
AXNodeData root;
|
|
root.id = 1;
|
|
root.role = ax::mojom::Role::kRootWebArea;
|
|
@@ -911,8 +923,7 @@ TEST_F(AXPlatformNodeAuraLinuxTest, AtkC
|
|
EXPECT_EQ(10, width);
|
|
EXPECT_EQ(10, height);
|
|
|
|
- atk_component_scroll_to_point(ATK_COMPONENT(child_obj), ATK_XY_SCREEN, 600,
|
|
- 650);
|
|
+ scroll_to_point(ATK_COMPONENT(child_obj), ATK_XY_SCREEN, 600, 650);
|
|
atk_component_get_extents(ATK_COMPONENT(child_obj), &x_left, &y_top, &width,
|
|
&height, ATK_XY_SCREEN);
|
|
EXPECT_EQ(610, x_left);
|
|
@@ -920,8 +931,7 @@ TEST_F(AXPlatformNodeAuraLinuxTest, AtkC
|
|
EXPECT_EQ(10, width);
|
|
EXPECT_EQ(10, height);
|
|
|
|
- atk_component_scroll_to_point(ATK_COMPONENT(child_obj), ATK_XY_PARENT, 10,
|
|
- 10);
|
|
+ scroll_to_point(ATK_COMPONENT(child_obj), ATK_XY_PARENT, 10, 10);
|
|
atk_component_get_extents(ATK_COMPONENT(child_obj), &x_left, &y_top, &width,
|
|
&height, ATK_XY_SCREEN);
|
|
// The test wrapper scrolls every element when scrolling, so this should be
|
|
@@ -938,6 +948,17 @@ TEST_F(AXPlatformNodeAuraLinuxTest, AtkC
|
|
}
|
|
|
|
TEST_F(AXPlatformNodeAuraLinuxTest, AtkComponentScrollTo) {
|
|
+ // There's a chance we may be compiled with a newer version of ATK and then
|
|
+ // run with an older one, so we need to do a runtime check for this method
|
|
+ // that is available in ATK 2.30 instead of linking directly.
|
|
+ ScrollToFunc scroll_to = reinterpret_cast<ScrollToFunc>(
|
|
+ dlsym(RTLD_DEFAULT, "atk_component_scroll_to"));
|
|
+ if (!scroll_to) {
|
|
+ LOG(WARNING) << "Skipping AtkComponentScrollTo"
|
|
+ " because ATK version < 2.30 detected.";
|
|
+ return;
|
|
+ }
|
|
+
|
|
AXNodeData root;
|
|
root.id = 1;
|
|
root.role = ax::mojom::Role::kRootWebArea;
|
|
@@ -965,7 +986,7 @@ TEST_F(AXPlatformNodeAuraLinuxTest, AtkC
|
|
EXPECT_EQ(10, width);
|
|
EXPECT_EQ(10, height);
|
|
|
|
- atk_component_scroll_to(ATK_COMPONENT(child_obj), ATK_SCROLL_ANYWHERE);
|
|
+ scroll_to(ATK_COMPONENT(child_obj), ATK_SCROLL_ANYWHERE);
|
|
atk_component_get_extents(ATK_COMPONENT(child_obj), &x_left, &y_top, &width,
|
|
&height, ATK_XY_SCREEN);
|
|
EXPECT_EQ(0, x_left);
|
|
diff -up chromium-129.0.6668.58/ui/accessibility/platform/inspect/ax_tree_formatter_auralinux.cc.me chromium-129.0.6668.58/ui/accessibility/platform/inspect/ax_tree_formatter_auralinux.cc
|
|
--- chromium-129.0.6668.58/ui/accessibility/platform/inspect/ax_tree_formatter_auralinux.cc.me 2024-09-18 19:27:20.965851455 +0200
|
|
+++ chromium-129.0.6668.58/ui/accessibility/platform/inspect/ax_tree_formatter_auralinux.cc 2024-09-18 19:28:06.221700512 +0200
|
|
@@ -474,18 +474,34 @@ void AXTreeFormatterAuraLinux::AddTableC
|
|
int row = 0, col = 0, row_span = 0, col_span = 0;
|
|
int n_row_headers = 0, n_column_headers = 0;
|
|
|
|
- AtkTableCell* cell = G_TYPE_CHECK_INSTANCE_CAST(
|
|
- (atk_object), atk_table_cell_get_type(), AtkTableCell);
|
|
+ // Properties obtained via AtkTableCell, if possible. If we do not have at
|
|
+ // least ATK 2.12, use the same logic in our AtkTableCell implementation so
|
|
+ // that tests can still be run.
|
|
+ if (AtkTableCellInterface::Exists()) {
|
|
+ AtkTableCell* cell = G_TYPE_CHECK_INSTANCE_CAST(
|
|
+ (atk_object), AtkTableCellInterface::GetType(), AtkTableCell);
|
|
|
|
- atk_table_cell_get_row_column_span(cell, &row, &col, &row_span, &col_span);
|
|
+ AtkTableCellInterface::GetRowColumnSpan(cell, &row, &col, &row_span,
|
|
+ &col_span);
|
|
|
|
- GPtrArray* column_headers = atk_table_cell_get_column_header_cells(cell);
|
|
- n_column_headers = column_headers->len;
|
|
- g_ptr_array_unref(column_headers);
|
|
+ GPtrArray* column_headers =
|
|
+ AtkTableCellInterface::GetColumnHeaderCells(cell);
|
|
+ n_column_headers = column_headers->len;
|
|
+ g_ptr_array_unref(column_headers);
|
|
|
|
- GPtrArray* row_headers = atk_table_cell_get_row_header_cells(cell);
|
|
- n_row_headers = row_headers->len;
|
|
- g_ptr_array_unref(row_headers);
|
|
+ GPtrArray* row_headers = AtkTableCellInterface::GetRowHeaderCells(cell);
|
|
+ n_row_headers = row_headers->len;
|
|
+ g_ptr_array_unref(row_headers);
|
|
+ } else {
|
|
+ row = node->GetTableRow().value_or(-1);
|
|
+ col = node->GetTableColumn().value_or(-1);
|
|
+ row_span = node->GetTableRowSpan().value_or(0);
|
|
+ col_span = node->GetTableColumnSpan().value_or(0);
|
|
+ if (role == ATK_ROLE_TABLE_CELL) {
|
|
+ n_column_headers = node->GetDelegate()->GetColHeaderNodeIds(col).size();
|
|
+ n_row_headers = node->GetDelegate()->GetRowHeaderNodeIds(row).size();
|
|
+ }
|
|
+ }
|
|
|
|
std::vector<std::string> cell_info;
|
|
cell_info.push_back(base::StringPrintf("row=%i", row));
|