appkit
Typed Cocoa / AppKit bindings for building native macOS desktop apps. The package is one generated module — the canonical entry point is import "appkit/appkit" as appkit; — produced by cpc-bindgen from the AppKit SDK headers, so it tracks the framework class-for-class: hundreds of Cocoa classes (Application, Window, View, Button, TextField, Menu, Toolbar, and the rest) each surface as a typed { _obj } wrapper carrying raw() and from_raw().
Callbacks are closure-free, in keeping with C+ having no closures. Action controls use Cocoa's target/action: a factory like Button::button_with_title(title, target, action) takes a target object and an action selector, and block-taking APIs accept a named fn(...) pointer plus a ctx: *u8 (for example DraggingItem::set_image_components_provider(cb, ctx)). Data crosses the boundary through objc/bridge: a str coerces to NSString, methods hand back Text, arrays arrive as Vec[T], and NSData is the Data wrapper; the geometry structs rt::Point, rt::Size, and rt::Rect cross verbatim.
Ownership: the "+1 normal form"
Types the generator recognizes as alloc/init-owned carry a drop(ref this) that releases their Objective-C object exactly once — Window, View, Menu, Toolbar, and the owned Foundation values (AttributedString, Data, and friends) all follow this one rule, so a wrapper that goes out of scope cannot leak. Objects handed back from autoreleasing factory methods (Button::button_with_title, TextField::label_with_string) or shared accessors (Application::shared_application) are non-owning wrappers with no drop, and are never released. Over 150 types carry the owning drop.
Drag and drop
AppKit supports both ends of a drag. A drop destination registers for dropped data, and a drag source can begin a drag from a mouseDragged: gesture by building DraggingItems (DraggingItem::new / DraggingItem::new_with_pasteboard_writer) and calling View::begin_dragging_session_with_items(items, event, source), which returns a DraggingSession. A runnable appkit_drag_drop recipe lives in the compiler repo.
Labels vs. fields
TextField::label_with_string is a true static label — non-editable and non-bezeled — so it does not behave like an input or accept dropped text. Use TextField::text_field_with_string (or the TextField initializers) when you want an editable field.
import "appkit/appkit" as appkit;
fn main() -> i32 {
let app = appkit::Application::shared_application();
app.set_activation_policy(appkit::ApplicationActivationPolicy::Regular);
// ... build window + controls ...
app.run();
return 0;
}
Parenting, symbols, and widgets
Every wrapper exposes raw() to hand its Objective-C pointer to a parent that will own it and from_raw() to re-wrap one, so a view moved into a parent is not double-released. The bindings also cover SF Symbols — Image::image_with_system_symbol_name(name, description) returns Option[Image] — layer-backed views via View::set_wants_layer, and broad toolbar and text coverage.
A runnable reference app lives in the compiler repo at
docs/examples/recipes/appkit_hello/; the public walkthrough is
AppKit hello. For the underlying Objective-C
message-send mechanics, see FFI. To drive an AppKit app from an
external agent, see the agent surface and
agent_appkit.