app.dhover×346 error×20all
// macOS/AppKit F02 demo — resize correctness (../../../features/f02-resize.md).
// A continuously refreshed, corner-anchored gradient survives a three-phase
// programmatic resize storm:
//   phase 1: eight setFrame:display:YES content-size changes (incl. odd sizes),
//   phase 2: three setContentSize: changes (the content-rect-first resize API),
//   phase 3: zoom: (a maximize-like state transition) and zoom: again to restore.
// Every geometry event is logged with BOTH the logical (point) and the physical
// (pixel, via convertRectToBacking:) size plus backingScaleFactor, and the demo
// asserts pixels == points × scale on each one (the Retina buffer-math deliverable).
// viewWillStartLiveResize/viewDidEndLiveResize and viewDidChangeBackingProperties
// are instrumented to prove which callbacks programmatic resizes do NOT trigger.
// Findings: ../../f02-resize.md; recipe and build command: ../../scaffold.md.
//
// Modes (environment variables):
//   WSI_AUTO_EXIT=1  bounded run: a ~16 ms NSTimer drives setNeedsDisplay:; the
//                    storm phases run on the tick schedule above; after ~135
//                    ticks [NSApp stop:nil] (plus a synthetic
//                    NSEventTypeApplicationDefined post) -> exit 0 (exit 1 if
//                    any point/pixel assertion failed).
//   (neither)        runs until the window closes — no storm, so a human can
//                    drag the window border and capture the *interactive*
//                    live-resize sequence (Tier C; see the manual-run queue).
//
// 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");
(struct) app.NSRect
NSRect
app.NSRect app.NSView.convertRectToBacking(app.NSRect rect)
convertRectToBacking
(
(struct) app.NSRect
NSRect
(parameter) app.NSRect rect
rect
) @selector("convertRectToBacking:");
} 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:");
void
void app.NSWindow.setContentSize(app.NSSize size)
setContentSize
(
(struct) app.NSSize
NSSize
(parameter) app.NSSize size
size
) @selector("setContentSize:");
void
void app.NSWindow.zoom(app.NSObject sender)
zoom
(
(class) app.NSObject
NSObject
(parameter) app.NSObject sender
sender
) @selector("zoom:");
bool
bool app.NSWindow.isZoomed()
isZoomed
() @selector("isZoomed");
(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 per the scaffold recipe: bodied // @selector methods are the subclass implementation; bodyless alloc/initWithFrame // bind to the inherited implementations. drawRect:/tick:/windowWillClose:/ // windowDidResize:/viewWillStartLiveResize/viewDidEndLiveResize/ // viewDidChangeBackingProperties are dispatched by selector and need no base // declaration — defining them with the right @selector shadows the NSView/ // delegate defaults. 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: the first call fires synchronously // inside setContentView: (our "first_configure"); every later call is one // `resize` event. 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(this, newSize); } void
void app.GradientView.drawRect(app.NSRect dirtyRect)
drawRect
(
(struct) app.NSRect
NSRect
(parameter) app.NSRect dirtyRect
dirtyRect
) @selector("drawRect:")
{ onDrawRect(this, this.
this.bounds
bounds
());
} // Interactive (mouse-drag) resize brackets — instrumented to prove they do // NOT fire for programmatic setFrame:/setContentSize:/zoom: (F02 finding; // the interactive path is Tier C, see the manual-run queue). void
void app.GradientView.viewWillStartLiveResize()
viewWillStartLiveResize
() @selector("viewWillStartLiveResize")
{ instr("live_resize_start"); } void
void app.GradientView.viewDidEndLiveResize()
viewDidEndLiveResize
() @selector("viewDidEndLiveResize")
{ instr("live_resize_end"); } // Fires when the backing scale changes (e.g. window moved between a 1x and // a 2x display) — expected absent in this single-display storm. void
void app.GradientView.viewDidChangeBackingProperties()
viewDidChangeBackingProperties
() @selector("viewDidChangeBackingProperties")
{ immutable double
_error_ scale
scale
= g_win !is null ? g_win.
g_win.backingScaleFactor
backingScaleFactor
() : 0.0;
instr("backing_changed", "scale=%.1f", scale); } void
void app.GradientView.tick(app.NSTimer timer)
tick
(
(class) app.NSTimer
NSTimer
(parameter) app.NSTimer timer
timer
) @selector("tick:")
{ onTick(this); } // NSWindowDelegate notification — ordering vs setFrameSize: is a finding. void
void app.GradientView.windowDidResize(app.NSObject notification)
windowDidResize
(
(class) app.NSObject
NSObject
(parameter) app.NSObject notification
notification
) @selector("windowDidResize:")
{ immutable
_error_ f
f
= g_win.
g_win.frame
frame
();
instr("window_did_resize", "frame=%dx%d zoomed=%d", cast(int) f.
f.size
size
.
f.size.width
width
, cast(int) f.
f.size
size
.
f.size.height
height
,
g_win.
g_win.isZoomed
isZoomed
() ? 1 : 0);
} 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 global) int app.g_buffersAllocated
g_buffersAllocated
,
(__gshared global) int app.g_mismatches
g_mismatches
;
__gshared bool
(__gshared global) bool app.g_auto
g_auto
;
__gshared bool
(__gshared global) bool app.g_firstConfigureSeen
g_firstConfigureSeen
,
(__gshared global) bool app.g_stopRequested
g_stopRequested
;
// Phase 1 — setFrame:display:YES storm: eight content sizes, including odd // point sizes (333x217, 415x289) to exercise the points->pixels rounding, ending // back at the initial size. immutable int[2][8]
(immutable global) immutable(int[2][8]) app.frameStormSizes
frameStormSizes
= [
[640, 400], [320, 240], [800, 520], [333, 217], [1024, 640], [415, 289], [560, 352], [480, 320], ]; enum
(constant) int app.frameStormStartTick = 30
frameStormStartTick
= 30;
// Phase 2 — setContentSize: storm (resizes the content rect in place; the // window's top-left is kept, so the *bottom* edge moves in AppKit's y-up space). immutable int[2][3]
(immutable global) immutable(int[2][3]) app.contentStormSizes
contentStormSizes
= [[600, 380], [280, 200], [480, 320]];
enum
(constant) int app.contentStormStartTick = 60
contentStormStartTick
= 60;
enum
(constant) int app.stormStrideTicks = 3
stormStrideTicks
= 3;
enum
(constant) int app.zoomTick = 75
zoomTick
= 75; // zoom: #1 — maximize-like transition
enum
(constant) int app.unzoomTick = 95
unzoomTick
= 95; // zoom: #2 — restore the saved user frame
enum
(constant) int app.autoExitTick = 135
autoExitTick
= 135;
// 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; } } // Round a point extent to pixels the way AppKit does (scale is 1.0 or 2.0, so // this is exact for integer point sizes). long
long app.pixelsFor(double points, double scale) nothrow @nogc
pixelsFor
(double
(parameter) double points
points
, double
(parameter) double scale
scale
) nothrow @nogc
{ return cast(long) (points * scale + 0.5); } void
void app.onViewResized(app.GradientView view, app.NSSize size)
onViewResized
(
(class) app.GradientView
GradientView
(parameter) app.GradientView view
view
,
(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;
// Physical size as AppKit reports it (convertRectToBacking:) vs the naive // points × scale math — asserting they agree is the Retina deliverable. immutable
_error_ backing
backing
= view.
view.convertRectToBacking
convertRectToBacking
(NSRect(NSPoint(0, 0), size));
immutable long
_error_ pw
pw
= cast(long) backing.
backing.size
size
.
backing.size.width
width
;
immutable long
_error_ ph
ph
= cast(long) backing.
backing.size
size
.
backing.size.height
height
;
immutable bool
_error_ match
match
= pw == pixelsFor(size.
size.width
width
, scale)
&& ph == pixelsFor(size.
size.height
height
, scale);
if (!match) ++g_mismatches; if (!g_firstConfigureSeen) { g_firstConfigureSeen = true; instr("first_configure", "points=%dx%d pixels=%lldx%lld scale=%.1f match=%d", cast(int) size.
size.width
width
, cast(int) size.
size.height
height
, pw, ph, scale, match ? 1 : 0);
} else { ++g_resizesSeen; instr("resize", "points=%dx%d pixels=%lldx%lld scale=%.1f match=%d", cast(int) size.
size.width
width
, cast(int) size.
size.height
height
, pw, ph, scale, match ? 1 : 0);
} } void
void app.onDrawRect(app.GradientView view, app.NSRect bounds)
onDrawRect
(
(class) app.GradientView
GradientView
(parameter) app.GradientView view
view
,
(struct) app.NSRect
NSRect
(parameter) app.NSRect bounds
bounds
)
{ // Buffer size from convertRectToBacking: — the authoritative points->pixels // mapping (identical to bounds × backingScaleFactor; asserted in // onViewResized on every geometry change). immutable
_error_ backing
backing
= view.
view.convertRectToBacking
convertRectToBacking
(bounds);
immutable
(unresolved type) size_t
size_t
_error_ pw
pw
= cast(
(unresolved type) size_t
size_t
) backing.
backing.size
size
.
backing.size.width
width
;
immutable
(unresolved type) size_t
size_t
_error_ ph
ph
= cast(
(unresolved type) size_t
size_t
) backing.
backing.size
size
.
backing.size.height
height
;
if (pw == 0 || ph == 0) return; // Buffer strategy: per-resize free+malloc, no pooling — reallocation only // when the pixel size actually changed (an F02 finding; see ../../f02-resize.md). if (pw != g_bufW || ph != g_bufH) { free(g_buf); g_buf = cast(uint*) malloc(pw * ph * 4); g_bufW = pw; g_bufH = ph; ++g_buffersAllocated; instr("buffer_alloc", "size=%zux%zu bytes=%zu n=%d", pw, ph, pw * ph * 4, g_buffersAllocated); } 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; instr("frame_callback", "t=%d points=%dx%d pixels=%zux%zu", g_frames, cast(int) bounds.
bounds.size
size
.
bounds.size.width
width
, cast(int) bounds.
bounds.size
size
.
bounds.size.height
height
, pw, ph);
} void
void app.runStormStep(int tick)
runStormStep
(int
(parameter) int tick
tick
)
{ // Phase 1: setFrame:display:YES — frame rect computed from the content rect. immutable
_error_ f1End
f1End
= frameStormStartTick + cast(int) frameStormSizes.length * stormStrideTicks;
if (tick >= frameStormStartTick && tick < f1End && (tick - frameStormStartTick) % stormStrideTicks == 0) { immutable
_error_ size
size
= frameStormSizes[(tick - frameStormStartTick) / 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);
return; } // Phase 2: setContentSize: — the content-rect-first API, no display flag. immutable
_error_ f2End
f2End
= contentStormStartTick + cast(int) contentStormSizes.length * stormStrideTicks;
if (tick >= contentStormStartTick && tick < f2End && (tick - contentStormStartTick) % stormStrideTicks == 0) { immutable
_error_ size
size
= contentStormSizes[(tick - contentStormStartTick) / stormStrideTicks];
instr("step", "name=setContentSize size=%dx%d", size[0], size[1]); g_win.
g_win.setContentSize
setContentSize
(NSSize(size[0], size[1]));
return; } // Phase 3: zoom: twice — a maximize-like state transition and its restore. if (tick == zoomTick || tick == unzoomTick) { instr("step", "name=zoom pre_zoomed=%d", g_win.
g_win.isZoomed
isZoomed
() ? 1 : 0);
g_win.
g_win.zoom
zoom
(null);
instr("step", "name=zoom_returned zoomed=%d", g_win.
g_win.isZoomed
isZoomed
() ? 1 : 0);
} } void
void app.onTick(app.GradientView view)
onTick
(
(class) app.GradientView
GradientView
(parameter) app.GradientView view
view
)
{ ++g_tick; view.
view.setNeedsDisplay
setNeedsDisplay
(true); // continuous refresh; AppKit coalesces dirty marks
if (!g_auto) return; // interactive mode: no storm — drag the border instead (Tier C) runStormStep(g_tick); if (g_tick < autoExitTick || g_stopRequested) return; g_stopRequested = true; 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; instrInit("APPKIT_F02"); instr("init_start", "auto_exit=%d", g_auto ? 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); instr("step", "name=NSApplication_sharedApplication"); g_app = NSApplication.
NSApplication.sharedApplication
sharedApplication
();
instr("step", "name=setActivationPolicy policy=regular"); g_app.
g_app.setActivationPolicy
setActivationPolicy
(NSApplicationActivationPolicyRegular);
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-f02"));
instr("window_created", "scale=%.1f", g_win.
g_win.backingScaleFactor
backingScaleFactor
());
// The D-defined NSView subclass becomes the content view (first // setFrameSize: -> first_configure fires synchronously inside // setContentView:) and the window delegate (windowDidResize:/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);
instr("step", "name=makeKeyAndOrderFront"); g_win.
g_win.makeKeyAndOrderFront
makeKeyAndOrderFront
(null);
g_app.
g_app.activateIgnoringOtherApps
activateIgnoringOtherApps
(true);
// A ~16 ms repeating NSTimer drives setNeedsDisplay: and the storm schedule. instr("step", "name=NSTimer_scheduledTimerWithTimeInterval interval_ms=16"); NSTimer.
NSTimer.scheduledTimerWithTimeInterval
scheduledTimerWithTimeInterval
(0.016, view, SEL.register("tick:"),
null, true); instr("step", "name=NSApp_run"); g_app.
g_app.run
run
();
instr("loop_exit", "frames=%d ticks=%d resizes=%d buffers=%d mismatches=%d", g_frames, g_tick, g_resizesSeen, g_buffersAllocated, g_mismatches); free(g_buf); return g_mismatches == 0 ? 0 : 1; }