diff --git a/Cargo.lock b/Cargo.lock index aee470eed..98da8f585 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -79,9 +79,9 @@ dependencies = [ "accesskit", "accesskit_consumer", "hashbrown", - "objc2 0.5.2", - "objc2-app-kit", - "objc2-foundation 0.2.2", + "objc2 0.6.4", + "objc2-app-kit 0.3.2", + "objc2-foundation 0.3.2", ] [[package]] @@ -434,6 +434,15 @@ 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 0.6.4", +] + [[package]] name = "blocking" version = "1.6.1" @@ -1149,15 +1158,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ "bitflags 2.8.0", - "block2", + "block2 0.5.1", "libc", "objc2 0.5.2", - "objc2-core-data", - "objc2-core-image", + "objc2-core-data 0.2.2", + "objc2-core-image 0.2.2", "objc2-foundation 0.2.2", "objc2-quartz-core 0.2.2", ] +[[package]] +name = "objc2-app-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" +dependencies = [ + "bitflags 2.8.0", + "block2 0.6.2", + "libc", + "objc2 0.6.4", + "objc2-cloud-kit 0.3.2", + "objc2-core-data 0.3.2", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-core-image 0.3.2", + "objc2-core-text", + "objc2-core-video", + "objc2-foundation 0.3.2", + "objc2-quartz-core 0.3.2", +] + [[package]] name = "objc2-cloud-kit" version = "0.2.2" @@ -1165,19 +1195,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" dependencies = [ "bitflags 2.8.0", - "block2", + "block2 0.5.1", "objc2 0.5.2", "objc2-core-location", "objc2-foundation 0.2.2", ] +[[package]] +name = "objc2-cloud-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" +dependencies = [ + "bitflags 2.8.0", + "objc2 0.6.4", + "objc2-foundation 0.3.2", +] + [[package]] name = "objc2-contacts" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" dependencies = [ - "block2", + "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", ] @@ -1189,11 +1230,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ "bitflags 2.8.0", - "block2", + "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", ] +[[package]] +name = "objc2-core-data" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa" +dependencies = [ + "bitflags 2.8.0", + "objc2 0.6.4", + "objc2-foundation 0.3.2", +] + [[package]] name = "objc2-core-foundation" version = "0.3.2" @@ -1224,24 +1276,59 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" dependencies = [ - "block2", + "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", "objc2-metal", ] +[[package]] +name = "objc2-core-image" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d563b38d2b97209f8e861173de434bd0214cf020e3423a52624cd1d989f006" +dependencies = [ + "objc2 0.6.4", + "objc2-foundation 0.3.2", +] + [[package]] name = "objc2-core-location" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" dependencies = [ - "block2", + "block2 0.5.1", "objc2 0.5.2", "objc2-contacts", "objc2-foundation 0.2.2", ] +[[package]] +name = "objc2-core-text" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" +dependencies = [ + "bitflags 2.8.0", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-core-graphics", +] + +[[package]] +name = "objc2-core-video" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d425caf1df73233f29fd8a5c3e5edbc30d2d4307870f802d18f00d83dc5141a6" +dependencies = [ + "bitflags 2.8.0", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-io-surface", +] + [[package]] name = "objc2-encode" version = "4.1.0" @@ -1255,7 +1342,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ "bitflags 2.8.0", - "block2", + "block2 0.5.1", "dispatch", "libc", "objc2 0.5.2", @@ -1268,6 +1355,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ "bitflags 2.8.0", + "block2 0.6.2", + "libc", "objc2 0.6.4", "objc2-core-foundation", ] @@ -1289,9 +1378,9 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" dependencies = [ - "block2", + "block2 0.5.1", "objc2 0.5.2", - "objc2-app-kit", + "objc2-app-kit 0.2.2", "objc2-foundation 0.2.2", ] @@ -1302,7 +1391,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ "bitflags 2.8.0", - "block2", + "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", ] @@ -1314,7 +1403,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ "bitflags 2.8.0", - "block2", + "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", "objc2-metal", @@ -1349,11 +1438,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" dependencies = [ "bitflags 2.8.0", - "block2", + "block2 0.5.1", "objc2 0.5.2", - "objc2-cloud-kit", - "objc2-core-data", - "objc2-core-image", + "objc2-cloud-kit 0.2.2", + "objc2-core-data 0.2.2", + "objc2-core-image 0.2.2", "objc2-core-location", "objc2-foundation 0.2.2", "objc2-link-presentation", @@ -1369,7 +1458,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" dependencies = [ - "block2", + "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", ] @@ -1381,7 +1470,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" dependencies = [ "bitflags 2.8.0", - "block2", + "block2 0.5.1", "objc2 0.5.2", "objc2-core-location", "objc2-foundation 0.2.2", @@ -2830,7 +2919,7 @@ dependencies = [ "android-activity", "atomic-waker", "bitflags 2.8.0", - "block2", + "block2 0.5.1", "bytemuck", "calloop", "cfg_aliases", @@ -2844,7 +2933,7 @@ dependencies = [ "memmap2", "ndk", "objc2 0.5.2", - "objc2-app-kit", + "objc2-app-kit 0.2.2", "objc2-foundation 0.2.2", "objc2-ui-kit", "orbclient", diff --git a/adapters/macos/Cargo.toml b/adapters/macos/Cargo.toml index 73ca74a01..48bb1f87d 100644 --- a/adapters/macos/Cargo.toml +++ b/adapters/macos/Cargo.toml @@ -18,14 +18,14 @@ default-target = "x86_64-apple-darwin" accesskit = { version = "0.24.1", path = "../../accesskit" } accesskit_consumer = { version = "0.38.0", path = "../../accesskit_consumer" } hashbrown.workspace = true -objc2 = "0.5.1" -objc2-foundation = { version = "0.2.0", features = [ +objc2 = "0.6.2" +objc2-foundation = { version = "0.3.1", features = [ "NSArray", "NSDictionary", "NSValue", "NSThread", ] } -objc2-app-kit = { version = "0.2.0", features = [ +objc2-app-kit = { version = "0.3.1", features = [ "NSAccessibility", "NSAccessibilityConstants", "NSAccessibilityElement", diff --git a/adapters/macos/src/adapter.rs b/adapters/macos/src/adapter.rs index 86b4b0073..e7c6a0c6b 100644 --- a/adapters/macos/src/adapter.rs +++ b/adapters/macos/src/adapter.rs @@ -15,7 +15,7 @@ use accesskit::{ TreeUpdate, }; use accesskit_consumer::{FilterResult, Tree}; -use objc2::rc::{Id, WeakId}; +use objc2::rc::{Retained, Weak}; use objc2_app_kit::NSView; use objc2_foundation::{MainThreadMarker, NSArray, NSObject, NSPoint}; use std::fmt::{Debug, Formatter}; @@ -25,7 +25,7 @@ const PLACEHOLDER_ROOT_ID: NodeId = NodeId(0); enum State { Inactive { - view: WeakId, + view: Weak, is_view_focused: bool, action_handler: Rc, mtm: MainThreadMarker, @@ -91,8 +91,8 @@ impl Adapter { is_view_focused: bool, action_handler: impl 'static + ActionHandler, ) -> Self { - let view = unsafe { Id::retain(view as *mut NSView) }.unwrap(); - let view = WeakId::from_id(&view); + let view = unsafe { Retained::retain(view as *mut NSView) }.unwrap(); + let view = Weak::from_retained(&view); let mtm = MainThreadMarker::new().unwrap(); let state = State::Inactive { view, @@ -229,20 +229,20 @@ impl Adapter { let state = tree.state(); let node = state.root(); let platform_nodes = if filter(&node) == FilterResult::Include { - vec![Id::into_super(Id::into_super( + vec![Retained::into_super(Retained::into_super( context.get_or_create_platform_node(node.id()), ))] } else { node.filtered_children(filter) .map(|node| { - Id::into_super(Id::into_super( + Retained::into_super(Retained::into_super( context.get_or_create_platform_node(node.id()), )) }) - .collect::>>() + .collect::>>() }; - let array = NSArray::from_vec(platform_nodes); - Id::autorelease_return(array) + let array = NSArray::from_retained_slice(&platform_nodes); + Retained::autorelease_return(array) } pub fn focus( @@ -254,14 +254,14 @@ impl Adapter { let state = tree.state(); if let Some(node) = state.focus() { if can_be_focused(&node) { - return Id::autorelease_return(context.get_or_create_platform_node(node.id())) + return Retained::autorelease_return(context.get_or_create_platform_node(node.id())) as *mut _; } } null_mut() } - fn weak_view(&self) -> &WeakId { + fn weak_view(&self) -> &Weak { match &self.state { State::Inactive { view, .. } => view, State::Placeholder { @@ -290,6 +290,6 @@ impl Adapter { let root = state.root(); let point = from_ns_point(&view, &root, point); let node = root.node_at_point(point, &filter).unwrap_or(root); - Id::autorelease_return(context.get_or_create_platform_node(node.id())) as *mut _ + Retained::autorelease_return(context.get_or_create_platform_node(node.id())) as *mut _ } } diff --git a/adapters/macos/src/context.rs b/adapters/macos/src/context.rs index fe2f10006..7e7b2b7cd 100644 --- a/adapters/macos/src/context.rs +++ b/adapters/macos/src/context.rs @@ -7,7 +7,7 @@ use crate::node::PlatformNode; use accesskit::{ActionHandler, ActionRequest}; use accesskit_consumer::{FullNodeId, Tree}; use hashbrown::HashMap; -use objc2::rc::{Id, WeakId}; +use objc2::rc::{Retained, Weak}; use objc2_app_kit::*; use objc2_foundation::MainThreadMarker; use std::fmt::Debug; @@ -32,10 +32,10 @@ impl ActionHandlerNoMut for ActionHandlerWrapper { } pub(crate) struct Context { - pub(crate) view: WeakId, + pub(crate) view: Weak, pub(crate) tree: RefCell, pub(crate) action_handler: Rc, - platform_nodes: RefCell>>, + platform_nodes: RefCell>>, pub(crate) mtm: MainThreadMarker, } @@ -53,7 +53,7 @@ impl Debug for Context { impl Context { pub(crate) fn new( - view: WeakId, + view: Weak, tree: Tree, action_handler: Rc, mtm: MainThreadMarker, @@ -67,7 +67,10 @@ impl Context { }) } - pub(crate) fn get_or_create_platform_node(self: &Rc, id: FullNodeId) -> Id { + pub(crate) fn get_or_create_platform_node( + self: &Rc, + id: FullNodeId, + ) -> Retained { let mut platform_nodes = self.platform_nodes.borrow_mut(); if let Some(result) = platform_nodes.get(&id) { return result.clone(); @@ -78,7 +81,7 @@ impl Context { result } - pub(crate) fn remove_platform_node(&self, id: FullNodeId) -> Option> { + pub(crate) fn remove_platform_node(&self, id: FullNodeId) -> Option> { let mut platform_nodes = self.platform_nodes.borrow_mut(); platform_nodes.remove(&id) } diff --git a/adapters/macos/src/event.rs b/adapters/macos/src/event.rs index fa0bddcc9..70b13c36c 100644 --- a/adapters/macos/src/event.rs +++ b/adapters/macos/src/event.rs @@ -36,9 +36,9 @@ impl QueuedEvent { Self::Announcement { text: node.value().unwrap(), priority: if node.live() == Live::Assertive { - NSAccessibilityPriorityLevel::NSAccessibilityPriorityHigh + NSAccessibilityPriorityLevel::High } else { - NSAccessibilityPriorityLevel::NSAccessibilityPriorityMedium + NSAccessibilityPriorityLevel::Medium }, } } @@ -77,7 +77,7 @@ impl QueuedEvent { } }; - let mut user_info = NSMutableDictionary::<_, AnyObject>::new(); + let user_info = NSMutableDictionary::<_, AnyObject>::new(); let text = NSString::from_str(&text); unsafe { user_info.setObject_forKey( diff --git a/adapters/macos/src/node.rs b/adapters/macos/src/node.rs index d07ba50b5..d62ef767d 100644 --- a/adapters/macos/src/node.rs +++ b/adapters/macos/src/node.rs @@ -15,17 +15,16 @@ use accesskit::{ }; use accesskit_consumer::{FilterResult, FullNodeId, NodeRef, Tree}; use objc2::{ - ClassType, DeclaredClass, declare_class, msg_send_id, - mutability::InteriorMutable, - rc::Id, + AnyThread, DeclaredClass, define_class, msg_send, + rc::Retained, runtime::{AnyObject, Sel}, sel, }; use objc2_app_kit::*; use objc2_foundation::{ - NSArray, NSAttributedString, NSCopying, NSInteger, NSMutableAttributedString, - NSMutableDictionary, NSNumber, NSObject, NSObjectProtocol, NSPoint, NSRange, NSRect, NSString, - NSURL, ns_string, + NSArray, NSAttributedString, NSAttributedStringKey, NSCopying, NSInteger, + NSMutableAttributedString, NSMutableDictionary, NSNumber, NSObject, NSPoint, NSRange, NSRect, + NSString, NSURL, ns_string, }; use std::rc::{Rc, Weak}; @@ -355,84 +354,71 @@ impl NodeWrapper<'_> { } } -// derived from objc2 0.6 `AnyObject::downcast_ref` -// TODO: can be removed after updating objc2 to 0.6 which has `AnyObject::downcast_ref` -fn downcast_ref(obj: &NSObject) -> Option<&T> { - obj.is_kind_of::() - .then(|| unsafe { &*(obj as *const NSObject).cast::() }) -} - +#[derive(Debug)] pub(crate) struct PlatformNodeIvars { context: Weak, node_id: FullNodeId, } -declare_class!( +define_class!( + #[unsafe(super(NSAccessibilityElement))] + #[derive(Debug)] + #[ivars = PlatformNodeIvars] + #[name = "AccessKitNode"] pub(crate) struct PlatformNode; - unsafe impl ClassType for PlatformNode { - #[inherits(NSObject)] - type Super = NSAccessibilityElement; - type Mutability = InteriorMutable; - const NAME: &'static str = "AccessKitNode"; - } - - impl DeclaredClass for PlatformNode { - type Ivars = PlatformNodeIvars; - } - - unsafe impl PlatformNode { - #[method_id(accessibilityParent)] - fn parent(&self) -> Option> { + impl PlatformNode { + #[unsafe(method_id(accessibilityParent))] + fn parent(&self) -> Option> { self.resolve_with_context(|node, _, context| { if let Some(parent) = node.filtered_parent(&filter) { - Some(Id::into_super(Id::into_super(Id::into_super(context.get_or_create_platform_node(parent.id()))))) + Some(Retained::into_super(Retained::into_super(Retained::into_super(context.get_or_create_platform_node(parent.id()))))) } else { context .view .load() - .and_then(|view| unsafe { NSAccessibility::accessibilityParent(&*view) }) + .and_then(|view| NSAccessibility::accessibilityParent(&*view)) } }) .flatten() } - #[method_id(accessibilityWindow)] - fn window(&self) -> Option> { + #[unsafe(method_id(accessibilityWindow))] + fn window(&self) -> Option> { self.resolve_with_context(|_, _, context| { context .view .load() - .and_then(|view| unsafe { NSAccessibility::accessibilityParent(&*view) }) + .and_then(|view| NSAccessibility::accessibilityParent(&*view)) }) .flatten() } - #[method_id(accessibilityTopLevelUIElement)] - fn top_level(&self) -> Option> { + #[unsafe(method_id(accessibilityTopLevelUIElement))] + fn top_level(&self) -> Option> { self.resolve_with_context(|_, _, context| { context .view .load() - .and_then(|view| unsafe { NSAccessibility::accessibilityParent(&*view) }) + .and_then(|view| NSAccessibility::accessibilityParent(&*view)) }) .flatten() } - #[method_id(accessibilityChildren)] - fn children(&self) -> Option>> { + #[unsafe(method_id(accessibilityChildren))] + fn children(&self) -> Option>> { self.children_internal() } - #[method_id(accessibilityChildrenInNavigationOrder)] - fn children_in_navigation_order(&self) -> Option>> { + #[unsafe(method_id(accessibilityChildrenInNavigationOrder))] + fn children_in_navigation_order(&self) -> Option>> { // For now, we assume the children are in navigation order. self.children_internal() } - #[method_id(accessibilitySelectedChildren)] - fn selected_children(&self) -> Option>> { + #[unsafe(method_id(accessibilitySelectedChildren))] + fn selected_children(&self) -> Option>> { self.resolve_with_context(|node, _, context| { let wrapper = NodeWrapper(node); if !wrapper.is_container_with_selectable_children() { @@ -442,13 +428,13 @@ declare_class!( .items(filter) .filter(|item| item.is_selected() == Some(true)) .map(|child| context.get_or_create_platform_node(child.id())) - .collect::>>(); - Some(NSArray::from_vec(platform_nodes)) + .collect::>>(); + Some(NSArray::from_retained_slice(&platform_nodes)) }) .flatten() } - #[method(accessibilityFrame)] + #[unsafe(method(accessibilityFrame))] fn frame(&self) -> NSRect { self.resolve_with_context(|node, _, context| { let view = match context.view.load() { @@ -461,7 +447,7 @@ declare_class!( node.bounding_box().map_or_else( || { if node.is_root() { - unsafe { NSAccessibility::accessibilityFrame(&*view) } + NSAccessibility::accessibilityFrame(&*view) } else { NSRect::ZERO } @@ -472,42 +458,42 @@ declare_class!( .unwrap_or(NSRect::ZERO) } - #[method_id(accessibilityRole)] - fn role(&self) -> Id { + #[unsafe(method_id(accessibilityRole))] + fn role(&self) -> Retained { self.resolve(ns_role) .unwrap_or(unsafe { NSAccessibilityUnknownRole }) .copy() } - #[method_id(accessibilitySubrole)] - fn sub_role(&self) -> Id { + #[unsafe(method_id(accessibilitySubrole))] + fn sub_role(&self) -> Retained { self.resolve(ns_sub_role) .unwrap_or(unsafe { NSAccessibilityUnknownSubrole }) .copy() } - #[method_id(accessibilityRoleDescription)] - fn role_description(&self) -> Option> { + #[unsafe(method_id(accessibilityRoleDescription))] + fn role_description(&self) -> Option> { self.resolve(|node| { if let Some(role_description) = node.role_description() { Some(NSString::from_str(role_description)) } else { - unsafe { msg_send_id![super(self), accessibilityRoleDescription] } + unsafe { msg_send![super(self), accessibilityRoleDescription] } } }) .flatten() } - #[method_id(accessibilityIdentifier)] - fn identifier(&self) -> Option> { + #[unsafe(method_id(accessibilityIdentifier))] + fn identifier(&self) -> Option> { self.resolve(|node| { node.author_id().map(NSString::from_str) }) .flatten() } - #[method_id(accessibilityTitle)] - fn title(&self) -> Option> { + #[unsafe(method_id(accessibilityTitle))] + fn title(&self) -> Option> { self.resolve(|node| { let wrapper = NodeWrapper(node); wrapper.title().map(|title| NSString::from_str(&title)) @@ -515,8 +501,8 @@ declare_class!( .flatten() } - #[method_id(accessibilityHelp)] - fn description(&self) -> Option> { + #[unsafe(method_id(accessibilityHelp))] + fn description(&self) -> Option> { self.resolve(|node| { let wrapper = NodeWrapper(node); wrapper.description().map(|description| NSString::from_str(&description)) @@ -524,8 +510,8 @@ declare_class!( .flatten() } - #[method_id(accessibilityPlaceholderValue)] - fn placeholder(&self) -> Option> { + #[unsafe(method_id(accessibilityPlaceholderValue))] + fn placeholder(&self) -> Option> { self.resolve(|node| { let wrapper = NodeWrapper(node); wrapper.placeholder().map(NSString::from_str) @@ -533,28 +519,28 @@ declare_class!( .flatten() } - #[method_id(accessibilityValue)] - fn value(&self) -> Option> { + #[unsafe(method_id(accessibilityValue))] + fn value(&self) -> Option> { self.resolve(|node| { let wrapper = NodeWrapper(node); wrapper.value().map(|value| match value { Value::Bool(value) => { - Id::into_super(Id::into_super(NSNumber::new_bool(value))) + Retained::into_super(Retained::into_super(NSNumber::new_bool(value))) } Value::Number(value) => { - Id::into_super(Id::into_super(NSNumber::new_f64(value))) + Retained::into_super(Retained::into_super(NSNumber::new_f64(value))) } Value::String(value) => { - Id::into_super(NSString::from_str(&value)) + Retained::into_super(NSString::from_str(&value)) } }) }) .flatten() } - #[method(setAccessibilityValue:)] + #[unsafe(method(setAccessibilityValue:))] fn set_value(&self, value: &NSObject) { - if let Some(string) = downcast_ref::(value) { + if let Some(string) = value.downcast_ref::() { self.resolve_with_context(|node, tree, context| { if let Some((target_node, target_tree)) = tree.state().locate_node(node.id()) { context.do_action(ActionRequest { @@ -565,7 +551,7 @@ declare_class!( }); } }); - } else if let Some(number) = downcast_ref::(value) { + } else if let Some(number) = value.downcast_ref::() { self.resolve_with_context(|node, tree, context| { if let Some((target_node, target_tree)) = tree.state().locate_node(node.id()) { context.do_action(ActionRequest { @@ -579,34 +565,35 @@ declare_class!( } } - #[method_id(accessibilityMinValue)] - fn min_value(&self) -> Option> { + #[unsafe(method_id(accessibilityMinValue))] + fn min_value(&self) -> Option> { self.resolve(|node| { node.min_numeric_value().map(NSNumber::new_f64) }) .flatten() } - #[method_id(accessibilityMaxValue)] - fn max_value(&self) -> Option> { + #[unsafe(method_id(accessibilityMaxValue))] + fn max_value(&self) -> Option> { self.resolve(|node| { node.max_numeric_value().map(NSNumber::new_f64) }) .flatten() } - #[method_id(accessibilityURL)] - fn url(&self) -> Option> { + + #[unsafe(method_id(accessibilityURL))] + fn url(&self) -> Option> { self.resolve(|node| { node.supports_url().then(|| node.url()).flatten().and_then(|url| { let ns_string = NSString::from_str(url); - unsafe { NSURL::URLWithString(&ns_string) } + NSURL::URLWithString(&ns_string) }) }) .flatten() } - #[method(accessibilityOrientation)] + #[unsafe(method(accessibilityOrientation))] fn orientation(&self) -> NSAccessibilityOrientation { self.resolve(|node| { match node.orientation() { @@ -618,24 +605,24 @@ declare_class!( .unwrap_or(NSAccessibilityOrientation::Unknown) } - #[method(isAccessibilityElement)] + #[unsafe(method(isAccessibilityElement))] fn is_accessibility_element(&self) -> bool { self.resolve(|node| filter(node) == FilterResult::Include) .unwrap_or(false) } - #[method(isAccessibilityFocused)] + #[unsafe(method(isAccessibilityFocused))] fn is_focused(&self) -> bool { self.resolve(|node| node.is_focused() && can_be_focused(node)) .unwrap_or(false) } - #[method(isAccessibilityEnabled)] + #[unsafe(method(isAccessibilityEnabled))] fn is_enabled(&self) -> bool { self.resolve(|node| !node.is_disabled()).unwrap_or(false) } - #[method(setAccessibilityFocused:)] + #[unsafe(method(setAccessibilityFocused:))] fn set_focused(&self, focused: bool) { self.resolve_with_context(|node, tree, context| { if focused { @@ -665,7 +652,7 @@ declare_class!( }); } - #[method(accessibilityPerformPress)] + #[unsafe(method(accessibilityPerformPress))] fn press(&self) -> bool { self.resolve_with_context(|node, tree, context| { let clickable = node.is_clickable(&filter); @@ -684,7 +671,7 @@ declare_class!( .unwrap_or(false) } - #[method(accessibilityPerformIncrement)] + #[unsafe(method(accessibilityPerformIncrement))] fn increment(&self) -> bool { self.resolve_with_context(|node, tree, context| { let supports_increment = node.supports_increment(&filter); @@ -703,7 +690,7 @@ declare_class!( .unwrap_or(false) } - #[method(accessibilityPerformDecrement)] + #[unsafe(method(accessibilityPerformDecrement))] fn decrement(&self) -> bool { self.resolve_with_context(|node, tree, context| { let supports_decrement = node.supports_decrement(&filter); @@ -722,12 +709,12 @@ declare_class!( .unwrap_or(false) } - #[method(accessibilityNotifiesWhenDestroyed)] + #[unsafe(method(accessibilityNotifiesWhenDestroyed))] fn notifies_when_destroyed(&self) -> bool { true } - #[method(accessibilityNumberOfCharacters)] + #[unsafe(method(accessibilityNumberOfCharacters))] fn number_of_characters(&self) -> NSInteger { self.resolve(|node| { if node.supports_text_ranges() { @@ -739,8 +726,8 @@ declare_class!( .unwrap_or(0) } - #[method_id(accessibilitySelectedText)] - fn selected_text(&self) -> Option> { + #[unsafe(method_id(accessibilitySelectedText))] + fn selected_text(&self) -> Option> { self.resolve(|node| { if node.supports_text_ranges() { if let Some(range) = node.text_selection() { @@ -753,7 +740,7 @@ declare_class!( .flatten() } - #[method(accessibilitySelectedTextRange)] + #[unsafe(method(accessibilitySelectedTextRange))] fn selected_text_range(&self) -> NSRange { self.resolve(|node| { if node.supports_text_ranges() { @@ -766,7 +753,7 @@ declare_class!( .unwrap_or_else(|| NSRange::new(0, 0)) } - #[method(accessibilityInsertionPointLineNumber)] + #[unsafe(method(accessibilityInsertionPointLineNumber))] fn insertion_point_line_number(&self) -> NSInteger { self.resolve(|node| { if node.supports_text_ranges() { @@ -779,7 +766,7 @@ declare_class!( .unwrap_or(0) } - #[method(accessibilityRangeForLine:)] + #[unsafe(method(accessibilityRangeForLine:))] fn range_for_line(&self, line_index: NSInteger) -> NSRange { self.resolve(|node| { if node.supports_text_ranges() && line_index >= 0 { @@ -792,7 +779,7 @@ declare_class!( .unwrap_or_else(|| NSRange::new(0, 0)) } - #[method(accessibilityRangeForPosition:)] + #[unsafe(method(accessibilityRangeForPosition:))] fn range_for_position(&self, point: NSPoint) -> NSRange { self.resolve_with_context(|node, _, context| { let view = match context.view.load() { @@ -812,8 +799,8 @@ declare_class!( .unwrap_or_else(|| NSRange::new(0, 0)) } - #[method_id(accessibilityStringForRange:)] - fn string_for_range(&self, range: NSRange) -> Option> { + #[unsafe(method_id(accessibilityStringForRange:))] + fn string_for_range(&self, range: NSRange) -> Option> { self.resolve(|node| { if node.supports_text_ranges() { if let Some(range) = from_ns_range(node, range) { @@ -826,85 +813,85 @@ declare_class!( .flatten() } - #[method_id(accessibilityAttributedStringForRange:)] - fn attributed_string_for_range(&self, range: NSRange) -> Option> { + #[unsafe(method_id(accessibilityAttributedStringForRange:))] + fn attributed_string_for_range(&self, range: NSRange) -> Option> { self.resolve(|node| { if node.supports_text_ranges() { if let Some(range) = from_ns_range(node, range) { - let mut result = NSMutableAttributedString::new(); - unsafe { result.beginEditing() }; + let result = NSMutableAttributedString::new(); + result.beginEditing(); range.traverse_text::<_, ()>(|node, text| { let ns_text = NSString::from_str(text); - let mut attrs = NSMutableDictionary::new(); + let attrs = NSMutableDictionary::::new(); if let Some(color) = node.background_color() { - attrs.insert_id( + attrs.insert( unsafe { NSAccessibilityBackgroundColorTextAttribute }, - to_color_attribute(color) + &to_color_attribute(color) ); } if let Some(color) = node.foreground_color() { - attrs.insert_id( + attrs.insert( unsafe { NSAccessibilityForegroundColorTextAttribute }, - to_color_attribute(color) + &to_color_attribute(color) ); } - let mut font_attrs = NSMutableDictionary::::new(); + let font_attrs = NSMutableDictionary::::new(); if let Some(family) = node.font_family() { - font_attrs.insert_id( + font_attrs.insert( unsafe { NSAccessibilityFontFamilyKey }, - Id::into_super(Id::into_super(NSString::from_str(family))) + &Retained::into_super(Retained::into_super(NSString::from_str(family))) ); } if let Some(size) = node.font_size() { - font_attrs.insert_id( + font_attrs.insert( unsafe { NSAccessibilityFontSizeKey }, - Id::into_super(Id::into_super(Id::into_super(NSNumber::new_f32(size)))) + &Retained::into_super(Retained::into_super(Retained::into_super(NSNumber::new_f32(size)))) ); } if let Some(weight) = node.font_weight() { if weight >= 700.0 { - font_attrs.insert_id( + font_attrs.insert( ns_string!("AXFontBold"), - Id::into_super(Id::into_super(Id::into_super(NSNumber::new_bool(true)))) + &Retained::into_super(Retained::into_super(Retained::into_super(NSNumber::new_bool(true)))) ); } } if node.is_italic() { - font_attrs.insert_id( + font_attrs.insert( ns_string!("AXFontItalic"), - Id::into_super(Id::into_super(Id::into_super(NSNumber::new_bool(true)))) + &Retained::into_super(Retained::into_super(Retained::into_super(NSNumber::new_bool(true)))) ); } if !font_attrs.is_empty() { - attrs.insert_id( + attrs.insert( unsafe { NSAccessibilityFontTextAttribute }, - Id::into_super(Id::into_super(Id::into_super(font_attrs))) + &Retained::into_super(Retained::into_super(Retained::into_super(font_attrs))) ); } if let Some(deco) = node.underline() { - attrs.insert_id( + attrs.insert( unsafe { NSAccessibilityUnderlineTextAttribute }, - Id::into_super(Id::into_super(Id::into_super(NSNumber::new_bool(true)))) + &Retained::into_super(Retained::into_super(Retained::into_super(NSNumber::new_bool(true)))) ); - attrs.insert_id( + attrs.insert( unsafe { NSAccessibilityUnderlineColorTextAttribute }, - to_color_attribute(deco.color) + &to_color_attribute(deco.color) ); } if let Some(deco) = node.strikethrough() { - attrs.insert_id( + attrs.insert( unsafe { NSAccessibilityStrikethroughTextAttribute }, - Id::into_super(Id::into_super(Id::into_super(NSNumber::new_bool(true)))) + &Retained::into_super(Retained::into_super(Retained::into_super(NSNumber::new_bool(true)))) ); - attrs.insert_id( + attrs.insert( unsafe { NSAccessibilityStrikethroughColorTextAttribute }, - to_color_attribute(deco.color) + &to_color_attribute(deco.color) ); } if let Some(language) = node.language() { - attrs.insert_id( + attrs.insert( unsafe { NSAccessibilityLanguageTextAttribute }, - Id::into_super(Id::into_super(NSString::from_str(language))) + &Retained::into_super(Retained::into_super(NSString::from_str(language))) ); } if let Some(align) = node.text_align() { @@ -914,17 +901,17 @@ declare_class!( TextAlign::Right => NSTextAlignment::Right, TextAlign::Justify => NSTextAlignment::Justified, }; - attrs.insert_id( + attrs.insert( unsafe { NSAccessibilityTextAlignmentAttribute }, - Id::into_super(Id::into_super(Id::into_super(NSNumber::new_isize(ns_align.0)))) + &Retained::into_super(Retained::into_super(Retained::into_super(NSNumber::new_isize(ns_align.0)))) ); } let part = unsafe { NSAttributedString::new_with_attributes(&ns_text, &attrs) }; - unsafe { result.appendAttributedString(&part) }; + result.appendAttributedString(&part); None }); - unsafe { result.endEditing() }; - return Some(Id::into_super(result)); + result.endEditing(); + return Some(Retained::into_super(result)); } } None @@ -932,7 +919,7 @@ declare_class!( .flatten() } - #[method(accessibilityFrameForRange:)] + #[unsafe(method(accessibilityFrameForRange:))] fn frame_for_range(&self, range: NSRange) -> NSRect { self.resolve_with_context(|node, _, context| { let view = match context.view.load() { @@ -957,7 +944,7 @@ declare_class!( .unwrap_or(NSRect::ZERO) } - #[method(accessibilityLineForIndex:)] + #[unsafe(method(accessibilityLineForIndex:))] fn line_for_index(&self, index: NSInteger) -> NSInteger { self.resolve(|node| { if node.supports_text_ranges() && index >= 0 { @@ -970,7 +957,7 @@ declare_class!( .unwrap_or(0) } - #[method(accessibilityRangeForIndex:)] + #[unsafe(method(accessibilityRangeForIndex:))] fn range_for_index(&self, index: NSInteger) -> NSRange { self.resolve(|node| { if node.supports_text_ranges() && index >= 0 { @@ -983,7 +970,7 @@ declare_class!( .unwrap_or_else(|| NSRange::new(0, 0)) } - #[method(accessibilityStyleRangeForIndex:)] + #[unsafe(method(accessibilityStyleRangeForIndex:))] fn style_range_for_index(&self, index: NSInteger) -> NSRange { self.resolve(|node| { if node.supports_text_ranges() && index >= 0 { @@ -1003,7 +990,7 @@ declare_class!( .unwrap_or_else(|| NSRange::new(0, 0)) } - #[method(setAccessibilitySelectedTextRange:)] + #[unsafe(method(setAccessibilitySelectedTextRange:))] fn set_selected_text_range(&self, range: NSRange) { self.resolve_with_context(|node, tree, context| { if node.supports_text_ranges() { @@ -1021,13 +1008,13 @@ declare_class!( }); } - #[method(isAccessibilityRequired)] + #[unsafe(method(isAccessibilityRequired))] fn is_required(&self) -> bool { self.resolve(|node| node.is_required()) .unwrap_or(false) } - #[method(isAccessibilitySelected)] + #[unsafe(method(isAccessibilitySelected))] fn is_selected(&self) -> bool { self.resolve(|node| { let wrapper = NodeWrapper(node); @@ -1038,7 +1025,7 @@ declare_class!( .unwrap_or(false) } - #[method(setAccessibilitySelected:)] + #[unsafe(method(setAccessibilitySelected:))] fn set_selected(&self, selected: bool) { self.resolve_with_context(|node, tree, context| { let wrapper = NodeWrapper(node); @@ -1062,8 +1049,9 @@ declare_class!( }); } - #[method_id(accessibilityAttributeValue:)] - fn accessibility_attribute_value(&self, attr: &NSString) -> Option> { + + #[unsafe(method_id(accessibilityAttributeValue:))] + fn accessibility_attribute_value(&self, attr: &NSString) -> Option> { self.resolve(|node| { if attr == ns_string!("AXBrailleLabel") && node.has_braille_label() { return Some(NSString::from_str(node.braille_label().unwrap())) @@ -1076,8 +1064,8 @@ declare_class!( .flatten() } - #[method_id(accessibilityRows)] - fn rows(&self) -> Option>> { + #[unsafe(method_id(accessibilityRows))] + fn rows(&self) -> Option>> { self.resolve_with_context(|node, _, context| { let wrapper = NodeWrapper(node); if !wrapper.is_container_with_selectable_children() { @@ -1086,14 +1074,14 @@ declare_class!( let platform_nodes = node .items(filter) .map(|child| context.get_or_create_platform_node(child.id())) - .collect::>>(); - Some(NSArray::from_vec(platform_nodes)) + .collect::>>(); + Some(NSArray::from_retained_slice(&platform_nodes)) }) .flatten() } - #[method_id(accessibilitySelectedRows)] - fn selected_rows(&self) -> Option>> { + #[unsafe(method_id(accessibilitySelectedRows))] + fn selected_rows(&self) -> Option>> { self.resolve_with_context(|node, _, context| { let wrapper = NodeWrapper(node); if !wrapper.is_container_with_selectable_children() { @@ -1103,13 +1091,13 @@ declare_class!( .items(filter) .filter(|item| item.is_selected() == Some(true)) .map(|child| context.get_or_create_platform_node(child.id())) - .collect::>>(); - Some(NSArray::from_vec(platform_nodes)) + .collect::>>(); + Some(NSArray::from_retained_slice(&platform_nodes)) }) .flatten() } - #[method(accessibilityPerformPick)] + #[unsafe(method(accessibilityPerformPick))] fn pick(&self) -> bool { self.resolve_with_context(|node, tree, context| { let wrapper = NodeWrapper(node); @@ -1131,10 +1119,10 @@ declare_class!( .unwrap_or(false) } - #[method_id(accessibilityLinkedUIElements)] - fn linked_ui_elements(&self) -> Option>> { + #[unsafe(method_id(accessibilityLinkedUIElements))] + fn linked_ui_elements(&self) -> Option>> { self.resolve_with_context(|node, _, context| { - let platform_nodes: Vec> = node + let platform_nodes: Vec> = node .controls() .filter(|controlled| filter(controlled) == FilterResult::Include) .map(|controlled| context.get_or_create_platform_node(controlled.id())) @@ -1142,14 +1130,14 @@ declare_class!( if platform_nodes.is_empty() { None } else { - Some(NSArray::from_vec(platform_nodes)) + Some(NSArray::from_retained_slice(&platform_nodes)) } }) .flatten() } - #[method_id(accessibilityTabs)] - fn tabs(&self) -> Option>> { + #[unsafe(method_id(accessibilityTabs))] + fn tabs(&self) -> Option>> { self.resolve_with_context(|node, _, context| { if node.role() != Role::TabList { return None; @@ -1158,13 +1146,13 @@ declare_class!( .filtered_children(filter) .filter(|child| child.role() == Role::Tab) .map(|tab| context.get_or_create_platform_node(tab.id())) - .collect::>>(); - Some(NSArray::from_vec(platform_nodes)) + .collect::>>(); + Some(NSArray::from_retained_slice(&platform_nodes)) }) .flatten() } - #[method(isAccessibilityModal)] + #[unsafe(method(isAccessibilityModal))] fn is_modal(&self) -> bool { self.resolve(|node| node.is_modal()) .unwrap_or(false) @@ -1177,18 +1165,18 @@ declare_class!( // of the legacy methods below only needs to cover actions not already // handled by the newer methods. - #[method_id(accessibilityActionNames)] - fn action_names(&self) -> Id> { + #[unsafe(method_id(accessibilityActionNames))] + fn action_names(&self) -> Retained> { let mut result = vec![]; self.resolve(|node| { if node.supports_action(Action::ScrollIntoView, &filter) { result.push(ns_string!(SCROLL_TO_VISIBLE_ACTION).copy()); } }); - NSArray::from_vec(result) + NSArray::from_retained_slice(&result) } - #[method(accessibilityPerformAction:)] + #[unsafe(method(accessibilityPerformAction:))] fn perform_action(&self, action: &NSString) { self.resolve_with_context(|node, tree, context| { if action == ns_string!(SCROLL_TO_VISIBLE_ACTION) { @@ -1204,7 +1192,7 @@ declare_class!( }); } - #[method(isAccessibilitySelectorAllowed:)] + #[unsafe(method(isAccessibilitySelectorAllowed:))] fn is_selector_allowed(&self, selector: Sel) -> bool { self.resolve(|node| { if selector == sel!(setAccessibilityFocused:) { @@ -1302,10 +1290,10 @@ declare_class!( ); impl PlatformNode { - pub(crate) fn new(context: Weak, node_id: FullNodeId) -> Id { + pub(crate) fn new(context: Weak, node_id: FullNodeId) -> Retained { let this = Self::alloc().set_ivars(PlatformNodeIvars { context, node_id }); - unsafe { msg_send_id![super(this), init] } + unsafe { msg_send![super(this), init] } } fn resolve_with_context(&self, f: F) -> Option @@ -1326,13 +1314,13 @@ impl PlatformNode { self.resolve_with_context(|node, _, _| f(node)) } - fn children_internal(&self) -> Option>> { + fn children_internal(&self) -> Option>> { self.resolve_with_context(|node, _, context| { let platform_nodes = node .filtered_children(filter) .map(|child| context.get_or_create_platform_node(child.id())) - .collect::>>(); - NSArray::from_vec(platform_nodes) + .collect::>>(); + NSArray::from_retained_slice(&platform_nodes) }) } } diff --git a/adapters/macos/src/patch.rs b/adapters/macos/src/patch.rs index 1b4732eb2..c4685799e 100644 --- a/adapters/macos/src/patch.rs +++ b/adapters/macos/src/patch.rs @@ -8,11 +8,11 @@ use objc2::{ encode::{Encode, EncodeArguments, EncodeReturn, Encoding}, ffi::class_addMethod, msg_send, - runtime::{AnyClass, AnyObject, Bool, MethodImplementation, Sel}, + runtime::{AnyClass, AnyObject, MethodImplementation, Sel}, sel, }; use objc2_app_kit::NSWindow; -use std::{ffi::CString, ptr::null_mut}; +use std::{ffi::CString, ptr::null_mut, str::FromStr}; extern "C" fn focus_forwarder(this: &NSWindow, _cmd: Sel) -> *mut AnyObject { unsafe { @@ -37,7 +37,7 @@ extern "C" fn focus_forwarder(this: &NSWindow, _cmd: Sel) -> *mut AnyObject { /// Also, this function assumes that the specified class is a subclass /// of `NSWindow`. pub unsafe fn add_focus_forwarder_to_window_class(class_name: &str) { - let class = AnyClass::get(class_name).unwrap(); + let class = AnyClass::get(&CString::from_str(class_name).unwrap()).unwrap(); unsafe { add_method( class as *const AnyClass as *mut AnyClass, @@ -67,19 +67,17 @@ where ); let types = method_type_encoding(&F::Return::ENCODING_RETURN, encs); - let success = Bool::from_raw(unsafe { - class_addMethod( - class as *mut _, - sel.as_ptr(), - Some(func.__imp()), - types.as_ptr(), - ) - }); + let success = unsafe { class_addMethod(class as *mut _, sel, func.__imp(), types.as_ptr()) }; assert!(success.as_bool(), "Failed to add method {sel:?}"); } fn count_args(sel: Sel) -> usize { - sel.name().chars().filter(|&c| c == ':').count() + sel.name() + .to_str() + .unwrap() + .chars() + .filter(|&c| c == ':') + .count() } fn method_type_encoding(ret: &Encoding, args: &[Encoding]) -> CString { diff --git a/adapters/macos/src/subclass.rs b/adapters/macos/src/subclass.rs index a873f7c85..1edf6cf7c 100644 --- a/adapters/macos/src/subclass.rs +++ b/adapters/macos/src/subclass.rs @@ -5,22 +5,26 @@ use accesskit::{ActionHandler, ActivationHandler, TreeUpdate}; use objc2::{ - ClassType, DeclaredClass, + AnyThread, DeclaredClass, declare::ClassBuilder, - declare_class, + define_class, ffi::{ OBJC_ASSOCIATION_RETAIN_NONATOMIC, objc_getAssociatedObject, objc_setAssociatedObject, object_setClass, }, - msg_send_id, - mutability::InteriorMutable, - rc::Id, + msg_send, + rc::Retained, runtime::{AnyClass, Sel}, sel, }; use objc2_app_kit::{NSView, NSWindow}; use objc2_foundation::{NSArray, NSObject, NSPoint}; -use std::{cell::RefCell, ffi::c_void, sync::Mutex}; +use std::{ + cell::RefCell, + ffi::{CString, c_void}, + str::FromStr, + sync::Mutex, +}; use crate::{Adapter, event::QueuedEvents}; @@ -42,33 +46,26 @@ struct AssociatedObjectIvars { prev_class: &'static AnyClass, } -declare_class!( +define_class! { + #[unsafe(super(NSObject))] + #[name = "AccessKitSubclassAssociatedObject"] + #[ivars = AssociatedObjectIvars] struct AssociatedObject; - - unsafe impl ClassType for AssociatedObject { - type Super = NSObject; - type Mutability = InteriorMutable; - const NAME: &'static str = "AccessKitSubclassAssociatedObject"; - } - - impl DeclaredClass for AssociatedObject { - type Ivars = AssociatedObjectIvars; - } -); +} impl AssociatedObject { fn new( adapter: Adapter, activation_handler: impl 'static + ActivationHandler, prev_class: &'static AnyClass, - ) -> Id { + ) -> Retained { let state = RefCell::new(AssociatedObjectState { adapter, activation_handler: Box::new(activation_handler), }); let this = Self::alloc().set_ivars(AssociatedObjectIvars { state, prev_class }); - unsafe { msg_send_id![super(this), init] } + unsafe { msg_send![super(this), init] } } } @@ -117,8 +114,8 @@ unsafe extern "C" fn hit_test(this: &NSView, _cmd: Sel, point: NSPoint) -> *mut /// Uses dynamic Objective-C subclassing to implement the `NSView` /// accessibility methods when normal subclassing isn't an option. pub struct SubclassingAdapter { - view: Id, - associated: Id, + view: Retained, + associated: Retained, } impl SubclassingAdapter { @@ -137,16 +134,16 @@ impl SubclassingAdapter { action_handler: impl 'static + ActionHandler, ) -> Self { let view = view as *mut NSView; - let retained_view = unsafe { Id::retain(view) }.unwrap(); + let retained_view = unsafe { Retained::retain(view) }.unwrap(); Self::new_internal(retained_view, activation_handler, action_handler) } fn new_internal( - retained_view: Id, + retained_view: Retained, activation_handler: impl 'static + ActivationHandler, action_handler: impl 'static + ActionHandler, ) -> Self { - let view = Id::as_ptr(&retained_view) as *mut NSView; + let view = Retained::as_ptr(&retained_view) as *mut NSView; if !unsafe { objc_getAssociatedObject(view as *const NSView as *const _, associated_object_key()) } @@ -164,7 +161,7 @@ impl SubclassingAdapter { objc_setAssociatedObject( view as *mut _, associated_object_key(), - Id::as_ptr(&associated) as *mut _, + Retained::as_ptr(&associated) as *mut _, OBJC_ASSOCIATION_RETAIN_NONATOMIC, ) }; @@ -172,8 +169,9 @@ impl SubclassingAdapter { let subclass = match subclasses.iter().find(|entry| entry.0 == prev_class) { Some(entry) => entry.1, None => { - let name = format!("AccessKitSubclassOf{}", prev_class.name()); - let mut builder = ClassBuilder::new(&name, prev_class).unwrap(); + let name = format!("AccessKitSubclassOf{}", prev_class.name().to_str().unwrap()); + let mut builder = + ClassBuilder::new(&CString::from_str(&name).unwrap(), prev_class).unwrap(); unsafe { builder.add_method( sel!(superclass), @@ -259,7 +257,7 @@ impl SubclassingAdapter { impl Drop for SubclassingAdapter { fn drop(&mut self) { let prev_class = self.associated.ivars().prev_class; - let view = Id::as_ptr(&self.view) as *mut NSView; + let view = Retained::as_ptr(&self.view) as *mut NSView; unsafe { object_setClass(view as *mut _, (prev_class as *const AnyClass).cast()) }; unsafe { objc_setAssociatedObject( diff --git a/adapters/macos/src/util.rs b/adapters/macos/src/util.rs index f5146a7b9..128ac4797 100644 --- a/adapters/macos/src/util.rs +++ b/adapters/macos/src/util.rs @@ -6,7 +6,8 @@ use accesskit::{Color, Point, Rect}; use accesskit_consumer::{NodeRef, TextPosition, TextRange}; use objc2::encode::{Encoding, RefEncode}; -use objc2::{msg_send, rc::Id, runtime::AnyObject}; +use objc2::rc::Retained; +use objc2::{msg_send, runtime::AnyObject}; use objc2_app_kit::*; use objc2_foundation::{NSPoint, NSRange, NSRect, NSSize}; @@ -94,15 +95,13 @@ unsafe impl RefEncode for CGColor { const ENCODING_REF: Encoding = Encoding::Pointer(&Encoding::Struct("CGColor", &[])); } -pub(crate) fn to_color_attribute(color: Color) -> Id { - let ns_color = unsafe { - NSColor::colorWithSRGBRed_green_blue_alpha( - color_channel_to_f64(color.red), - color_channel_to_f64(color.green), - color_channel_to_f64(color.blue), - color_channel_to_f64(color.alpha), - ) - }; +pub(crate) fn to_color_attribute(color: Color) -> Retained { + let ns_color = NSColor::colorWithSRGBRed_green_blue_alpha( + color_channel_to_f64(color.red), + color_channel_to_f64(color.green), + color_channel_to_f64(color.blue), + color_channel_to_f64(color.alpha), + ); let cg_color: *const CGColor = unsafe { msg_send![&ns_color, CGColor] }; - unsafe { Id::retain(cg_color as *mut AnyObject).unwrap() } + unsafe { Retained::retain(cg_color as *mut AnyObject).unwrap() } }