app.dhover×286 error×20all
// macOS/AppKit windowing scaffold — ../../example/app.d evolved into a full demo:
// a custom NSView subclass (defined **in D** via `extern (Objective-C)`) whose
// `drawRect:` blits a CPU-rendered gradient through CoreGraphics, an NSTimer-driven
// redraw loop inside `[NSApp run]`, a programmatic `setFrame:display:` resize storm,
// and clean termination. Instrumented per ../../../features/f01-first-pixel.md and
// ../../../features/f02-resize.md via instrument.d. Findings: ../../scaffold.md.
//
// Modes (environment variables):
//   WSI_AUTO_EXIT=1  bounded run: a ~16 ms NSTimer drives setNeedsDisplay:; after
//                    ~30 ticks a 6-step setFrame:display: resize storm; after
//                    ~120 ticks [NSApp stop:nil] (plus a synthetic
//                    NSEventTypeApplicationDefined post, without which stop: only
//                    takes effect on the *next* real event) -> clean exit 0.
//   WSI_HOLD=1       like AUTO_EXIT but no storm and ~600 ticks (~10 s), so an
//                    external observer (the CGWindowListCopyWindowInfo sidecar)
//                    can inspect the window while it is up.
//   (neither)        runs until the window closes (windowWillClose: ->
//                    [NSApp terminate:]).
//
// Headless-safe: prints `SKIP:` and exits 0 when there is no window server
// (CGMainDisplayID() == 0), per the research-docs guidelines.
module 
(module) app
app
;
import
(package) core
core
.
(module) core.attribute

This 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

@copyrightCopyright Jacob Carlborg 2015.@licenseBoost License 1.0@authorsJacob Carlborg
attribute
: selector;
module `core.attribute` import `selector` not found
import
(package) core
core
.
(package) core.stdc
stdc
.
(module) core.stdc.stdio

D header file for C99 <stdio.h>

pubs.opengroup.org/onlinepubs/009695399/basedefs/stdio.h.html, stdio.h

Source

core/stdc/stdio.d

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseDistributed under the Boost Software License 1.0. (See accompanying file LICENSE)@authorsSean Kelly, Alex Rønne Petersen@standardsISO/IEC 9899:1999 (E)
stdio
:
(alias) app.printf = int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogc
printf
;
import
(package) core
core
.
(package) core.stdc
stdc
.
(module) core.stdc.stdlib

D header file for C99.

pubs.opengroup.org/onlinepubs/009695399/basedefs/stdlib.h.html, stdlib.h

Source

core/stdc/stdlib.d

@copyrightCopyright Sean Kelly 2005 - 2014.@licenseDistributed under the Boost Software License 1.0. (See accompanying file LICENSE)@authorsSean Kelly@standardsISO/IEC 9899:1999 (E)
stdlib
:
(alias) app.getenv = char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogc
getenv
,
(alias) app.malloc = void* core.stdc.stdlib.malloc(ulong size) nothrow @nogc
malloc
,
(alias) app.free = void core.stdc.stdlib.free(void* ptr) nothrow @nogc
free
;
import instrument : instr, instrInit;
unable to read module `instrument` Expected 'instrument.d' or 'instrument/package.d' in one of the following import paths:
unable to read module `instrument` Expected 'instrument.d' or 'instrument/package.d' in one of the following import paths:
unable to read module `instrument` Expected 'instrument.d' or 'instrument/package.d' in one of the following import paths:
import objc.autorelease : autoreleasepool_push, autoreleasepool_pop; // objective-d
unable to read module `autorelease` Expected 'objc/autorelease.d' or 'objc/autorelease/package.d' in one of the following import paths:
unable to read module `autorelease` Expected 'objc/autorelease.d' or 'objc/autorelease/package.d' in one of the following import paths:
unable to read module `autorelease` Expected 'objc/autorelease.d' or 'objc/autorelease/package.d' in one of the following import paths:
// Objective-C runtime selector lookup (objective-d wraps libobjc; declaring // sel_registerName ourselves would clash with objc.rt's typed declaration). import objc.rt : SEL;
unable to read module `rt` Expected 'objc/rt.d' or 'objc/rt/package.d' in one of the following import paths:
unable to read module `rt` Expected 'objc/rt.d' or 'objc/rt/package.d' in one of the following import paths:
unable to read module `rt` Expected 'objc/rt.d' or 'objc/rt/package.d' in one of the following import paths:
// --- C-level declarations ----------------------------------------------------- // CoreGraphics C API — linked transitively via the Cocoa umbrella framework. // CGRect has the same layout as NSRect (4 CGFloat = double on 64-bit), so the // struct-by-value calls below reuse NSRect. The CF objects (CGColorSpaceRef, // CGDataProviderRef, CGImageRef, CGContextRef) are opaque pointers. extern (C) nothrow @nogc { uint
uint app.CGMainDisplayID() nothrow @nogc
CGMainDisplayID
();
void*
void* app.CGColorSpaceCreateDeviceRGB() nothrow @nogc
CGColorSpaceCreateDeviceRGB
();
void
void app.CGColorSpaceRelease(void* space) nothrow @nogc
CGColorSpaceRelease
(void*
(parameter) void* space
space
);
void*
void* app.CGDataProviderCreateWithData(void* info, const(void)* data, ulong size, void* releaseCallback) nothrow @nogc
CGDataProviderCreateWithData
(void*
(parameter) void* info
info
, const(void)*
(parameter) const(void)* data
data
,
(alias) object.size_t = ulong
size_t
(parameter) ulong size
size
,
void*
(parameter) void* releaseCallback
releaseCallback
);
void
void app.CGDataProviderRelease(void* provider) nothrow @nogc
CGDataProviderRelease
(void*
(parameter) void* provider
provider
);
void*
void* app.CGImageCreate(ulong width, ulong height, ulong bitsPerComponent, ulong bitsPerPixel, ulong bytesPerRow, void* colorSpace, uint bitmapInfo, void* provider, const(double)* decode, bool shouldInterpolate, int intent) nothrow @nogc
CGImageCreate
(
(alias) object.size_t = ulong
size_t
(parameter) ulong width
width
,
(alias) object.size_t = ulong
size_t
(parameter) ulong height
height
,
(alias) object.size_t = ulong
size_t
(parameter) ulong bitsPerComponent
bitsPerComponent
,
(alias) object.size_t = ulong
size_t
(parameter) ulong bitsPerPixel
bitsPerPixel
,
(alias) object.size_t = ulong
size_t
(parameter) ulong bytesPerRow
bytesPerRow
, void*
(parameter) void* colorSpace
colorSpace
, uint
(parameter) uint bitmapInfo
bitmapInfo
,
void*
(parameter) void* provider
provider
, const(double)*
(parameter) const(double)* decode
decode
, bool
(parameter) bool shouldInterpolate
shouldInterpolate
, int
(parameter) int intent
intent
);
void
void app.CGImageRelease(void* image) nothrow @nogc
CGImageRelease
(void*
(parameter) void* image
image
);
void
void app.CGContextDrawImage(void* ctx, app.NSRect rect, void* image) nothrow @nogc
CGContextDrawImage
(void*
(parameter) void* ctx
ctx
,
(struct) app.NSRect
NSRect
(parameter) app.NSRect rect
rect
, void*
(parameter) void* image
image
);
} enum uint
(constant) uint app.kCGImageAlphaNoneSkipFirst = 6u
kCGImageAlphaNoneSkipFirst
= 6; // XRGB: alpha byte present, ignored
enum uint
(constant) uint app.kCGBitmapByteOrder32Little = 8192u
kCGBitmapByteOrder32Little
= 2 << 12; // 32-bit little-endian packing
enum int
(constant) int app.kCGRenderingIntentDefault = 0
kCGRenderingIntentDefault
= 0;
// Cocoa geometry (CGFloat == double on 64-bit). Plain C structs, not ObjC objects. extern (C) struct
(struct) app.NSPoint
NSPoint
{ double
(field) double app.NSPoint.x
x
,
(field) double app.NSPoint.y
y
;
} extern (C) struct
(struct) app.NSSize
NSSize
{ double
(field) double app.NSSize.width
width
,
(field) double app.NSSize.height
height
;
} extern (C) struct
(struct) app.NSRect
NSRect
{
(struct) app.NSPoint
NSPoint
(field) app.NSPoint app.NSRect.origin
origin
;
(struct) app.NSSize
NSSize
(field) app.NSSize app.NSRect.size
size
;
} // --- AppKit class declarations (objective-d bundles Foundation, not AppKit) ---- extern (Objective-C): extern class
(class) app.NSObject
NSObject
class `app.NSObject` Objective-C classes not supported
{ // `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.NSString
NSString
:
(class) app.NSObject
NSObject
class `app.NSString` Objective-C classes not supported
{ static
(class) app.NSString
NSString
app.NSString app.NSString.alloc()
alloc
() @selector("alloc");
(class) app.NSString
NSString
app.NSString app.NSString.initWithUTF8String(const(char)* s)
initWithUTF8String
(const(char)*
(parameter) const(char)* s
s
) @selector("initWithUTF8String:");
} extern class
(class) app.NSResponder
NSResponder
:
(class) app.NSObject
NSObject
class `app.NSResponder` Objective-C classes not supported
{ } extern class
(class) app.NSEvent
NSEvent
:
(class) app.NSObject
NSObject
class `app.NSEvent` Objective-C classes not supported
{ static
(class) app.NSEvent
NSEvent
app.NSEvent app.NSEvent.otherEventWithType(long type, app.NSPoint location, ulong modifierFlags, double timestamp, long windowNumber, app.NSObject context, short subtype, long data1, long data2)
otherEventWithType
(long
(parameter) long type
type
,
(struct) app.NSPoint
NSPoint
(parameter) app.NSPoint location
location
, ulong
(parameter) ulong modifierFlags
modifierFlags
,
double
(parameter) double timestamp
timestamp
, long
(parameter) long windowNumber
windowNumber
,
(class) app.NSObject
NSObject
(parameter) app.NSObject context
context
, short
(parameter) short subtype
subtype
,
long
(parameter) long data1
data1
, long
(parameter) long data2
data2
)
@selector("otherEventWithType:location:modifierFlags:timestamp:windowNumber:context:subtype:data1:data2:"); } extern class
(class) app.NSTimer
NSTimer
:
(class) app.NSObject
NSObject
class `app.NSTimer` Objective-C classes not supported
{ static
(class) app.NSTimer
NSTimer
app.NSTimer.scheduledTimerWithTimeInterval
scheduledTimerWithTimeInterval
(double interval,
(class) app.NSObject
NSObject
target,
SEL sel,
(class) app.NSObject
NSObject
userInfo, bool repeats)
@selector("scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:"); } extern class
(class) app.NSGraphicsContext
NSGraphicsContext
:
(class) app.NSObject
NSObject
class `app.NSGraphicsContext` Objective-C classes not supported
{ static
(class) app.NSGraphicsContext
NSGraphicsContext
app.NSGraphicsContext app.NSGraphicsContext.currentContext()
currentContext
() @selector("currentContext");
void*
void* app.NSGraphicsContext.CGContext()
CGContext
() @selector("CGContext"); // CGContextRef
} extern class
(class) app.NSApplication
NSApplication
:
(class) app.NSResponder
NSResponder
class `app.NSApplication` Objective-C classes not supported
{ static
(class) app.NSApplication
NSApplication
app.NSApplication app.NSApplication.sharedApplication()
sharedApplication
() @selector("sharedApplication");
void
void app.NSApplication.setActivationPolicy(long policy)
setActivationPolicy
(long
(parameter) long policy
policy
) @selector("setActivationPolicy:");
void
void app.NSApplication.activateIgnoringOtherApps(bool flag)
activateIgnoringOtherApps
(bool
(parameter) bool flag
flag
) @selector("activateIgnoringOtherApps:");
void
void app.NSApplication.run()
run
() @selector("run");
void
void app.NSApplication.stop(app.NSObject sender)
stop
(
(class) app.NSObject
NSObject
(parameter) app.NSObject sender
sender
) @selector("stop:");
void
void app.NSApplication.postEvent(app.NSEvent event, bool atStart)
postEvent
(
(class) app.NSEvent
NSEvent
(parameter) app.NSEvent event
event
, bool
(parameter) bool atStart
atStart
) @selector("postEvent:atStart:");
void
void app.NSApplication.terminate(app.NSObject sender)
terminate
(
(class) app.NSObject
NSObject
(parameter) app.NSObject sender
sender
) @selector("terminate:");
} extern class
(class) app.NSView
NSView
:
(class) app.NSResponder
NSResponder
class `app.NSView` Objective-C classes not supported
{ void
void app.NSView.setFrameSize(app.NSSize newSize)
setFrameSize
(
(struct) app.NSSize
NSSize
(parameter) app.NSSize newSize
newSize
) @selector("setFrameSize:");
void
void app.NSView.setNeedsDisplay(bool flag)
setNeedsDisplay
(bool
(parameter) bool flag
flag
) @selector("setNeedsDisplay:");
(struct) app.NSRect
NSRect
app.NSRect app.NSView.bounds()
bounds
() @selector("bounds");
} extern class
(class) app.NSWindow
NSWindow
:
(class) app.NSResponder
NSResponder
class `app.NSWindow` Objective-C classes not supported
{ static
(class) app.NSWindow
NSWindow
app.NSWindow app.NSWindow.alloc()
alloc
() @selector("alloc");
(class) app.NSWindow
NSWindow
app.NSWindow app.NSWindow.initWithContentRect(app.NSRect contentRect, ulong styleMask, ulong backing, bool defer)
initWithContentRect
(
(struct) app.NSRect
NSRect
(parameter) app.NSRect contentRect
contentRect
, ulong
(parameter) ulong styleMask
styleMask
,
ulong
(parameter) ulong backing
backing
, bool
(parameter) bool defer
defer
) @selector("initWithContentRect:styleMask:backing:defer:");
void
void app.NSWindow.setTitle(app.NSString title)
setTitle
(
(class) app.NSString
NSString
(parameter) app.NSString title
title
) @selector("setTitle:");
void
void app.NSWindow.setContentView(app.NSView view)
setContentView
(
(class) app.NSView
NSView
(parameter) app.NSView view
view
) @selector("setContentView:");
void
void app.NSWindow.setDelegate(app.NSObject anObject)
setDelegate
(
(class) app.NSObject
NSObject
(parameter) app.NSObject anObject
anObject
) @selector("setDelegate:");
void
void app.NSWindow.makeKeyAndOrderFront(app.NSObject sender)
makeKeyAndOrderFront
(
(class) app.NSObject
NSObject
(parameter) app.NSObject sender
sender
) @selector("makeKeyAndOrderFront:");
void
void app.NSWindow.setFrame(app.NSRect frameRect, bool display)
setFrame
(
(struct) app.NSRect
NSRect
(parameter) app.NSRect frameRect
frameRect
, bool
(parameter) bool display
display
) @selector("setFrame:display:");
(struct) app.NSRect
NSRect
app.NSRect app.NSWindow.frame()
frame
() @selector("frame");
(struct) app.NSRect
NSRect
app.NSRect app.NSWindow.frameRectForContentRect(app.NSRect contentRect)
frameRectForContentRect
(
(struct) app.NSRect
NSRect
(parameter) app.NSRect contentRect
contentRect
) @selector("frameRectForContentRect:");
double
double app.NSWindow.backingScaleFactor()
backingScaleFactor
() @selector("backingScaleFactor");
} // --- The custom NSView subclass, defined in D ---------------------------------- // A *non-extern* `extern (Objective-C)` class: the D compiler emits real // Objective-C class metadata, the runtime registers `GradientView` at load, and // AppKit dispatches `drawRect:` / `setFrameSize:` to the D method bodies below. // Bodyless `@selector` methods (alloc/initWithFrame) bind to the inherited // NSObject/NSView implementations. The view doubles as the window delegate // (`windowWillClose:`) and the NSTimer target (`tick:`) — delegate/timer lookup // is by selector, so no protocol declaration is needed. class
(class) app.GradientView
GradientView
:
(class) app.NSView
NSView
class `app.GradientView` Objective-C classes not supported
{ static
(class) app.GradientView
GradientView
app.GradientView app.GradientView.alloc()
alloc
() @selector("alloc");
(class) app.GradientView
GradientView
app.GradientView app.GradientView.initWithFrame(app.NSRect frame)
initWithFrame
(
(struct) app.NSRect
NSRect
(parameter) app.NSRect frame
frame
) @selector("initWithFrame:");
// AppKit's geometry callback to a view: called when the window sizes the // content view to fit (first call = our "first_configure") and on every // later window resize. Must forward to super or the view never resizes. override void
void app.GradientView.setFrameSize(app.NSSize newSize)
setFrameSize
(
(struct) app.NSSize
NSSize
(parameter) app.NSSize newSize
newSize
) @selector("setFrameSize:")
{ super.
super.setFrameSize
setFrameSize
(newSize);
onViewResized(newSize); } void
void app.GradientView.drawRect(app.NSRect dirtyRect)
drawRect
(
(struct) app.NSRect
NSRect
(parameter) app.NSRect dirtyRect
dirtyRect
) @selector("drawRect:")
{ onDrawRect(this.
this.bounds
bounds
());
} void
void app.GradientView.tick(app.NSTimer timer)
tick
(
(class) app.NSTimer
NSTimer
(parameter) app.NSTimer timer
timer
) @selector("tick:")
{ onTick(this); } void
void app.GradientView.windowWillClose(app.NSObject notification)
windowWillClose
(
(class) app.NSObject
NSObject
(parameter) app.NSObject notification
notification
) @selector("windowWillClose:")
{ instr("close_requested"); g_app.
g_app.terminate
terminate
(null);
} } extern (D): // back to D linkage for the rest of the module enum
(constant) int app.NSApplicationActivationPolicyRegular = 0
NSApplicationActivationPolicyRegular
= 0;
enum : ulong {
(enum value) app.NSWindowStyleMaskTitled = 1LU
NSWindowStyleMaskTitled
= 1,
(enum value) app.NSWindowStyleMaskClosable = 2LU
NSWindowStyleMaskClosable
= 2,
(enum value) app.NSWindowStyleMaskResizable = 8LU
NSWindowStyleMaskResizable
= 8,
} enum ulong
(constant) ulong app.NSBackingStoreBuffered = 2LU
NSBackingStoreBuffered
= 2;
enum long
(constant) long app.NSEventTypeApplicationDefined = 15L
NSEventTypeApplicationDefined
= 15;
// --- Demo state (single window — module globals keep the ObjC class trivial) --- __gshared
(class) app.NSApplication
NSApplication
(__gshared global) app.NSApplication app.g_app
g_app
;
__gshared
(class) app.NSWindow
NSWindow
(__gshared global) app.NSWindow app.g_win
g_win
;
__gshared uint*
(__gshared global) uint* app.g_buf
g_buf
; // CPU framebuffer, 0xAARRGGBB (BGRA bytes, LE)
__gshared
(alias) object.size_t = ulong
size_t
(__gshared global) ulong app.g_bufW
g_bufW
,
(__gshared global) ulong app.g_bufH
g_bufH
;
__gshared int
(__gshared global) int app.g_tick
g_tick
,
(__gshared global) int app.g_frames
g_frames
,
(__gshared global) int app.g_resizesSeen
g_resizesSeen
;
__gshared bool
(__gshared global) bool app.g_auto
g_auto
,
(__gshared global) bool app.g_hold
g_hold
;
__gshared bool
(__gshared global) bool app.g_firstConfigureSeen
g_firstConfigureSeen
,
(__gshared global) bool app.g_firstPixelSeen
g_firstPixelSeen
;
// Resize storm: 6 content-size changes, ending back at the initial size. immutable int[2][6]
(immutable global) immutable(int[2][6]) app.stormSizes
stormSizes
=
[[640, 400], [320, 240], [800, 520], [416, 288], [560, 352], [480, 320]]; enum
(constant) int app.stormStartTick = 30
stormStartTick
= 30;
enum
(constant) int app.stormStrideTicks = 3
stormStrideTicks
= 3;
enum
(constant) int app.autoExitTick = 120
autoExitTick
= 120;
enum
(constant) int app.holdExitTick = 600
holdExitTick
= 600; // ~10 s for the CGWindowList sidecar
// Corner-anchored diagonal gradient: geometry visibly tracks the window size // (per F02 — stretching or a stale buffer is immediately visible). void
void app.renderGradient(uint* buf, ulong w, ulong h) nothrow @nogc
renderGradient
(uint*
(parameter) uint* buf
buf
,
(alias) object.size_t = ulong
size_t
(parameter) ulong w
w
,
(alias) object.size_t = ulong
size_t
(parameter) ulong h
h
) nothrow @nogc
{ foreach (
(parameter) y
y
; 0 .. h)
foreach (
(parameter) x
x
; 0 .. w)
{ immutable
_error_ r
r
= cast(uint) (x * 255 / w);
immutable
_error_ g
g
= cast(uint) (y * 255 / h);
immutable
_error_ b
b
= cast(uint) ((x + y) * 255 / (w + h));
buf[y * w + x] = 0xFF00_0000 | (r << 16) | (g << 8) | b; } } void
void app.onViewResized(app.NSSize size)
onViewResized
(
(struct) app.NSSize
NSSize
(parameter) app.NSSize size
size
)
{ immutable double
_error_ scale
scale
= g_win !is null ? g_win.
g_win.backingScaleFactor
backingScaleFactor
() : 1.0;
if (!g_firstConfigureSeen) { g_firstConfigureSeen = true; instr("first_configure", "size=%dx%d scale=%.1f", cast(int) size.
size.width
width
, cast(int) size.
size.height
height
, scale);
} else { ++g_resizesSeen; instr("resize", "size=%dx%d scale=%.1f", cast(int) size.
size.width
width
, cast(int) size.
size.height
height
, scale);
} } void
void app.onDrawRect(app.NSRect bounds)
onDrawRect
(
(struct) app.NSRect
NSRect
(parameter) app.NSRect bounds
bounds
)
{ immutable double
_error_ scale
scale
= g_win.
g_win.backingScaleFactor
backingScaleFactor
();
immutable
(unresolved type) size_t
size_t
_error_ pw
pw
= cast(
(unresolved type) size_t
size_t
) (bounds.
bounds.size
size
.
bounds.size.width
width
* scale);
immutable
(unresolved type) size_t
size_t
_error_ ph
ph
= cast(
(unresolved type) size_t
size_t
) (bounds.
bounds.size
size
.
bounds.size.height
height
* scale);
if (pw == 0 || ph == 0) return; // Per-resize realloc (the simplest strategy — a finding for F02). if (pw != g_bufW || ph != g_bufH) { free(g_buf); g_buf = cast(uint*) malloc(pw * ph * 4); g_bufW = pw; g_bufH = ph; instr("buffer_alloc", "size=%zux%zu bytes=%zu", pw, ph, pw * ph * 4); } renderGradient(g_buf, pw, ph); // Wrap the pixel buffer in a CGImage and draw it into the view's current // CGContext. The image is pw×ph *pixels* drawn into a points rect — Quartz // maps points->pixels via the context's CTM, so the blit is 1:1 on screen. void*
_error_ cs
cs
= CGColorSpaceCreateDeviceRGB();
void*
_error_ dp
dp
= CGDataProviderCreateWithData(null, g_buf, pw * ph * 4, null);
void*
_error_ img
img
= CGImageCreate(pw, ph, 8, 32, pw * 4, cs,
kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst, dp, null, false, kCGRenderingIntentDefault); void*
_error_ ctx
ctx
= NSGraphicsContext.
NSGraphicsContext.currentContext
currentContext
().
NSGraphicsContext.currentContext().CGContext
CGContext
();
CGContextDrawImage(ctx, bounds, img); CGImageRelease(img); CGDataProviderRelease(dp); CGColorSpaceRelease(cs); ++g_frames; if (!g_firstPixelSeen) { g_firstPixelSeen = true; // "Presented" = return of the first drawRect:. CoreAnimation may still // defer actual compositing to the end-of-cycle CATransaction commit — // this is the strongest confirmation AppKit gives a software renderer. instr("first_pixel_presented", "t=%d", g_frames); } instr("frame_callback", "t=%d", g_frames); } void
void app.onTick(app.GradientView view)
onTick
(
(class) app.GradientView
GradientView
(parameter) app.GradientView view
view
)
{ ++g_tick; view.
view.setNeedsDisplay
setNeedsDisplay
(true);
if (g_auto && !g_hold && g_tick >= stormStartTick && g_tick < stormStartTick + cast(int) stormSizes.length * stormStrideTicks && (g_tick - stormStartTick) % stormStrideTicks == 0) { immutable
_error_ size
size
= stormSizes[(g_tick - stormStartTick) / stormStrideTicks];
immutable
_error_ content
content
= NSRect(NSPoint(120, 120), NSSize(size[0], size[1]));
instr("step", "name=setFrame_display size=%dx%d", size[0], size[1]); g_win.
g_win.setFrame
setFrame
(g_win.
g_win.frameRectForContentRect
frameRectForContentRect
(content), true);
} if (!(g_auto || g_hold)) return; immutable
_error_ limit
limit
= g_hold ? holdExitTick : autoExitTick;
if (g_tick >= limit) { instr("step", "name=NSApp_stop tick=%d", g_tick); g_app.
g_app.stop
stop
(null);
// stop: is only checked after an event is dispatched; without a real // event in the queue [NSApp run] would keep blocking. Post a synthetic // application-defined event so the loop wakes up and exits.
(unresolved type) NSEvent
NSEvent
_error_ ev
ev
= NSEvent.
NSEvent.otherEventWithType
otherEventWithType
(NSEventTypeApplicationDefined,
NSPoint(0, 0), 0, 0, 0, null, 0, 0, 0); g_app.
g_app.postEvent
postEvent
(ev, true);
} } int
int D main()
main
()
{ g_auto = getenv("WSI_AUTO_EXIT") !is null; g_hold = getenv("WSI_HOLD") !is null; instrInit("APPKIT"); instr("init_start", "auto_exit=%d hold=%d", g_auto ? 1 : 0, g_hold ? 1 : 0); instr("step", "name=CGMainDisplayID"); if (CGMainDisplayID() == 0) { printf("SKIP: no macOS window server (CGMainDisplayID == 0)\n"); return 0; } // objective-d's autorelease pool wraps the AppKit setup; [NSApp run] drains // its own per-event pools. auto
_error_ pool
pool
= autoreleasepool_push();
scope (exit) autoreleasepool_pop(pool); // 1. The shared application object (connects to the WindowServer). instr("step", "name=NSApplication_sharedApplication"); g_app = NSApplication.
NSApplication.sharedApplication
sharedApplication
();
instr("step", "name=setActivationPolicy policy=regular"); g_app.
g_app.setActivationPolicy
setActivationPolicy
(NSApplicationActivationPolicyRegular);
// 2. A titled, closable, resizable window with a buffered backing store. immutable
_error_ contentRect
contentRect
= NSRect(NSPoint(120, 120), NSSize(480, 320));
instr("step", "name=NSWindow_initWithContentRect size=480x320"); g_win = NSWindow.
NSWindow.alloc
alloc
().
NSWindow.alloc().initWithContentRect
initWithContentRect
(contentRect,
NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable, NSBackingStoreBuffered, false); g_win.
g_win.setTitle
setTitle
(NSString.
NSString.alloc
alloc
().
NSString.alloc().initWithUTF8String
initWithUTF8String
("wsi-scaffold"));
instr("window_created", "scale=%.1f", g_win.
g_win.backingScaleFactor
backingScaleFactor
());
// 3. The D-defined NSView subclass becomes the content view; installing it // triggers the first setFrameSize: (-> first_configure). It also serves // as window delegate for windowWillClose:. instr("step", "name=GradientView_initWithFrame");
(unresolved type) GradientView
GradientView
_error_ view
view
= GradientView.
GradientView.alloc
alloc
().
GradientView.alloc().initWithFrame
initWithFrame
(contentRect);
instr("step", "name=setContentView"); g_win.
g_win.setContentView
setContentView
(view);
g_win.
g_win.setDelegate
setDelegate
(view);
// 4. Show + activate. instr("step", "name=makeKeyAndOrderFront"); g_win.
g_win.makeKeyAndOrderFront
makeKeyAndOrderFront
(null);
g_app.
g_app.activateIgnoringOtherApps
activateIgnoringOtherApps
(true);
// 5. A ~16 ms repeating NSTimer on the run loop drives setNeedsDisplay: // (and the auto-exit/storm schedule). AppKit coalesces the dirty marks // into drawRect: calls on the next run-loop drawing pass. instr("step", "name=NSTimer_scheduledTimerWithTimeInterval interval_ms=16"); NSTimer.
NSTimer.scheduledTimerWithTimeInterval
scheduledTimerWithTimeInterval
(0.016, view, SEL.register("tick:"),
null, true); // 6. Cede the main thread to AppKit. Returns only after [NSApp stop:]. instr("step", "name=NSApp_run"); g_app.
g_app.run
run
();
instr("loop_exit", "frames=%d ticks=%d resizes=%d", g_frames, g_tick, g_resizesSeen); free(g_buf); return 0; }