@@ -18,12 +18,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5469156abf83b372574df59b660375739725f7b5a3c78dc47b80f9ec0450c43"
dependencies = [
"accesskit",
- "accesskit_consumer",
+ "accesskit_consumer 0.34.0",
"atspi-common",
"serde",
"zvariant",
]
+[[package]]
+name = "accesskit_atspi_common"
+version = "0.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "842fd8203e6dfcf531d24f5bac792088edfba7d6b35844fead191603fb32a260"
+dependencies = [
+ "accesskit",
+ "accesskit_consumer 0.35.0",
+ "atspi-common",
+ "phf 0.13.1",
+ "serde",
+ "zvariant",
+]
+
[[package]]
name = "accesskit_consumer"
version = "0.34.0"
@@ -34,6 +48,30 @@ dependencies = [
"hashbrown 0.16.1",
]
+[[package]]
+name = "accesskit_consumer"
+version = "0.35.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53cf47daed85312e763fbf85ceca136e0d7abc68e0a7e12abe11f48172bc3b10"
+dependencies = [
+ "accesskit",
+ "hashbrown 0.16.1",
+]
+
+[[package]]
+name = "accesskit_macos"
+version = "0.26.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "534bc3fdc89a64a1db3c46b33c198fde2b7c3c7d094e5809c8c8bf2970c18243"
+dependencies = [
+ "accesskit",
+ "accesskit_consumer 0.35.0",
+ "hashbrown 0.16.1",
+ "objc2 0.5.2",
+ "objc2-app-kit",
+ "objc2-foundation 0.2.2",
+]
+
[[package]]
name = "accesskit_unix"
version = "0.20.0"
@@ -41,7 +79,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14984a017441d2efc3b0fb6a08ef9b83c17719479ba72f1f0c6e08bea9dd92ec"
dependencies = [
"accesskit",
- "accesskit_atspi_common",
+ "accesskit_atspi_common 0.17.0",
+ "async-channel 2.5.0",
+ "async-executor",
+ "async-task",
+ "atspi",
+ "futures-lite 2.6.1",
+ "futures-util",
+ "serde",
+ "zbus",
+]
+
+[[package]]
+name = "accesskit_unix"
+version = "0.21.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90e549dd7c6562b6a2ea807b44726e6241707db054a817dc4c7e2b8d3b39bfac"
+dependencies = [
+ "accesskit",
+ "accesskit_atspi_common 0.18.0",
"async-channel 2.5.0",
"async-executor",
"async-task",
@@ -2232,13 +2288,22 @@ dependencies = [
"generic-array",
]
+[[package]]
+name = "block2"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f"
+dependencies = [
+ "objc2 0.5.2",
+]
+
[[package]]
name = "block2"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5"
dependencies = [
- "objc2",
+ "objc2 0.6.3",
]
[[package]]
@@ -2280,7 +2345,7 @@ version = "3.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89ec27229c38ed0eb3c0feee3d2c1d6a4379ae44f418a29a658890e062d8f365"
dependencies = [
- "darling 0.20.11",
+ "darling 0.21.3",
"ident_case",
"prettyplease",
"proc-macro2",
@@ -3089,7 +3154,7 @@ dependencies = [
"http_client_tls",
"httparse",
"log",
- "objc2-foundation",
+ "objc2-foundation 0.3.1",
"parking_lot",
"paths",
"postage",
@@ -3996,13 +4061,13 @@ dependencies = [
"ndk-context",
"num-derive",
"num-traits",
- "objc2",
+ "objc2 0.6.3",
"objc2-audio-toolbox",
"objc2-avf-audio",
"objc2-core-audio",
"objc2-core-audio-types",
"objc2-core-foundation",
- "objc2-foundation",
+ "objc2-foundation 0.3.1",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
@@ -5113,9 +5178,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38"
dependencies = [
"bitflags 2.10.0",
- "block2",
+ "block2 0.6.2",
"libc",
- "objc2",
+ "objc2 0.6.3",
]
[[package]]
@@ -7738,8 +7803,8 @@ dependencies = [
"naga 28.0.0",
"num_cpus",
"objc",
- "objc2",
- "objc2-metal",
+ "objc2 0.6.3",
+ "objc2-metal 0.3.1",
"parking",
"parking_lot",
"pathfinder_geometry",
@@ -7784,7 +7849,7 @@ name = "gpui_linux"
version = "0.1.0"
dependencies = [
"accesskit",
- "accesskit_unix",
+ "accesskit_unix 0.21.0",
"anyhow",
"as-raw-xcb-connection",
"ashpd",
@@ -7832,6 +7897,8 @@ dependencies = [
name = "gpui_macos"
version = "0.1.0"
dependencies = [
+ "accesskit",
+ "accesskit_macos",
"anyhow",
"async-task",
"block",
@@ -11390,6 +11457,22 @@ dependencies = [
"objc_id",
]
+[[package]]
+name = "objc-sys"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310"
+
+[[package]]
+name = "objc2"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804"
+dependencies = [
+ "objc-sys",
+ "objc2-encode",
+]
+
[[package]]
name = "objc2"
version = "0.6.3"
@@ -11399,6 +11482,22 @@ dependencies = [
"objc2-encode",
]
+[[package]]
+name = "objc2-app-kit"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff"
+dependencies = [
+ "bitflags 2.10.0",
+ "block2 0.5.1",
+ "libc",
+ "objc2 0.5.2",
+ "objc2-core-data",
+ "objc2-core-image",
+ "objc2-foundation 0.2.2",
+ "objc2-quartz-core",
+]
+
[[package]]
name = "objc2-audio-toolbox"
version = "0.3.1"
@@ -11407,11 +11506,11 @@ checksum = "10cbe18d879e20a4aea544f8befe38bcf52255eb63d3f23eca2842f3319e4c07"
dependencies = [
"bitflags 2.10.0",
"libc",
- "objc2",
+ "objc2 0.6.3",
"objc2-core-audio",
"objc2-core-audio-types",
"objc2-core-foundation",
- "objc2-foundation",
+ "objc2-foundation 0.3.1",
]
[[package]]
@@ -11420,8 +11519,8 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfc1d11521c211a7ebe17739fc806719da41f56c6b3f949d9861b459188ce910"
dependencies = [
- "objc2",
- "objc2-foundation",
+ "objc2 0.6.3",
+ "objc2-foundation 0.3.1",
]
[[package]]
@@ -11431,10 +11530,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca44961e888e19313b808f23497073e3f6b3c22bb485056674c8b49f3b025c82"
dependencies = [
"dispatch2",
- "objc2",
+ "objc2 0.6.3",
"objc2-core-audio-types",
"objc2-core-foundation",
- "objc2-foundation",
+ "objc2-foundation 0.3.1",
]
[[package]]
@@ -11444,7 +11543,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a89f2ec274a0cf4a32642b2991e8b351a404d290da87bb6a9a9d8632490bd1c"
dependencies = [
"bitflags 2.10.0",
- "objc2",
+ "objc2 0.6.3",
+]
+
+[[package]]
+name = "objc2-core-data"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef"
+dependencies = [
+ "bitflags 2.10.0",
+ "block2 0.5.1",
+ "objc2 0.5.2",
+ "objc2-foundation 0.2.2",
]
[[package]]
@@ -11454,10 +11565,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536"
dependencies = [
"bitflags 2.10.0",
- "block2",
+ "block2 0.6.2",
"dispatch2",
"libc",
- "objc2",
+ "objc2 0.6.3",
+]
+
+[[package]]
+name = "objc2-core-image"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80"
+dependencies = [
+ "block2 0.5.1",
+ "objc2 0.5.2",
+ "objc2-foundation 0.2.2",
+ "objc2-metal 0.2.2",
]
[[package]]
@@ -11466,6 +11589,18 @@ version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33"
+[[package]]
+name = "objc2-foundation"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
+dependencies = [
+ "bitflags 2.10.0",
+ "block2 0.5.1",
+ "libc",
+ "objc2 0.5.2",
+]
+
[[package]]
name = "objc2-foundation"
version = "0.3.1"
@@ -11473,9 +11608,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c"
dependencies = [
"bitflags 2.10.0",
- "block2",
+ "block2 0.6.2",
"libc",
- "objc2",
+ "objc2 0.6.3",
"objc2-core-foundation",
]
@@ -11489,6 +11624,18 @@ dependencies = [
"objc2-core-foundation",
]
+[[package]]
+name = "objc2-metal"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6"
+dependencies = [
+ "bitflags 2.10.0",
+ "block2 0.5.1",
+ "objc2 0.5.2",
+ "objc2-foundation 0.2.2",
+]
+
[[package]]
name = "objc2-metal"
version = "0.3.1"
@@ -11496,11 +11643,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f246c183239540aab1782457b35ab2040d4259175bd1d0c58e46ada7b47a874"
dependencies = [
"bitflags 2.10.0",
- "block2",
+ "block2 0.6.2",
"dispatch2",
- "objc2",
+ "objc2 0.6.3",
"objc2-core-foundation",
- "objc2-foundation",
+ "objc2-foundation 0.3.1",
+]
+
+[[package]]
+name = "objc2-quartz-core"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a"
+dependencies = [
+ "bitflags 2.10.0",
+ "block2 0.5.1",
+ "objc2 0.5.2",
+ "objc2-foundation 0.2.2",
+ "objc2-metal 0.2.2",
]
[[package]]
@@ -12633,6 +12793,17 @@ dependencies = [
"phf_shared 0.12.1",
]
+[[package]]
+name = "phf"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf"
+dependencies = [
+ "phf_macros 0.13.1",
+ "phf_shared 0.13.1",
+ "serde",
+]
+
[[package]]
name = "phf_codegen"
version = "0.11.3"
@@ -12663,6 +12834,16 @@ dependencies = [
"phf_shared 0.12.1",
]
+[[package]]
+name = "phf_generator"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737"
+dependencies = [
+ "fastrand 2.3.0",
+ "phf_shared 0.13.1",
+]
+
[[package]]
name = "phf_macros"
version = "0.11.3"
@@ -12689,6 +12870,19 @@ dependencies = [
"syn 2.0.117",
]
+[[package]]
+name = "phf_macros"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef"
+dependencies = [
+ "phf_generator 0.13.1",
+ "phf_shared 0.13.1",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+]
+
[[package]]
name = "phf_shared"
version = "0.11.3"
@@ -12707,6 +12901,15 @@ dependencies = [
"siphasher 1.0.1",
]
+[[package]]
+name = "phf_shared"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266"
+dependencies = [
+ "siphasher 1.0.1",
+]
+
[[package]]
name = "picker"
version = "0.1.0"
@@ -21927,7 +22130,7 @@ dependencies = [
name = "zed"
version = "0.229.0"
dependencies = [
- "accesskit_unix",
+ "accesskit_unix 0.20.0",
"acp_thread",
"acp_tools",
"action_log",
@@ -2,6 +2,7 @@ use crate::{
BoolExt, DisplayLink, MacDisplay, NSRange, NSStringExt, events::platform_input_from_native,
ns_string, renderer,
};
+use accesskit_macos::SubclassingAdapter;
#[cfg(any(test, feature = "test-support"))]
use anyhow::Result;
use block::ConcreteBlock;
@@ -113,11 +114,38 @@ unsafe extern "C" {
) -> i32;
}
+// todo! Apache license from accesskit_winit until end
+pub struct AdapterWrapper {
+ adapter: SubclassingAdapter,
+}
+
+impl AdapterWrapper {
+ pub unsafe fn new(
+ window: *mut c_void,
+ activation_handler: impl 'static + accesskit::ActivationHandler,
+ action_handler: impl 'static + accesskit::ActionHandler,
+ ) -> Self {
+ let adapter = unsafe { SubclassingAdapter::for_window(window, activation_handler, action_handler) };
+ Self { adapter }
+ }
+
+ pub fn update_if_active(&mut self, updater: impl FnOnce() -> accesskit::TreeUpdate) {
+ if let Some(events) = self.adapter.update_if_active(updater) {
+ events.raise();
+ }
+ }
+}
+// todo! end
+
#[ctor]
unsafe fn build_classes() {
unsafe {
WINDOW_CLASS = build_window_class("GPUIWindow", class!(NSWindow));
PANEL_CLASS = build_window_class("GPUIPanel", class!(NSPanel));
+
+ accesskit_macos::add_focus_forwarder_to_window_class("GPUIWindow");
+ accesskit_macos::add_focus_forwarder_to_window_class("GPUIPanel");
+
VIEW_CLASS = {
let mut decl = ClassDecl::new("GPUIView", class!(NSView)).unwrap();
decl.add_ivar::<*mut c_void>(WINDOW_STATE_IVAR);
@@ -442,6 +470,7 @@ struct MacWindowState {
activated_least_once: bool,
// The parent window if this window is a sheet (Dialog kind)
sheet_parent: Option<id>,
+ accesskit: Option<AdapterWrapper>,
}
impl MacWindowState {
@@ -765,6 +794,7 @@ impl MacWindow {
toggle_tab_bar_callback: None,
activated_least_once: false,
sheet_parent: None,
+ accesskit: None,
})));
(*native_window).set_ivar(
@@ -1636,6 +1666,54 @@ impl PlatformWindow for MacWindow {
let mut this = self.0.lock();
this.renderer.render_to_image(scene)
}
+
+ fn a11y_init(&self, callbacks: gpui::A11yCallbacks) {
+ let mut state = self.0.lock();
+
+ if state.accesskit.is_some() {
+ panic!("cannot initialize accesskit twice");
+ }
+
+ // dbg!(state.native_window);
+ let window = state.native_window as *mut c_void;
+ // let native_view = state.native_view.as_ptr();
+ // unsafe {
+ // eprintln!(
+ // "[a11y] native_view class: {}",
+ // (*native_view).class().name()
+ // )
+ // };
+
+ let adapter = unsafe { AdapterWrapper::new(window, callbacks.activation, callbacks.action) };
+
+ unsafe {
+ let content_view: id = msg_send![state.native_window, contentView];
+ let class = (*content_view).class();
+ eprintln!(
+ "[a11y debug] Content view class after adapter: {}",
+ class.name()
+ );
+ }
+ state.accesskit = Some(adapter);
+ }
+
+ fn a11y_tree_update(&mut self, tree_update: accesskit::TreeUpdate) {
+ let mut state = self.0.lock();
+
+ let Some(adapter) = &mut state.accesskit else {
+ panic!("cannot update accesskit tree - not initialized");
+ };
+
+ adapter.update_if_active(|| tree_update);
+ }
+
+ fn a11y_update_window_bounds(&self) {
+ // todo! figure this out
+ }
+
+ fn is_a11y_active(&self) -> bool {
+ true
+ }
}
impl rwh::HasWindowHandle for MacWindow {