GTK 4 中的辅助功能

上周 GTK 3.99.3 版本中的重大新闻是,我们为新的辅助功能实现提供了第一个重要的后端。因此,现在是深入了解 GTK 4 中辅助功能的好时机。

概述

让我们快速回顾一下辅助功能在 Linux 上的工作方式。其中的参与者是应用程序和辅助技术 (AT),例如屏幕阅读器(例如,Orca)、放大镜等。

AT 的目的通常是为用户提供与应用程序交互的替代方式,这些方式是根据他们的需求量身定制的(例如,放大的视图、大声朗读的文本或语音命令)。为此,AT 需要有关应用程序 UI 的大量详细信息,而这正是辅助功能栈发挥作用的地方——它是应用程序(或其工具包)和 AT 之间的连接层。

应用程序和 AT 通过辅助功能总线相互通信,这是一个 D-Bus 会话总线的单独实例,使用 AT-SPI 项目描述的接口。应用程序的 UI 元素在总线上表示为对象,这些对象实现了某种抽象的接口,例如 TextValue。应用程序发出信号来传达 UI 中的更改,AT 可以调用对象上的方法来获取信息或进行更改(例如,更改 Value 接口的当前值以移动它所代表的 GtkScale)。

发生了什么变化

在 GTK 2 和 3 中,这是以一种笨拙的间接方式完成的:GTK 小部件具有辅助的可访问对象,这些对象是 ATK 接口的实现(转换 1:GTK ➙ ATK)。然后,这些对象被转换为 AT-SPI 对象(转换 2:ATK ➙ AT-SPI),这些对象通过 at-spi2-atk 中的适配器代码在辅助功能总线上表示。另一方面,AT 然后使用 pyatspi 将 AT-SPI 接口转换为 Python 对象(转换 3:AT-SPI ➙ Python)。

这种多步骤的过程效率低下、有损且难以维护;它需要在至少三个组件上实现相同的功能,并且导致文档化的 AT-SPI 方法和属性与实际通过辅助功能总线发送的方法和属性之间存在差异。

在 GTK 4 中,我们通过删除 ATK 和 at-spi2-atk 来简化应用程序端。小部件现在实现了一个 GtkAccessible 接口,该接口允许它们设置许多角色、状态、属性和关系,这些属性和关系或多或少直接取自 W3C 发布的 WAI-ARIA 规范。GTK 辅助功能 API 的 AT-SPI 后端然后获取这些受 ARIA 启发的属性(以及小部件本身的知识),并将小部件在辅助功能总线上表示为对象,为它们实现相关的 AT-SPI 接口。

这是一种更直接的方法,并且与 Qt 和 Web 浏览器已经做的事情相匹配。

应用程序 API

以下是您在应用程序中使用 GTK 4 时最可能遇到的辅助功能 API 的要点

设置可访问角色。 角色是对小部件语义的描述,AT 将使用它来决定应向其用户呈现哪种行为。设置角色是一次性操作,这意味着它必须在小部件创建时完成,或者在 class_init 中,或者在实例初始化期间完成

gtk_widget_class_set_accessible_role (widget_class,  
                                      GTK_ACCESSIBLE_ROLE_BUTTON);

更新小部件的可访问状态或属性。 每当小部件的可访问表示发生更改时,都应执行此操作

gtk_accessible_update_property (GTK_ACCESSIBLE (widget),
                       GTK_ACCESSIBLE_PROPERTY_VALUE_MIN, minimum,
                       GTK_ACCESSIBLE_PROPERTY_VALUE_NOW, value,
                       GTK_ACCESSIBLE_PROPERTY_VALUE_MAX, maximum,
                       -1);

GTK 参考文档提供了 辅助功能 API 的概述,其中包括针对应用程序开发人员和小部件编写者的指南。

下一步是什么?

对于 GTK 4.0,我们专注于完成 AT-SPI 后端。但是有了新的 API 和后端分离,我们有了一条明确的道路,可以为其他平台创建辅助功能后端,这是我们希望在后续 GTK 4 版本中研究的内容。

在 Linux 上,我们希望与其他利益相关者合作,使 AT-SPI 接口现代化,以最终克服在某些地方仍然可见的 CORBA 遗留问题。其中的一部分是将从辅助功能总线转向应用程序和 AT 之间的对等连接;这将增强辅助功能堆栈的安全性,并填补诸如 Flatpak 等技术使用的沙箱中的一个漏洞。

将来,我们希望引入一些工具,以确保应用程序开发人员意识到缺少辅助功能注释,例如为其 UI 中的图标和图像提供标签属性或 labelled-by 关系;或者确保每个 UI 元素都在可访问的树中正确表示。我们已经为 GtkAccessible 接口提供了一个测试后端,可用于编写单元测试并验证角色和属性在必要时是否已更新。