public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
From: Than Ngo <than@redhat.com>
To: git-commits@fedoraproject.org
Subject: [rpms/chromium] epel9-next: workaround for build error due to old atk version on el8
Date: Fri, 07 Aug 2026 16:06:58 GMT	[thread overview]
Message-ID: <178611881841.1.6900284494396389900.rpms-chromium-ddd82910888e@fedoraproject.org> (raw)

A new commit has been pushed.

Repo   : rpms/chromium
Branch : epel9-next
Commit : ddd82910888e222f53d06d13f8ce709ec09012ab
Author : Than Ngo <than@redhat.com>
Date   : 2024-09-18T20:37:15+02:00
Stats  : +1088/-1 in 2 file(s)
URL    : https://src.fedoraproject.org/rpms/chromium/c/ddd82910888e222f53d06d13f8ce709ec09012ab?branch=epel9-next

Log:
workaround for build error due to old atk version on el8

---
diff --git a/chromium-129-el8-atk-compiler-error.patch b/chromium-129-el8-atk-compiler-error.patch
new file mode 100644
index 0000000..58e4cfb
--- /dev/null
+++ b/chromium-129-el8-atk-compiler-error.patch
@@ -0,0 +1,1083 @@
+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));

diff --git a/chromium.spec b/chromium.spec
index 0c399a7..7e0661a 100644
--- a/chromium.spec
+++ b/chromium.spec
@@ -39,7 +39,7 @@
 %global build_chromedriver 1
 
 # enable|disable headless client build
-%global build_headless 1
+%global build_headless 0
 %ifarch ppc64le
 %global build_headless 0
 %endif
@@ -362,6 +362,9 @@ Patch150: chromium-124-qt6.patch
 Patch305: chromium-124-el8-arm64-memory_tagging.patch
 Patch306: chromium-127-el8-ifunc-header.patch
 
+# workaround for build error due to old atk version on el8
+Patch307: chromium-129-el8-atk-compiler-error.patch
+
 # enable fstack-protector-strong
 Patch312: chromium-123-fstack-protector-strong.patch
 
@@ -1084,6 +1087,7 @@ Qt6 UI for chromium.
 %patch -P305 -p1 -b .el8-memory_tagging
 %patch -P306 -p1 -b .el8-ifunc-header
 %endif
+%patch -P307 -p1 -b .el8-atk-compiler-error
 %endif
 
 %patch -P312 -p1 -b .fstack-protector-strong

                 reply	other threads:[~2026-08-07 16:06 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=178611881841.1.6900284494396389900.rpms-chromium-ddd82910888e@fedoraproject.org \
    --to=than@redhat.com \
    --cc=git-commits@fedoraproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox