C+
Packages · View as Markdown

appkit

Typed Cocoa / AppKit bindings for building native macOS desktop apps. 15 sub-modules cover the framework: runtime, application, window, view, controls, text, containers, data, graphics, menu, dialogs, panels, toolbar, controllers, and convert.

Callbacks are closure-free: Button::set_on_click(fn(*u8)) stashes a named function on the sender via objc_setAssociatedObject, in keeping with C+ having no closures. The appkit/convert module is the C+ to Objective-C data bridge for Text, Vec[T], and NSData; primitives and #[repr(C)] structs (NSPoint, NSSize, NSRect) cross the boundary verbatim.

Ownership: the "+1 normal form"

Every alloc/init widget wrapper owns its Objective-C object and releases it exactly once in drop — controls, text, containers, toolbar items, panels, controllers, data views, and the base views all follow this one rule, so a wrapper that goes out of scope cannot leak. Factory, shared, and top-level objects that AppKit itself owns (windows, the application, the status bar, shared panels, colors, and fonts) are correctly non-owned and never released. Every appkit sub-module ships with tests.

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 with create_drag_source_view plus begin_string_drag / DraggingItem / begin_dragging_session. A runnable appkit_drag_drop recipe lives in the compiler repo.

Labels vs. fields

TextField::new_label is a true static label — non-editable and non-bezeled — so it does not behave like an input or accept dropped text. Use the regular TextField constructors when you want an editable field.

import "appkit/application" as application;
import "appkit/window" as window;

fn main() -> i32 {
    let pool = application::AutoreleasePool::new();
    let app  = application::Application::shared();
    app.set_activation_policy(0 as i64);
    // ... build window + controls ...
    app.run();
    pool.drain();
    return 0;
}

A runnable reference app lives in the compiler repo at docs/examples/recipes/appkit_hello/. For the underlying Objective-C message-send mechanics, see FFI.