// X11 F14 demo — window state & vetoable close (../../f14-window-state.md,
// spec ../../../features/f14-window-state.md). Evolves the scaffold
// (../scaffold/app.d) event loop; presentation is reduced to a server-side
// XFillRectangle (state events, not pixels, are the subject here).
//
// What it exercises:
// * maximize toggle / fullscreen toggle via _NET_WM_STATE ClientMessages to
// the root window (EWMH: _NET_WM_STATE_MAXIMIZED_HORZ+VERT,
// _NET_WM_STATE_FULLSCREEN, action _NET_WM_STATE_TOGGLE)
// * minimize via XIconifyWindow (ICCCM WM_CHANGE_STATE -> IconicState),
// restore via XMapWindow + _NET_ACTIVE_WINDOW
// * every resulting event is logged until the dust settles: PropertyNotify
// on _NET_WM_STATE / WM_STATE (the atom list is re-read and decoded each
// change), ConfigureNotify sizes, Map/Unmap/ReparentNotify,
// VisibilityNotify, and FocusIn/FocusOut with the full mode/detail decode
// * vetoable close: a "dirty" flag vetoes the first WM_DELETE_WINDOW
// ClientMessage (the request is purely advisory — there is nothing to
// "return" to the WM); the second request closes
// * WSI_NO_WM_DELETE=1 omits WM_DELETE_WINDOW from WM_PROTOCOLS: a WM-side
// close then falls back to XKillClient and the connection dies (XIO error
// handler logs `connection_lost` and exits 0 — that *is* the finding)
//
// Modes: WSI_AUTO_EXIT=1 self-drives the whole transition schedule (the same
// handlers the keys call) and exits 0 — works on bare Xvfb (no WM: requests
// vanish; the silence is logged) and under a WM. WSI_DRIVEN=1 instead waits
// ~12 s for externally injected keys (xdotool; see run.sh):
// m maximize-toggle i iconify r restore f fullscreen-toggle
// d dirty-toggle c self-send a WM_DELETE_WINDOW request q quit
// Headless-safe: no display -> prints `SKIP:` and exits 0.
module (module) appapp;
import (module) cc; // ImportC: Xlib + Xutil + Xatom (+ unused XShm) + poll
import (module) instrumentinstrument;
import (package) corecore.(package) core.stdcstdc.(module) core.stdc.configD compatible types that correspond to various basic types in associated
C and C++ compilers.
Source
core/stdc/config.d
config : c_long, c_ulong;
import (package) corecore.(package) core.stdcstdc.(module) core.stdc.stdioD header file for C99 <stdio.h>
pubs.opengroup.org/onlinepubs/009695399/basedefs/stdio.h.html, stdio.h
Source
core/stdc/stdio.d
stdio : (alias) app.printf = int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogcprintf, (alias) app.snprintf = int core.stdc.stdio.snprintf(scope char* s, ulong n, scope const(char*) format, scope const ...) nothrow @nogcsnprintf;
import (package) corecore.(package) core.stdcstdc.(module) core.stdc.stdlibD header file for C99.
pubs.opengroup.org/onlinepubs/009695399/basedefs/stdlib.h.html, stdlib.h
Source
core/stdc/stdlib.d
stdlib : (alias) app.exit = noreturn core.stdc.stdlib.exit(int status) nothrow @nogcexit, (alias) app.getenv = char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogcgetenv;
// Macros ImportC cannot export, re-declared (see ../scaffold/app.d):
enum : c_long
{
(enum value) app.KeyPressMask = 1LKeyPressMask = 1L << 0,
(enum value) app.ExposureMask = 32768LExposureMask = 1L << 15,
(enum value) app.VisibilityChangeMask = 65536LVisibilityChangeMask = 1L << 16,
(enum value) app.StructureNotifyMask = 131072LStructureNotifyMask = 1L << 17,
(enum value) app.SubstructureNotifyMask = 524288LSubstructureNotifyMask = 1L << 19,
(enum value) app.SubstructureRedirectMask = 1048576LSubstructureRedirectMask = 1L << 20,
(enum value) app.FocusChangeMask = 2097152LFocusChangeMask = 1L << 21,
(enum value) app.PropertyChangeMask = 4194304LPropertyChangeMask = 1L << 22,
}
enum // XEvent.type discriminators
{
(enum value) app.KeyPress = 2KeyPress = 2,
(enum value) app.FocusIn = 9FocusIn = 9,
(enum value) app.FocusOut = 10FocusOut = 10,
(enum value) app.Expose = 12Expose = 12,
(enum value) app.VisibilityNotify = 15VisibilityNotify = 15,
(enum value) app.UnmapNotify = 18UnmapNotify = 18,
(enum value) app.MapNotify = 19MapNotify = 19,
(enum value) app.ReparentNotify = 21ReparentNotify = 21,
(enum value) app.ConfigureNotify = 22ConfigureNotify = 22,
(enum value) app.PropertyNotify = 28PropertyNotify = 28,
(enum value) app.ClientMessage = 33ClientMessage = 33,
}
enum (constant) int app.False = 0False = 0;
enum (constant) int app.True = 1True = 1;
enum (constant) int app.POLLIN = 1POLLIN = 0x001;
enum (constant) int app.XA_ATOM = 4XA_ATOM = 4; // Xatom.h: #define XA_ATOM ((Atom) 4) — a cast macro
enum (constant) int app.AnyPropertyType = 0AnyPropertyType = 0;
enum (constant) int app.NoEventMask = 0NoEventMask = 0;
// EWMH _NET_WM_STATE ClientMessage actions (EWMH spec, _NET_WM_STATE):
enum : c_long
{
(enum value) app._NET_WM_STATE_REMOVE = 0L_NET_WM_STATE_REMOVE = 0,
(enum value) app._NET_WM_STATE_ADD = 1L_NET_WM_STATE_ADD = 1,
(enum value) app._NET_WM_STATE_TOGGLE = 2L_NET_WM_STATE_TOGGLE = 2,
}
// ICCCM WM_STATE / WM_CHANGE_STATE state values:
enum { (enum value) app.WithdrawnState = 0WithdrawnState = 0, (enum value) app.NormalState = 1NormalState = 1, (enum value) app.IconicState = 3IconicState = 3 }
// The FocusIn/FocusOut "Notify* zoo" (Xlib ch. 10.8, <X11/X.h>):
static immutable (alias) object.string = stringstring[4] (immutable global) immutable(string[4]) app.focusModesfocusModes =
["NotifyNormal", "NotifyGrab", "NotifyUngrab", "NotifyWhileGrabbed"];
static immutable (alias) object.string = stringstring[8] (immutable global) immutable(string[8]) app.focusDetailsfocusDetails = [
"NotifyAncestor", "NotifyVirtual", "NotifyInferior", "NotifyNonlinear",
"NotifyNonlinearVirtual", "NotifyPointer", "NotifyPointerRoot", "NotifyDetailNone",
];
struct (struct) app.DemoDemo
{
Display* (field) _error_ app.Demo.dpydpy;
Window (field) _error_ app.Demo.rootroot, (field) _error_ app.Demo.winwin;
int (field) int app.Demo.screenscreen;
Atom (field) _error_ app.Demo.netWmStatenetWmState, (field) _error_ app.Demo.netMaxHnetMaxH, (field) _error_ app.Demo.netMaxVnetMaxV, (field) _error_ app.Demo.netFullscreennetFullscreen, (field) _error_ app.Demo.netActivenetActive;
Atom (field) _error_ app.Demo.wmProtocolswmProtocols, (field) _error_ app.Demo.wmDeletewmDelete, (field) _error_ app.Demo.wmStatewmState;
bool (field) bool app.Demo.dirtydirty, (field) bool app.Demo.runningrunning = true;
int (field) int app.Demo.requestsrequests, (field) int app.Demo.stateChangesstateChanges, (field) int app.Demo.configuresconfigures, (field) int app.Demo.unmapsMapsunmapsMaps, (field) int app.Demo.focusEventsfocusEvents;
}
__gshared int (__gshared global) int app.g_xerrorsg_xerrors;
extern (C) int app.onXErroronXError(Display* (parameter) Display* dpydpy, XErrorEvent* (parameter) XErrorEvent* ee) @nogc nothrow
{
++g_xerrors;
emitf("x_error", "code=%d request=%d", e.error_code, e.request_code);
return 0;
}
// Fires when the server severs the connection (the XKillClient probe). The
// handler must not return; exiting 0 keeps the probe pass green — losing the
// connection is the documented outcome, not a demo failure.
extern (C) int app.onXIOErroronXIOError(Display* (parameter) Display* dpydpy) @nogc nothrow
{
emit("connection_lost via=XIOError likely=XKillClient");
exit(0);
}
/// EWMH state change: a ClientMessage *to the root window* with
/// SubstructureRedirect|SubstructureNotify in the event mask — only a WM
/// (the client that selected SubstructureRedirect on the root) receives it.
void app.sendNetWmStateEWMH state change: a ClientMessage to the root window with
SubstructureRedirect|SubstructureNotify in the event mask — only a WM
(the client that selected SubstructureRedirect on the root) receives it.
sendNetWmState(ref (struct) app.DemoDemo (parameter) Demo dd, c_long action, Atom a1, Atom a2,
const(char)* kind) @nogc nothrow
{
XEvent _error_ ee;
e.xclient.e.xclient.typetype = ClientMessage;
e.xclient.window = d.d.winwin;
e.xclient.message_type = d.d.netWmStatenetWmState;
e.xclient.e.xclient.formatformat = 32;
e.xclient.data.l[0] = action;
e.xclient.data.l[1] = cast(c_long) a1;
e.xclient.data.l[2] = cast(c_long) a2;
e.xclient.data.l[3] = 1; // source indication: normal application
XSendEvent(d.d.dpydpy, d.d.rootroot, False,
SubstructureRedirectMask | SubstructureNotifyMask, &e);
XFlush(d.d.dpydpy);
++d.d.requestsrequests;
emitf("state_request", "kind=%s action=%ld target=root", kind, action);
}
void app.requestActivaterequestActivate(ref (struct) app.DemoDemo (parameter) Demo dd) @nogc nothrow
{
XEvent _error_ ee;
e.xclient.e.xclient.typetype = ClientMessage;
e.xclient.window = d.d.winwin;
e.xclient.message_type = d.d.netActivenetActive;
e.xclient.e.xclient.formatformat = 32;
e.xclient.data.l[0] = 1; // source: application
XSendEvent(d.d.dpydpy, d.d.rootroot, False,
SubstructureRedirectMask | SubstructureNotifyMask, &e);
XFlush(d.d.dpydpy);
++d.d.requestsrequests;
emit("state_request kind=activate target=root");
}
/// Self-deliver the WM_PROTOCOLS/WM_DELETE_WINDOW ClientMessage — the close
/// request is just an event any client may send; the WM sends exactly this.
void app.sendCloseRequestSelf-deliver the WM_PROTOCOLS/WM_DELETE_WINDOW ClientMessage — the close
request is just an event any client may send; the WM sends exactly this.
sendCloseRequest(ref (struct) app.DemoDemo (parameter) Demo dd) @nogc nothrow
{
XEvent _error_ ee;
e.xclient.e.xclient.typetype = ClientMessage;
e.xclient.window = d.d.winwin;
e.xclient.message_type = d.d.wmProtocolswmProtocols;
e.xclient.e.xclient.formatformat = 32;
e.xclient.data.l[0] = cast(c_long) d.d.wmDeletewmDelete;
XSendEvent(d.d.dpydpy, d.d.winwin, False, NoEventMask, &e);
XFlush(d.d.dpydpy);
emit("step name=XSendEvent msg=WM_DELETE_WINDOW to=self");
}
/// Re-read and decode the _NET_WM_STATE atom list (PropertyNotify carries no
/// payload — the new value must be fetched with XGetWindowProperty).
void app.logNetWmStateRe-read and decode the NET_WM_STATE atom list (PropertyNotify carries no
payload — the new value must be fetched with XGetWindowProperty).
logNetWmState(ref (struct) app.DemoDemo (parameter) Demo dd) nothrow
{
Atom _error_ typetype;
int _error_ formatformat;
c_ulong _error_ nitemsnitems, _error_ afterafter;
ubyte* _error_ propprop;
XGetWindowProperty(d.d.dpydpy, d.d.winwin, d.d.netWmStatenetWmState, 0, 32, False, XA_ATOM,
&type, &format, &nitems, &after, &prop);
char[256] _error_ bufbuf = '\0';
(unresolved type) size_tsize_t _error_ offoff;
foreach ((parameter) ii; 0 .. cast((unresolved type) size_tsize_t) nitems)
{
const _error_ aa = (cast(Atom*) prop)[i];
char* _error_ namename = XGetAtomName(d.d.dpydpy, a);
off += snprintf(buf.ptr + off, buf.buf.lengthlength - off, "%s%s",
i ? ",".ptr : "".ptr, name);
XFree(name);
}
if (prop !is null)
XFree(prop);
++d.d.stateChangesstateChanges;
emitf("state_changed", "states=[%s]", buf.ptr);
}
/// Decode the ICCCM WM_STATE property (set by the WM): the first CARD32 is
/// Withdrawn/Normal/Iconic — the only reliable iconified-or-not signal.
void app.logWmStateDecode the ICCCM WM_STATE property (set by the WM): the first CARD32 is
Withdrawn/Normal/Iconic — the only reliable iconified-or-not signal.
logWmState(ref (struct) app.DemoDemo (parameter) Demo dd) nothrow
{
Atom _error_ typetype;
int _error_ formatformat;
c_ulong _error_ nitemsnitems, _error_ afterafter;
ubyte* _error_ propprop;
XGetWindowProperty(d.d.dpydpy, d.d.winwin, d.d.wmStatewmState, 0, 2, False, AnyPropertyType,
&type, &format, &nitems, &after, &prop);
if (prop !is null && nitems >= 1)
{
const _error_ vv = *cast(c_ulong*) prop;
emitf("state_changed", "wm_state=%s", v == IconicState
? "iconic".ptr : v == NormalState ? "normal".ptr : "withdrawn".ptr);
++d.d.stateChangesstateChanges;
}
if (prop !is null)
XFree(prop);
}
void app.redrawredraw(ref (struct) app.DemoDemo (parameter) Demo dd, int w, int h) @nogc nothrow
{
GC _error_ gcgc = XDefaultGC(d.d.dpydpy, d.d.screenscreen);
XSetForeground(d.d.dpydpy, gc, d.d.dirtydirty ? 0xc04040 : 0x4070b0);
XFillRectangle(d.d.dpydpy, d.d.winwin, gc, 0, 0, cast(uint) w, cast(uint) h);
}
// One named action per key; the auto schedule calls the same handler.
void app.actact(ref (struct) app.DemoDemo (parameter) Demo dd, char (parameter) char keykey) nothrow
{
switch (key)
{
case 'm':
sendNetWmState(d, _NET_WM_STATE_TOGGLE, d.d.netMaxHnetMaxH, d.d.netMaxVnetMaxV, "maximize_toggle");
break;
case 'f':
sendNetWmState(d, _NET_WM_STATE_TOGGLE, d.d.netFullscreennetFullscreen, 0, "fullscreen_toggle");
break;
case 'i':
// Xutil convenience: sends the ICCCM WM_CHANGE_STATE ClientMessage
// (IconicState) to the root — again, only a WM listens.
const _error_ stst = XIconifyWindow(d.d.dpydpy, d.d.winwin, d.d.screenscreen);
XFlush(d.d.dpydpy);
++d.d.requestsrequests;
emitf("state_request", "kind=minimize via=XIconifyWindow sent=%d", st);
break;
case 'r':
sendNetWmState(d, _NET_WM_STATE_REMOVE, d.d.netMaxHnetMaxH, d.d.netMaxVnetMaxV, "restore_maximize");
sendNetWmState(d, _NET_WM_STATE_REMOVE, d.d.netFullscreennetFullscreen, 0, "restore_fullscreen");
XMapWindow(d.d.dpydpy, d.d.winwin); // de-iconify (ICCCM: map the window)
emit("state_request kind=restore via=XMapWindow");
requestActivate(d);
break;
case 'd':
d.d.dirtydirty = !d.d.dirtydirty;
emitf("dirty", "flag=%d", cast(int) d.d.dirtydirty);
break;
case 'c':
sendCloseRequest(d);
break;
case 'q':
d.d.runningrunning = false;
break;
default:
break;
}
}
int int D main()main()
{
void instrument.initInstrument(const(char)* demoName) nothrow @nogcNames the demo, starts the monotonic clock, and emits init_start.
Call this first, before any platform API call.
initInstrument("f14_x11");
const (local variable) const(bool) autoExitautoExit = char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogcgetenv("WSI_AUTO_EXIT") !is null;
const (local variable) const(bool) drivendriven = char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogcgetenv("WSI_DRIVEN") !is null;
const (local variable) const(bool) noWmDeletenoWmDelete = char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogcgetenv("WSI_NO_WM_DELETE") !is null;
(struct) app.DemoDemo (local variable) _error_ dd;
d.d.dpydpy = XOpenDisplay(null);
if (d.(field) _error_ d.dpydpy is null)
{
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogcprintf("SKIP: no X11 display (XOpenDisplay returned null)\n");
return 0;
}
XSetErrorHandler(&onXError);
XSetIOErrorHandler(&onXIOError);
void instrument.emitf(scope const(char)* kind, scope const(char)* fmt, ...) nothrow @nogcEmit an event with a printf-formatted key=value ... payload.
emitf("step", "name=XOpenDisplay fd=%d", XConnectionNumber(d.d.dpydpy));
d.d.screenscreen = XDefaultScreen(d.d.dpydpy);
d.d.rootroot = XRootWindow(d.d.dpydpy, d.d.screenscreen);
int (local variable) int widthwidth = 480, (local variable) int heightheight = 320;
d.d.winwin = XCreateSimpleWindow(d.d.dpydpy, d.d.rootroot, 20, 20, width, height, 1,
XBlackPixel(d.d.dpydpy, d.d.screenscreen), XWhitePixel(d.d.dpydpy, d.d.screenscreen));
XStoreName(d.d.dpydpy, d.d.winwin, "Sparkles \xc2\xb7 X11 F14 window state");
d.d.netWmStatenetWmState = XInternAtom(d.d.dpydpy, "_NET_WM_STATE", False);
d.d.netMaxHnetMaxH = XInternAtom(d.d.dpydpy, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
d.d.netMaxVnetMaxV = XInternAtom(d.d.dpydpy, "_NET_WM_STATE_MAXIMIZED_VERT", False);
d.d.netFullscreennetFullscreen = XInternAtom(d.d.dpydpy, "_NET_WM_STATE_FULLSCREEN", False);
d.d.netActivenetActive = XInternAtom(d.d.dpydpy, "_NET_ACTIVE_WINDOW", False);
d.d.wmProtocolswmProtocols = XInternAtom(d.d.dpydpy, "WM_PROTOCOLS", False);
d.d.wmDeletewmDelete = XInternAtom(d.d.dpydpy, "WM_DELETE_WINDOW", False);
d.d.wmStatewmState = XInternAtom(d.d.dpydpy, "WM_STATE", False);
if ((local variable) const(bool) noWmDeletenoWmDelete)
void instrument.emit(scope const(char)* kind) nothrow @nogcEmit an event with no key=value payload.
emit("step name=XSetWMProtocols skipped=WSI_NO_WM_DELETE");
else
XSetWMProtocols(d.d.dpydpy, d.d.winwin, &d.d.wmDeletewmDelete, 1);
XSelectInput(d.d.dpydpy, d.d.winwin, ExposureMask | KeyPressMask | StructureNotifyMask
| PropertyChangeMask | FocusChangeMask | VisibilityChangeMask);
XMapWindow(d.d.dpydpy, d.d.winwin);
void instrument.emitf(scope const(char)* kind, scope const(char)* fmt, ...) nothrow @nogcEmit an event with a printf-formatted key=value ... payload.
emitf("window_created", "xid=0x%lx size=%dx%d", d.(field) _error_ d.winwin, (local variable) int widthwidth, (local variable) int heightheight);
// The self-driven schedule (µs since init) — same handlers as the keys.
static immutable struct (struct) app.main.StepStep { long (field) immutable(long) app.main.Step.tt; char (field) immutable(char) app.main.Step.keykey; }
static immutable (struct) app.main.StepStep[9] (immutable global) immutable(app.main.Step[9]) app.main.scheduleschedule = [
{400_000, 'm'}, {900_000, 'm'}, {1_400_000, 'i'}, {1_900_000, 'r'},
{2_400_000, 'f'}, {2_900_000, 'f'}, {3_400_000, 'd'},
{3_500_000, 'c'}, /* dirty -> vetoed */ {3_900_000, 'c'}, /* closes */
];
(alias) object.size_t = ulongsize_t (local variable) ulong nextStepnextStep;
const (local variable) const(int) deadlinedeadline = (local variable) const(bool) drivendriven ? 12_000_000 : 5_000_000;
const (local variable) const(_error_) fdfd = XConnectionNumber(d.d.dpydpy);
while (d.(field) _error_ d.runningrunning)
{
while (XPending(d.d.dpydpy) > 0)
{
XEvent (local variable) _error_ evev;
XNextEvent(d.d.dpydpy, &ev);
switch (ev.(field) _error_ ev.typetype)
{
case ConfigureNotify:
++d.d.configuresconfigures;
emitf("configure", "size=%dx%d pos=%d+%d send_event=%d",
ev.xconfigure.ev.xconfigure.widthwidth, ev.xconfigure.ev.xconfigure.heightheight,
ev.xconfigure.x, ev.xconfigure.y, cast(int) ev.xany.send_event);
width = ev.xconfigure.ev.xconfigure.widthwidth;
height = ev.xconfigure.ev.xconfigure.heightheight;
break;
case MapNotify:
++d.d.unmapsMapsunmapsMaps;
emit("map_notify");
break;
case UnmapNotify:
++d.d.unmapsMapsunmapsMaps;
emitf("unmap_notify", "send_event=%d", cast(int) ev.xany.send_event);
break;
case ReparentNotify:
emitf("reparent_notify", "parent=0x%lx", ev.xreparent.parent);
break;
case VisibilityNotify:
emitf("visibility", "state=%d", ev.xvisibility.state);
break;
case PropertyNotify:
char* _error_ namename = XGetAtomName(d.d.dpydpy, ev.xproperty.atom);
emitf("property_notify", "atom=%s state=%s", name,
ev.xproperty.state == 0 ? "NewValue".ptr : "Deleted".ptr);
XFree(name);
if (ev.xproperty.atom == d.d.netWmStatenetWmState && ev.xproperty.state == 0)
logNetWmState(d);
else if (ev.xproperty.atom == d.d.wmStatewmState && ev.xproperty.state == 0)
logWmState(d);
break;
case FocusIn:
case FocusOut:
++d.d.focusEventsfocusEvents;
emitf("focus", "state=%s mode=%s detail=%s",
ev.ev.typetype == FocusIn ? "in".ptr : "out".ptr,
focusModes[ev.xfocus.mode].ptr, focusDetails[ev.xfocus.detail].ptr);
break;
case Expose:
if (ev.xexpose.count == 0)
redraw(d, width, height);
break;
case ClientMessage:
if (ev.xclient.message_type == d.d.wmProtocolswmProtocols
&& cast(Atom) ev.xclient.data.l[0] == d.d.wmDeletewmDelete)
{
if (d.d.dirtydirty)
{
// The veto: simply do nothing. WM_DELETE_WINDOW is
// advisory (ICCCM §4.2.8.1) — there is no reply, no
// return value, nothing to send back. Ignoring it IS
// the veto; the WM cannot tell refusal from sloth.
d.d.dirtydirty = false;
emit("close_requested veto=1 action=ignored_dirty_cleared");
redraw(d, width, height);
}
else
{
emit("close_requested veto=0 action=quit");
d.d.runningrunning = false;
}
}
break;
case KeyPress:
const _error_ symsym = XLookupKeysym(&ev.xkey, 0);
emitf("key", "sym=0x%lx", sym);
if (sym >= 'a' && sym <= 'z')
act(d, cast(char) sym);
break;
default:
break;
}
}
if ((local variable) const(bool) autoExitautoExit && !(local variable) const(bool) drivendriven && (local variable) ulong nextStepnextStep < (immutable global) immutable(app.main.Step[9]) app.main.scheduleschedule.(constant) ulong immutable(app.main.Step[9]).length = 9LUlength
&& long instrument.nowUs() nothrow @nogcMicroseconds elapsed since initInstrument.
nowUs() >= (immutable global) immutable(app.main.Step[9]) app.main.scheduleschedule[(local variable) ulong nextStepnextStep].(field) immutable(long) app.main.Step.tt)
{
act(d, schedule[nextStep].schedule[nextStep].keykey);
++(local variable) ulong nextStepnextStep;
}
if (((local variable) const(bool) autoExitautoExit || (local variable) const(bool) drivendriven) && long instrument.nowUs() nothrow @nogcMicroseconds elapsed since initInstrument.
nowUs() > (local variable) const(int) deadlinedeadline)
{
void instrument.emit(scope const(char)* kind) nothrow @nogcEmit an event with no key=value payload.
emit("auto_exit reason=deadline");
break;
}
if (!(local variable) const(bool) autoExitautoExit && !(local variable) const(bool) drivendriven && (local variable) ulong nextStepnextStep == 0)
(local variable) ulong nextStepnextStep = 1; // interactive: no schedule, keys only
pollfd (local variable) _error_ pfdpfd;
pfd.pfd.fdfd = fd;
pfd.events = POLLIN;
pfd.revents = 0;
poll(&pfd, 1, (autoExit || driven) ? 20 : -1);
}
void instrument.emitf(scope const(char)* kind, scope const(char)* fmt, ...) nothrow @nogcEmit an event with a printf-formatted key=value ... payload.
emitf("summary", "requests=%d state_changes=%d configures=%d map_unmap=%d "
~ "focus=%d x_errors=%d", d.(field) _error_ d.requestsrequests, d.(field) _error_ d.stateChangesstateChanges, d.(field) _error_ d.configuresconfigures,
d.(field) _error_ d.unmapsMapsunmapsMaps, d.(field) _error_ d.focusEventsfocusEvents, (__gshared global) int app.g_xerrorsg_xerrors);
XDestroyWindow(d.d.dpydpy, d.d.winwin);
XCloseDisplay(d.d.dpydpy);
return 0;
}