app.dhover×492 error×20all
// macOS/AppKit F10 demo — pointer lock / confine / relative motion
// (../../../features/f10-pointer-capture.md).
// The mouselook problem on macOS is assembled from three independent pieces:
// stop the cursor (CGAssociateMouseAndMouseCursorPosition(false)), hide it
// (NSCursor.hide — app-scoped counter — vs CGDisplayHideCursor — per-display),
// and read relative motion (NSEvent.deltaX/deltaY on mouseMoved:, which keeps
// flowing while the cursor is pinned). There is NO public confine-to-rect API;
// this demo implements the warp-back workaround and logs its artifacts.
//
// What it logs (A[ssh]; locked console — no real pointer, so motion is driven by
// synthetic NSEvents dispatched in-process, the f06/f07 route-1 workhorse):
//   - lock enter/exit: CGAssociateMouseAndMouseCursorPosition return value (and
//     the absence of any read-back getter), NSCursor.hide/unhide pairing,
//     saved-position capture + CGWarpMouseCursorPosition restore on exit;
//   - the two ways to build a delta-bearing synthetic mouseMoved:
//       a. +[NSEvent mouseEventWithType:...] — the constructor has NO delta
//          parameters; the wrapped event's deltaX/deltaY are the probe;
//       b. CGEventCreateMouseEvent + CGEventSetIntegerValueField(
//          kCGMouseEventDeltaX/Y) wrapped via +[NSEvent eventWithCGEvent:] —
//          read back at the CG layer, at the wrapped-NSEvent layer, and at the
//          view's mouseMoved: (whatever delta survives each hop is the finding);
//   - CGWarpMouseCursorPosition: CGError + CGEventCreate location read-back
//     (does the warp move the CG-side pointer under a locked session?), whether
//     any mouseMoved is generated by the warp, and the classic suppression
//     interval (CGEventSourceGet/SetLocalEventsSuppressionInterval);
//   - CGDisplayHideCursor/CGDisplayShowCursor returns, contrasted with the
//     app-scoped NSCursor counter;
//   - the confine workaround: a center-half confine rect, scripted motion that
//     leaves it, warp-back + the artifact (the out-of-bounds event is already
//     delivered before the warp can react);
//   - a crosshair/angle readout (yaw/pitch integrated from deltas) drawn in
//     drawRect: (visible pixels are Tier C; the numbers are in the log).
//
// Modes: WSI_AUTO_EXIT=1 = bounded scripted run; without it the window stays up
// and a mouse click toggles mouselook for a manual (Tier C) session.
// Headless-safe: prints `SKIP:` and exits 0 when there is no window server.
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
;
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:
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:
// --- Geometry (NSPoint/NSRect are layout-identical to CGPoint/CGRect) ------------ 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
;
} // --- CoreGraphics C API ----------------------------------------------------------- extern (C) nothrow @nogc { uint
uint app.CGMainDisplayID() nothrow @nogc
CGMainDisplayID
();
(struct) app.NSRect
NSRect
app.NSRect app.CGDisplayBounds(uint display) nothrow @nogc
CGDisplayBounds
(uint
(parameter) uint display
display
);
// The lock trio: dissociate, warp, hide (display-scoped variant). int
int app.CGAssociateMouseAndMouseCursorPosition(uint connected) nothrow @nogc
CGAssociateMouseAndMouseCursorPosition
(uint
(parameter) uint connected
connected
); // CGError
int
int app.CGWarpMouseCursorPosition(app.NSPoint newPosition) nothrow @nogc
CGWarpMouseCursorPosition
(
(struct) app.NSPoint
NSPoint
(parameter) app.NSPoint newPosition
newPosition
); // CGError
int
int app.CGDisplayHideCursor(uint display) nothrow @nogc
CGDisplayHideCursor
(uint
(parameter) uint display
display
); // CGError
int
int app.CGDisplayShowCursor(uint display) nothrow @nogc
CGDisplayShowCursor
(uint
(parameter) uint display
display
); // CGError
// Pointer-position read-back + synthetic mouse events with delta fields. void*
void* app.CGEventCreate(void* source) nothrow @nogc
CGEventCreate
(void*
(parameter) void* source
source
);
(struct) app.NSPoint
NSPoint
app.NSPoint app.CGEventGetLocation(void* event) nothrow @nogc
CGEventGetLocation
(void*
(parameter) void* event
event
);
void*
void* app.CGEventCreateMouseEvent(void* source, uint type, app.NSPoint pos, uint button) nothrow @nogc
CGEventCreateMouseEvent
(void*
(parameter) void* source
source
, uint
(parameter) uint type
type
,
(struct) app.NSPoint
NSPoint
(parameter) app.NSPoint pos
pos
, uint
(parameter) uint button
button
);
void
void app.CGEventSetIntegerValueField(void* event, uint field, long value) nothrow @nogc
CGEventSetIntegerValueField
(void*
(parameter) void* event
event
, uint
(parameter) uint field
field
, long
(parameter) long value
value
);
long
long app.CGEventGetIntegerValueField(void* event, uint field) nothrow @nogc
CGEventGetIntegerValueField
(void*
(parameter) void* event
event
, uint
(parameter) uint field
field
);
// The classic warp-suppression-interval knob (per event source). void*
void* app.CGEventSourceCreate(int stateID) nothrow @nogc
CGEventSourceCreate
(int
(parameter) int stateID
stateID
);
double
double app.CGEventSourceGetLocalEventsSuppressionInterval(void* source) nothrow @nogc
CGEventSourceGetLocalEventsSuppressionInterval
(void*
(parameter) void* source
source
);
void
void app.CGEventSourceSetLocalEventsSuppressionInterval(void* source, double seconds) nothrow @nogc
CGEventSourceSetLocalEventsSuppressionInterval
(void*
(parameter) void* source
source
, double
(parameter) double seconds
seconds
);
void
void app.CFRelease(void* obj) nothrow @nogc
CFRelease
(void*
(parameter) void* obj
obj
);
void
void app.CGContextSetRGBFillColor(void* ctx, double r, double g, double b, double a) nothrow @nogc
CGContextSetRGBFillColor
(void*
(parameter) void* ctx
ctx
, double
(parameter) double r
r
, double
(parameter) double g
g
, double
(parameter) double b
b
, double
(parameter) double a
a
);
void
void app.CGContextFillRect(void* ctx, app.NSRect rect) nothrow @nogc
CGContextFillRect
(void*
(parameter) void* ctx
ctx
,
(struct) app.NSRect
NSRect
(parameter) app.NSRect rect
rect
);
} enum uint
(constant) uint app.kCGEventMouseMoved = 5u
kCGEventMouseMoved
= 5; // CGEventType
enum uint
(constant) uint app.kCGMouseEventDeltaX = 4u
kCGMouseEventDeltaX
= 4; // CGEventField
enum uint
(constant) uint app.kCGMouseEventDeltaY = 5u
kCGMouseEventDeltaY
= 5;
enum int
(constant) int app.kCGEventSourceStateCombinedSessionState = 0
kCGEventSourceStateCombinedSessionState
= 0;
// --- AppKit class declarations ---------------------------------------------------- extern (Objective-C): extern class
(class) app.NSObject
NSObject
class `app.NSObject` Objective-C classes not supported
{ } 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.NSEvent
NSEvent
:
(class) app.NSObject
NSObject
class `app.NSEvent` Objective-C classes not supported
{ static
(class) app.NSEvent
NSEvent
app.NSEvent app.NSEvent.mouseEventWithType(long type, app.NSPoint location, ulong modifierFlags, double timestamp, long windowNumber, app.NSObject context, long eventNumber, long clickCount, double pressure)
mouseEventWithType
(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
, long
(parameter) long eventNumber
eventNumber
,
long
(parameter) long clickCount
clickCount
, double
(parameter) double pressure
pressure
)
@selector("mouseEventWithType:location:modifierFlags:timestamp:windowNumber:context:eventNumber:clickCount:pressure:"); static
(class) app.NSEvent
NSEvent
app.NSEvent app.NSEvent.eventWithCGEvent(void* cgEvent)
eventWithCGEvent
(void*
(parameter) void* cgEvent
cgEvent
) @selector("eventWithCGEvent:");
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:"); static
(struct) app.NSPoint
NSPoint
app.NSPoint app.NSEvent.mouseLocation()
mouseLocation
() @selector("mouseLocation");
long
long app.NSEvent.type()
type
() @selector("type");
(struct) app.NSPoint
NSPoint
app.NSPoint app.NSEvent.locationInWindow()
locationInWindow
() @selector("locationInWindow");
double
double app.NSEvent.deltaX()
deltaX
() @selector("deltaX");
double
double app.NSEvent.deltaY()
deltaY
() @selector("deltaY");
long
long app.NSEvent.windowNumber()
windowNumber
() @selector("windowNumber");
(class) app.NSObject
NSObject
app.NSObject app.NSEvent.window()
window
() @selector("window");
} extern class
(class) app.NSCursor
NSCursor
:
(class) app.NSObject
NSObject
class `app.NSCursor` Objective-C classes not supported
{ static void
void app.NSCursor.hide()
hide
() @selector("hide");
static void
void app.NSCursor.unhide()
unhide
() @selector("unhide");
} 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
(parameter) NSObject target
target
,
SEL sel,
(class) app.NSObject
NSObject
userInfo, bool repeats)
@selector("scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:"); } extern class
(class) app.NSApplication
NSApplication
:
(class) app.NSObject
NSObject
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:");
} 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");
} extern class
(class) app.NSView
NSView
:
(class) app.NSObject
NSObject
class `app.NSView` Objective-C classes not supported
{ bool
bool app.NSView.acceptsFirstResponder()
acceptsFirstResponder
() @selector("acceptsFirstResponder");
(struct) app.NSRect
NSRect
app.NSRect app.NSView.bounds()
bounds
() @selector("bounds");
void
void app.NSView.setNeedsDisplay(bool flag)
setNeedsDisplay
(bool
(parameter) bool flag
flag
) @selector("setNeedsDisplay:");
} extern class
(class) app.NSWindow
NSWindow
:
(class) app.NSObject
NSObject
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.NSObject view)
setContentView
(
(class) app.NSObject
NSObject
(parameter) app.NSObject view
view
) @selector("setContentView:");
void
void app.NSWindow.makeKeyAndOrderFront(app.NSObject sender)
makeKeyAndOrderFront
(
(class) app.NSObject
NSObject
(parameter) app.NSObject sender
sender
) @selector("makeKeyAndOrderFront:");
bool
bool app.NSWindow.makeFirstResponder(app.NSObject responder)
makeFirstResponder
(
(class) app.NSObject
NSObject
(parameter) app.NSObject responder
responder
) @selector("makeFirstResponder:");
void
void app.NSWindow.sendEvent(app.NSEvent event)
sendEvent
(
(class) app.NSEvent
NSEvent
(parameter) app.NSEvent event
event
) @selector("sendEvent:");
long
long app.NSWindow.windowNumber()
windowNumber
() @selector("windowNumber");
(struct) app.NSRect
NSRect
app.NSRect app.NSWindow.frame()
frame
() @selector("frame");
(struct) app.NSRect
NSRect
app.NSRect app.NSWindow.convertRectToScreen(app.NSRect r)
convertRectToScreen
(
(struct) app.NSRect
NSRect
(parameter) app.NSRect r
r
) @selector("convertRectToScreen:");
bool
bool app.NSWindow.acceptsMouseMovedEvents()
acceptsMouseMovedEvents
() @selector("acceptsMouseMovedEvents");
void
void app.NSWindow.setAcceptsMouseMovedEvents(bool flag)
setAcceptsMouseMovedEvents
(bool
(parameter) bool flag
flag
) @selector("setAcceptsMouseMovedEvents:");
} // The mouselook view: logs abs+rel motion, integrates a yaw/pitch readout, and // enforces the confine rect (warp-back workaround) while it is active. class
(class) app.LookView
LookView
:
(class) app.NSView
NSView
class `app.LookView` Objective-C classes not supported
{ static
(class) app.LookView
LookView
app.LookView app.LookView.alloc()
alloc
() @selector("alloc");
(class) app.LookView
LookView
app.LookView app.LookView.initWithFrame(app.NSRect frame)
initWithFrame
(
(struct) app.NSRect
NSRect
(parameter) app.NSRect frame
frame
) @selector("initWithFrame:");
override bool
bool app.LookView.acceptsFirstResponder()
acceptsFirstResponder
() @selector("acceptsFirstResponder")
{ return true; } void
void app.LookView.drawRect(app.NSRect dirtyRect)
drawRect
(
(struct) app.NSRect
NSRect
(parameter) app.NSRect dirtyRect
dirtyRect
) @selector("drawRect:")
{ // Tier-C visual aid: dark field, confine region, crosshair at yaw/pitch. void*
_error_ ctx
ctx
= NSGraphicsContext.
NSGraphicsContext.currentContext
currentContext
().
NSGraphicsContext.currentContext().CGContext
CGContext
();
immutable
_error_ b
b
= this.
this.bounds
bounds
();
CGContextSetRGBFillColor(ctx, 0.12, 0.12, 0.14, 1); CGContextFillRect(ctx, b); if (g_confine) { CGContextSetRGBFillColor(ctx, 0.18, 0.22, 0.18, 1); CGContextFillRect(ctx, confineRectView(b)); } immutable
_error_ cx
cx
= b.
b.size
size
.
b.size.width
width
/ 2 + clampd(g_yaw, -100, 100);
immutable
_error_ cy
cy
= b.
b.size
size
.
b.size.height
height
/ 2 - clampd(g_pitch, -100, 100);
CGContextSetRGBFillColor(ctx, 0.9, 0.3, 0.2, 1); CGContextFillRect(ctx, NSRect(NSPoint(cx - 12, cy - 1), NSSize(24, 2))); CGContextFillRect(ctx, NSRect(NSPoint(cx - 1, cy - 12), NSSize(2, 24))); } void
void app.LookView.mouseMoved(app.NSEvent e)
mouseMoved
(
(class) app.NSEvent
NSEvent
(parameter) app.NSEvent e
e
) @selector("mouseMoved:")
{ onMotion(e, "mouseMoved"); } void
void app.LookView.mouseDragged(app.NSEvent e)
mouseDragged
(
(class) app.NSEvent
NSEvent
(parameter) app.NSEvent e
e
) @selector("mouseDragged:")
{ onMotion(e, "mouseDragged"); } void
void app.LookView.mouseDown(app.NSEvent e)
mouseDown
(
(class) app.NSEvent
NSEvent
(parameter) app.NSEvent e
e
) @selector("mouseDown:")
{ // Interactive (Tier C) toggle: click = mouselook on/off. instr("mouse_down", "lock_toggle=%d", g_lock ? 0 : 1); if (!g_auto) g_lock ? exitLock() : enterLock(); } void
void app.LookView.tick(app.NSTimer t)
tick
(
(class) app.NSTimer
NSTimer
(parameter) app.NSTimer t
t
) @selector("tick:")
{ onStep(); } } extern (D): // back to D linkage 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.NSEventTypeMouseMoved = 5L
NSEventTypeMouseMoved
= 5;
enum long
(constant) long app.NSEventTypeApplicationDefined = 15L
NSEventTypeApplicationDefined
= 15;
// --- Demo state ------------------------------------------------------------------- __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
(class) app.LookView
LookView
(__gshared global) app.LookView app.g_view
g_view
;
__gshared long
(__gshared global) long app.g_winNum
g_winNum
;
__gshared bool
(__gshared global) bool app.g_auto
g_auto
;
__gshared int
(__gshared global) int app.g_step
g_step
;
__gshared bool
(__gshared global) bool app.g_lock
g_lock
; // mouselook active
__gshared
(struct) app.NSPoint
NSPoint
(__gshared global) app.NSPoint app.g_savedCG
g_savedCG
; // CG-coord pointer position captured at lock enter
__gshared double
(__gshared global) double app.g_yaw
g_yaw
= 0,
(__gshared global) double app.g_pitch
g_pitch
= 0; // crosshair readout, degrees-ish
__gshared bool
(__gshared global) bool app.g_confine
g_confine
; // confine workaround active
__gshared
(struct) app.NSRect
NSRect
(__gshared global) app.NSRect app.g_confineScreen
g_confineScreen
; // confine rect in AppKit screen coords (y-up)
__gshared int
(__gshared global) int app.g_arrivals
g_arrivals
; // mouseMoved/mouseDragged deliveries
__gshared int
(__gshared global) int app.g_arrivalsAtWarp
g_arrivalsAtWarp
; // snapshot to detect warp-generated events
__gshared int
(__gshared global) int app.g_warps
g_warps
; // confine warp-backs issued
__gshared int
(__gshared global) int app.g_outOfBounds
g_outOfBounds
; // events delivered outside the confine rect
__gshared const(char)*
(__gshared global) const(char)* app.g_route
g_route
= "none"; // current injection route label
double
double app.clampd(double v, double lo, double hi) nothrow @nogc
clampd
(double
(parameter) double v
v
, double
(parameter) double lo
lo
, double
(parameter) double hi
hi
) nothrow @nogc
{ return v < lo ? lo : (v > hi ? hi : v); } // --- Coordinate helpers ----------------------------------------------------------- // AppKit screen coords are bottom-left-origin y-up; CG global coords are // top-left-origin y-down. Flip via the main display height (single-display box).
(struct) app.NSPoint
NSPoint
app.NSPoint app.screenToCG(app.NSPoint p)
screenToCG
(
(struct) app.NSPoint
NSPoint
(parameter) app.NSPoint p
p
)
{ immutable
_error_ db
db
= CGDisplayBounds(CGMainDisplayID());
return NSPoint(p.
p.x
x
, db.
db.size
size
.
db.size.height
height
- p.
p.y
y
);
}
(struct) app.NSPoint
NSPoint
app.NSPoint app.cgPointerLocation()
cgPointerLocation
()
{ void*
_error_ ev
ev
= CGEventCreate(null);
immutable
_error_ p
p
= CGEventGetLocation(ev);
CFRelease(ev); return p; } // Window-content point -> AppKit screen point (content view origin == window base).
(struct) app.NSPoint
NSPoint
app.NSPoint app.viewToScreen(app.NSPoint p)
viewToScreen
(
(struct) app.NSPoint
NSPoint
(parameter) app.NSPoint p
p
)
{ return g_win.
g_win.convertRectToScreen
convertRectToScreen
(NSRect(p, NSSize(1, 1))).
g_win.convertRectToScreen(NSRect(p, NSSize(1, 1))).origin
origin
;
}
(struct) app.NSRect
NSRect
app.NSRect app.confineRectView(app.NSRect b)
confineRectView
(
(struct) app.NSRect
NSRect
(parameter) app.NSRect b
b
)
{ // Center half of the content view. return NSRect(NSPoint(b.
b.size
size
.
b.size.width
width
/ 4, b.
b.size
size
.
b.size.height
height
/ 4),
NSSize(b.
b.size
size
.
b.size.width
width
/ 2, b.
b.size
size
.
b.size.height
height
/ 2));
} // --- Lock enter/exit --------------------------------------------------------------- void
void app.enterLock()
enterLock
()
{ g_savedCG = cgPointerLocation(); instr("lock_save", "cg_pos=(%.1f,%.1f)", g_savedCG.
g_savedCG.x
x
, g_savedCG.
g_savedCG.y
y
);
NSCursor.
NSCursor.hide
hide
();
instr("cursor", "op=NSCursor_hide scope=app note=balanced_counter"); immutable
_error_ err
err
= CGAssociateMouseAndMouseCursorPosition(0);
g_lock = true; // There is no CGGetAssociateMouseAndMouseCursorPosition — the association // state is write-only; the app must track it itself. instr("lock", "state=on assoc_err=%d readback=no_public_getter", err); } void
void app.exitLock()
exitLock
()
{ immutable
_error_ err
err
= CGAssociateMouseAndMouseCursorPosition(1);
immutable
_error_ werr
werr
= CGWarpMouseCursorPosition(g_savedCG);
immutable
_error_ after
after
= cgPointerLocation();
NSCursor.
NSCursor.unhide
unhide
();
instr("cursor", "op=NSCursor_unhide scope=app"); g_lock = false; instr("lock", "state=off assoc_err=%d restore_warp_err=%d target=(%.1f,%.1f) readback=(%.1f,%.1f)", err, werr, g_savedCG.
g_savedCG.x
x
, g_savedCG.
g_savedCG.y
y
, after.
after.x
x
, after.
after.y
y
);
} // --- Motion handling (the view's mouseMoved/mouseDragged funnel) ------------------- void
void app.onMotion(app.NSEvent e, const(char)* kind)
onMotion
(
(class) app.NSEvent
NSEvent
(parameter) app.NSEvent e
e
, const(char)*
(parameter) const(char)* kind
kind
)
{ ++g_arrivals; immutable
_error_ dx
dx
= e.
e.deltaX
deltaX
();
immutable
_error_ dy
dy
= e.
e.deltaY
deltaY
();
(unresolved type) NSPoint
NSPoint
_error_ p
p
= e.
e.locationInWindow
locationInWindow
();
// A window-less event (CGEvent-wrapped) reports locationInWindow in AppKit // screen coords already; a window-bound one needs conversion. immutable
(unresolved type) NSPoint
NSPoint
_error_ sp
sp
= e.
e.window
window
() !is null ? viewToScreen(p) : p;
instr("pointer", "abs x=%.1f y=%.1f screen=(%.1f,%.1f) kind=%s win=%ld", p.
p.x
x
, p.
p.y
y
, sp.
sp.x
x
, sp.
sp.y
y
, kind, e.
e.windowNumber
windowNumber
());
// NSEvent deltas are post-acceleration (WindowServer ballistics) — raw=0. // Raw counts would need IOHIDManager, below the window system. instr("pointer", "rel dx=%.2f dy=%.2f raw=0 route=%s", dx, dy, g_route); if (g_lock) { g_yaw += dx * 0.5; g_pitch += dy * 0.5; instr("mouselook", "yaw=%.2f pitch=%.2f", g_yaw, g_pitch); g_view.
g_view.setNeedsDisplay
setNeedsDisplay
(true);
} if (g_confine) enforceConfine(sp); } void
void app.enforceConfine(app.NSPoint screenPt)
enforceConfine
(
(struct) app.NSPoint
NSPoint
(parameter) app.NSPoint screenPt
screenPt
)
{ immutable
_error_ r
r
= g_confineScreen;
immutable
_error_ inX
inX
= screenPt.
screenPt.x
x
>= r.
r.origin
origin
.
r.origin.x
x
&& screenPt.
screenPt.x
x
<= r.
r.origin
origin
.
r.origin.x
x
+ r.
r.size
size
.
r.size.width
width
;
immutable
_error_ inY
inY
= screenPt.
screenPt.y
y
>= r.
r.origin
origin
.
r.origin.y
y
&& screenPt.
screenPt.y
y
<= r.
r.origin
origin
.
r.origin.y
y
+ r.
r.size
size
.
r.size.height
height
;
if (inX && inY) return; // The artifact: this event ALREADY arrived at an out-of-bounds position — // the warp is reactive, one event too late, every time the pointer leaves. ++g_outOfBounds; immutable
_error_ clamped
clamped
= NSPoint(
clampd(screenPt.
screenPt.x
x
, r.
r.origin
origin
.
r.origin.x
x
, r.
r.origin
origin
.
r.origin.x
x
+ r.
r.size
size
.
r.size.width
width
),
clampd(screenPt.
screenPt.y
y
, r.
r.origin
origin
.
r.origin.y
y
, r.
r.origin
origin
.
r.origin.y
y
+ r.
r.size
size
.
r.size.height
height
));
immutable
_error_ err
err
= CGWarpMouseCursorPosition(screenToCG(clamped));
++g_warps; instr("confine", "warp from=(%.1f,%.1f) to=(%.1f,%.1f) err=%d note=event_already_delivered_outside", screenPt.
screenPt.x
x
, screenPt.
screenPt.y
y
, clamped.
clamped.x
x
, clamped.
clamped.y
y
, err);
} // --- Synthetic motion injection ----------------------------------------------------- // Dispatch in-process: try [window sendEvent:]; if the view never sees it, fall // back to calling mouseMoved: directly (either outcome is logged). void
void app.dispatchMouse(app.NSEvent e, const(char)* label)
dispatchMouse
(
(class) app.NSEvent
NSEvent
(parameter) app.NSEvent e
e
, const(char)*
(parameter) const(char)* label
label
)
{ if (e is null) { instr("inject", "label=%s result=nil_event", label); return; } immutable
_error_ before
before
= g_arrivals;
g_route = "sendEvent"; g_win.
g_win.sendEvent
sendEvent
(e);
if (g_arrivals == before) { instr("route", "label=%s sendEvent=not_delivered fallback=direct", label); g_route = "direct"; g_view.
g_view.mouseMoved
mouseMoved
(e);
} else instr("route", "label=%s sendEvent=delivered", label); g_route = "none"; } // Probe (a): the plain NSEvent constructor — it has NO delta parameters. void
void app.injectPlainMove(app.NSPoint viewPt, const(char)* label)
injectPlainMove
(
(struct) app.NSPoint
NSPoint
(parameter) app.NSPoint viewPt
viewPt
, const(char)*
(parameter) const(char)* label
label
)
{
(unresolved type) NSEvent
NSEvent
_error_ e
e
= NSEvent.
NSEvent.mouseEventWithType
mouseEventWithType
(NSEventTypeMouseMoved, viewPt, 0, 0,
g_winNum, null, 0, 0, 0); instr("inject", "route=nsevent label=%s loc=(%.0f,%.0f) ctor_deltas=none wrapped_dx=%.2f wrapped_dy=%.2f", label, viewPt.
viewPt.x
x
, viewPt.
viewPt.y
y
, e.
e.deltaX
deltaX
(), e.
e.deltaY
deltaY
());
dispatchMouse(e, label); } // Probe (b): CGEvent with kCGMouseEventDeltaX/Y set, wrapped via eventWithCGEvent. void
void app.injectCGMove(app.NSPoint screenPt, long dx, long dy, const(char)* label)
injectCGMove
(
(struct) app.NSPoint
NSPoint
(parameter) app.NSPoint screenPt
screenPt
, long
(parameter) long dx
dx
, long
(parameter) long dy
dy
, const(char)*
(parameter) const(char)* label
label
)
{ void*
_error_ cg
cg
= CGEventCreateMouseEvent(null, kCGEventMouseMoved, screenToCG(screenPt), 0);
if (cg is null) { instr("inject", "route=cgevent_wrap label=%s result=create_failed", label); return; } CGEventSetIntegerValueField(cg, kCGMouseEventDeltaX, dx); CGEventSetIntegerValueField(cg, kCGMouseEventDeltaY, dy); instr("inject", "route=cgevent_wrap label=%s cg_dx=%ld cg_dy=%ld", label, CGEventGetIntegerValueField(cg, kCGMouseEventDeltaX), CGEventGetIntegerValueField(cg, kCGMouseEventDeltaY));
(unresolved type) NSEvent
NSEvent
_error_ e
e
= NSEvent.
NSEvent.eventWithCGEvent
eventWithCGEvent
(cg);
if (e !is null) instr("wrap", "label=%s type=%ld wrapped_dx=%.2f wrapped_dy=%.2f win=%ld", label, e.
e.type
type
(), e.
e.deltaX
deltaX
(), e.
e.deltaY
deltaY
(), e.
e.windowNumber
windowNumber
());
dispatchMouse(e, label); CFRelease(cg); } // --- The scripted run ---------------------------------------------------------------- void
void app.stopApp()
stopApp
()
{ instr("step", "name=NSApp_stop"); g_app.
g_app.stop
stop
(null);
(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); // stop: is only checked after an event dispatch
} void
void app.onStep()
onStep
()
{ if (!g_auto) return; immutable
_error_ b
b
= g_view.
g_view.bounds
bounds
();
immutable
_error_ center
center
= NSPoint(b.
b.size
size
.
b.size.width
width
/ 2, b.
b.size
size
.
b.size.height
height
/ 2);
switch (g_step) { case 0: // Baseline reads: AppKit vs CG pointer position, mouse-moved opt-in. { immutable
_error_ nsLoc
nsLoc
= NSEvent.
NSEvent.mouseLocation
mouseLocation
();
immutable
_error_ cgLoc
cgLoc
= cgPointerLocation();
instr("baseline", "nsevent_mouseLocation=(%.1f,%.1f) cgevent_location=(%.1f,%.1f) accepts_mouse_moved=%d", nsLoc.
nsLoc.x
x
, nsLoc.
nsLoc.y
y
, cgLoc.
cgLoc.x
x
, cgLoc.
cgLoc.y
y
,
g_win.
g_win.acceptsMouseMovedEvents
acceptsMouseMovedEvents
() ? 1 : 0);
} break; case 1: enterLock(); break; case 2: // (a) plain synthetic mouseMoved: no way to carry a delta. injectPlainMove(center, "plain_move_center"); break; case 3: // (b) CGEvent-backed with deltas. injectCGMove(viewToScreen(center), 12, -7, "cg_move_delta_12_-7"); break; case 4: injectCGMove(viewToScreen(center), 3, 4, "cg_move_delta_3_4"); break; case 5: // Warp while locked: CGError + CG-side read-back. { immutable
_error_ target
target
= screenToCG(viewToScreen(center));
immutable
_error_ before
before
= cgPointerLocation();
immutable
_error_ err
err
= CGWarpMouseCursorPosition(target);
immutable
_error_ after
after
= cgPointerLocation();
g_arrivalsAtWarp = g_arrivals; instr("warp", "target=(%.1f,%.1f) err=%d before=(%.1f,%.1f) after=(%.1f,%.1f)", target.
target.x
x
, target.
target.y
y
, err, before.
before.x
x
, before.
before.y
y
, after.
after.x
x
, after.
after.y
y
);
} break; case 6: // Did the warp synthesize any motion event? + suppression interval. { instr("warp_events", "arrivals_since_warp=%d note=warp_generates_no_events_documented", g_arrivals - g_arrivalsAtWarp); void*
_error_ src
src
= CGEventSourceCreate(kCGEventSourceStateCombinedSessionState);
if (src !is null) { immutable
_error_ def
def
= CGEventSourceGetLocalEventsSuppressionInterval(src);
CGEventSourceSetLocalEventsSuppressionInterval(src, 0.0); instr("suppression_interval", "default_s=%.3f set_s=0.000 readback_s=%.3f scope=per_event_source", def, CGEventSourceGetLocalEventsSuppressionInterval(src)); CFRelease(src); } else instr("suppression_interval", "result=source_create_failed"); } break; case 7: exitLock(); break; case 8: // Display-scoped hide/show, for contrast with NSCursor's app counter. { immutable
_error_ did
did
= CGMainDisplayID();
immutable
_error_ h
h
= CGDisplayHideCursor(did);
immutable
_error_ s
s
= CGDisplayShowCursor(did);
instr("cursor", "op=CGDisplayHideCursor err=%d display=%u scope=display", h, did); instr("cursor", "op=CGDisplayShowCursor err=%d display=%u scope=display", s, did); } break; case 9: // Confine workaround on: center half of the content view. { immutable
_error_ rv
rv
= confineRectView(b);
g_confineScreen = NSRect(viewToScreen(rv.
rv.origin
origin
), rv.
rv.size
size
);
g_confine = true; instr("confine", "rect_view=(%.0f,%.0f %.0fx%.0f) rect_screen=(%.0f,%.0f %.0fx%.0f) api=none_public mechanism=warp_back", rv.
rv.origin
origin
.
rv.origin.x
x
, rv.
rv.origin
origin
.
rv.origin.y
y
, rv.
rv.size
size
.
rv.size.width
width
, rv.
rv.size
size
.
rv.size.height
height
,
g_confineScreen.
g_confineScreen.origin
origin
.
g_confineScreen.origin.x
x
, g_confineScreen.
g_confineScreen.origin
origin
.
g_confineScreen.origin.y
y
,
g_confineScreen.
g_confineScreen.size
size
.
g_confineScreen.size.width
width
, g_confineScreen.
g_confineScreen.size
size
.
g_confineScreen.size.height
height
);
g_view.
g_view.setNeedsDisplay
setNeedsDisplay
(true);
} break; case 10: // Inside: no warp expected. injectCGMove(viewToScreen(center), 5, 0, "confine_inside"); break; case 11: // Past the right edge of the confine rect. injectCGMove(viewToScreen(NSPoint(b.
b.size
size
.
b.size.width
width
- 10, center.
center.y
y
)), 40, 0,
"confine_outside_right"); break; case 12: // Far past the top-left corner. injectCGMove(viewToScreen(NSPoint(5, b.
b.size
size
.
b.size.height
height
- 5)), -60, -50,
"confine_outside_topleft"); break; case 13: injectCGMove(viewToScreen(center), 10, 10, "confine_inside_again"); break; case 14: g_confine = false; instr("confine", "state=off out_of_bounds_deliveries=%d warps=%d", g_outOfBounds, g_warps); break; case 15: stopApp(); break; default: break; } ++g_step; } int
int D main()
main
()
{ g_auto = getenv("WSI_AUTO_EXIT") !is null; instrInit("APPKIT_F10"); 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; } auto
_error_ pool
pool
= autoreleasepool_push();
scope (exit) autoreleasepool_pop(pool); g_app = NSApplication.
NSApplication.sharedApplication
sharedApplication
();
g_app.
g_app.setActivationPolicy
setActivationPolicy
(NSApplicationActivationPolicyRegular);
immutable
_error_ contentRect
contentRect
= NSRect(NSPoint(120, 120), NSSize(480, 320));
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-f10-pointer-capture"));
g_view = LookView.
LookView.alloc
alloc
().
LookView.alloc().initWithFrame
initWithFrame
(NSRect(NSPoint(0, 0), contentRect.
contentRect.size
size
));
g_win.
g_win.setContentView
setContentView
(g_view);
g_win.
g_win.makeKeyAndOrderFront
makeKeyAndOrderFront
(null);
g_app.
g_app.activateIgnoringOtherApps
activateIgnoringOtherApps
(true);
g_win.
g_win.makeFirstResponder
makeFirstResponder
(g_view);
g_winNum = g_win.
g_win.windowNumber
windowNumber
();
// mouseMoved: is opt-in on macOS — without this, only drags arrive. immutable
_error_ beforeOptIn
beforeOptIn
= g_win.
g_win.acceptsMouseMovedEvents
acceptsMouseMovedEvents
();
g_win.
g_win.setAcceptsMouseMovedEvents
setAcceptsMouseMovedEvents
(true);
instr("window_created", "win_num=%ld accepts_mouse_moved_default=%d set=1", g_winNum, beforeOptIn ? 1 : 0); instr("step", "name=script_timer_start interval_ms=150"); NSTimer.
NSTimer.scheduledTimerWithTimeInterval
scheduledTimerWithTimeInterval
(0.15, g_view, SEL.register("tick:"), null, true);
instr("step", "name=NSApp_run"); g_app.
g_app.run
run
();
instr("loop_exit", "steps=%d arrivals=%d warps=%d", g_step, g_arrivals, g_warps); return 0; }