app.dhover×459 error×158all
// F16 clipboard + DnD demo — wl_data_device_manager on top of the xdg-shell
// scaffold (../scaffold/app.d; findings: ../../f16-clipboard-dnd.md).
//
// ONE client, TWO toplevels (A = wsi-f16-a, the source; B = wsi-f16-b, the
// drop target) — clipboard and drag-and-drop are the SAME machinery
// (wl_data_source / wl_data_offer over pipe fds), exercised end to end:
//
//   stale probe   at startup, before ANY input event exists, a wl_data_source
//                 is offered and wl_data_device.set_selection(serial=0) is
//                 attempted — the Wayland divergence under test: the clipboard
//                 cannot be claimed without a recent input serial. ./run.sh
//                 then proves with `wl-paste` (a real second client) that no
//                 selection was installed.
//   copy          an injected right-click on A yields a REAL serial; a new
//                 source offering text/plain;charset=utf-8 + text/plain
//                 (payload é漢🎈) is installed; `wl-paste -l` / `wl-paste`
//                 read it back (the demo serves wl_data_source.send by
//                 writing the fd) — then `wl-copy` takes the selection over
//                 and the demo logs wl_data_source.cancelled (ownership loss).
//   paste         when a wtype-plugged keyboard gives the client keyboard
//                 focus, wl_data_device.data_offer + selection deliver
//                 wl-copy's offer; the demo logs the offered MIME types and
//                 receives the bytes through its own pipe.
//   dnd           an injected left-press on A starts
//                 wl_data_device.start_drag (actions copy|move) WHILE the
//                 button is held; the injector sweeps the pointer into B and
//                 releases. Both sides of the negotiation are one process,
//                 so the full sequence is in one log: enter(A)/motion/leave,
//                 enter(B), offer accept + set_actions(preferred=move),
//                 source_actions/action, drop, receive-pipe transfer,
//                 finish, dnd_drop_performed, dnd_finished.
//
// Headless-safe: no compositor → SKIP, exit 0; a seat-less compositor
// (headless weston) logs the registry probe and exits 0.
module 
(module) app
app
;
import c; // ImportC: wayland-client + xdg-shell glue + pipe/poll
unable to read module `c` Expected 'c.d' or 'c/package.d' in one of the following import paths:
unable to read module `c` Expected 'c.d' or 'c/package.d' in one of the following import paths:
import instrument;
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
(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.atoi = int core.stdc.stdlib.atoi(scope const(char*) nptr) nothrow @nogc
atoi
,
(alias) app.getenv = char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogc
getenv
;
import
(package) core
core
.
(package) core.stdc
stdc
.
(module) core.stdc.string

D header file for C99.

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

Source

core/stdc/string.d

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseDistributed under the Boost Software License 1.0. (See accompanying file LICENSE)@authorsSean Kelly@standardsISO/IEC 9899:1999 (E)
string
:
(alias) app.strcmp = int core.stdc.string.strcmp(scope const(char*) s1, scope const(char*) s2) pure nothrow @nogc
strcmp
,
(alias) app.strlen = ulong core.stdc.string.strlen(scope const(char*) s) pure nothrow @nogc
strlen
,
(alias) app.strncpy = char* core.stdc.string.strncpy(return scope char* s1, scope const(char*) s2, ulong n) pure nothrow @nogc
strncpy
;
enum int
(constant) int app.winWidth = 640
winWidth
= 640;
enum int
(constant) int app.winHeight = 480
winHeight
= 480;
enum uint
(constant) uint app.BTN_LEFT = 272u
BTN_LEFT
= 0x110,
(constant) uint app.BTN_RIGHT = 273u
BTN_RIGHT
= 0x111;
__gshared immutable char*
(immutable global) immutable(char*) app.mimeUtf8
mimeUtf8
= "text/plain;charset=utf-8";
__gshared immutable char*
(immutable global) immutable(char*) app.mimePlain
mimePlain
= "text/plain";
__gshared immutable char*
(immutable global) immutable(char*) app.clipPayload
clipPayload
= "é漢🎈"; // 9 UTF-8 bytes
__gshared immutable char*
(immutable global) immutable(char*) app.dndPayload
dndPayload
= "dnd-payload-é漢🎈";
// -------------------------------------------------------------------- state struct
(struct) app.Buffer
Buffer
{ wl_buffer*
(field) _error_ app.Buffer.handle
handle
;
undefined identifier `wl_buffer`
uint*
(field) uint* app.Buffer.pixels
pixels
;
(alias) object.size_t = ulong
size_t
(field) ulong app.Buffer.byteSize
byteSize
;
int
(field) int app.Buffer.width
width
,
(field) int app.Buffer.height
height
;
bool
(field) bool app.Buffer.busy
busy
;
} struct
(struct) app.Surf
Surf
{ wl_surface*
(field) _error_ app.Surf.surface
surface
;
undefined identifier `wl_surface`
xdg_surface*
(field) _error_ app.Surf.xdgSurface
xdgSurface
;
undefined identifier `xdg_surface`, did you mean variable `xdgSurface`?
xdg_toplevel*
(field) _error_ app.Surf.toplevel
toplevel
;
undefined identifier `xdg_toplevel`
(struct) app.Buffer
Buffer
[2]
(field) _error_ app.Surf.buffers
buffers
;
int
(field) int app.Surf.width
width
=
(constant) int app.winWidth = 640
winWidth
,
(field) int app.Surf.height
height
=
(constant) int app.winHeight = 480
winHeight
;
int
(field) int app.Surf.pendingW
pendingW
,
(field) int app.Surf.pendingH
pendingH
;
bool
(field) bool app.Surf.configured
configured
;
} /// One in-flight wl_data_offer.receive transfer (read end of the pipe). struct
(struct) app.Pipe

One in-flight wl_data_offer.receive transfer (read end of the pipe).

Pipe
{ int
(field) int app.Pipe.fd
fd
= -1;
wl_data_offer*
(field) _error_ app.Pipe.offer
offer
;
undefined identifier `wl_data_offer`
char[4096]
(field) char[4096] app.Pipe.buf
buf
;
(alias) object.size_t = ulong
size_t
(field) ulong app.Pipe.len
len
;
} /// MIME types announced by a wl_data_offer before its enter/selection event. struct
(struct) app.OfferInfo

MIME types announced by a wl_data_offer before its enter/selection event.

OfferInfo
{ wl_data_offer*
(field) _error_ app.OfferInfo.offer
offer
;
undefined identifier `wl_data_offer`
char[64][8]
(field) char[64][8] app.OfferInfo.mimes
mimes
; // up to 8 MIME strings of 63 chars
int
(field) int app.OfferInfo.mimeCount
mimeCount
;
uint
(field) uint app.OfferInfo.sourceActions
sourceActions
;
} enum
(alias) object.size_t = ulong
size_t
(constant) ulong app.IDX_A = 0LU
IDX_A
= 0,
(constant) ulong app.IDX_B = 1LU
IDX_B
= 1;
__gshared immutable(char*)[2]
(immutable global) immutable(char*[2]) app.g_surfNames
g_surfNames
= ["A", "B"];
__gshared { wl_display*
_error_ app.g_display
g_display
;
undefined identifier `wl_display`, did you mean variable `g_display`?
wl_registry*
_error_ app.g_registry
g_registry
;
undefined identifier `wl_registry`, did you mean variable `g_registry`?
wl_compositor*
_error_ app.g_compositor
g_compositor
;
undefined identifier `wl_compositor`, did you mean variable `g_compositor`?
wl_shm*
_error_ app.g_shm
g_shm
;
undefined identifier `wl_shm`, did you mean variable `g_shm`?
xdg_wm_base*
_error_ app.g_wmBase
g_wmBase
;
undefined identifier `xdg_wm_base`
wl_seat*
_error_ app.g_seat
g_seat
;
undefined identifier `wl_seat`, did you mean variable `g_seat`?
wl_pointer*
_error_ app.g_pointer
g_pointer
;
undefined identifier `wl_pointer`, did you mean variable `g_pointer`?
wl_keyboard*
_error_ app.g_keyboard
g_keyboard
;
undefined identifier `wl_keyboard`, did you mean variable `g_keyboard`?
wl_data_device_manager*
_error_ app.g_ddm
g_ddm
;
undefined identifier `wl_data_device_manager`
uint
(__gshared global) uint app.g_ddmVersion
g_ddmVersion
;
wl_data_device*
_error_ app.g_dataDevice
g_dataDevice
;
undefined identifier `wl_data_device`
wl_data_source*
_error_ app.g_selSource
g_selSource
; // currently installed selection source
undefined identifier `wl_data_source`
wl_data_source*
_error_ app.g_staleSource
g_staleSource
; // the serial=0 probe source
undefined identifier `wl_data_source`
wl_data_source*
_error_ app.g_dragSource
g_dragSource
;
undefined identifier `wl_data_source`
wl_data_offer*
_error_ app.g_dndOffer
g_dndOffer
; // current drag offer (target side)
undefined identifier `wl_data_offer`
(struct) app.OfferInfo

MIME types announced by a wl_data_offer before its enter/selection event.

OfferInfo
[4]
_error_ app.g_offers
g_offers
;
(struct) app.Surf
Surf
[2]
_error_ app.g_surfs
g_surfs
;
int
(__gshared global) int app.g_focusIdx
g_focusIdx
= -1;
double
(__gshared global) double app.g_ptrX
g_ptrX
,
(__gshared global) double app.g_ptrY
g_ptrY
;
uint
(__gshared global) uint app.g_dndEnterSerial
g_dndEnterSerial
;
int
(__gshared global) int app.g_dndMotions
g_dndMotions
;
(struct) app.Pipe

One in-flight wl_data_offer.receive transfer (read end of the pipe).

Pipe
[2]
_error_ app.g_pipes
g_pipes
; // [0] selection paste, [1] dnd drop — independent
bool
(__gshared global) bool app.g_running
g_running
= true,
(__gshared global) bool app.g_autoExit
g_autoExit
,
(__gshared global) bool app.g_staleProbeSent
g_staleProbeSent
;
bool
(__gshared global) bool app.g_dndFinished
g_dndFinished
;
long
(__gshared global) long app.g_runUsCap
g_runUsCap
= 2_500_000;
long
(__gshared global) long app.g_firstPaintUs
g_firstPaintUs
= -1,
(__gshared global) long app.g_exitAtUs
g_exitAtUs
= -1;
int
(__gshared global) int app.g_frames
g_frames
;
} // ---------------------------------------------------------- offer registry
(struct) app.OfferInfo

MIME types announced by a wl_data_offer before its enter/selection event.

OfferInfo
*
app.offerInfo
offerInfo
(wl_data_offer* o) nothrow @nogc
undefined identifier `wl_data_offer`
{ foreach (ref
(parameter) oi
oi
; g_offers)
if (oi.
oi.offer
offer
is o)
return &oi; return null; }
(struct) app.OfferInfo

MIME types announced by a wl_data_offer before its enter/selection event.

OfferInfo
*
app.offerInfoNew
offerInfoNew
(wl_data_offer* o) nothrow @nogc
undefined identifier `wl_data_offer`
{ foreach (ref
(parameter) oi
oi
; g_offers)
if (oi.
oi.offer
offer
is null)
{ oi.
oi.offer
offer
= o;
oi.
oi.mimeCount
mimeCount
= 0;
oi.
oi.sourceActions
sourceActions
= 0;
return &oi; } g_offers[0].
g_offers[0].offer
offer
= o; // recycle the oldest slot
g_offers[0].
g_offers[0].mimeCount
mimeCount
= 0;
g_offers[0].
g_offers[0].sourceActions
sourceActions
= 0;
return &g_offers[0]; } void
app.offerInfoDrop
offerInfoDrop
(wl_data_offer* o) nothrow @nogc
undefined identifier `wl_data_offer`
{ foreach (ref
(parameter) oi
oi
; g_offers)
if (oi.
oi.offer
offer
is o)
oi.
oi.offer
offer
= null;
} void
app.logOfferMimes
logOfferMimes
(const(char)* kind,
(struct) app.OfferInfo

MIME types announced by a wl_data_offer before its enter/selection event.

OfferInfo
*
(parameter) OfferInfo* oi
oi
) nothrow @nogc
{ instrEvent(kind, "mime_count=%d", oi !is null ? oi.
oi.mimeCount
mimeCount
: -1);
if (oi !is null) foreach (
(parameter) i
i
; 0 .. oi.
oi.mimeCount
mimeCount
)
instrEvent("offer_mime", "i=%d mime=%s", i, oi.
oi.mimes
mimes
[i].ptr);
} bool
app.offerHas
offerHas
(
(struct) app.OfferInfo

MIME types announced by a wl_data_offer before its enter/selection event.

OfferInfo
*
(parameter) OfferInfo* oi
oi
, const(char)* mime) nothrow @nogc
{ if (oi is null) return false; foreach (
(parameter) i
i
; 0 .. oi.
oi.mimeCount
mimeCount
)
if (strcmp(oi.
oi.mimes
mimes
[i].ptr, mime) == 0)
return true; return false; } // ------------------------------------------------------------ data source extern (C) void
app.onSourceTarget
onSourceTarget
(void* data, wl_data_source*
(parameter) wl_data_source* s
s
, const(char)* mime) nothrow @nogc
undefined identifier `wl_data_source`
{ // DnD only: the target's current accept state (null = would reject). instrEvent("source_target", "mime=%s", mime !is null ? mime : "(null)"); } extern (C) void
app.onSourceSend
onSourceSend
(void* data, wl_data_source*
(parameter) wl_data_source* s
s
, const(char)* mime, int
(parameter) int fd
fd
) nothrow @nogc
undefined identifier `wl_data_source`
{ const(char)*
_error_ payload
payload
= s is g_dragSource ? dndPayload : clipPayload;
immutable
_error_ len
len
= strlen(payload);
immutable
_error_ written
written
= write(fd, payload, len);
close(fd); instrEvent("clip_send", "source=%s fmt=%s bytes=%lld", s is g_dragSource ? "dnd".ptr : "selection".ptr, mime, cast(long) written); } extern (C) void
app.onSourceCancelled
onSourceCancelled
(void* data, wl_data_source*
(parameter) wl_data_source* s
s
) nothrow @nogc
undefined identifier `wl_data_source`
{ // Selection: ownership loss (another client set the selection). // DnD: the drag was rejected/ended without a successful drop. instrEvent("ownership_lost", "source=%s", s is g_dragSource ? "dnd".ptr : (s is g_staleSource ? "stale".ptr : "selection".ptr)); if (s is g_selSource) g_selSource = null; else if (s is g_staleSource) g_staleSource = null; else if (s is g_dragSource) g_dragSource = null; wsi_data_source_destroy(s); } extern (C) void
app.onSourceDndDropPerformed
onSourceDndDropPerformed
(void* data, wl_data_source*
(parameter) wl_data_source* s
s
) nothrow @nogc
undefined identifier `wl_data_source`
{ instrEvent("source_dnd_drop_performed"); } extern (C) void
app.onSourceDndFinished
onSourceDndFinished
(void* data, wl_data_source*
(parameter) wl_data_source* s
s
) nothrow @nogc
undefined identifier `wl_data_source`
{ instrEvent("source_dnd_finished", "note=target-done-source-may-delete-on-move"); if (s is g_dragSource) g_dragSource = null; wsi_data_source_destroy(s); g_dndFinished = true; g_exitAtUs = instrNowUs() + 1_000_000; // wind down shortly after } extern (C) void
app.onSourceAction
onSourceAction
(void* data, wl_data_source*
(parameter) wl_data_source* s
s
, uint action) nothrow @nogc
undefined identifier `wl_data_source`
{ instrEvent("source_action", "dnd_action=%u", action); } __gshared wl_data_source_listener
_error_ app.g_sourceListener
g_sourceListener
= {
undefined identifier `wl_data_source_listener`
&onSourceTarget, &onSourceSend, &onSourceCancelled, &onSourceDndDropPerformed, &onSourceDndFinished, &onSourceAction }; wl_data_source*
app.makeTextSource
makeTextSource
(bool forDnd) nothrow @nogc
undefined identifier `wl_data_source`
{ wl_data_source*
_error_ s
s
= wsi_ddm_create_data_source(g_ddm);
wsi_data_source_add_listener(s, &g_sourceListener, null); wsi_data_source_offer(s, mimeUtf8); wsi_data_source_offer(s, mimePlain); if (forDnd && g_ddmVersion >= 3) wsi_data_source_set_actions(s, WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE); instrEvent("clip_offer", "kind=%s formats=[%s,%s]%s", forDnd ? "dnd".ptr : "selection".ptr, mimeUtf8, mimePlain, forDnd ? " actions=copy|move".ptr : "".ptr); return s; } // ------------------------------------------------------------- data offer extern (C) void
app.onOfferOffer
onOfferOffer
(void* data, wl_data_offer* o, const(char)* mime) nothrow @nogc
undefined identifier `wl_data_offer`
{
(unresolved type) OfferInfo
OfferInfo
*
_error_ oi
oi
= offerInfo(o);
if (oi !is null && oi.
oi.mimeCount
mimeCount
< oi.
oi.mimes
mimes
.
oi.mimes.length
length
)
{ strncpy(oi.
oi.mimes
mimes
[oi.
oi.mimeCount
mimeCount
].ptr, mime, 63);
oi.
oi.mimes
mimes
[oi.
oi.mimeCount
mimeCount
][63] = '\0';
oi.
oi.mimeCount
mimeCount
++;
} } extern (C) void
app.onOfferSourceActions
onOfferSourceActions
(void* data, wl_data_offer* o, uint actions) nothrow @nogc
undefined identifier `wl_data_offer`
{
(unresolved type) OfferInfo
OfferInfo
*
_error_ oi
oi
= offerInfo(o);
if (oi !is null) oi.
oi.sourceActions
sourceActions
= actions;
instrEvent("offer_source_actions", "actions=%u", actions); } extern (C) void
app.onOfferAction
onOfferAction
(void* data, wl_data_offer* o, uint action) nothrow @nogc
undefined identifier `wl_data_offer`
{ // The compositor's pick from source-actions ∩ target-actions (and the // target's preference) — who chose copy vs move, answered here. instrEvent("offer_action", "dnd_action=%u note=compositor-resolved", action); } __gshared wl_data_offer_listener
_error_ app.g_offerListener
g_offerListener
= {
undefined identifier `wl_data_offer_listener`
&onOfferOffer, &onOfferSourceActions, &onOfferAction }; /// Begin an fd transfer from `o` (slot 0 = selection paste, slot 1 = dnd /// post-drop read); the pipe's read end joins the poll loop and is drained /// to EOF there. The two slots are independent — a selection offer /// re-delivered right after a drop must not clobber the dnd transfer. void
app.receiveFrom

Begin an fd transfer from o (slot 0 = selection paste, slot 1 = dnd post-drop read); the pipe's read end joins the poll loop and is drained to EOF there. The two slots are independent — a selection offer re-delivered right after a drop must not clobber the dnd transfer.

receiveFrom
(wl_data_offer* o, bool
(parameter) bool isDnd
isDnd
) nothrow @nogc
undefined identifier `wl_data_offer`
{
(unresolved type) Pipe
Pipe
*
_error_ p
p
= &g_pipes[isDnd ? 1 : 0];
if (p.
p.fd
fd
>= 0)
{ close(p.
p.fd
fd
);
p.
p.fd
fd
= -1;
} int[2]
_error_ fds
fds
;
if (wsi_pipe2_cloexec(fds.ptr) != 0) return; wsi_data_offer_receive(o, mimeUtf8, fds[1]); close(fds[1]); wl_display_flush(g_display); p.
p.fd
fd
= fds[0];
p.
p.offer
offer
= o;
p.
p.len
len
= 0;
instrEvent("clip_request", "kind=%s fmt=%s", isDnd ? "dnd".ptr : "selection".ptr, mimeUtf8); } void
void app.drainPipe(bool isDnd) nothrow @nogc
drainPipe
(bool
(parameter) bool isDnd
isDnd
) nothrow @nogc
{
(struct) app.Pipe

One in-flight wl_data_offer.receive transfer (read end of the pipe).

Pipe
*
(local variable) _error_ p
p
= &g_pipes[isDnd ? 1 : 0];
immutable
(local variable) immutable(_error_) n
n
= read(p.
p.fd
fd
, p.
p.buf
buf
.ptr + p.
p.len
len
, p.
p.buf
buf
.
p.buf.length
length
- 1 - p.
p.len
len
);
undefined identifier `read`
if (n > 0) { p.
(field) _error_ p.len
len
+= n;
return; } close(p.
p.fd
fd
);
undefined identifier `close`
p.
p.fd
fd
= -1;
p.
(field) _error_ p.buf
buf
[p.
p.len
len
] = '\0';
instrEvent(isDnd ? "dnd_drop_data" : "paste_data",
undefined identifier `instrEvent`, did you mean import `instrument`?
"bytes=%lld text=%s", cast(long) p.
p.len
len
, p.
p.buf
buf
.ptr);
if (
(parameter) bool isDnd
isDnd
&& p.
(field) _error_ p.offer
offer
!is null)
{ if (
(__gshared global) uint app.g_ddmVersion
g_ddmVersion
>= 3)
wsi_data_offer_finish(p.
p.offer
offer
); // "the drag-and-drop operation ended successfully"
undefined identifier `wsi_data_offer_finish`
instrEvent("dnd_finish_sent");
undefined identifier `instrEvent`, did you mean import `instrument`?
wsi_data_offer_destroy(p.
p.offer
offer
);
undefined identifier `wsi_data_offer_destroy`
offerInfoDrop(p.
p.offer
offer
);
if (g_dndOffer is p.
(field) _error_ p.offer
offer
)
g_dndOffer = null; } p.
p.offer
offer
= null;
} // ------------------------------------------------------------- data device extern (C) void
app.onDataOffer
onDataOffer
(void* data, wl_data_device* d, wl_data_offer* o) nothrow @nogc
undefined identifier `wl_data_device`
undefined identifier `wl_data_offer`
{ // A new offer object: its MIME list arrives as offer events BEFORE the // enter/selection event that tells us what it is for. offerInfoNew(o); wsi_data_offer_add_listener(o, &g_offerListener, null); instrEvent("data_offer", "offer=%p", o); } extern (C) void
app.onDndEnter
onDndEnter
(void* data, wl_data_device* d, uint serial,
undefined identifier `wl_data_device`
wl_surface*
(parameter) wl_surface* surface
surface
, int
(parameter) int x
x
, int
(parameter) int y
y
, wl_data_offer* o) nothrow @nogc
undefined identifier `wl_surface`
undefined identifier `wl_data_offer`
{ immutable
_error_ idx
idx
= surfIndexOf(surface);
g_dndEnterSerial = serial; g_dndOffer = o;
(unresolved type) OfferInfo
OfferInfo
*
_error_ oi
oi
= offerInfo(o);
instrEvent("dnd_enter", "surface=%s serial=%u pos=%.1f,%.1f", idx >= 0 ? g_surfNames[idx] : "other", serial, x / 256.0, y / 256.0); logOfferMimes("dnd_enter_formats", oi); if (o !is null && offerHas(oi, mimeUtf8)) { // Target-side negotiation: accept the mime, then declare our action // set + preference (the compositor resolves the final dnd_action). wsi_data_offer_accept(o, serial, mimeUtf8); if (g_ddmVersion >= 3) wsi_data_offer_set_actions(o, WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE, WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE); instrEvent("dnd_accept", "serial=%u fmt=%s actions=copy|move preferred=move", serial, mimeUtf8); } } extern (C) void
app.onDndLeave
onDndLeave
(void* data, wl_data_device* d) nothrow @nogc
undefined identifier `wl_data_device`
{ instrEvent("dnd_leave", "motions_seen=%d", g_dndMotions); g_dndOffer = null; } extern (C) void
app.onDndMotion
onDndMotion
(void* data, wl_data_device* d, uint time, int
(parameter) int x
x
, int
(parameter) int y
y
) nothrow @nogc
undefined identifier `wl_data_device`
{ g_dndMotions++; if (g_dndMotions <= 2 || g_dndMotions % 4 == 0) instrEvent("dnd_motion", "n=%d pos=%.1f,%.1f", g_dndMotions, x / 256.0, y / 256.0); } extern (C) void
app.onDndDrop
onDndDrop
(void* data, wl_data_device* d) nothrow @nogc
undefined identifier `wl_data_device`
{ instrEvent("dnd_drop", "have_offer=%d", g_dndOffer !is null ? 1 : 0); if (g_dndOffer !is null) receiveFrom(g_dndOffer, true); } extern (C) void
app.onSelection
onSelection
(void* data, wl_data_device* d, wl_data_offer* o) nothrow @nogc
undefined identifier `wl_data_device`
undefined identifier `wl_data_offer`
{ if (o is null) { instrEvent("selection", "offer=null note=selection-cleared"); return; }
(unresolved type) OfferInfo
OfferInfo
*
_error_ oi
oi
= offerInfo(o);
instrEvent("selection", "offer=%p own_source=%d", o, g_selSource !is null ? 1 : 0); logOfferMimes("selection_formats", oi); if (g_selSource is null && offerHas(oi, mimeUtf8)) receiveFrom(o, false); // paste: another client's clipboard else { wsi_data_offer_destroy(o); offerInfoDrop(o); } } __gshared wl_data_device_listener
_error_ app.g_dataDeviceListener
g_dataDeviceListener
= {
undefined identifier `wl_data_device_listener`
&onDataOffer, &onDndEnter, &onDndLeave, &onDndMotion, &onDndDrop, &onSelection }; // ----------------------------------------------------------------- pointer int
app.surfIndexOf
surfIndexOf
(wl_surface*
(parameter) wl_surface* s
s
) nothrow @nogc
undefined identifier `wl_surface`
{ foreach (
(parameter) i
i
, ref
(parameter) sf
sf
; g_surfs)
if (sf.
sf.surface
surface
is s)
return cast(int) i; return -1; } extern (C) void
app.onPointerEnter
onPointerEnter
(void* data, wl_pointer*
(parameter) wl_pointer* p
p
, uint serial,
undefined identifier `wl_pointer`, did you mean variable `g_pointer`?
wl_surface* surf, int sx, int sy) nothrow @nogc
undefined identifier `wl_surface`
{ g_focusIdx = surfIndexOf(surf); g_ptrX = sx / 256.0; g_ptrY = sy / 256.0; instrEvent("pointer_enter", "surface=%s serial=%u pos=%.1f,%.1f", g_focusIdx >= 0 ? g_surfNames[g_focusIdx] : "other", serial, g_ptrX, g_ptrY); } extern (C) void
app.onPointerLeave
onPointerLeave
(void* data, wl_pointer*
(parameter) wl_pointer* p
p
, uint serial, wl_surface* surf) nothrow @nogc
undefined identifier `wl_pointer`, did you mean variable `g_pointer`?
undefined identifier `wl_surface`
{ g_focusIdx = -1; } extern (C) void
app.onPointerMotion
onPointerMotion
(void* data, wl_pointer*
(parameter) wl_pointer* p
p
, uint time, int sx, int sy) nothrow @nogc
undefined identifier `wl_pointer`, did you mean variable `g_pointer`?
{ g_ptrX = sx / 256.0; g_ptrY = sy / 256.0; } extern (C) void
app.onPointerButton
onPointerButton
(void* data, wl_pointer*
(parameter) wl_pointer* p
p
, uint serial, uint time,
undefined identifier `wl_pointer`, did you mean variable `g_pointer`?
uint button, uint state) nothrow @nogc { instrEvent("button", "surface=%s serial=%u button=0x%x state=%u", g_focusIdx >= 0 ? g_surfNames[g_focusIdx] : "none", serial, button, state); if (state != WL_POINTER_BUTTON_STATE_PRESSED || g_focusIdx != IDX_A) return; if (button == BTN_RIGHT) { // COPY with a REAL input serial — the valid counterpart of the // startup stale-serial probe. if (g_selSource !is null) { wsi_data_source_destroy(g_selSource); g_selSource = null; } g_selSource = makeTextSource(false); wsi_data_device_set_selection(g_dataDevice, g_selSource, serial); instrEvent("set_selection", "serial=%u note=valid-input-serial", serial); } else if (button == BTN_LEFT && g_dragSource is null) { // DnD: start_drag must carry the serial of an implicit grab — the // injector holds BTN_LEFT down through the whole sweep. g_dragSource = makeTextSource(true); wsi_data_device_start_drag(g_dataDevice, g_dragSource, g_surfs[IDX_A].
g_surfs[IDX_A].surface
surface
, null, serial);
instrEvent("dnd_start", "origin=A serial=%u icon=none", serial); } } extern (C) void
app.onPointerAxis
onPointerAxis
(void* data, wl_pointer*
(parameter) wl_pointer* p
p
, uint time, uint axis, int value) nothrow @nogc {}
undefined identifier `wl_pointer`, did you mean variable `g_pointer`?
extern (C) void
app.onPointerFrame
onPointerFrame
(void* data, wl_pointer*
(parameter) wl_pointer* p
p
) nothrow @nogc {}
undefined identifier `wl_pointer`, did you mean variable `g_pointer`?
extern (C) void
app.onPointerAxisSource
onPointerAxisSource
(void* data, wl_pointer*
(parameter) wl_pointer* p
p
, uint src) nothrow @nogc {}
undefined identifier `wl_pointer`, did you mean variable `g_pointer`?
extern (C) void
app.onPointerAxisStop
onPointerAxisStop
(void* data, wl_pointer*
(parameter) wl_pointer* p
p
, uint time, uint axis) nothrow @nogc {}
undefined identifier `wl_pointer`, did you mean variable `g_pointer`?
extern (C) void
app.onPointerAxisDiscrete
onPointerAxisDiscrete
(void* data, wl_pointer*
(parameter) wl_pointer* p
p
, uint axis, int discrete) nothrow @nogc {}
undefined identifier `wl_pointer`, did you mean variable `g_pointer`?
extern (C) void
app.onPointerAxisValue120
onPointerAxisValue120
(void* data, wl_pointer*
(parameter) wl_pointer* p
p
, uint axis, int v120) nothrow @nogc {}
undefined identifier `wl_pointer`, did you mean variable `g_pointer`?
extern (C) void
app.onPointerAxisRelDir
onPointerAxisRelDir
(void* data, wl_pointer*
(parameter) wl_pointer* p
p
, uint axis, uint dir) nothrow @nogc {}
undefined identifier `wl_pointer`, did you mean variable `g_pointer`?
__gshared wl_pointer_listener
_error_ app.g_pointerListener
g_pointerListener
= {
undefined identifier `wl_pointer_listener`
&onPointerEnter, &onPointerLeave, &onPointerMotion, &onPointerButton, &onPointerAxis, &onPointerFrame, &onPointerAxisSource, &onPointerAxisStop, &onPointerAxisDiscrete, &onPointerAxisValue120, &onPointerAxisRelDir }; // ---------------------------------------------------------------- keyboard extern (C) void
app.onKeymap
onKeymap
(void* data, wl_keyboard* kb, uint format, int
(parameter) int fd
fd
, uint
(parameter) uint size
size
) nothrow @nogc
undefined identifier `wl_keyboard`, did you mean variable `g_keyboard`?
{ close(fd); } extern (C) void
app.onKeyboardEnter
onKeyboardEnter
(void* data, wl_keyboard* kb, uint serial,
undefined identifier `wl_keyboard`, did you mean variable `g_keyboard`?
wl_surface* surf, wl_array* keys) nothrow @nogc
undefined identifier `wl_surface`
undefined identifier `wl_array`
{ // The selection offer is delivered around THIS moment — "when a client // gains keyboard focus" is the delivery contract for selection events. immutable
_error_ idx
idx
= surfIndexOf(surf);
instrEvent("keyboard_enter", "surface=%s serial=%u", idx >= 0 ? g_surfNames[idx] : "other", serial); } extern (C) void
app.onKeyboardLeave
onKeyboardLeave
(void* data, wl_keyboard* kb, uint serial, wl_surface* surf) nothrow @nogc {}
undefined identifier `wl_keyboard`, did you mean variable `g_keyboard`?
undefined identifier `wl_surface`
extern (C) void
app.onKey
onKey
(void* data, wl_keyboard* kb, uint serial, uint time, uint key, uint state) nothrow @nogc
undefined identifier `wl_keyboard`, did you mean variable `g_keyboard`?
{ instrEvent("key", "key=%u state=%u serial=%u", key, state, serial); } extern (C) void
app.onModifiers
onModifiers
(void* data, wl_keyboard* kb, uint serial,
undefined identifier `wl_keyboard`, did you mean variable `g_keyboard`?
uint depressed, uint latched, uint locked, uint group) nothrow @nogc {} extern (C) void
app.onRepeatInfo
onRepeatInfo
(void* data, wl_keyboard* kb, int rate, int delay) nothrow @nogc {}
undefined identifier `wl_keyboard`, did you mean variable `g_keyboard`?
__gshared wl_keyboard_listener
_error_ app.g_keyboardListener
g_keyboardListener
= {
undefined identifier `wl_keyboard_listener`
&onKeymap, &onKeyboardEnter, &onKeyboardLeave, &onKey, &onModifiers, &onRepeatInfo }; // ------------------------------------------------------------------- seat extern (C) void
app.onSeatCapabilities
onSeatCapabilities
(void* data, wl_seat*
(parameter) wl_seat* s
s
, uint caps) nothrow @nogc
undefined identifier `wl_seat`, did you mean variable `g_seat`?
{ instrEvent("seat_capabilities", "caps=%u", caps); immutable
_error_ hasPointer
hasPointer
= (caps & WL_SEAT_CAPABILITY_POINTER) != 0;
immutable
_error_ hasKeyboard
hasKeyboard
= (caps & WL_SEAT_CAPABILITY_KEYBOARD) != 0;
if (hasPointer && g_pointer is null) { g_pointer = wsi_seat_get_pointer(g_seat); wsi_pointer_add_listener(g_pointer, &g_pointerListener, null); } else if (!hasPointer && g_pointer !is null) { wsi_pointer_destroy(g_pointer); g_pointer = null; g_focusIdx = -1; } if (hasKeyboard && g_keyboard is null) { g_keyboard = wsi_seat_get_keyboard(g_seat); wsi_keyboard_add_listener(g_keyboard, &g_keyboardListener, null); } else if (!hasKeyboard && g_keyboard !is null) { wsi_keyboard_destroy(g_keyboard); g_keyboard = null; } } extern (C) void
app.onSeatName
onSeatName
(void* data, wl_seat*
(parameter) wl_seat* s
s
, const(char)* name) nothrow @nogc {}
undefined identifier `wl_seat`, did you mean variable `g_seat`?
__gshared wl_seat_listener
_error_ app.g_seatListener
g_seatListener
= {&onSeatCapabilities, &onSeatName};
undefined identifier `wl_seat_listener`
extern (C) void
app.onGlobal
onGlobal
(void* data, wl_registry* reg, uint name,
undefined identifier `wl_registry`, did you mean variable `g_registry`?
const(char)* iface, uint ver) nothrow @nogc { static uint
uint capped(uint advertised, uint want) nothrow @nogc
capped
(uint
(parameter) uint advertised
advertised
, uint
(parameter) uint want
want
) nothrow @nogc
{ return advertised < want ? advertised : want; } if (strcmp(iface, wl_compositor_interface.name) == 0) g_compositor = cast(wl_compositor*) wsi_registry_bind(reg, name, &wl_compositor_interface, capped(ver, 6)); else if (strcmp(iface, wl_shm_interface.name) == 0) g_shm = cast(wl_shm*) wsi_registry_bind(reg, name, &wl_shm_interface, 1); else if (strcmp(iface, xdg_wm_base_interface.name) == 0) g_wmBase = cast(xdg_wm_base*) wsi_registry_bind(reg, name, &xdg_wm_base_interface, 1); else if (strcmp(iface, wl_seat_interface.name) == 0 && g_seat is null) { g_seat = cast(wl_seat*) wsi_registry_bind(reg, name, &wl_seat_interface, capped(ver, 5)); wsi_seat_add_listener(g_seat, &g_seatListener, null); } else if (strcmp(iface, wl_data_device_manager_interface.name) == 0) { // v3 = dnd actions (set_actions / action / finish). g_ddmVersion = capped(ver, 3); g_ddm = cast(wl_data_device_manager*) wsi_registry_bind(reg, name, &wl_data_device_manager_interface, g_ddmVersion); } } extern (C) void
app.onGlobalRemove
onGlobalRemove
(void* data, wl_registry* reg, uint name) nothrow @nogc {}
undefined identifier `wl_registry`, did you mean variable `g_registry`?
__gshared wl_registry_listener
_error_ app.g_registryListener
g_registryListener
= {&onGlobal, &onGlobalRemove};
undefined identifier `wl_registry_listener`
// ------------------------------------------------ window plumbing (scaffold) bool
app.ensureBuffer
ensureBuffer
(ref
(struct) app.Buffer
Buffer
(parameter) Buffer b
b
, int w, int h) nothrow @nogc
{ if (b.
b.handle
handle
!is null && (b.
b.width
width
!= w || b.
b.height
height
!= h))
{ wsi_buffer_destroy(b.
b.handle
handle
);
munmap(b.
b.pixels
pixels
, b.
b.byteSize
byteSize
);
b = Buffer.init; } if (b.
b.handle
handle
!is null)
return true; immutable
_error_ stride
stride
= w * 4;
immutable
_error_ size
size
= cast(
(unresolved type) size_t
size_t
) stride * h;
immutable
_error_ fd
fd
= memfd_create("wsi-f16", MFD_CLOEXEC);
if (fd < 0 || ftruncate(fd, cast(long) size) != 0) return false; void*
_error_ mem
mem
= mmap(null, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (mem is cast(void*)-1) { close(fd); return false; } wl_shm_pool*
_error_ pool
pool
= wsi_shm_create_pool(g_shm, fd, cast(int) size);
b.
b.handle
handle
= wsi_shm_pool_create_buffer(pool, 0, w, h, stride, WL_SHM_FORMAT_ARGB8888);
wsi_shm_pool_destroy(pool); close(fd); wsi_buffer_add_listener(b.
b.handle
handle
, &g_bufferListener, &b);
b.
b.pixels
pixels
= cast(uint*) mem;
b.
b.byteSize
byteSize
= size;
b.
b.width
width
= w;
b.
b.height
height
= h;
return true; } void
void app.render(ulong idx) nothrow @nogc
render
(
(alias) object.size_t = ulong
size_t
(parameter) ulong idx
idx
) nothrow @nogc
{
(struct) app.Surf
Surf
*
(local variable) _error_ s
s
= &g_surfs[idx];
if (s.
(field) _error_ s.surface
surface
is null || !s.
(field) _error_ s.configured
configured
)
return;
(struct) app.Buffer
Buffer
*
(local variable) _error_ buf
buf
= null;
foreach (ref
(parameter) b
b
; s.
(field) _error_ s.buffers
buffers
)
if (!b.
b.busy
busy
)
{ buf = &b; break; } if (buf is null || !ensureBuffer(*buf, s.
s.width
width
, s.
s.height
height
))
return; immutable uint
(local variable) immutable(uint) bg
bg
=
(parameter) ulong idx
idx
==
(constant) ulong app.IDX_A = 0LU
IDX_A
? 0xff35506a : 0xff6a5035; // A blue, B amber
foreach (
(parameter) y
y
; 0 .. buf.
(field) _error_ buf.height
height
)
foreach (
(parameter) x
x
; 0 .. buf.
buf.width
width
)
buf.
buf.pixels
pixels
[cast(
(unresolved type) size_t
size_t
) y * buf.
buf.width
width
+ x] = bg;
wsi_surface_attach(s.
s.surface
surface
, buf.
buf.handle
handle
, 0, 0);
undefined identifier `wsi_surface_attach`
wsi_surface_damage_buffer(s.
s.surface
surface
, 0, 0, buf.
buf.width
width
, buf.
buf.height
height
);
undefined identifier `wsi_surface_damage_buffer`
wsi_surface_commit(s.
s.surface
surface
);
undefined identifier `wsi_surface_commit`
buf.
buf.busy
busy
= true;
(__gshared global) int app.g_frames
g_frames
++;
} extern (C) void
app.onWmBasePing
onWmBasePing
(void* data, xdg_wm_base*
(parameter) xdg_wm_base* b
b
, uint serial) nothrow @nogc
undefined identifier `xdg_wm_base`
{ wsi_wm_base_pong(b, serial); } extern (C) void
app.onToplevelConfigure
onToplevelConfigure
(void* data, xdg_toplevel* t, int w, int h,
undefined identifier `xdg_toplevel`
wl_array* states) nothrow @nogc
undefined identifier `wl_array`
{
(unresolved type) Surf
Surf
*
_error_ s
s
= &g_surfs[cast(
(unresolved type) size_t
size_t
) data];
s.
s.pendingW
pendingW
= w;
s.
s.pendingH
pendingH
= h;
} extern (C) void
app.onXdgSurfaceConfigure
onXdgSurfaceConfigure
(void* data, xdg_surface*
(parameter) xdg_surface* s
s
, uint serial) nothrow @nogc
undefined identifier `xdg_surface`
{ immutable
_error_ idx
idx
= cast(
(unresolved type) size_t
size_t
) data;
(unresolved type) Surf
Surf
*
_error_ sf
sf
= &g_surfs[idx];
sf.
sf.width
width
= sf.
sf.pendingW
pendingW
> 0 ? sf.
sf.pendingW
pendingW
: winWidth;
sf.
sf.height
height
= sf.
sf.pendingH
pendingH
> 0 ? sf.
sf.pendingH
pendingH
: winHeight;
wsi_xdg_surface_ack_configure(s, serial); sf.
sf.configured
configured
= true;
render(idx); if (g_firstPaintUs < 0 && g_surfs[IDX_A].
g_surfs[IDX_A].configured
configured
&& g_surfs[IDX_B].
g_surfs[IDX_B].configured
configured
)
{ g_firstPaintUs = instrNowUs(); instrFirstConfigure(); } } extern (C) void
app.onToplevelClose
onToplevelClose
(void* data, xdg_toplevel* t) nothrow @nogc
undefined identifier `xdg_toplevel`
{ instrCloseRequested(); g_running = false; } extern (C) void
app.onToplevelConfigureBounds
onToplevelConfigureBounds
(void* data, xdg_toplevel* t, int w, int h) nothrow @nogc {}
undefined identifier `xdg_toplevel`
extern (C) void
app.onToplevelWmCapabilities
onToplevelWmCapabilities
(void* data, xdg_toplevel* t, wl_array* caps) nothrow @nogc {}
undefined identifier `xdg_toplevel`
undefined identifier `wl_array`
extern (C) void
app.onBufferRelease
onBufferRelease
(void* data, wl_buffer*
(parameter) wl_buffer* b
b
) nothrow @nogc
undefined identifier `wl_buffer`
{ (cast(
(unresolved type) Buffer
Buffer
*) data).
(cast(Buffer*)data).busy
busy
= false;
} __gshared xdg_wm_base_listener
_error_ app.g_wmBaseListener
g_wmBaseListener
= {&onWmBasePing};
undefined identifier `xdg_wm_base_listener`
__gshared xdg_surface_listener
_error_ app.g_xdgSurfaceListener
g_xdgSurfaceListener
= {&onXdgSurfaceConfigure};
undefined identifier `xdg_surface_listener`
__gshared xdg_toplevel_listener
_error_ app.g_toplevelListener
g_toplevelListener
= {
undefined identifier `xdg_toplevel_listener`
&onToplevelConfigure, &onToplevelClose, &onToplevelConfigureBounds, &onToplevelWmCapabilities }; __gshared wl_buffer_listener
_error_ app.g_bufferListener
g_bufferListener
= {&onBufferRelease};
undefined identifier `wl_buffer_listener`
void
void app.makeWindow(ulong idx, const(char)* appId) nothrow @nogc
makeWindow
(
(alias) object.size_t = ulong
size_t
(parameter) ulong idx
idx
, const(char)*
(parameter) const(char)* appId
appId
) nothrow @nogc
{
(struct) app.Surf
Surf
*
(local variable) _error_ s
s
= &g_surfs[idx];
s.
s.surface
surface
= wsi_compositor_create_surface(g_compositor);
s.
s.xdgSurface
xdgSurface
= wsi_wm_base_get_xdg_surface(g_wmBase, s.
s.surface
surface
);
wsi_xdg_surface_add_listener(s.
s.xdgSurface
xdgSurface
, &g_xdgSurfaceListener, cast(void*) idx);
undefined identifier `wsi_xdg_surface_add_listener`
s.
s.toplevel
toplevel
= wsi_xdg_surface_get_toplevel(s.
s.xdgSurface
xdgSurface
);
wsi_toplevel_add_listener(s.
s.toplevel
toplevel
, &g_toplevelListener, cast(void*) idx);
undefined identifier `wsi_toplevel_add_listener`
wsi_toplevel_set_title(s.
s.toplevel
toplevel
, appId);
undefined identifier `wsi_toplevel_set_title`
wsi_toplevel_set_app_id(s.
s.toplevel
toplevel
, appId);
undefined identifier `wsi_toplevel_set_app_id`
wsi_surface_commit(s.
s.surface
surface
);
undefined identifier `wsi_surface_commit`
} // --------------------------------------------------------------------- main /// The startup probe: set_selection with serial=0 before ANY input event /// exists anywhere on this connection. THE Wayland clipboard divergence: /// without a recent input serial there is no clipboard write. void
void app.staleSelectionProbe() nothrow @nogc

The startup probe: set_selection with serial=0 before ANY input event exists anywhere on this connection. THE Wayland clipboard divergence: without a recent input serial there is no clipboard write.

staleSelectionProbe
() nothrow @nogc
{ g_staleSource = makeTextSource(false); wsi_data_device_set_selection(g_dataDevice, g_staleSource, 0);
undefined identifier `wsi_data_device_set_selection`
wl_display_flush(g_display);
undefined identifier `wl_display_flush`
(__gshared global) bool app.g_staleProbeSent
g_staleProbeSent
= true;
instrEvent("set_selection", "serial=0 note=stale-no-input-event-exists");
undefined identifier `instrEvent`, did you mean import `instrument`?
} int
int D main(string[] args)
main
(
(alias) object.string = string
string
[]
(parameter) string[] args
args
)
{ static int
int app.main.parseInt(in char[] s) pure nothrow @nogc @safe
parseInt
(in char[]
(parameter) const(char[]) s
s
) nothrow @nogc
{ int
(local variable) int v
v
;
foreach (
(parameter) const(char) ch
ch
;
(parameter) const(char[]) s
s
)
if (
(local variable) const(char) ch
ch
>= '0' &&
(local variable) const(char) ch
ch
<= '9')
(local variable) int v
v
=
(local variable) int v
v
* 10 + (
(local variable) const(char) ch
ch
- '0');
return
(local variable) int v
v
;
} if (
(parameter) string[] args
args
.
(field) ulong string[].length
length
>= 2 &&
(parameter) string[] args
args
[1].
(field) ulong string.length
length
>= 4 &&
(parameter) string[] args
args
[1][0 .. 4] == "inje")
{ import inject : injectClick, injectDrag;
unable to read module `inject` Expected 'inject.d' or 'inject/package.d' in one of the following import paths:
if (
(parameter) string[] args
args
.
(field) ulong string[].length
length
== 6 &&
(parameter) string[] args
args
[2].
(field) ulong string.length
length
>= 2 &&
(parameter) string[] args
args
[2][0 .. 2] == "cl")
return injectClick(parseInt(args[3]), parseInt(args[4]), parseInt(args[5]));
undefined identifier `injectClick`
if (
(parameter) string[] args
args
.
(field) ulong string[].length
length
== 7 &&
(parameter) string[] args
args
[2].
(field) ulong string.length
length
>= 2 &&
(parameter) string[] args
args
[2][0 .. 2] == "dr")
return injectDrag(parseInt(args[3]), parseInt(args[4]),
undefined identifier `injectDrag`
parseInt(args[5]), parseInt(args[6]));
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogc
printf
("usage: inject click <x> <y> <btn> | inject drag <x1> <y1> <x2> <y2>\n");
return 2; } instrInit("f16_wayland");
undefined identifier `instrInit`
const
(local variable) const(char*) autoEnv
autoEnv
=
char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogc
getenv
("WSI_AUTO_EXIT");
(__gshared global) bool app.g_autoExit
g_autoExit
=
(local variable) const(char*) autoEnv
autoEnv
!is null && *
(local variable) const(char*) autoEnv
autoEnv
== '1';
const
(local variable) const(char*) runMs
runMs
=
char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogc
getenv
("WSI_RUN_MS");
if (
(local variable) const(char*) runMs
runMs
!is null)
(__gshared global) long app.g_runUsCap
g_runUsCap
=
int core.stdc.stdlib.atoi(scope const(char*) nptr) nothrow @nogc
atoi
(
(local variable) const(char*) runMs
runMs
) * 1000L;
g_display = wl_display_connect(null); if (g_display is null) {
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogc
printf
("SKIP: no Wayland compositor (wl_display_connect returned null)\n");
return 0; } g_registry = wsi_display_get_registry(g_display); wsi_registry_add_listener(g_registry, &g_registryListener, null);
undefined identifier `wsi_registry_add_listener`
wl_display_roundtrip(g_display); // globals
undefined identifier `wl_display_roundtrip`
wl_display_roundtrip(g_display); // seat capabilities
undefined identifier `wl_display_roundtrip`
if (g_compositor is null || g_shm is null || g_wmBase is null) {
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogc
printf
("SKIP: compositor lacks a required global\n");
wl_display_disconnect(g_display);
undefined identifier `wl_display_disconnect`
return 0; } instrEvent("globals", "data_device_manager=%d version=%u seat=%d",
undefined identifier `instrEvent`, did you mean import `instrument`?
g_ddm !is null ? 1 : 0, g_ddmVersion, g_seat !is null ? 1 : 0); if (g_ddm is null || g_seat is null) { // headless weston: wl_data_device_manager IS advertised, but with no // seat there is no wl_data_device to bind it to — the clipboard is // seat-scoped by construction. Registry probe is the Tier-A evidence.
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogc
printf
("ok: data_device_manager=%d but seat=%d; clipboard is seat-scoped, nothing to exercise\n",
g_ddm !is null ? 1 : 0, g_seat !is null ? 1 : 0); wl_display_disconnect(g_display);
undefined identifier `wl_display_disconnect`
return 0; } g_dataDevice = wsi_ddm_get_data_device(g_ddm, g_seat); wsi_data_device_add_listener(g_dataDevice, &g_dataDeviceListener, null);
undefined identifier `wsi_data_device_add_listener`
wsi_wm_base_add_listener(g_wmBase, &g_wmBaseListener, null);
undefined identifier `wsi_wm_base_add_listener`
void app.makeWindow(ulong idx, const(char)* appId) nothrow @nogc
makeWindow
(
(constant) ulong app.IDX_A = 0LU
IDX_A
, "wsi-f16-a");
void app.makeWindow(ulong idx, const(char)* appId) nothrow @nogc
makeWindow
(
(constant) ulong app.IDX_B = 1LU
IDX_B
, "wsi-f16-b");
instrWindowCreated();
undefined identifier `instrWindowCreated`
immutable
(local variable) immutable(_error_) dispFd
dispFd
= wl_display_get_fd(g_display);
undefined identifier `wl_display_get_fd`
while (
(__gshared global) bool app.g_running
g_running
)
{ while (wl_display_prepare_read(g_display) != 0)
undefined identifier `wl_display_prepare_read`
wl_display_dispatch_pending(g_display);
undefined identifier `wl_display_dispatch_pending`
wl_display_flush(g_display);
undefined identifier `wl_display_flush`
pollfd[3]
(local variable) _error_ pfds
pfds
= [
undefined identifier `pollfd`
pollfd(dispFd, POLLIN, 0),
undefined identifier `pollfd`
pollfd(g_pipes[0].
g_pipes[0].fd
fd
, POLLIN, 0),
undefined identifier `pollfd`
pollfd(g_pipes[1].
g_pipes[1].fd
fd
, POLLIN, 0),
undefined identifier `pollfd`
]; if (poll(pfds.ptr, 3, 50) > 0 && (pfds[0].revents & POLLIN))
undefined identifier `poll`
undefined identifier `POLLIN`
wl_display_read_events(g_display);
undefined identifier `wl_display_read_events`
else wl_display_cancel_read(g_display);
undefined identifier `wl_display_cancel_read`
if (wl_display_dispatch_pending(g_display) == -1)
undefined identifier `wl_display_dispatch_pending`
{ instrEvent("display_error", "errno=%d", wl_display_get_error(g_display));
undefined identifier `instrEvent`, did you mean import `instrument`?
break; } foreach (
(local variable) int i
i
; 0 .. 2)
if (g_pipes[i].
(field) _error_ (__error)[i].fd
fd
>= 0 && (pfds[i + 1].revents & (POLLIN | POLLHUP)))
undefined identifier `POLLIN`
undefined identifier `POLLHUP`
void app.drainPipe(bool isDnd) nothrow @nogc
drainPipe
(
(local variable) int i
i
== 1);
if (!
(__gshared global) bool app.g_staleProbeSent
g_staleProbeSent
&&
(__gshared global) long app.g_firstPaintUs
g_firstPaintUs
>= 0
&& instrNowUs() >
(__gshared global) long app.g_firstPaintUs
g_firstPaintUs
+ 300_000)
undefined identifier `instrNowUs`
void app.staleSelectionProbe() nothrow @nogc

The startup probe: set_selection with serial=0 before ANY input event exists anywhere on this connection. THE Wayland clipboard divergence: without a recent input serial there is no clipboard write.

staleSelectionProbe
();
if (
(__gshared global) long app.g_exitAtUs
g_exitAtUs
>= 0 && instrNowUs() >
(__gshared global) long app.g_exitAtUs
g_exitAtUs
)
undefined identifier `instrNowUs`
(__gshared global) bool app.g_running
g_running
= false;
if (
(__gshared global) bool app.g_autoExit
g_autoExit
&& instrNowUs() >
(__gshared global) long app.g_runUsCap
g_runUsCap
)
undefined identifier `instrNowUs`
(__gshared global) bool app.g_running
g_running
= false;
} instrEvent("summary", "dnd_finished=%d dnd_motions=%d sel_source_alive=%d",
undefined identifier `instrEvent`, did you mean import `instrument`?
g_dndFinished ? 1 : 0, g_dndMotions, g_selSource !is null ? 1 : 0); // Teardown: children before parents. foreach (ref
(parameter) p
p
; g_pipes)
if (p.
p.fd
fd
>= 0)
close(p.
p.fd
fd
);
if (g_dragSource !is null) wsi_data_source_destroy(g_dragSource);
undefined identifier `wsi_data_source_destroy`
if (g_selSource !is null) wsi_data_source_destroy(g_selSource);
undefined identifier `wsi_data_source_destroy`
if (g_staleSource !is null) wsi_data_source_destroy(g_staleSource);
undefined identifier `wsi_data_source_destroy`
if (g_dataDevice !is null) wsi_data_device_release(g_dataDevice);
undefined identifier `wsi_data_device_release`
if (g_ddm !is null) wsi_ddm_destroy(g_ddm);
undefined identifier `wsi_ddm_destroy`
foreach (
(parameter) idx
idx
; 0 .. g_surfs.
(field) _error_ g_surfs.length
length
)
{
(unresolved type) Surf
Surf
*
_error_ s
s
= &g_surfs[idx];
foreach (ref
(parameter) b
b
; s.
s.buffers
buffers
)
if (b.
b.handle
handle
!is null)
{ wsi_buffer_destroy(b.
b.handle
handle
);
munmap(b.
b.pixels
pixels
, b.
b.byteSize
byteSize
);
} wsi_toplevel_destroy(s.
s.toplevel
toplevel
);
wsi_xdg_surface_destroy(s.
s.xdgSurface
xdgSurface
);
wsi_surface_destroy(s.
s.surface
surface
);
} if (g_keyboard !is null) wsi_keyboard_destroy(g_keyboard);
undefined identifier `wsi_keyboard_destroy`
if (g_pointer !is null) wsi_pointer_destroy(g_pointer);
undefined identifier `wsi_pointer_destroy`
if (g_seat !is null) wsi_seat_destroy(g_seat);
undefined identifier `wsi_seat_destroy`
wsi_wm_base_destroy(g_wmBase);
undefined identifier `wsi_wm_base_destroy`
wl_proxy_destroy(cast(wl_proxy*) g_shm);
undefined identifier `wl_proxy_destroy`
wl_proxy_destroy(cast(wl_proxy*) g_compositor);
undefined identifier `wl_proxy_destroy`
wl_proxy_destroy(cast(wl_proxy*) g_registry);
undefined identifier `wl_proxy_destroy`
wl_display_disconnect(g_display);
undefined identifier `wl_display_disconnect`
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogc
printf
("ok: dnd_finished=%d dnd_motions=%d\n",
(__gshared global) bool app.g_dndFinished
g_dndFinished
? 1 : 0,
(__gshared global) int app.g_dndMotions
g_dndMotions
);
return 0; }