Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions mcpp.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ members = [
"tests/examples/abseil",
"tests/examples/archive",
"tests/examples/argparse",
"tests/examples/accesskit",
"tests/examples/asio-module",
"tests/examples/asio-ssl",
"tests/examples/boost-asio",
Expand Down
88 changes: 88 additions & 0 deletions pkgs/c/compat.accesskit.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
-- compat.accesskit — AccessKit's C bindings (accesskit-c), prebuilt: a UI
-- describes its tree once and AccessKit serves it to each platform's
-- assistive technology — UI Automation on Windows, NSAccessibility on macOS,
-- AT-SPI on Linux (a screen reader, a magnifier, voice control).
--
-- THE LIBRARY IS RUST, SO ITS RELEASE IS THE ARTIFACT. Building it here would
-- need a Rust toolchain in the recipe; upstream's release archive carries the
-- header and a static library for every platform it supports, built from the
-- tagged source by its own CI. This descriptor exposes the header and links the
-- static library of the host's platform, with the system libraries upstream's
-- own `accesskit-config.cmake` names for each.
--
-- WHAT IS NOT COVERED: upstream ships no Linux arm64 build, and this version
-- links macOS arm64 and Windows x86_64 (the x86_64 Mac and arm64 Windows
-- libraries are in the archive too, but the index states one library path per
-- platform). A consumer that wants AccessKit there gates its use by platform.
--
-- One archive for all three platforms (about 64 MB): the paths below reach into
-- its `accesskit-c-0.23.1/` wrap layer; mcpp rewrites a relative `-L` to the
-- package's own directory.
package = {
spec = "1",
namespace = "compat",
name = "accesskit",
description = "AccessKit C bindings (prebuilt static library): one accessibility tree served to UIA, NSAccessibility and AT-SPI",
licenses = {"MIT", "Apache-2.0"},
repo = "https://github.com/AccessKit/accesskit-c",
type = "package",

-- A new release is found and fetched by the updater; the library paths
-- below name the archive's versioned wrap layer, so its candidate build
-- says when they need the new version too.
extensions = {
autoupdate = {
tag = "${version}",
url = "https://github.com/AccessKit/accesskit-c/releases/download/${tag}/accesskit-c-${version}.zip",
},
},

xpm = {
linux = {
["0.23.1"] = {
url = "https://github.com/AccessKit/accesskit-c/releases/download/0.23.1/accesskit-c-0.23.1.zip",
sha256 = "35b7ca8a6f1e038b5da35e1e9e5a0adaed9bfcf21e1496d29598fbbadcc7043f",
},
["latest"] = { ref = "0.23.1" },
},
macosx = {
["0.23.1"] = {
url = "https://github.com/AccessKit/accesskit-c/releases/download/0.23.1/accesskit-c-0.23.1.zip",
sha256 = "35b7ca8a6f1e038b5da35e1e9e5a0adaed9bfcf21e1496d29598fbbadcc7043f",
},
["latest"] = { ref = "0.23.1" },
},
windows = {
["0.23.1"] = {
url = "https://github.com/AccessKit/accesskit-c/releases/download/0.23.1/accesskit-c-0.23.1.zip",
sha256 = "35b7ca8a6f1e038b5da35e1e9e5a0adaed9bfcf21e1496d29598fbbadcc7043f",
},
["latest"] = { ref = "0.23.1" },
},
},

mcpp = {
language = "c++23",
import_std = false,
c_standard = "c11",
include_dirs = { "*/include" },
generated_files = {
["mcpp_generated/accesskit_anchor.c"] = "int mcpp_compat_accesskit_anchor(void) { return 0; }\n",
},
sources = { "mcpp_generated/accesskit_anchor.c" },
targets = { ["accesskit"] = { kind = "lib" } },
deps = {},
-- The static library and what upstream's accesskit-config.cmake links beside it.
linux = {
ldflags = { "-Laccesskit-c-0.23.1/lib/linux/x86_64/static", "-l:libaccesskit.a", "-static-libgcc", "-lm" },
},
macosx = {
ldflags = { "-Laccesskit-c-0.23.1/lib/macos/arm64/static", "-laccesskit",
"-framework", "AppKit", "-framework", "Foundation", "-framework", "CoreFoundation", "-lobjc", "-lc++" },
},
windows = {
ldflags = { "-Laccesskit-c-0.23.1/lib/windows/x86_64/msvc/static", "-laccesskit",
"-lbcrypt", "-lntdll", "-lpropsys", "-lruntimeobject", "-luiautomationcore", "-luserenv", "-lws2_32" },
},
},
}
9 changes: 9 additions & 0 deletions tests/examples/accesskit/mcpp.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# compat.accesskit test project: a tree built and handed to AccessKit, and on
# Linux an AT-SPI adapter made and given the tree. `compat` redirect inherited
# from the workspace root.
[package]
name = "accesskit-tests"
version = "0.1.0"

[dependencies.compat]
accesskit = "0.23.1"
58 changes: 58 additions & 0 deletions tests/examples/accesskit/tests/tree.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Behavioral test: compat.accesskit builds a tree (a window holding a button
// with a label, focusable, clickable), reads it back through the library's own
// debug view, and on Linux makes an AT-SPI adapter and gives it the tree. Not
// merely an include: these calls reach the prebuilt Rust library.
#include <accesskit.h>
#include <cstdio>
#include <cstring>

static accesskit_tree_update *tree(void *userdata) {
(void)userdata;
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_add_action(button, ACCESSKIT_ACTION_FOCUS);
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;
}

#if defined(__linux__)
static void act(accesskit_action_request *request, void *userdata) {
(void)userdata;
accesskit_action_request_free(request);
}
static void deactivated(void *userdata) { (void)userdata; }
#endif

int main(void) {
accesskit_tree_update *update = tree(nullptr);
if (!update) {
fprintf(stderr, "no tree update\n");
return 1;
}
char *debug = accesskit_tree_update_debug(update);
const int named = debug && strstr(debug, "Save") != NULL;
if (debug) accesskit_string_free(debug);
accesskit_tree_update_free(update);
if (!named) {
fprintf(stderr, "the tree update does not hold the button's label\n");
return 1;
}
#if defined(__linux__)
accesskit_unix_adapter *adapter = accesskit_unix_adapter_new(reinterpret_cast<accesskit_activation_handler_callback>(tree), nullptr, act, nullptr, deactivated, nullptr);
if (!adapter) {
fprintf(stderr, "no AT-SPI adapter\n");
return 1;
}
accesskit_unix_adapter_update_window_focus_state(adapter, true);
accesskit_unix_adapter_free(adapter);
#endif
printf("accesskit: a window and its button, served\n");
return 0;
}
Loading