app.dhover×669 error×25all
// macOS/AppKit F07 demo — IME / text input via NSTextInputClient
// (../../../features/f07-text-input.md).
// F06 proved the boundary: WITHOUT NSTextInputClient, interpretKeyEvents: routes to
// the legacy single-arg insertText: and a synthetic dead key passes through verbatim
// (´ then e, never é). This demo implements the FULL NSTextInputClient protocol on a
// custom view and shows the boundary flipping: the same synthetic option-e + e pair
// now produces setMarkedText:"´" (composition pending, rendered inline with an
// underline) followed by insertText:"é" replacing the marked text.
//
// The view keeps a single-line editor model (committed UTF-16 buffer + inline marked
// text + caret) and logs EVERY protocol callback with its arguments — the call
// choreography is the deliverable. Conformance is attached at runtime
// (class_addProtocol with the AppKit-registered NSTextInputClient protocol), and the
// demo logs conformsToProtocol: before/after plus -[NSView inputContext] for a
// conforming vs a plain view (the "bespoke view exposes no inputContext" trap).
//
// Choreographed under WSI_AUTO_EXIT=1 (synthetic NSEvents through [window sendEvent:]
// -> keyDown: -> interpretKeyEvents:, the f06 route 1):
//   a. plain text "hi"            -> which insertText variant fires now?
//   b. option-e then e            -> dead-key composition through marked text
//   c. option-e then Esc          -> cancel mid-composition (unmarkText? cancelOperation:?)
//   d. option-e then focus loss   -> marked-text fate on resignFirstResponder
//   e. insertText:"X" range={0,2} -> direct replacementRange semantics on committed text
//   f. firstRectForCharacterRange at both ends -> the caret/candidate-window anchor math
// Real CJK (Pinyin) input needs an unlocked session + enabled IME -> Tier C script in
// ../../f07-text-input.md.
//
// 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
,
(alias) app.snprintf = int core.stdc.stdio.snprintf(scope char* s, ulong n, scope const(char*) format, scope const ...) nothrow @nogc
snprintf
;
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, Class, Protocol;
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:
extern (C) nothrow @nogc { uint
uint app.CGMainDisplayID() nothrow @nogc
CGMainDisplayID
();
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
);
// Route 2 (cgevent_wrap): a CGEvent created against a private event source gives // the NSEvent a real HID-style event backing (and the source owns dead-key state), // WITHOUT posting through the WindowServer tap (which f06 showed is not routed to // a locked, non-frontmost app). The CGEvent is wrapped in-process via // +[NSEvent eventWithCGEvent:] and dispatched straight to the view. void*
void* app.CGEventSourceCreate(int stateID) nothrow @nogc
CGEventSourceCreate
(int
(parameter) int stateID
stateID
);
void*
void* app.CGEventCreateKeyboardEvent(void* source, ushort vk, bool keyDown) nothrow @nogc
CGEventCreateKeyboardEvent
(void*
(parameter) void* source
source
, ushort
(parameter) ushort vk
vk
, bool
(parameter) bool keyDown
keyDown
);
void
void app.CGEventSetFlags(void* event, ulong flags) nothrow @nogc
CGEventSetFlags
(void*
(parameter) void* event
event
, ulong
(parameter) ulong flags
flags
);
void
void app.CFRelease(void* o) nothrow @nogc
CFRelease
(void*
(parameter) void* o
o
);
} enum int
(constant) int app.kCGEventSourceStatePrivate = -1
kCGEventSourceStatePrivate
= -1;
enum ulong
(constant) ulong app.kCGEventFlagMaskAlternate = 524288LU
kCGEventFlagMaskAlternate
= 1UL << 19;
// --- Cocoa geometry / NSRange ---------------------------------------------------- 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
;
} extern (C) struct
(struct) app.NSRange
NSRange
{ ulong
(field) ulong app.NSRange.location
location
,
(field) ulong app.NSRange.length
length
; // NSUInteger
} enum ulong
(constant) ulong app.NSNotFound = 9223372036854775807LU
NSNotFound
= 0x7FFF_FFFF_FFFF_FFFF; // NSIntegerMax
// --- AppKit class declarations --------------------------------------------------- extern (Objective-C): extern class
(class) app.NSObject
NSObject
class `app.NSObject` Objective-C classes not supported
{ bool
app.NSObject.respondsToSelector
respondsToSelector
(SEL
(parameter) SEL sel
sel
) @selector("respondsToSelector:");
Class
app.NSObject.objcClass
objcClass
() @selector("class");
} 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:");
(class) app.NSString
NSString
app.NSString app.NSString.initWithCharacters(const(ushort)* chars, ulong length)
initWithCharacters
(const(ushort)*
(parameter) const(ushort)* chars
chars
, ulong
(parameter) ulong length
length
)
@selector("initWithCharacters:length:"); const(char)*
const(char)* app.NSString.UTF8String()
UTF8String
() @selector("UTF8String");
ulong
ulong app.NSString.length()
length
() @selector("length");
ushort
ushort app.NSString.characterAtIndex(ulong index)
characterAtIndex
(ulong
(parameter) ulong index
index
) @selector("characterAtIndex:");
} extern class
(class) app.NSAttributedString
NSAttributedString
:
(class) app.NSObject
NSObject
class `app.NSAttributedString` Objective-C classes not supported
{ static
(class) app.NSAttributedString
NSAttributedString
app.NSAttributedString app.NSAttributedString.alloc()
alloc
() @selector("alloc");
(class) app.NSAttributedString
NSAttributedString
app.NSAttributedString app.NSAttributedString.initWithString(app.NSString s)
initWithString
(
(class) app.NSString
NSString
(parameter) app.NSString s
s
) @selector("initWithString:");
(class) app.NSString
NSString
app.NSString app.NSAttributedString.string()
string
() @selector("string");
} extern class
(class) app.NSArray
NSArray
:
(class) app.NSObject
NSObject
class `app.NSArray` Objective-C classes not supported
{ static
(class) app.NSArray
NSArray
app.NSArray app.NSArray.array()
array
() @selector("array");
static
(class) app.NSArray
NSArray
app.NSArray app.NSArray.arrayWithObject(app.NSObject o)
arrayWithObject
(
(class) app.NSObject
NSObject
(parameter) app.NSObject o
o
) @selector("arrayWithObject:");
} extern class
(class) app.NSResponder
NSResponder
:
(class) app.NSObject
NSObject
class `app.NSResponder` Objective-C classes not supported
{ void
void app.NSResponder.interpretKeyEvents(app.NSArray events)
interpretKeyEvents
(
(class) app.NSArray
NSArray
(parameter) app.NSArray events
events
) @selector("interpretKeyEvents:");
bool
bool app.NSResponder.becomeFirstResponder()
becomeFirstResponder
() @selector("becomeFirstResponder");
bool
bool app.NSResponder.resignFirstResponder()
resignFirstResponder
() @selector("resignFirstResponder");
} 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.keyEventWithType(long type, app.NSPoint location, ulong modifierFlags, double timestamp, long windowNumber, app.NSObject context, app.NSString characters, app.NSString charactersIgnoringModifiers, bool isARepeat, ushort keyCode)
keyEventWithType
(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
,
(class) app.NSString
NSString
(parameter) app.NSString characters
characters
,
(class) app.NSString
NSString
(parameter) app.NSString charactersIgnoringModifiers
charactersIgnoringModifiers
, bool
(parameter) bool isARepeat
isARepeat
, ushort
(parameter) ushort keyCode
keyCode
)
@selector("keyEventWithType:location:modifierFlags:timestamp:windowNumber:context:characters:charactersIgnoringModifiers:isARepeat:keyCode:"); 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
(class) app.NSEvent
NSEvent
app.NSEvent app.NSEvent.eventWithCGEvent(void* cgEvent)
eventWithCGEvent
(void*
(parameter) void* cgEvent
cgEvent
) @selector("eventWithCGEvent:");
ushort
ushort app.NSEvent.keyCode()
keyCode
() @selector("keyCode");
long
long app.NSEvent.type()
type
() @selector("type");
(class) app.NSString
NSString
app.NSString app.NSEvent.characters()
characters
() @selector("characters");
ulong
ulong app.NSEvent.modifierFlags()
modifierFlags
() @selector("modifierFlags");
} 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
(parameter) SEL 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");
} extern class
(class) app.NSTextInputContext
NSTextInputContext
:
(class) app.NSObject
NSObject
class `app.NSTextInputContext` Objective-C classes not supported
{ void
void app.NSTextInputContext.activate()
activate
() @selector("activate");
bool
bool app.NSTextInputContext.handleEvent(app.NSEvent e)
handleEvent
(
(class) app.NSEvent
NSEvent
(parameter) app.NSEvent e
e
) @selector("handleEvent:");
(class) app.NSString
NSString
app.NSString app.NSTextInputContext.selectedKeyboardInputSource()
selectedKeyboardInputSource
() @selector("selectedKeyboardInputSource");
} 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:");
} extern class
(class) app.NSView
NSView
:
(class) app.NSResponder
NSResponder
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:");
(struct) app.NSRect
NSRect
app.NSRect app.NSView.convertRect(app.NSRect rect, app.NSView view)
convertRect
(
(struct) app.NSRect
NSRect
(parameter) app.NSRect rect
rect
,
(class) app.NSView
NSView
(parameter) app.NSView view
view
) @selector("convertRect:toView:");
(struct) app.NSPoint
NSPoint
app.NSPoint app.NSView.convertPoint(app.NSPoint point, app.NSView view)
convertPoint
(
(struct) app.NSPoint
NSPoint
(parameter) app.NSPoint point
point
,
(class) app.NSView
NSView
(parameter) app.NSView view
view
) @selector("convertPoint:fromView:");
(class) app.NSTextInputContext
NSTextInputContext
app.NSTextInputContext app.NSView.inputContext()
inputContext
() @selector("inputContext");
} 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:");
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.convertRectToScreen(app.NSRect rect)
convertRectToScreen
(
(struct) app.NSRect
NSRect
(parameter) app.NSRect rect
rect
) @selector("convertRectToScreen:");
(struct) app.NSRect
NSRect
app.NSRect app.NSWindow.convertRectFromScreen(app.NSRect rect)
convertRectFromScreen
(
(struct) app.NSRect
NSRect
(parameter) app.NSRect rect
rect
) @selector("convertRectFromScreen:");
} // A focusable view WITHOUT NSTextInputClient: the focus-loss target, and the negative // control for -[NSView inputContext] (a bespoke view that never told AppKit it can // accept text input gets no input context at all — the Uno/sokol trap from the survey). class
(class) app.PlainView
PlainView
:
(class) app.NSView
NSView
class `app.PlainView` Objective-C classes not supported
{ static
(class) app.PlainView
PlainView
app.PlainView app.PlainView.alloc()
alloc
() @selector("alloc");
(class) app.PlainView
PlainView
app.PlainView app.PlainView.initWithFrame(app.NSRect frame)
initWithFrame
(
(struct) app.NSRect
NSRect
(parameter) app.NSRect frame
frame
) @selector("initWithFrame:");
override bool
bool app.PlainView.acceptsFirstResponder()
acceptsFirstResponder
() @selector("acceptsFirstResponder")
{ return true; } } // The editor view. Bodied methods implement NSTextInputClient (conformance metadata is // attached at runtime in main — see attachProtocol); the editor model lives in module // globals (g_text/g_marked/g_caret). class
(class) app.TextView
TextView
:
(class) app.NSView
NSView
class `app.TextView` Objective-C classes not supported
{ static
(class) app.TextView
TextView
app.TextView app.TextView.alloc()
alloc
() @selector("alloc");
(class) app.TextView
TextView
app.TextView app.TextView.initWithFrame(app.NSRect frame)
initWithFrame
(
(struct) app.NSRect
NSRect
(parameter) app.NSRect frame
frame
) @selector("initWithFrame:");
override bool
bool app.TextView.acceptsFirstResponder()
acceptsFirstResponder
() @selector("acceptsFirstResponder")
{ return true; } override bool
bool app.TextView.becomeFirstResponder()
becomeFirstResponder
() @selector("becomeFirstResponder")
{ instr("focus", "state=become"); return super.
super.becomeFirstResponder
becomeFirstResponder
();
} override bool
bool app.TextView.resignFirstResponder()
resignFirstResponder
() @selector("resignFirstResponder")
{ instr("focus", "state=resign has_marked=%d", g_hasMarked ? 1 : 0); immutable
_error_ r
r
= super.
super.resignFirstResponder
resignFirstResponder
();
logState("after_resign"); return r; } void
void app.TextView.keyDown(app.NSEvent e)
keyDown
(
(class) app.NSEvent
NSEvent
(parameter) app.NSEvent e
e
) @selector("keyDown:")
{
(unresolved type) NSString
NSString
_error_ txt
txt
= e.
e.characters
characters
();
instr("key", "code=%u text=%s", e.
e.keyCode
keyCode
(), txt !is null ? txt.
txt.UTF8String
UTF8String
() : "");
if (g_useIke) // WSI_USE_IKE=1: the NSResponder-convenience route { this.
this.interpretKeyEvents
interpretKeyEvents
(NSArray.
NSArray.arrayWithObject
arrayWithObject
(e));
instr("interpret_key_events", "returned code=%u", e.
e.keyCode
keyCode
());
return; } // The real-app pattern (interpretKeyEvents: does the same internally): offer // the event to the input context; only if it declines run the key bindings.
(unresolved type) NSTextInputContext
NSTextInputContext
_error_ ctx
ctx
= this.
this.inputContext
inputContext
();
immutable
_error_ handled
handled
= ctx !is null && ctx.
ctx.handleEvent
handleEvent
(e);
instr("handle_event", "ctx=%s handled=%d", ctx !is null ? "non-nil".ptr : "nil".ptr, handled ? 1 : 0); if (!handled) this.
this.interpretKeyEvents
interpretKeyEvents
(NSArray.
NSArray.arrayWithObject
arrayWithObject
(e));
} // --- NSTextInputClient ------------------------------------------------------- void
void app.TextView.insertTextRR(app.NSObject s, app.NSRange repl)
insertTextRR
(
(class) app.NSObject
NSObject
(parameter) app.NSObject s
s
,
(struct) app.NSRange
NSRange
(parameter) app.NSRange repl
repl
) @selector("insertText:replacementRange:")
{ char[48]
_error_ rb
rb
;
(unresolved type) NSString
NSString
_error_ str
str
= stringOf(s);
instr("tic_insert_text", "text=%s class=%s repl=%s", u8(str), s !is null ? s.
s.objcClass
objcClass
().name : "<nil>", rs(repl, rb));
(unresolved type) size_t
size_t
_error_ loc
loc
= g_caret,
_error_ del
del
= 0;
if (g_hasMarked) { loc = g_markedLoc; // insert replaces the pending marked text clearMarked(); } else if (repl.
repl.location
location
!= NSNotFound)
{ loc = cast(
(unresolved type) size_t
size_t
) repl.
repl.location
location
;
del = cast(
(unresolved type) size_t
size_t
) repl.
repl.length
length
;
} spliceCommitted(loc, del, str); g_caret = loc + nsLen(str); logState("insert"); this.
this.setNeedsDisplay
setNeedsDisplay
(true);
} // Legacy pre-NSTextInputClient sink — with conformance attached this must go dead // (in f06, without conformance, ALL text landed here). void
void app.TextView.insertTextLegacy(app.NSObject s)
insertTextLegacy
(
(class) app.NSObject
NSObject
(parameter) app.NSObject s
s
) @selector("insertText:")
{ instr("insert_text_legacy", "text=%s", u8(stringOf(s))); } void
void app.TextView.setMarkedTextSR(app.NSObject s, app.NSRange sel, app.NSRange repl)
setMarkedTextSR
(
(class) app.NSObject
NSObject
(parameter) app.NSObject s
s
,
(struct) app.NSRange
NSRange
(parameter) app.NSRange sel
sel
,
(struct) app.NSRange
NSRange
(parameter) app.NSRange repl
repl
)
@selector("setMarkedText:selectedRange:replacementRange:") { char[48]
_error_ rb1
rb1
,
_error_ rb2
rb2
;
(unresolved type) NSString
NSString
_error_ str
str
= stringOf(s);
instr("tic_set_marked_text", "text=%s class=%s sel=%s repl=%s", u8(str), s !is null ? s.
s.objcClass
objcClass
().name : "<nil>", rs(sel, rb1), rs(repl, rb2));
if (!g_hasMarked) g_markedLoc = repl.
repl.location
location
!= NSNotFound ? cast(
(unresolved type) size_t
size_t
) repl.
repl.location
location
: g_caret;
g_markedLen = nsLen(str); foreach (
(parameter) i
i
; 0 .. g_markedLen)
g_marked[i] = str.
str.characterAtIndex
characterAtIndex
(i);
g_hasMarked = g_markedLen > 0; // an empty string unmarks per the protocol docs g_selInMarked = sel; logState("set_marked"); this.
this.setNeedsDisplay
setNeedsDisplay
(true);
} void
void app.TextView.unmarkText()
unmarkText
() @selector("unmarkText")
{ instr("tic_unmark_text", "marked_len=%zu note=committing_pending_text", g_markedLen); // Per the protocol: accept the marked text as if it had been inserted normally. if (g_hasMarked) { spliceUtf16(g_markedLoc, 0, g_marked[0 .. g_markedLen]); g_caret = g_markedLoc + g_markedLen; clearMarked(); } logState("unmark"); this.
this.setNeedsDisplay
setNeedsDisplay
(true);
}
(struct) app.NSRange
NSRange
app.NSRange app.TextView.selectedRange()
selectedRange
() @selector("selectedRange")
{
(unresolved type) NSRange
NSRange
_error_ r
r
= g_hasMarked
? NSRange(g_markedLoc + g_selInMarked.
g_selInMarked.location
location
, g_selInMarked.
g_selInMarked.length
length
)
: NSRange(g_caret, 0); char[48]
_error_ rb
rb
;
instr("tic_selected_range", "-> %s", rs(r, rb)); return r; }
(struct) app.NSRange
NSRange
app.NSRange app.TextView.markedRange()
markedRange
() @selector("markedRange")
{
(unresolved type) NSRange
NSRange
_error_ r
r
= g_hasMarked ? NSRange(g_markedLoc, g_markedLen) : NSRange(NSNotFound, 0);
char[48]
_error_ rb
rb
;
instr("tic_marked_range", "-> %s", rs(r, rb)); return r; } bool
bool app.TextView.hasMarkedText()
hasMarkedText
() @selector("hasMarkedText")
{ instr("tic_has_marked_text", "-> %d", g_hasMarked ? 1 : 0); return g_hasMarked; }
(class) app.NSAttributedString
NSAttributedString
app.NSAttributedString app.TextView.attributedSubstring(app.NSRange range, app.NSRange* actual)
attributedSubstring
(
(struct) app.NSRange
NSRange
(parameter) app.NSRange range
range
,
(struct) app.NSRange
NSRange
*
(parameter) app.NSRange* actual
actual
)
@selector("attributedSubstringForProposedRange:actualRange:") { immutable
_error_ total
total
= docLen();
(unresolved type) size_t
size_t
_error_ loc
loc
= range.
range.location
location
> total ? total : cast(
(unresolved type) size_t
size_t
) range.
range.location
location
;
(unresolved type) size_t
size_t
_error_ len
len
= loc + range.
range.length
length
> total ? total - loc : cast(
(unresolved type) size_t
size_t
) range.
range.length
length
;
ushort[256]
_error_ tmp
tmp
;
foreach (
(parameter) i
i
; 0 .. len)
tmp[i] = docCharAt(loc + i); if (actual !is null) *actual = NSRange(loc, len); char[48]
_error_ rb
rb
;
instr("tic_attributed_substring", "range=%s actual={%zu,%zu}", rs(range, rb), loc, len);
(unresolved type) NSString
NSString
_error_ sub
sub
= NSString.
NSString.alloc
alloc
().
NSString.alloc().initWithCharacters
initWithCharacters
(tmp.ptr, len);
return NSAttributedString.
NSAttributedString.alloc
alloc
().
NSAttributedString.alloc().initWithString
initWithString
(sub);
}
(class) app.NSArray
NSArray
app.NSArray app.TextView.validAttributesForMarkedText()
validAttributesForMarkedText
() @selector("validAttributesForMarkedText")
{ instr("tic_valid_attributes", "-> empty"); return NSArray.
NSArray.array
array
();
} // The candidate-window anchor: the IME asks for the on-screen rect of a character // range; the answer must be in SCREEN coordinates. Logged on every call — this is // how a candidate window follows the caret.
(struct) app.NSRect
NSRect
app.NSRect app.TextView.firstRect(app.NSRange range, app.NSRange* actual)
firstRect
(
(struct) app.NSRange
NSRange
(parameter) app.NSRange range
range
,
(struct) app.NSRange
NSRange
*
(parameter) app.NSRange* actual
actual
)
@selector("firstRectForCharacterRange:actualRange:") { immutable
_error_ total
total
= docLen();
(unresolved type) size_t
size_t
_error_ loc
loc
= range.
range.location
location
== NSNotFound || range.
range.location
location
> total
? g_caret : cast(
(unresolved type) size_t
size_t
) range.
range.location
location
;
immutable
_error_ len
len
= range.
range.length
length
== 0 ? 1 : cast(
(unresolved type) size_t
size_t
) range.
range.length
length
;
immutable
_error_ viewRect
viewRect
= NSRect(NSPoint(textX + cellW * loc, baseY),
NSSize(cellW * len, cellH)); immutable
_error_ winRect
winRect
= this.
this.convertRect
convertRect
(viewRect, null);
immutable
_error_ scr
scr
= g_win.
g_win.convertRectToScreen
convertRectToScreen
(winRect);
if (actual !is null) *actual = NSRange(loc, range.
range.length
length
);
char[48]
_error_ rb
rb
;
instr("tic_first_rect", "range=%s view=(%.0f,%.0f %.0fx%.0f) screen=(%.0f,%.0f %.0fx%.0f)", rs(range, rb), viewRect.
viewRect.origin
origin
.
viewRect.origin.x
x
, viewRect.
viewRect.origin
origin
.
viewRect.origin.y
y
,
viewRect.
viewRect.size
size
.
viewRect.size.width
width
, viewRect.
viewRect.size
size
.
viewRect.size.height
height
, scr.
scr.origin
origin
.
scr.origin.x
x
, scr.
scr.origin
origin
.
scr.origin.y
y
,
scr.
scr.size
size
.
scr.size.width
width
, scr.
scr.size
size
.
scr.size.height
height
);
return scr; } ulong
ulong app.TextView.characterIndexForPoint(app.NSPoint screenPoint)
characterIndexForPoint
(
(struct) app.NSPoint
NSPoint
(parameter) app.NSPoint screenPoint
screenPoint
) @selector("characterIndexForPoint:")
{ immutable
_error_ winRect
winRect
= g_win.
g_win.convertRectFromScreen
convertRectFromScreen
(
NSRect(screenPoint, NSSize(0, 0))); immutable
_error_ vp
vp
= this.
this.convertPoint
convertPoint
(winRect.
winRect.origin
origin
, null);
immutable double
_error_ rel
rel
= (vp.
vp.x
x
- textX) / cellW;
immutable
_error_ total
total
= docLen();
(unresolved type) size_t
size_t
_error_ idx
idx
= rel < 0 ? 0 : cast(
(unresolved type) size_t
size_t
) rel;
if (idx > total) idx = total; instr("tic_character_index", "screen=(%.0f,%.0f) view_x=%.1f -> %zu", screenPoint.
screenPoint.x
x
, screenPoint.
screenPoint.y
y
, vp.
vp.x
x
, idx);
return idx; } void
app.TextView.doCommandBySelector
doCommandBySelector
(SEL
(parameter) SEL sel
sel
) @selector("doCommandBySelector:")
{ instr("do_command", "selector=%s has_marked=%d", sel.name, g_hasMarked ? 1 : 0); } // --- rendering: committed cells gray, marked cells blue with an underline ----- // (Text is rendered as colored character cells, not glyphs — the locked-screen // A[ssh] session composites nothing anyway; the marked/committed distinction and // the underline are what F07 requires to be visible in the model.) void
void app.TextView.drawRect(app.NSRect dirty)
drawRect
(
(struct) app.NSRect
NSRect
(parameter) app.NSRect dirty
dirty
) @selector("drawRect:")
{ void*
_error_ ctx
ctx
= NSGraphicsContext.
NSGraphicsContext.currentContext
currentContext
().
NSGraphicsContext.currentContext().CGContext
CGContext
();
CGContextSetRGBFillColor(ctx, 0.12, 0.12, 0.14, 1); CGContextFillRect(ctx, this.
this.bounds
bounds
());
immutable
_error_ total
total
= docLen();
foreach (
(parameter) i
i
; 0 .. total)
{ immutable
_error_ marked
marked
= g_hasMarked && i >= g_markedLoc && i < g_markedLoc + g_markedLen;
immutable
_error_ x
x
= textX + cellW * i;
if (marked) { CGContextSetRGBFillColor(ctx, 0.35, 0.55, 0.95, 1); // marked: blue cell CGContextFillRect(ctx, NSRect(NSPoint(x, baseY), NSSize(cellW - 1, cellH))); CGContextSetRGBFillColor(ctx, 1, 1, 1, 1); // + 2 pt underline CGContextFillRect(ctx, NSRect(NSPoint(x, baseY - 3), NSSize(cellW - 1, 2))); } else { CGContextSetRGBFillColor(ctx, 0.7, 0.7, 0.7, 1); // committed: gray cell CGContextFillRect(ctx, NSRect(NSPoint(x, baseY), NSSize(cellW - 1, cellH))); } } // caret: 1 pt vertical bar at the insertion point (display position) immutable
_error_ caretDisp
caretDisp
= g_hasMarked ? g_markedLoc + g_markedLen : g_caret;
CGContextSetRGBFillColor(ctx, 1, 0.85, 0.3, 1); CGContextFillRect(ctx, NSRect(NSPoint(textX + cellW * caretDisp, baseY - 1), NSSize(1, cellH + 2))); } void
void app.TextView.windowWillClose(app.NSObject notification)
windowWillClose
(
(class) app.NSObject
NSObject
(parameter) app.NSObject notification
notification
) @selector("windowWillClose:")
{ instr("close_requested"); g_app.
g_app.stop
stop
(null);
} } 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.NSEventTypeKeyDown = 10L
NSEventTypeKeyDown
= 10;
enum long
(constant) long app.NSEventTypeKeyUp = 11L
NSEventTypeKeyUp
= 11;
enum long
(constant) long app.NSEventTypeApplicationDefined = 15L
NSEventTypeApplicationDefined
= 15;
enum ulong
(constant) ulong app.NSEventModifierFlagOption = 524288LU
NSEventModifierFlagOption
= 1UL << 19;
// Single-line editor cell metrics (points; also the firstRect/characterIndex math). enum double
(constant) double app.textX = 10.0
textX
= 10,
(constant) double app.baseY = 20.0
baseY
= 20,
(constant) double app.cellW = 9.0
cellW
= 9,
(constant) double app.cellH = 16.0
cellH
= 16;
// --- 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.TextView
TextView
(__gshared global) app.TextView app.g_view
g_view
;
__gshared
(class) app.PlainView
PlainView
(__gshared global) app.PlainView app.g_plain
g_plain
;
__gshared long
(__gshared global) long app.g_winNum
g_winNum
;
__gshared int
(__gshared global) int app.g_step
g_step
;
__gshared void*
(__gshared global) void* app.g_cgSrc
g_cgSrc
; // private CGEventSource: owns dead-key state for route 2
__gshared bool
(__gshared global) bool app.g_useIke
g_useIke
; // WSI_USE_IKE=1: interpretKeyEvents: instead of handleEvent:
__gshared ushort[512]
(__gshared global) ushort[512] app.g_text
g_text
; // committed text, UTF-16 units
__gshared
(alias) object.size_t = ulong
size_t
(__gshared global) ulong app.g_textLen
g_textLen
;
__gshared
(alias) object.size_t = ulong
size_t
(__gshared global) ulong app.g_caret
g_caret
;
__gshared ushort[64]
(__gshared global) ushort[64] app.g_marked
g_marked
; // pending (pre-edit) text, rendered inline at g_markedLoc
__gshared
(alias) object.size_t = ulong
size_t
(__gshared global) ulong app.g_markedLoc
g_markedLoc
,
(__gshared global) ulong app.g_markedLen
g_markedLen
;
__gshared bool
(__gshared global) bool app.g_hasMarked
g_hasMarked
;
__gshared
(struct) app.NSRange
NSRange
(__gshared global) app.NSRange app.g_selInMarked
g_selInMarked
;
(alias) object.size_t = ulong
size_t
ulong app.nsLen(app.NSString s)
nsLen
(
(class) app.NSString
NSString
(parameter) app.NSString s
s
)
{ return s is null ? 0 : cast(
(unresolved type) size_t
size_t
) s.
s.length
length
();
} const(char)*
const(char)* app.u8(app.NSString s)
u8
(
(class) app.NSString
NSString
(parameter) app.NSString s
s
)
{ return s is null ? "<nil>" : s.
s.UTF8String
UTF8String
();
} // The `id` params of insertText:/setMarkedText: are NSString OR NSAttributedString.
(class) app.NSString
NSString
app.NSString app.stringOf(app.NSObject s)
stringOf
(
(class) app.NSObject
NSObject
(parameter) app.NSObject s
s
)
{ if (s is null) return null; if (s.
s.respondsToSelector
respondsToSelector
(SEL.register("string")))
return (cast(
(unresolved type) NSAttributedString
NSAttributedString
) s).
(cast(NSAttributedString)s).string
string
();
return cast(
(unresolved type) NSString
NSString
) s;
} const(char)*
const(char)* app.rs(in app.NSRange r, char[] buf)
rs
(in
(struct) app.NSRange
NSRange
(parameter) const(app.NSRange) r
r
, char[]
(parameter) char[] buf
buf
)
{ if (r.
r.location
location
== NSNotFound)
snprintf(buf.ptr, buf.
buf.length
length
, "{NSNotFound,%llu}", r.
r.length
length
);
else snprintf(buf.ptr, buf.
buf.length
length
, "{%llu,%llu}", r.
r.location
location
, r.
r.length
length
);
return buf.ptr; } void
void app.clearMarked()
clearMarked
()
{ g_hasMarked = false; g_markedLen = 0; g_selInMarked = NSRange(0, 0); } void
void app.spliceUtf16(ulong loc, ulong del, scope const(ushort)[] ins)
spliceUtf16
(
(alias) object.size_t = ulong
size_t
(parameter) ulong loc
loc
,
(alias) object.size_t = ulong
size_t
(parameter) ulong del
del
, scope const(ushort)[]
(parameter) const(ushort)[] ins
ins
)
{ if (loc > g_textLen) loc = g_textLen; if (loc + del > g_textLen) del = g_textLen - loc; immutable
_error_ newLen
newLen
= g_textLen - del + ins.
ins.length
length
;
if (newLen > g_text.
g_text.length
length
)
return; // shift the tail (forward iteration for a left shift, reverse for a right shift) if (ins.
ins.length
length
< del)
foreach (
(parameter) i
i
; 0 .. g_textLen - loc - del)
g_text[loc + ins.
ins.length
length
+ i] = g_text[loc + del + i];
else if (ins.
ins.length
length
> del)
foreach_reverse (
(parameter) i
i
; 0 .. g_textLen - loc - del)
g_text[loc + ins.
ins.length
length
+ i] = g_text[loc + del + i];
foreach (
(parameter) i
i
,
(parameter) u
u
; ins)
g_text[loc + i] = u; g_textLen = newLen; } void
void app.spliceCommitted(ulong loc, ulong del, app.NSString s)
spliceCommitted
(
(alias) object.size_t = ulong
size_t
(parameter) ulong loc
loc
,
(alias) object.size_t = ulong
size_t
(parameter) ulong del
del
,
(class) app.NSString
NSString
(parameter) app.NSString s
s
)
{ ushort[128]
_error_ tmp
tmp
;
immutable
_error_ n
n
= nsLen(s) > tmp.
tmp.length
length
? tmp.
tmp.length
length
: nsLen(s);
foreach (
(parameter) i
i
; 0 .. n)
tmp[i] = s.
s.characterAtIndex
characterAtIndex
(i);
spliceUtf16(loc, del, tmp[0 .. n]); }
(alias) object.size_t = ulong
size_t
ulong app.docLen()
docLen
()
{ return g_textLen + (g_hasMarked ? g_markedLen : 0); } ushort
ushort app.docCharAt(ulong i)
docCharAt
(
(alias) object.size_t = ulong
size_t
(parameter) ulong i
i
)
{ if (!g_hasMarked || i < g_markedLoc) return g_text[i]; if (i < g_markedLoc + g_markedLen) return g_marked[i - g_markedLoc]; return g_text[i - g_markedLen]; } // BMP-only UTF-16 -> UTF-8 (enough for ASCII/é/´); writes a NUL-terminated C string. void
void app.utf16ToUtf8(const(ushort)* s, ulong n, char* o) nothrow @nogc
utf16ToUtf8
(const(ushort)*
(parameter) const(ushort)* s
s
,
(alias) object.size_t = ulong
size_t
(parameter) ulong n
n
, char*
(parameter) char* o
o
) nothrow @nogc
{
(unresolved type) size_t
size_t
_error_ j
j
= 0;
foreach (
(parameter) i
i
; 0 .. n)
{ immutable uint
_error_ c
c
= s[i];
if (c < 0x80) o[j++] = cast(char) c; else if (c < 0x800) { o[j++] = cast(char)(0xC0 | (c >> 6)); o[j++] = cast(char)(0x80 | (c & 0x3F)); } else { o[j++] = cast(char)(0xE0 | (c >> 12)); o[j++] = cast(char)(0x80 | ((c >> 6) & 0x3F)); o[j++] = cast(char)(0x80 | (c & 0x3F)); } } o[j] = 0; } void
void app.logState(const(char)* at)
logState
(const(char)*
(parameter) const(char)* at
at
)
{ char[1600]
_error_ cb
cb
;
char[256]
_error_ mb
mb
;
utf16ToUtf8(g_text.ptr, g_textLen, cb.ptr); utf16ToUtf8(g_marked.ptr, g_markedLen, mb.ptr); instr("state", "at=%s text=\"%s\" caret=%zu marked=\"%s\" marked_at=%zu", at, cb.ptr, g_caret, mb.ptr, g_markedLoc); } // --- Synthetic key injection (f06 route 1) ---------------------------------------- struct
(struct) app.KeySpec
KeySpec
{ ushort
(field) ushort app.KeySpec.code
code
;
ulong
(field) ulong app.KeySpec.flags
flags
;
(alias) object.string = string
string
(field) string app.KeySpec.chars
chars
;
(alias) object.string = string
string
(field) string app.KeySpec.charsNoMod
charsNoMod
;
(alias) object.string = string
string
(field) string app.KeySpec.label
label
;
} immutable
(struct) app.KeySpec
KeySpec
(immutable global) immutable(app.KeySpec) app.optE
optE
=
(struct) app.KeySpec
KeySpec
(14,
(constant) ulong app.NSEventModifierFlagOption = 524288LU
NSEventModifierFlagOption
, "´", "e", "opt_e_deadacute");
void
void app.inject(in app.KeySpec k)
inject
(in
(struct) app.KeySpec
KeySpec
(parameter) const(app.KeySpec) k
k
)
{ instr("inject", "route=nsevent label=%.*s code=%u", cast(int) k.
k.label
label
.
k.label.length
length
, k.
k.label
label
.ptr, k.
k.code
code
);
(unresolved type) NSString
NSString
_error_ ch
ch
= NSString.
NSString.alloc
alloc
().
NSString.alloc().initWithUTF8String
initWithUTF8String
(k.
k.chars
chars
.ptr);
(unresolved type) NSString
NSString
_error_ cm
cm
= NSString.
NSString.alloc
alloc
().
NSString.alloc().initWithUTF8String
initWithUTF8String
(k.
k.charsNoMod
charsNoMod
.ptr);
g_win.
g_win.sendEvent
sendEvent
(NSEvent.
NSEvent.keyEventWithType
keyEventWithType
(NSEventTypeKeyDown, NSPoint(0, 0), k.
k.flags
flags
,
0, g_winNum, null, ch, cm, false, k.
k.code
code
));
g_win.
g_win.sendEvent
sendEvent
(NSEvent.
NSEvent.keyEventWithType
keyEventWithType
(NSEventTypeKeyUp, NSPoint(0, 0), k.
k.flags
flags
,
0, g_winNum, null, ch, cm, false, k.
k.code
code
));
} // Route 2: CGEvent-backed NSEvent, dispatched in-process to the view's keyDown: // (never posted to the WindowServer). The shared private source keeps dead-key state // across calls, and the wrapped NSEvent carries a real event ref for TSM. void
void app.injectCG(ushort code, ulong flags, const(char)* label)
injectCG
(ushort
(parameter) ushort code
code
, ulong
(parameter) ulong flags
flags
, const(char)*
(parameter) const(char)* label
label
)
{ void*
_error_ down
down
= CGEventCreateKeyboardEvent(g_cgSrc, code, true);
if (down is null) { instr("inject", "route=cgevent_wrap label=%s result=create_failed", label); return; } if (flags != 0) CGEventSetFlags(down, flags);
(unresolved type) NSEvent
NSEvent
_error_ e
e
= NSEvent.
NSEvent.eventWithCGEvent
eventWithCGEvent
(down);
(unresolved type) NSString
NSString
_error_ txt
txt
= e !is null ? e.
e.characters
characters
() : null;
instr("inject", "route=cgevent_wrap label=%s code=%u wrapped_type=%ld wrapped_text=%s", label, code, e !is null ? e.
e.type
type
() : -1, txt !is null ? txt.
txt.UTF8String
UTF8String
() : "<nil>");
if (e !is null) g_view.
g_view.keyDown
keyDown
(e);
CFRelease(down); } 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
()
{ switch (g_step) { case 0: // a. plain text — which insertText variant fires WITH conformance? inject(KeySpec(4, 0, "h", "h", "letter_h")); break; case 1: inject(KeySpec(34, 0, "i", "i", "letter_i")); break; case 2: // b1. dead key as a plain synthetic NSEvent (the f06 verbatim path) inject(optE); break; case 3: inject(KeySpec(14, 0, "e", "e", "letter_e_after_dead")); break; case 4: // b2. dead key as a CGEvent-backed NSEvent: does TSM compose now? injectCG(14, kCGEventFlagMaskAlternate, "opt_e_deadacute"); break; case 5: injectCG(14, 0, "letter_e_compose"); break; case 6: // c. cancel mid-composition with Esc injectCG(14, kCGEventFlagMaskAlternate, "opt_e_deadacute"); break; case 7: injectCG(53, 0, "escape_mid_composition"); break; case 8: // d. focus loss mid-composition injectCG(14, kCGEventFlagMaskAlternate, "opt_e_deadacute"); break; case 9: instr("step", "name=focus_steal target=PlainView has_marked=%d", g_hasMarked ? 1 : 0); g_win.
g_win.makeFirstResponder
makeFirstResponder
(g_plain);
break; case 10: instr("step", "name=focus_restore target=TextView"); g_win.
g_win.makeFirstResponder
makeFirstResponder
(g_view);
break; case 11: // e. replacementRange semantics: replace committed chars {0,2} directly instr("step", "name=direct_insert_replacement text=X repl={0,2}"); g_view.
g_view.insertTextRR
insertTextRR
(NSString.
NSString.alloc
alloc
().
NSString.alloc().initWithUTF8String
initWithUTF8String
("X"), NSRange(0, 2));
break; case 12: // f. the candidate-anchor math at both ends of the line { instr("step", "name=direct_first_rect at=start_and_caret");
(unresolved type) NSRange
NSRange
_error_ actual
actual
;
g_view.
g_view.firstRect
firstRect
(NSRange(0, 1), &actual);
immutable
_error_ r
r
= g_view.
g_view.firstRect
firstRect
(NSRange(g_caret, 1), &actual);
g_view.
g_view.characterIndexForPoint
characterIndexForPoint
(r.
r.origin
origin
); // round-trip the anchor point
break; } default: stopApp(); break; } ++g_step; } extern (Objective-C) class
(class) app.StepTarget
StepTarget
:
(class) app.NSObject
NSObject
class `app.StepTarget` Objective-C classes not supported
{ static
(class) app.StepTarget
StepTarget
app.StepTarget app.StepTarget.alloc()
alloc
() @selector("alloc");
(class) app.StepTarget
StepTarget
app.StepTarget app.StepTarget.init()
init
() @selector("init");
void
void app.StepTarget.step(app.NSTimer t)
step
(
(class) app.NSTimer
NSTimer
(parameter) app.NSTimer t
t
) @selector("step:")
{ onStep(); } } // Attach the AppKit-registered NSTextInputClient protocol to the D-defined class at // runtime. AppKit gates the whole IME path on conformsToProtocol: — implementing the // methods alone is not enough for -[NSView inputContext] to create an input context. void
void app.attachProtocol(app.TextView probe)
attachProtocol
(
(class) app.TextView
TextView
(parameter) app.TextView probe
probe
)
{ Class
_error_ cls
cls
= Class.lookup("TextView");
if (cls.ptr is null) cls = probe.
probe.objcClass
objcClass
(); // D may emit a mangled runtime name; ask the instance
Protocol
_error_ proto
proto
= Protocol.get("NSTextInputClient");
instr("protocol_attach", "class=%s protocol_found=%d conforms_before=%d", cls.name, proto.ptr !is null ? 1 : 0, cls.conformsTo(proto) ? 1 : 0); if (proto.ptr is null) return; immutable
_error_ added
added
= cls.addProtocol(proto);
instr("protocol_attach", "added=%d conforms_after=%d", added ? 1 : 0, cls.conformsTo(proto) ? 1 : 0); } int
int D main()
main
()
{ immutable
_error_ autoExit
autoExit
= getenv("WSI_AUTO_EXIT") !is null;
g_useIke = getenv("WSI_USE_IKE") !is null; immutable
_error_ noActivate
noActivate
= getenv("WSI_NO_ACTIVATE") !is null;
instrInit("APPKIT_F07"); instr("init_start", "auto_exit=%d use_ike=%d no_activate=%d", autoExit ? 1 : 0, g_useIke ? 1 : 0, noActivate ? 1 : 0); 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, 120));
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-f07-text-input"));
g_view = TextView.
TextView.alloc
alloc
().
TextView.alloc().initWithFrame
initWithFrame
(contentRect);
g_plain = PlainView.
PlainView.alloc
alloc
().
PlainView.alloc().initWithFrame
initWithFrame
(NSRect(NSPoint(0, 0), NSSize(10, 10)));
// Conformance dance BEFORE first-responder setup, so the input context is created // against a conforming class. attachProtocol(g_view); g_win.
g_win.setContentView
setContentView
(g_view);
g_win.
g_win.setDelegate
setDelegate
(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
();
// The inputContext split: conforming view gets one, plain view does not.
(unresolved type) NSTextInputContext
NSTextInputContext
_error_ ctx
ctx
= g_view.
g_view.inputContext
inputContext
();
instr("input_context", "view=TextView ctx=%s", ctx !is null ? "non-nil".ptr : "nil".ptr); instr("input_context", "view=PlainView ctx=%s", g_plain.
g_plain.inputContext
inputContext
() !is null ? "non-nil".ptr : "nil".ptr);
if (ctx !is null) {
(unresolved type) NSString
NSString
_error_ src
src
= ctx.
ctx.selectedKeyboardInputSource
selectedKeyboardInputSource
();
instr("input_context", "selected_source=%s", src !is null ? src.
src.UTF8String
UTF8String
() : "<nil>");
if (!noActivate) { ctx.
ctx.activate
activate
(); // force TSM activation (normally done on app activation)
src = ctx.
ctx.selectedKeyboardInputSource
selectedKeyboardInputSource
();
instr("input_context", "after_activate selected_source=%s", src !is null ? src.
src.UTF8String
UTF8String
() : "<nil>");
} } instr("window_created", "win_num=%ld first_responder=TextView", g_winNum); g_cgSrc = CGEventSourceCreate(kCGEventSourceStatePrivate); instr("cg_source", "state=private created=%d", g_cgSrc !is null ? 1 : 0); if (autoExit) {
(unresolved type) StepTarget
StepTarget
_error_ target
target
= StepTarget.
StepTarget.alloc
alloc
().
StepTarget.alloc().init
init
();
instr("step", "name=script_timer_start interval_ms=250"); NSTimer.
NSTimer.scheduledTimerWithTimeInterval
scheduledTimerWithTimeInterval
(0.25, target, SEL.register("step:"),
null, true); } instr("step", "name=NSApp_run"); g_app.
g_app.run
run
();
instr("loop_exit", "steps=%d", g_step); return 0; }