// Minimal macOS/AppKit window — the irreducible Cocoa sequence GLFW/SDL/winit wrap
// on macOS: [NSApplication sharedApplication] -> [NSWindow initWithContentRect:…]
// -> makeKeyAndOrderFront: -> [NSApp run]. Objective-C is reached through D's
// built-in `extern(Objective-C)` + `@selector` interop, with the `objective-d`
// package providing the Objective-C runtime linkage and the scoped autorelease
// pool. AppKit classes are hand-declared (objective-d bundles Foundation, not
// AppKit). See ../index.md (the macOS/AppKit OS-API survey).
//
// Headless-safe: an SSH/headless session has no window server, so `CGMainDisplayID`
// returns 0 — we print `SKIP:` and exit 0 (creating an NSWindow without a window
// server is undefined). With a logged-in session it creates and shows a real
// window. Bounded: we create + order-front + return rather than block in
// `[NSApp run]` (a real app loops there — noted below) so CI never hangs.
module (module) appapp;
import (package) corecore.(module) core.attributeThis module contains UDA's (User Defined Attributes) either used in
the runtime or special UDA's recognized by compiler.
Attribute Name, Linkage, Description
gnuAbiTag, C++,
Declares an ABI tag on a C++ symbol.
mustuse,,
Ensures that values of a struct or union type are not discarded.
optional, Objective-C,
Makes an Objective-C interface method optional.
selector, Objective-C,
Attaches an Objective-C selector to a method.
standalone,,
Marks a shared module constructor as not depending on any
other module constructor being run first.
weak,,
Specifies that a global symbol should be emitted with weak linkage.
Source
core/attribute.d
attribute : selector;
import (package) corecore.(package) core.stdcstdc.(module) core.stdc.stdioD header file for C99 <stdio.h>
pubs.opengroup.org/onlinepubs/009695399/basedefs/stdio.h.html, stdio.h
Source
core/stdc/stdio.d
stdio : (alias) app.printf = int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogcprintf;
import objc.autorelease : autoreleasepool_push, autoreleasepool_pop; // objective-d
// CoreGraphics (linked transitively by Cocoa): 0 when there is no window server.
extern (C) uint uint app.CGMainDisplayID() nothrow @nogcCGMainDisplayID() nothrow @nogc;
// Cocoa geometry (CGFloat == double on 64-bit). Plain C structs, not ObjC objects.
extern (C) struct (struct) app.NSPointNSPoint
{
double (field) double app.NSPoint.xx, (field) double app.NSPoint.yy;
}
extern (C) struct (struct) app.NSSizeNSSize
{
double (field) double app.NSSize.widthwidth, (field) double app.NSSize.heightheight;
}
extern (C) struct (struct) app.NSRectNSRect
{
(struct) app.NSPointNSPoint (field) app.NSPoint app.NSRect.originorigin;
(struct) app.NSSizeNSSize (field) app.NSSize app.NSRect.sizesize;
}
extern (Objective-C):
extern class (class) app.NSObjectNSObject
{
// `alloc` is declared on the leaf classes that need it (with their own return
// type) to avoid an Objective-C covariant-return clash on the base method.
}
extern class (class) app.NSStringNSString : (class) app.NSObjectNSObject
{
static (class) app.NSStringNSString app.NSString app.NSString.alloc()alloc() @selector("alloc");
(class) app.NSStringNSString app.NSString app.NSString.initWithUTF8String(const(char)* s)initWithUTF8String(const(char)* (parameter) const(char)* ss) @selector("initWithUTF8String:");
}
extern class (class) app.NSResponderNSResponder : (class) app.NSObjectNSObject
{
}
extern class (class) app.NSApplicationNSApplication : (class) app.NSResponderNSResponder
{
static (class) app.NSApplicationNSApplication app.NSApplication app.NSApplication.sharedApplication()sharedApplication() @selector("sharedApplication");
void void app.NSApplication.setActivationPolicy(long policy)setActivationPolicy(long (parameter) long policypolicy) @selector("setActivationPolicy:");
void void app.NSApplication.activateIgnoringOtherApps(bool flag)activateIgnoringOtherApps(bool (parameter) bool flagflag) @selector("activateIgnoringOtherApps:");
void void app.NSApplication.run()run() @selector("run");
}
extern class (class) app.NSWindowNSWindow : (class) app.NSResponderNSResponder
{
static (class) app.NSWindowNSWindow app.NSWindow app.NSWindow.alloc()alloc() @selector("alloc");
(class) app.NSWindowNSWindow app.NSWindow app.NSWindow.initWithContentRect(app.NSRect contentRect, ulong styleMask, ulong backing, bool defer)initWithContentRect((struct) app.NSRectNSRect (parameter) app.NSRect contentRectcontentRect, ulong (parameter) ulong styleMaskstyleMask,
ulong (parameter) ulong backingbacking, bool (parameter) bool deferdefer) @selector("initWithContentRect:styleMask:backing:defer:");
void void app.NSWindow.setTitle(app.NSString title)setTitle((class) app.NSStringNSString (parameter) app.NSString titletitle) @selector("setTitle:");
void void app.NSWindow.makeKeyAndOrderFront(app.NSObject sender)makeKeyAndOrderFront((class) app.NSObjectNSObject (parameter) app.NSObject sendersender) @selector("makeKeyAndOrderFront:");
}
extern (D): // back to D linkage for the rest of the module
enum (constant) int app.NSApplicationActivationPolicyRegular = 0NSApplicationActivationPolicyRegular = 0;
enum : ulong
{
(enum value) app.NSWindowStyleMaskTitled = 1LUNSWindowStyleMaskTitled = 1,
(enum value) app.NSWindowStyleMaskClosable = 2LUNSWindowStyleMaskClosable = 2,
(enum value) app.NSWindowStyleMaskResizable = 8LUNSWindowStyleMaskResizable = 8,
}
enum ulong (constant) ulong app.NSBackingStoreBuffered = 2LUNSBackingStoreBuffered = 2;
int int D main()main()
{
if (CGMainDisplayID() == 0)
{
printf("SKIP: no macOS window server (CGMainDisplayID == 0)\n");
return 0;
}
// objective-d's autorelease pool wraps the AppKit object creation.
auto _error_ poolpool = autoreleasepool_push();
scope (exit)
autoreleasepool_pop(pool);
// 1. The shared application object (connects to the WindowServer).
(unresolved type) NSApplicationNSApplication _error_ appapp = NSApplication.NSApplication.sharedApplicationsharedApplication();
app.app.setActivationPolicysetActivationPolicy(NSApplicationActivationPolicyRegular);
// 2. Create a titled, closable, resizable window with a buffered backing store.
(unresolved type) NSRectNSRect _error_ frameframe = NSRect(NSPoint(120, 120), NSSize(480, 320));
(unresolved type) NSWindowNSWindow _error_ winwin = NSWindow.NSWindow.allocalloc().NSWindow.alloc().initWithContentRectinitWithContentRect(frame,
NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable,
NSBackingStoreBuffered, false);
win.win.setTitlesetTitle(NSString.NSString.allocalloc().NSString.alloc().initWithUTF8StringinitWithUTF8String("Sparkles · macOS (AppKit)"));
// 3. Order it front and activate. A real app would now block in `app.run()`;
// we return so CI is bounded.
win.win.makeKeyAndOrderFrontmakeKeyAndOrderFront(null);
app.app.activateIgnoringOtherAppsactivateIgnoringOtherApps(true);
printf("ok: created and showed an NSWindow (a real app would call [NSApp run])\n");
return 0;
}