diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index d6479bb6..7cf7a4ca 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -1616,6 +1616,11 @@ jobs: shell: bash run: python3 tests/mwrap/check_installed_template.py --mcpp "$MCPP" --package mcpplibs.mwrap.md4c@0.5.3 + - name: Installed accesskit wrapper archive and actual default tree template + if: contains(format(' {0} ', env.MEMBERS), ' accesskit-tree ') && matrix.toolchain == 'default' + shell: bash + run: python3 tests/mwrap/check_installed_template.py --mcpp "$MCPP" --package mcpplibs.mwrap.accesskit@0.23.1 + - name: Installed Lua wrapper archive and actual default script template if: contains(format(' {0} ', env.MEMBERS), ' lua-embed ') && matrix.toolchain == 'default' shell: bash diff --git a/mcpp.toml b/mcpp.toml index d36127b5..17f0bc9c 100644 --- a/mcpp.toml +++ b/mcpp.toml @@ -17,6 +17,7 @@ members = [ "tests/mwrap/ffmpeg-cpu", "tests/mwrap/imgui-headless", "tests/mwrap/md4c-render", + "tests/mwrap/accesskit-tree", "tests/mwrap/lua-embed", "tests/mwrap/quickjs-embed", "tests/mwrap/pocketpy-embed", diff --git a/pkgs/mwrap/accesskit.lua b/pkgs/mwrap/accesskit.lua new file mode 100644 index 00000000..83c71b3a --- /dev/null +++ b/pkgs/mwrap/accesskit.lua @@ -0,0 +1,38 @@ +-- Immutable upstream-aligned mwrap source release (accesskit-m mwrap-0.23.1). +-- The CN mirror is added by a maintainer with mcpp-res access; until then CN +-- users fall back to the GitHub release (docs/cn-mirror.md). +package = { + spec = "1", + namespace = "mcpplibs.mwrap", + name = "accesskit", + description = "accesskit-m: AccessKit's C bindings as a C++23 module (one accessibility tree served to UIA, NSAccessibility and AT-SPI)", + licenses = { "Apache-2.0" }, + repo = "https://github.com/mcpplibs/accesskit-m", + type = "package", + extensions = { + autoupdate = { + tag = "mwrap-${version}", + url = "https://github.com/mcpplibs/accesskit-m/releases/download/${tag}/accesskit-m-${version}.tar.gz", + }, + }, + xpm = { + linux = { + ["0.23.1"] = { + url = "https://github.com/mcpplibs/accesskit-m/releases/download/mwrap-0.23.1/accesskit-m-0.23.1.tar.gz", + sha256 = "799928a7914f3eef7808f358f6bd14c8b18b141e0cd4f34eff99ea8b282fe893", + }, + }, + macosx = { + ["0.23.1"] = { + url = "https://github.com/mcpplibs/accesskit-m/releases/download/mwrap-0.23.1/accesskit-m-0.23.1.tar.gz", + sha256 = "799928a7914f3eef7808f358f6bd14c8b18b141e0cd4f34eff99ea8b282fe893", + }, + }, + windows = { + ["0.23.1"] = { + url = "https://github.com/mcpplibs/accesskit-m/releases/download/mwrap-0.23.1/accesskit-m-0.23.1.tar.gz", + sha256 = "799928a7914f3eef7808f358f6bd14c8b18b141e0cd4f34eff99ea8b282fe893", + }, + }, + }, +} diff --git a/tests/mwrap/accesskit-tree/mcpp.toml b/tests/mwrap/accesskit-tree/mcpp.toml new file mode 100644 index 00000000..e44f3ee3 --- /dev/null +++ b/tests/mwrap/accesskit-tree/mcpp.toml @@ -0,0 +1,11 @@ +[package] +name = "accesskit-tree" +version = "0.23.1" +description = "Consume the immutable accesskit wrapper: build a tree update through the module and read it back" + +[indices] +# Use the complete candidate built-in index prepared by tests/run_members.sh. +# An explicit empty table overrides the legacy workspace redirect. + +[dependencies] +"mcpplibs.mwrap.accesskit" = "0.23.1" diff --git a/tests/mwrap/accesskit-tree/tests/behavior.cpp b/tests/mwrap/accesskit-tree/tests/behavior.cpp new file mode 100644 index 00000000..8a6049a1 --- /dev/null +++ b/tests/mwrap/accesskit-tree/tests/behavior.cpp @@ -0,0 +1,48 @@ +// Through the module: a window holding a button built, read back through the +// library's debug view, and on Linux served by an AT-SPI adapter. The names +// are AccessKit's own (no namespace of this package's). +import std; +import mcpplibs.mwrap.accesskit; + +namespace { + +accesskit_tree_update* tree(void*) { + accesskit_node* window = accesskit_node_new(ACCESSKIT_ROLE_WINDOW); + accesskit_node_set_label(window, "Settings"); + accesskit_node_push_child(window, 2); + accesskit_node* button = accesskit_node_new(ACCESSKIT_ROLE_BUTTON); + accesskit_node_set_label(button, "Save"); + accesskit_node_add_action(button, ACCESSKIT_ACTION_CLICK); + accesskit_node_set_toggled(button, ACCESSKIT_TOGGLED_FALSE); + accesskit_tree_update* update = accesskit_tree_update_with_capacity_and_focus(2, 2); + accesskit_tree_update_set_tree_info(update, accesskit_tree_info_new(1)); + accesskit_tree_update_push_node(update, 1, window); + accesskit_tree_update_push_node(update, 2, button); + return update; +} + +} // namespace + +int main() { + accesskit_tree_update* update = tree(nullptr); + char* debug = accesskit_tree_update_debug(update); + const bool named = debug && std::string_view(debug).contains("Save") && std::string_view(debug).contains("Settings"); + if (debug) accesskit_string_free(debug); + accesskit_tree_update_free(update); + if (!named) { + std::println(std::cerr, "the update does not hold the window and its button"); + return 1; + } +#if defined(__linux__) + accesskit_unix_adapter* adapter = accesskit_unix_adapter_new( + tree, nullptr, [](accesskit_action_request* r, void*) { accesskit_action_request_free(r); }, nullptr, [](void*) {}, nullptr); + if (!adapter) { + std::println(std::cerr, "no AT-SPI adapter"); + return 1; + } + accesskit_unix_adapter_update_window_focus_state(adapter, true); + accesskit_unix_adapter_free(adapter); +#endif + std::println("accesskit through its module: a window and its button"); + return 0; +}