diff --git a/bindings/c/cbindgen.toml b/bindings/c/cbindgen.toml index b5357f27..84d02fb4 100644 --- a/bindings/c/cbindgen.toml +++ b/bindings/c/cbindgen.toml @@ -15,7 +15,7 @@ after_includes = """#ifdef _WIN32 usize_is_size_t = true [export] -include = ["Size", "tree_update", "Vec2"] +include = ["Size", "Vec2"] prefix = "accesskit_" renaming_overrides_prefixing = true diff --git a/bindings/c/examples/windows/hello_world.c b/bindings/c/examples/windows/hello_world.c index 25e4e1b4..3ff90fd2 100644 --- a/bindings/c/examples/windows/hello_world.c +++ b/bindings/c/examples/windows/hello_world.c @@ -79,13 +79,11 @@ void window_state_free(struct window_state *state) { free(state); } -accesskit_opt_node_id window_state_focus(struct window_state *state) { - accesskit_opt_node_id result; - result.has_value = state->is_window_focused; - if (result.has_value) { - result.value = state->focus; +void window_state_set_tree_update_focus(struct window_state *state, + accesskit_tree_update *update) { + if (state->is_window_focused) { + accesskit_tree_update_set_focus(update, state->focus); } - return result; } accesskit_node *window_state_build_root(struct window_state *state) { @@ -106,21 +104,17 @@ accesskit_tree_update *window_state_build_initial_tree( build_button(BUTTON_1_ID, "Button 1", state->node_classes); accesskit_node *button_2 = build_button(BUTTON_2_ID, "Button 2", state->node_classes); - accesskit_tree_update *result = - accesskit_tree_update_new((state->announcement != NULL) ? 4 : 3); - result->tree.has_value = true; - result->tree.value = accesskit_tree_new(WINDOW_ID); - result->focus = window_state_focus(state); - result->ids[0] = WINDOW_ID; - result->nodes[0] = root; - result->ids[1] = BUTTON_1_ID; - result->nodes[1] = button_1; - result->ids[2] = BUTTON_2_ID; - result->nodes[2] = button_2; + accesskit_tree_update *result = accesskit_tree_update_with_capacity( + (state->announcement != NULL) ? 4 : 3); + accesskit_tree_update_set_tree(result, accesskit_tree_new(WINDOW_ID)); + window_state_set_tree_update_focus(state, result); + accesskit_tree_update_push_node(result, WINDOW_ID, root); + accesskit_tree_update_push_node(result, BUTTON_1_ID, button_1); + accesskit_tree_update_push_node(result, BUTTON_2_ID, button_2); if (state->announcement != NULL) { - result->ids[3] = ANNOUNCEMENT_ID; - result->nodes[3] = + accesskit_node *announcement = build_announcement(state->announcement, state->node_classes); + accesskit_tree_update_push_node(result, ANNOUNCEMENT_ID, announcement); } return result; } @@ -165,12 +159,10 @@ void window_state_press_button(struct window_state *state, accesskit_node *announcement = build_announcement(text, state->node_classes); accesskit_node *root = window_state_build_root(state); - accesskit_tree_update *update = accesskit_tree_update_new(2); - update->ids[0] = ANNOUNCEMENT_ID; - update->nodes[0] = announcement; - update->ids[1] = WINDOW_ID; - update->nodes[1] = root; - update->focus = window_state_focus(state); + accesskit_tree_update *update = accesskit_tree_update_with_capacity(2); + accesskit_tree_update_push_node(update, ANNOUNCEMENT_ID, announcement); + accesskit_tree_update_push_node(update, WINDOW_ID, root); + window_state_set_tree_update_focus(state, update); accesskit_windows_queued_events *events = accesskit_windows_adapter_update(state->adapter, update); accesskit_windows_queued_events_raise(events); @@ -184,10 +176,9 @@ struct window_state *get_window_state(HWND window) { void update_focus(HWND window, bool is_window_focused) { struct window_state *state = get_window_state(window); state->is_window_focused = is_window_focused; - accesskit_opt_node_id focus = window_state_focus(state); if (state->adapter != NULL) { - accesskit_tree_update *update = accesskit_tree_update_new(0); - update->focus = focus; + accesskit_tree_update *update = accesskit_tree_update_new(); + window_state_set_tree_update_focus(state, update); accesskit_windows_queued_events *events = accesskit_windows_adapter_update(state->adapter, update); accesskit_windows_queued_events_raise(events); diff --git a/bindings/c/src/common.rs b/bindings/c/src/common.rs index af0ab25f..c8048eb8 100644 --- a/bindings/c/src/common.rs +++ b/bindings/c/src/common.rs @@ -911,8 +911,6 @@ impl tree { } } -opt_struct! { opt_tree, tree } - impl From for Tree { fn from(tree: tree) -> Self { Self { @@ -922,65 +920,72 @@ impl From for Tree { } } -/// Use `accesskit_tree_update_new` to create this struct. Do not reallocate `ids` and `nodes`. -#[repr(C)] pub struct tree_update { - pub node_count: usize, - pub ids: *mut node_id, - pub nodes: *mut *mut node, - pub tree: opt_tree, - pub focus: opt_node_id, + _private: [u8; 0], } impl CastPtr for tree_update { - type RustType = tree_update; + type RustType = TreeUpdate; } impl BoxCastPtr for tree_update {} impl tree_update { #[no_mangle] - pub extern "C" fn accesskit_tree_update_new(node_count: usize) -> *mut tree_update { - let mut ids = Vec::with_capacity(node_count); - let mut nodes = Vec::with_capacity(node_count); - let update = tree_update { - node_count, - ids: ids.as_mut_ptr(), - nodes: nodes.as_mut_ptr(), - tree: opt_tree::default(), - focus: opt_node_id::default(), + pub extern "C" fn accesskit_tree_update_new() -> *mut tree_update { + let update = TreeUpdate::default(); + BoxCastPtr::to_mut_ptr(update) + } + + #[no_mangle] + pub extern "C" fn accesskit_tree_update_with_capacity(capacity: usize) -> *mut tree_update { + let update = TreeUpdate { + nodes: Vec::with_capacity(capacity), + ..Default::default() }; - mem::forget(ids); - mem::forget(nodes); BoxCastPtr::to_mut_ptr(update) } #[no_mangle] pub extern "C" fn accesskit_tree_update_free(update: *mut tree_update) { - drop(TreeUpdate::from(box_from_ptr(update))); + drop(box_from_ptr(update)); } -} -impl From> for TreeUpdate { - fn from(update: Box) -> Self { - let ids = unsafe { - Vec::from_raw_parts( - update.ids as *mut NodeId, - update.node_count, - update.node_count, - ) - }; - let nodes = - unsafe { Vec::from_raw_parts(update.nodes, update.node_count, update.node_count) }; - Self { - nodes: ids - .into_iter() - .zip(nodes.into_iter().map(box_from_ptr)) - .map(|(id, node)| (id, *node)) - .collect::>(), - tree: update.tree.into(), - focus: update.focus.into(), - } + /// Appends the provided node to the tree update's list of nodes. + /// Takes ownership of `node`. + #[no_mangle] + pub extern "C" fn accesskit_tree_update_push_node( + update: *mut tree_update, + id: node_id, + node: *mut node, + ) { + let update = mut_from_ptr(update); + let node = box_from_ptr(node); + update.nodes.push((id.into(), *node)); + } + + #[no_mangle] + pub extern "C" fn accesskit_tree_update_set_tree(update: *mut tree_update, tree: tree) { + let update = mut_from_ptr(update); + update.tree = Some(tree.into()); + } + + #[no_mangle] + pub extern "C" fn accesskit_tree_update_clear_tree(update: *mut tree_update) { + let update = mut_from_ptr(update); + update.tree = None; + } + + #[no_mangle] + pub extern "C" fn accesskit_tree_update_set_focus(update: *mut tree_update, focus: node_id) { + let update = mut_from_ptr(update); + update.focus = Some(focus.into()); + } + + #[no_mangle] + pub extern "C" fn accesskit_tree_update_clear_focus(update: *mut tree_update) { + let update = mut_from_ptr(update); + update.focus = None; } } diff --git a/bindings/c/src/macos.rs b/bindings/c/src/macos.rs index d9bfd4ae..0e778562 100644 --- a/bindings/c/src/macos.rs +++ b/bindings/c/src/macos.rs @@ -53,7 +53,7 @@ impl macos_adapter { ) -> *mut macos_adapter { let initial_state = box_from_ptr(initial_state); let handler = box_from_ptr(handler); - let adapter = Adapter::new(view, initial_state.into(), handler); + let adapter = Adapter::new(view, *initial_state, handler); BoxCastPtr::to_mut_ptr(adapter) } @@ -71,7 +71,7 @@ impl macos_adapter { ) -> *mut macos_queued_events { let adapter = ref_from_ptr(adapter); let update = box_from_ptr(update); - let events = adapter.update(update.into()); + let events = adapter.update(*update); BoxCastPtr::to_mut_ptr(events) } @@ -130,7 +130,7 @@ impl macos_subclassing_adapter { let handler = box_from_ptr(handler); let adapter = SubclassingAdapter::new( view, - move || box_from_ptr(source(source_userdata)).into(), + move || *box_from_ptr(source(source_userdata)), handler, ); BoxCastPtr::to_mut_ptr(adapter) @@ -157,7 +157,7 @@ impl macos_subclassing_adapter { let handler = box_from_ptr(handler); let adapter = SubclassingAdapter::for_window( window, - move || box_from_ptr(source(source_userdata)).into(), + move || *box_from_ptr(source(source_userdata)), handler, ); BoxCastPtr::to_mut_ptr(adapter) @@ -179,7 +179,7 @@ impl macos_subclassing_adapter { ) -> *mut macos_queued_events { let adapter = ref_from_ptr(adapter); let update = box_from_ptr(update); - let events = adapter.update(update.into()); + let events = adapter.update(*update); BoxCastPtr::to_mut_ptr(events) } @@ -192,8 +192,8 @@ impl macos_subclassing_adapter { ) -> *mut macos_queued_events { let update_factory = update_factory.unwrap(); let adapter = ref_from_ptr(adapter); - let events = adapter - .update_if_active(|| box_from_ptr(update_factory(update_factory_userdata)).into()); + let events = + adapter.update_if_active(|| *box_from_ptr(update_factory(update_factory_userdata))); match events { Some(events) => BoxCastPtr::to_mut_ptr(events), None => ptr::null_mut(), diff --git a/bindings/c/src/unix.rs b/bindings/c/src/unix.rs index 783f26fb..74df45a4 100644 --- a/bindings/c/src/unix.rs +++ b/bindings/c/src/unix.rs @@ -43,7 +43,7 @@ impl unix_adapter { app_name, toolkit_name, toolkit_version, - move || box_from_ptr(initial_state(initial_state_userdata)).into(), + move || *box_from_ptr(initial_state(initial_state_userdata)), handler, ); adapter.map_or_else(ptr::null_mut, BoxCastPtr::to_mut_ptr) @@ -72,6 +72,6 @@ impl unix_adapter { ) { let adapter = ref_from_ptr(adapter); let update = box_from_ptr(update); - adapter.update(update.into()); + adapter.update(*update); } } diff --git a/bindings/c/src/windows.rs b/bindings/c/src/windows.rs index 32f6a510..3b376263 100644 --- a/bindings/c/src/windows.rs +++ b/bindings/c/src/windows.rs @@ -77,7 +77,7 @@ impl windows_adapter { let initial_state = box_from_ptr(initial_state); let handler = box_from_ptr(handler); let uia_init_marker = *box_from_ptr(uia_init_marker); - let adapter = Adapter::new(hwnd, initial_state.into(), handler, uia_init_marker); + let adapter = Adapter::new(hwnd, *initial_state, handler, uia_init_marker); BoxCastPtr::to_mut_ptr(adapter) } @@ -95,7 +95,7 @@ impl windows_adapter { ) -> *mut windows_queued_events { let adapter = ref_from_ptr(adapter); let update = box_from_ptr(update); - let events = adapter.update(update.into()); + let events = adapter.update(*update); BoxCastPtr::to_mut_ptr(events) } @@ -134,7 +134,7 @@ impl windows_subclassing_adapter { let handler = box_from_ptr(handler); let adapter = SubclassingAdapter::new( hwnd, - move || box_from_ptr(source(source_userdata)).into(), + move || *box_from_ptr(source(source_userdata)), handler, ); BoxCastPtr::to_mut_ptr(adapter) @@ -156,7 +156,7 @@ impl windows_subclassing_adapter { ) -> *mut windows_queued_events { let adapter = ref_from_ptr(adapter); let update = box_from_ptr(update); - let events = adapter.update(update.into()); + let events = adapter.update(*update); BoxCastPtr::to_mut_ptr(events) } @@ -169,8 +169,8 @@ impl windows_subclassing_adapter { ) -> *mut windows_queued_events { let update_factory = update_factory.unwrap(); let adapter = ref_from_ptr(adapter); - let events = adapter - .update_if_active(|| box_from_ptr(update_factory(update_factory_userdata)).into()); + let events = + adapter.update_if_active(|| *box_from_ptr(update_factory(update_factory_userdata))); match events { Some(events) => BoxCastPtr::to_mut_ptr(events), None => ptr::null_mut(),