app.dhover×421 error×37all
// X11 F15 demo — popup with grab (../../f15-popup.md, spec
// ../../../features/f15-popup.md). Evolves the scaffold (../scaffold/app.d)
// event loop; rendering is server-side XFillRectangle (the subject is the
// secondary-surface + grab model, not pixels).
//
// What it exercises:
//   * a menu-like popup: override-redirect window (CWOverrideRedirect — the
//     WM never sees it) + XGrabPointer (owner_events=False,
//     ButtonPress|ButtonRelease|PointerMotion) + XGrabKeyboard, raised with
//     XRaiseWindow; 3 fake items with hover highlight (motion inside the
//     grab); item click activates; outside click dismisses (the grab is WHY
//     the popup sees clicks it does not own); Esc dismisses
//   * grab routing choice: ONE pointer grab on the first popup,
//     owner_events=False, so every pointer event arrives relative to the
//     grab window and hit-testing is done in root coordinates against the
//     app-known popup-chain rects (the alternative — owner_events=True or
//     re-grabbing on the submenu — is discussed in the findings doc)
//   * edge correctness: opening near the bottom-right screen corner — the
//     APP must clamp; the math is logged (no compositor/positioner exists)
//   * nested submenu one level deep (second override-redirect window),
//     opened on hovering item 2; stacking verified via XQueryTree
//   * probes: XGrabPointer return codes when a second client already holds
//     a grab (AlreadyGrabbed); event starvation of a second client's window
//     while the grab is held (driven mode, see run.sh)
//
// Modes: WSI_AUTO_EXIT=1 self-drives placement/stacking/grab-code probes
// (no synthetic input needed) and exits 0. WSI_DRIVEN=1 waits ~14 s for
// xdotool-injected clicks/keys (run.sh): right-click opens the menu at the
// pointer, hover/submenu/item-click/outside-click/Esc are all real pointer
// events through the grab. Headless-safe: no display -> `SKIP:`, exit 0.
module 
(module) app
app
;
import
(module) c
c
; // ImportC: Xlib + Xutil + Xatom (+ unused XShm) + poll
C preprocess command `cpp` failed for file `/home/runner/work/sparkles/sparkles/docs/research/window-system-integration/os-apis/x11/examples/f15-popup/c.c`, exit status 1
import
(module) instrument
instrument
;
import
(package) core
core
.
(package) core.stdc
stdc
.
(module) core.stdc.config

D compatible types that correspond to various basic types in associated C and C++ compilers.

Source

core/stdc/config.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)
config
: c_long, c_ulong;
import
(package) core
core
.
(package) core.stdc
stdc
.
(module) core.stdc.stdio

D header file for C99 <stdio.h>

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

Source

core/stdc/stdio.d

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseDistributed under the Boost Software License 1.0. (See accompanying file LICENSE)@authorsSean Kelly, Alex Rønne Petersen@standardsISO/IEC 9899:1999 (E)
stdio
:
(alias) app.printf = int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogc
printf
;
import
(package) core
core
.
(package) core.stdc
stdc
.
(module) core.stdc.stdlib

D header file for C99.

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

Source

core/stdc/stdlib.d

@copyrightCopyright Sean Kelly 2005 - 2014.@licenseDistributed under the Boost Software License 1.0. (See accompanying file LICENSE)@authorsSean Kelly@standardsISO/IEC 9899:1999 (E)
stdlib
:
(alias) app.getenv = char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogc
getenv
;
// Macros ImportC cannot export, re-declared (see ../scaffold/app.d): enum : c_long {
(enum value) app.KeyPressMask = 1L
KeyPressMask
= 1L << 0,
(enum value) app.ButtonPressMask = 4L
ButtonPressMask
= 1L << 2,
(enum value) app.ButtonReleaseMask = 8L
ButtonReleaseMask
= 1L << 3,
(enum value) app.PointerMotionMask = 64L
PointerMotionMask
= 1L << 6,
(enum value) app.ExposureMask = 32768L
ExposureMask
= 1L << 15,
(enum value) app.StructureNotifyMask = 131072L
StructureNotifyMask
= 1L << 17,
(enum value) app.FocusChangeMask = 2097152L
FocusChangeMask
= 1L << 21,
} enum // XEvent.type discriminators {
(enum value) app.KeyPress = 2
KeyPress
= 2,
(enum value) app.ButtonPress = 4
ButtonPress
= 4,
(enum value) app.ButtonRelease = 5
ButtonRelease
= 5,
(enum value) app.MotionNotify = 6
MotionNotify
= 6,
(enum value) app.FocusIn = 9
FocusIn
= 9,
(enum value) app.FocusOut = 10
FocusOut
= 10,
(enum value) app.Expose = 12
Expose
= 12,
(enum value) app.MapNotify = 19
MapNotify
= 19,
(enum value) app.ConfigureNotify = 22
ConfigureNotify
= 22,
(enum value) app.ClientMessage = 33
ClientMessage
= 33,
} enum : c_ulong // XCreateWindow attribute mask bits {
(enum value) app.CWBackPixel = 2LU
CWBackPixel
= 1L << 1,
(enum value) app.CWBorderPixel = 8LU
CWBorderPixel
= 1L << 3,
(enum value) app.CWOverrideRedirect = 512LU
CWOverrideRedirect
= 1L << 9,
(enum value) app.CWSaveUnder = 1024LU
CWSaveUnder
= 1L << 10,
(enum value) app.CWEventMask = 2048LU
CWEventMask
= 1L << 11,
} enum
(constant) int app.False = 0
False
= 0;
enum
(constant) int app.True = 1
True
= 1;
enum
(constant) int app.POLLIN = 1
POLLIN
= 0x001;
enum
(constant) int app.None = 0
None
= 0;
enum
(constant) int app.CurrentTime = 0
CurrentTime
= 0;
enum
(constant) int app.GrabModeAsync = 1
GrabModeAsync
= 1;
enum
(constant) int app.InputOutput = 1
InputOutput
= 1;
enum
(constant) int app.CopyFromParent = 0
CopyFromParent
= 0;
enum
(constant) int app.XK_Escape = 65307
XK_Escape
= 0xff1b;
// XGrabPointer/XGrabKeyboard return codes (<X11/X.h>): static immutable
(alias) object.string = string
string
[5]
(immutable global) immutable(string[5]) app.grabCodes
grabCodes
=
["GrabSuccess", "AlreadyGrabbed", "GrabInvalidTime", "GrabNotViewable", "GrabFrozen"]; // FocusIn/FocusOut mode decode (<X11/X.h>) — grab-generated focus events // (NotifyGrab/NotifyUngrab) are NOT window-manager focus: static immutable
(alias) object.string = string
string
[4]
(immutable global) immutable(string[4]) app.focusModes
focusModes
=
["NotifyNormal", "NotifyGrab", "NotifyUngrab", "NotifyWhileGrabbed"]; enum
(constant) int app.itemH = 24
itemH
= 24,
(constant) int app.menuW = 160
menuW
= 160,
(constant) int app.menuItems = 3
menuItems
= 3;
enum
(constant) int app.menuH = 72
menuH
=
(constant) int app.itemH = 24
itemH
*
(constant) int app.menuItems = 3
menuItems
;
struct
(struct) app.Menu
Menu
{ Window
(field) _error_ app.Menu.win
win
;
undefined identifier `Window`
int
(field) int app.Menu.x
x
,
(field) int app.Menu.y
y
; // root coordinates
bool
(field) bool app.Menu.open
open
;
int
(field) int app.Menu.hover
hover
= -1;
} struct
(struct) app.Demo
Demo
{ Display*
(field) _error_ app.Demo.dpy
dpy
,
(field) _error_ app.Demo.dpy2
dpy2
; // dpy2: the independent "second client" connection
undefined identifier `Display`
undefined identifier `Display`
Window
(field) _error_ app.Demo.root
root
,
(field) _error_ app.Demo.main
main
,
(field) _error_ app.Demo.second
second
;
undefined identifier `Window`
undefined identifier `Window`
undefined identifier `Window`
int
(field) int app.Demo.screen
screen
,
(field) int app.Demo.screenW
screenW
,
(field) int app.Demo.screenH
screenH
;
GC
(field) _error_ app.Demo.gc
gc
;
undefined identifier `GC`
Atom
(field) _error_ app.Demo.wmProtocols
wmProtocols
,
(field) _error_ app.Demo.wmDelete
wmDelete
;
undefined identifier `Atom`
undefined identifier `Atom`
(struct) app.Menu
Menu
[2]
(field) _error_ app.Demo.menus
menus
; // [0] the popup menu, [1] its submenu
bool
(field) bool app.Demo.running
running
= true,
(field) bool app.Demo.grabbed
grabbed
,
(field) bool app.Demo.swallowRelease
swallowRelease
;
int
(field) int app.Demo.opens
opens
,
(field) int app.Demo.dismissals
dismissals
,
(field) int app.Demo.activations
activations
,
(field) int app.Demo.hoverChanges
hoverChanges
;
int
(field) int app.Demo.secondClientEvents
secondClientEvents
,
(field) int app.Demo.popupFocusEvents
popupFocusEvents
;
} __gshared int
(__gshared global) int app.g_xerrors
g_xerrors
;
extern (C) int
app.onXError
onXError
(Display*
(parameter) Display* dpy
dpy
, XErrorEvent* e) @nogc nothrow
undefined identifier `Display`
undefined identifier `XErrorEvent`
{ ++g_xerrors; emitf("x_error", "code=%d request=%d", e.error_code, e.request_code); return 0; } Window
app.makeOverrideRedirect
makeOverrideRedirect
(ref
(struct) app.Demo
Demo
(parameter) Demo d
d
, int
(parameter) int x
x
, int
(parameter) int y
y
, uint w, uint h) @nogc nothrow
undefined identifier `Window`
{ XSetWindowAttributes
_error_ attrs
attrs
;
attrs.override_redirect = True; // the WM neither decorates nor manages it attrs.background_pixel = 0x202020; attrs.border_pixel = 0x808080; attrs.save_under = True; attrs.event_mask = ExposureMask | FocusChangeMask; return XCreateWindow(d.
d.dpy
dpy
, d.
d.root
root
, x, y, w, h, 1, CopyFromParent,
InputOutput, null /* CopyFromParent visual */ , CWBackPixel | CWBorderPixel | CWOverrideRedirect | CWSaveUnder | CWEventMask, &attrs); } void
app.drawMenu
drawMenu
(ref
(struct) app.Demo
Demo
(parameter) Demo d
d
, ref
(struct) app.Menu
Menu
(parameter) Menu m
m
) @nogc nothrow
{ if (!m.
m.open
open
)
return; foreach (
(parameter) i
i
; 0 .. menuItems)
{ XSetForeground(d.
d.dpy
dpy
, d.
d.gc
gc
, i == m.
m.hover
hover
? 0x6090d0 : 0x383838);
XFillRectangle(d.
d.dpy
dpy
, m.
m.win
win
, d.
d.gc
gc
, 2, i * itemH + 2,
menuW - 4, itemH - 4); } XFlush(d.
d.dpy
dpy
);
} /// Is the popup (or submenu) on top of the stack? XQueryTree returns root's /// children bottom-to-top; override-redirect windows fight no WM for slots, /// but a WM may still restack other windows around them. void
app.logStacking

Is the popup (or submenu) on top of the stack? XQueryTree returns root's children bottom-to-top; override-redirect windows fight no WM for slots, but a WM may still restack other windows around them.

logStacking
(ref
(struct) app.Demo
Demo
(parameter) Demo d
d
, Window expectTop, const(char)* label) @nogc nothrow
undefined identifier `Window`
{ Window
_error_ rootRet
rootRet
,
_error_ parentRet
parentRet
;
Window*
_error_ children
children
;
uint
_error_ n
n
;
XQueryTree(d.
d.dpy
dpy
, d.
d.root
root
, &rootRet, &parentRet, &children, &n);
const
_error_ top
top
= n ? children[n - 1] : 0;
emitf("stacking", "probe=%s topmost=0x%lx expected=0x%lx on_top=%d", label, top, expectTop, cast(int)(top == expectTop)); if (children !is null) XFree(children); } /// Open the popup at the pointer/anchor with app-side edge clamping — on X11 /// nobody else will move it (contrast: a Wayland xdg_positioner lets the /// compositor slide/flip it). The clamp math is the finding; log it. void
app.openMenu

Open the popup at the pointer/anchor with app-side edge clamping — on X11 nobody else will move it (contrast: a Wayland xdg_positioner lets the compositor slide/flip it). The clamp math is the finding; log it.

openMenu
(ref
(struct) app.Demo
Demo
(parameter) Demo d
d
,
(alias) object.size_t = ulong
size_t
idx, int anchorX, int anchorY,
const(char)* cause) @nogc nothrow {
(unresolved type) Menu
Menu
*
_error_ m
m
= &d.
d.menus
menus
[idx];
int
_error_ x
x
= anchorX,
_error_ y
y
= anchorY;
if (x + menuW + 2 > d.
d.screenW
screenW
)
x = d.
d.screenW
screenW
- menuW - 2;
if (y + menuH + 2 > d.
d.screenH
screenH
)
y = d.
d.screenH
screenH
- menuH - 2;
emitf("popup_open", "menu=%zu anchor=%d,%d gravity=bottom-right cause=%s", idx, anchorX, anchorY, cause); if (m.
m.win
win
== None)
m.
m.win
win
= makeOverrideRedirect(d, x, y, menuW, menuH);
else XMoveWindow(d.
d.dpy
dpy
, m.
m.win
win
, x, y);
m.
m.x
x
= x;
m.
m.y
y
= y;
m.
m.open
open
= true;
m.
m.hover
hover
= -1;
XMapRaised(d.
d.dpy
dpy
, m.
m.win
win
); // map + XRaiseWindow in one request
emitf("popup_placed", "menu=%zu rect=%dx%d+%d+%d repositioned=%d " ~ "clamp=anchor+size>screen(%dx%d)", idx, menuW, menuH, x, y, cast(int)(x != anchorX || y != anchorY), d.
d.screenW
screenW
, d.
d.screenH
screenH
);
++d.
d.opens
opens
;
if (idx == 0 && !d.
d.grabbed
grabbed
)
{ // owner_events=False: during the grab EVERY pointer event in the // whole session is reported to THIS client, relative to the grab // window — including clicks over windows we do not own. That is // the entire outside-click-dismissal mechanism. const
_error_ pg
pg
= XGrabPointer(d.
d.dpy
dpy
, m.
m.win
win
, False,
cast(uint)(ButtonPressMask | ButtonReleaseMask | PointerMotionMask), GrabModeAsync, GrabModeAsync, None, None, CurrentTime); const
_error_ kg
kg
= XGrabKeyboard(d.
d.dpy
dpy
, m.
m.win
win
, False, GrabModeAsync,
GrabModeAsync, CurrentTime); emitf("grab", "state=acquired pointer=%s keyboard=%s owner_events=0", grabCodes[pg].ptr, grabCodes[kg].ptr); d.
d.grabbed
grabbed
= pg == 0;
} logStacking(d, m.
m.win
win
, "after_map_raised");
} void
app.dismissAll
dismissAll
(ref
(struct) app.Demo
Demo
(parameter) Demo d
d
, const(char)* cause) @nogc nothrow
{ if (d.
d.grabbed
grabbed
)
{ XUngrabPointer(d.
d.dpy
dpy
, CurrentTime);
XUngrabKeyboard(d.
d.dpy
dpy
, CurrentTime);
emit("grab state=released"); d.
d.grabbed
grabbed
= false;
} foreach_reverse (ref
(parameter) m
m
; d.
d.menus
menus
)
if (m.
m.open
open
)
{ XUnmapWindow(d.
d.dpy
dpy
, m.
m.win
win
);
m.
m.open
open
= false;
} XFlush(d.
d.dpy
dpy
);
++d.
d.dismissals
dismissals
;
emitf("popup_dismiss", "cause=%s", cause); } /// Root-coordinate hit test across the popup chain (submenu first: it is on /// top). Returns menu index, item via `item`; -1 if outside everything. int
app.hitTest

Root-coordinate hit test across the popup chain (submenu first: it is on top). Returns menu index, item via item; -1 if outside everything.

hitTest
(ref
(struct) app.Demo
Demo
(parameter) Demo d
d
, int xr, int yr, out int
(parameter) int item
item
) @nogc nothrow
{ foreach_reverse (
(parameter) i
i
; 0 .. d.
d.menus
menus
.
d.menus.length
length
)
{ const
_error_ m
m
= &d.
d.menus
menus
[i];
if (m.
m.open
open
&& xr >= m.
m.x
x
&& xr < m.
m.x
x
+ menuW && yr >= m.
m.y
y
&& yr < m.
m.y
y
+ menuH)
{ item = (yr - m.
m.y
y
) / itemH;
return cast(int) i; } } item = -1; return -1; } /// The "another grab already exists" probe: the second client grabs first, /// then we try — XGrabPointer returns AlreadyGrabbed (1) instead of any /// event; the failure is a synchronous return code, not an error. void
app.probeGrabConflict

The "another grab already exists" probe: the second client grabs first, then we try — XGrabPointer returns AlreadyGrabbed (1) instead of any event; the failure is a synchronous return code, not an error.

probeGrabConflict
(ref
(struct) app.Demo
Demo
(parameter) Demo d
d
) @nogc nothrow
{ const
_error_ g2
g2
= XGrabPointer(d.
d.dpy2
dpy2
, d.
d.second
second
, False,
cast(uint) ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); XSync(d.
d.dpy2
dpy2
, False);
emitf("probe", "name=second_client_grab result=%s", grabCodes[g2].ptr); const
_error_ g1
g1
= XGrabPointer(d.
d.dpy
dpy
, d.
d.main
main
, False,
cast(uint) ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); emitf("probe", "name=our_grab_while_other_holds result=%s", grabCodes[g1].ptr); XUngrabPointer(d.
d.dpy2
dpy2
, CurrentTime);
XSync(d.
d.dpy2
dpy2
, False);
const
_error_ g3
g3
= XGrabPointer(d.
d.dpy
dpy
, d.
d.main
main
, False,
cast(uint) ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); emitf("probe", "name=our_grab_after_release result=%s", grabCodes[g3].ptr); if (g3 == 0) XUngrabPointer(d.
d.dpy
dpy
, CurrentTime);
XFlush(d.
d.dpy
dpy
);
} void
app.handleMotion
handleMotion
(ref
(struct) app.Demo
Demo
(parameter) Demo d
d
, int xr, int yr) @nogc nothrow
{ int
_error_ item
item
;
const
_error_ mi
mi
= hitTest(d, xr, yr, item);
if (mi < 0) return;
(unresolved type) Menu
Menu
*
_error_ m
m
= &d.
d.menus
menus
[mi];
if (item != m.
m.hover
hover
)
{ m.
m.hover
hover
= item;
++d.
d.hoverChanges
hoverChanges
;
emitf("hover", "menu=%d item=%d", mi, item); drawMenu(d, *m); // Item 2 of the root menu carries the submenu: open it flush with // the item's right edge; hovering items 0/1 closes it again. if (mi == 0 && item == menuItems - 1 && !d.
d.menus
menus
[1].
d.menus[1].open
open
)
openMenu(d, 1, m.
m.x
x
+ menuW - 4, m.
m.y
y
+ item * itemH, "submenu_hover");
else if (mi == 0 && item < menuItems - 1 && d.
d.menus
menus
[1].
d.menus[1].open
open
)
{ XUnmapWindow(d.
d.dpy
dpy
, d.
d.menus
menus
[1].
d.menus[1].win
win
);
d.
d.menus
menus
[1].
d.menus[1].open
open
= false;
emit("popup_dismiss cause=submenu_parent_hover menu=1"); } } } int
int D main()
main
()
{
void instrument.initInstrument(const(char)* demoName) nothrow @nogc

Names the demo, starts the monotonic clock, and emits init_start. Call this first, before any platform API call.

initInstrument
("f15_x11");
const
(local variable) const(bool) autoExit
autoExit
=
char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogc
getenv
("WSI_AUTO_EXIT") !is null;
const
(local variable) const(bool) driven
driven
=
char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogc
getenv
("WSI_DRIVEN") !is null;
(struct) app.Demo
Demo
(local variable) _error_ d
d
;
d.
d.dpy
dpy
= XOpenDisplay(null);
if (d.
(field) _error_ d.dpy
dpy
is null)
{
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogc
printf
("SKIP: no X11 display (XOpenDisplay returned null)\n");
return 0; } XSetErrorHandler(&onXError);
undefined identifier `XSetErrorHandler`
d.
d.screen
screen
= XDefaultScreen(d.
d.dpy
dpy
);
d.
d.root
root
= XRootWindow(d.
d.dpy
dpy
, d.
d.screen
screen
);
d.
d.screenW
screenW
= XDisplayWidth(d.
d.dpy
dpy
, d.
d.screen
screen
);
d.
d.screenH
screenH
= XDisplayHeight(d.
d.dpy
dpy
, d.
d.screen
screen
);
d.
d.gc
gc
= XDefaultGC(d.
d.dpy
dpy
, d.
d.screen
screen
);
void instrument.emitf(scope const(char)* kind, scope const(char)* fmt, ...) nothrow @nogc

Emit an event with a printf-formatted key=value ... payload.

emitf
("step", "name=XOpenDisplay fd=%d screen=%dx%d",
XConnectionNumber(d.
d.dpy
dpy
), d.
(field) _error_ d.screenW
screenW
, d.
(field) _error_ d.screenH
screenH
);
undefined identifier `XConnectionNumber`
d.
d.main
main
= XCreateSimpleWindow(d.
d.dpy
dpy
, d.
d.root
root
, 20, 20, 480, 320, 1,
XBlackPixel(d.
d.dpy
dpy
, d.
d.screen
screen
), 0x4070b0);
XStoreName(d.
d.dpy
dpy
, d.
d.main
main
, "Sparkles \xc2\xb7 X11 F15 popup");
undefined identifier `XStoreName`
d.
d.wmProtocols
wmProtocols
= XInternAtom(d.
d.dpy
dpy
, "WM_PROTOCOLS", False);
d.
d.wmDelete
wmDelete
= XInternAtom(d.
d.dpy
dpy
, "WM_DELETE_WINDOW", False);
XSetWMProtocols(d.
d.dpy
dpy
, d.
d.main
main
, &d.
d.wmDelete
wmDelete
, 1);
undefined identifier `XSetWMProtocols`
// ButtonReleaseMask matters: the release of the popup-opening click can // reach the server BEFORE the XGrabPointer issued in response to the // press — it is then delivered by the normal masks, not the grab. XSelectInput(d.
d.dpy
dpy
, d.
d.main
main
, ExposureMask | KeyPressMask | ButtonPressMask
undefined identifier `XSelectInput`
| ButtonReleaseMask | StructureNotifyMask); XMapWindow(d.
d.dpy
dpy
, d.
d.main
main
);
undefined identifier `XMapWindow`
void instrument.emitf(scope const(char)* kind, scope const(char)* fmt, ...) nothrow @nogc

Emit an event with a printf-formatted key=value ... payload.

emitf
("window_created", "xid=0x%lx size=480x320+20+20", d.
(field) _error_ d.main
main
);
// The independent second client: its own connection, its own window. It // exists to measure what a grab does to everyone else (run.sh clicks it // while the popup grab is held: it must receive nothing). d.
d.dpy2
dpy2
= XOpenDisplay(null);
d.
d.second
second
= XCreateSimpleWindow(d.
d.dpy2
dpy2
, XRootWindow(d.
d.dpy2
dpy2
, 0), 520, 20,
100, 100, 1, 0, 0xb0b040); XStoreName(d.
d.dpy2
dpy2
, d.
d.second
second
, "Sparkles \xc2\xb7 F15 second client");
undefined identifier `XStoreName`
XSelectInput(d.
d.dpy2
dpy2
, d.
d.second
second
, ButtonPressMask | ExposureMask);
undefined identifier `XSelectInput`
XMapWindow(d.
d.dpy2
dpy2
, d.
d.second
second
);
undefined identifier `XMapWindow`
XFlush(d.
d.dpy2
dpy2
);
undefined identifier `XFlush`
void instrument.emitf(scope const(char)* kind, scope const(char)* fmt, ...) nothrow @nogc

Emit an event with a printf-formatted key=value ... payload.

emitf
("second_client", "fd=%d xid=0x%lx size=100x100+520+20",
XConnectionNumber(d.
d.dpy2
dpy2
), d.
(field) _error_ d.second
second
);
undefined identifier `XConnectionNumber`
// Self-driven probe schedule (µs since init), driven mode skips it: enum
(enum) app.main.Act
Act
{
(enum value) app.main.Act.open = 0
open
,
(enum value) app.main.Act.openSub = 1
openSub
,
(enum value) app.main.Act.dismiss = 2
dismiss
,
(enum value) app.main.Act.edgeOpen = 3
edgeOpen
,
(enum value) app.main.Act.grabConflict = 4
grabConflict
,
(enum value) app.main.Act.quit = 5
quit
}
static immutable struct
(struct) app.main.Step
Step
{ long
(field) immutable(long) app.main.Step.t
t
;
(enum) app.main.Act
Act
(field) immutable(app.main.Act) app.main.Step.a
a
; }
static immutable
(struct) app.main.Step
Step
[8]
(immutable global) immutable(app.main.Step[8]) app.main.schedule
schedule
= [
{400_000,
(enum) app.main.Act
Act
.
(enum value) app.main.Act.open = 0
open
}, {700_000,
(enum) app.main.Act
Act
.
(enum value) app.main.Act.openSub = 1
openSub
}, {1_000_000,
(enum) app.main.Act
Act
.
(enum value) app.main.Act.dismiss = 2
dismiss
},
{1_300_000,
(enum) app.main.Act
Act
.
(enum value) app.main.Act.edgeOpen = 3
edgeOpen
}, {1_700_000,
(enum) app.main.Act
Act
.
(enum value) app.main.Act.dismiss = 2
dismiss
},
{2_000_000,
(enum) app.main.Act
Act
.
(enum value) app.main.Act.grabConflict = 4
grabConflict
}, {2_400_000,
(enum) app.main.Act
Act
.
(enum value) app.main.Act.quit = 5
quit
}, {0,
(enum) app.main.Act
Act
.
(enum value) app.main.Act.quit = 5
quit
},
];
(alias) object.size_t = ulong
size_t
(local variable) ulong nextStep
nextStep
;
const
(local variable) const(int) deadline
deadline
=
(local variable) const(bool) driven
driven
? 14_000_000 : 4_000_000;
const
(local variable) const(_error_) fd
fd
= XConnectionNumber(d.
d.dpy
dpy
);
undefined identifier `XConnectionNumber`
const
(local variable) const(_error_) fd2
fd2
= XConnectionNumber(d.
d.dpy2
dpy2
);
undefined identifier `XConnectionNumber`
while (d.
(field) _error_ d.running
running
)
{ while (XPending(d.
d.dpy
dpy
) > 0)
undefined identifier `XPending`
{ XEvent
(local variable) _error_ ev
ev
;
undefined identifier `XEvent`
XNextEvent(d.
d.dpy
dpy
, &ev);
undefined identifier `XNextEvent`
switch (ev.type) { case ButtonPress: d.
d.swallowRelease
swallowRelease
= false; // the swallow applies only to the
// release that immediately follows the opening press emitf("button", "state=press n=%d window=0x%lx pos=%d,%d root=%d,%d " ~ "grabbed=%d", ev.xbutton.button, ev.xbutton.window, ev.xbutton.
ev.xbutton.x
x
, ev.xbutton.
ev.xbutton.y
y
, ev.xbutton.x_root,
ev.xbutton.y_root, cast(int) d.
d.grabbed
grabbed
);
if (d.
d.grabbed
grabbed
)
{ int
_error_ item
item
;
if (hitTest(d, ev.xbutton.x_root, ev.xbutton.y_root, item) < 0) dismissAll(d, "outside_click"); } else if (ev.xbutton.window == d.
d.main
main
&& ev.xbutton.button == 3)
{ openMenu(d, 0, ev.xbutton.x_root, ev.xbutton.y_root, "right_click"); // The release of the click that OPENED the menu would // otherwise instantly activate the item now under the // pointer — every menu toolkit swallows it. d.
d.swallowRelease
swallowRelease
= true;
} break; case ButtonRelease: if (d.
d.swallowRelease
swallowRelease
)
{ d.
d.swallowRelease
swallowRelease
= false;
emit("button state=release swallowed=open_click"); } else if (d.
d.grabbed
grabbed
)
{ int
_error_ item
item
;
const
_error_ mi
mi
= hitTest(d, ev.xbutton.x_root, ev.xbutton.y_root, item);
if (mi >= 0) { ++d.
d.activations
activations
;
emitf("popup_item_activated", "menu=%d item=%d", mi, item); dismissAll(d, "item_activated"); } } break; case MotionNotify: if (d.
d.grabbed
grabbed
)
handleMotion(d, ev.xmotion.x_root, ev.xmotion.y_root); break; case KeyPress: const
_error_ sym
sym
= XLookupKeysym(&ev.xkey, 0);
emitf("key", "sym=0x%lx via_grab=%d", sym, cast(int) d.
d.grabbed
grabbed
);
if (sym == XK_Escape && d.
d.grabbed
grabbed
)
dismissAll(d, "esc"); else if (sym == 'q' && !d.
d.grabbed
grabbed
)
d.
d.running
running
= false;
break; case FocusIn: case FocusOut: // Popups never receive WM focus — keyboard arrives only via // the grab. Any focus event reaching a popup is the server's // grab bookkeeping; the mode says so. foreach (ref
(parameter) m
m
; d.
d.menus
menus
)
if (ev.xany.window == m.
m.win
win
)
{ ++d.
d.popupFocusEvents
popupFocusEvents
;
emitf("focus", "window=0x%lx state=%s mode=%s", ev.xany.window, ev.type == FocusIn ? "in".ptr : "out".ptr, focusModes[ev.xfocus.mode].ptr); } break; case Expose: if (ev.xexpose.count != 0) break; foreach (ref
(parameter) m
m
; d.
d.menus
menus
)
if (ev.xexpose.window == m.
m.win
win
)
drawMenu(d, m); break; case ClientMessage: if (cast(Atom) ev.xclient.data.l[0] == d.
d.wmDelete
wmDelete
)
d.
d.running
running
= false;
break; default: break; } } // Drain the second client's queue — its silence during the grab is // the starvation measurement. while (XPending(d.
d.dpy2
dpy2
) > 0)
undefined identifier `XPending`
{ XEvent
(local variable) _error_ ev2
ev2
;
undefined identifier `XEvent`
XNextEvent(d.
d.dpy2
dpy2
, &ev2);
undefined identifier `XNextEvent`
if (ev2.type ==
(enum value) app.ButtonPress = 4
ButtonPress
)
{ ++d.
(field) _error_ d.secondClientEvents
secondClientEvents
;
void instrument.emitf(scope const(char)* kind, scope const(char)* fmt, ...) nothrow @nogc

Emit an event with a printf-formatted key=value ... payload.

emitf
("second_client", "event=button_press pos=%d,%d during_grab=%d",
ev2.xbutton.
(field) _error_ ev2.xbutton.x
x
, ev2.xbutton.
(field) _error_ ev2.xbutton.y
y
, cast(int) d.
(field) _error_ d.grabbed
grabbed
);
} } if (
(local variable) const(bool) autoExit
autoExit
&& !
(local variable) const(bool) driven
driven
&&
(local variable) ulong nextStep
nextStep
<
(immutable global) immutable(app.main.Step[8]) app.main.schedule
schedule
.
(constant) ulong immutable(app.main.Step[8]).length = 8LU
length
&&
long instrument.nowUs() nothrow @nogc

Microseconds elapsed since initInstrument.

nowUs
() >=
(immutable global) immutable(app.main.Step[8]) app.main.schedule
schedule
[
(local variable) ulong nextStep
nextStep
].
(field) immutable(long) app.main.Step.t
t
)
{ final switch (
(immutable global) immutable(app.main.Step[8]) app.main.schedule
schedule
[
(local variable) ulong nextStep
nextStep
].
(field) immutable(app.main.Act) app.main.Step.a
a
)
{ case
(enum) app.main.Act
Act
.
(enum value) app.main.Act.open = 0
open
:
openMenu(d, 0, 200, 200, "auto"); break; case
(enum) app.main.Act
Act
.
(enum value) app.main.Act.openSub = 1
openSub
:
d.
(field) _error_ d.menus
menus
[0].
(__error)[0].hover
hover
= menuItems - 1;
drawMenu(d, d.
d.menus
menus
[0]);
openMenu(d, 1, d.
d.menus
menus
[0].
d.menus[0].x
x
+ menuW - 4,
d.
d.menus
menus
[0].
d.menus[0].y
y
+ (menuItems - 1) * itemH, "auto");
break; case
(enum) app.main.Act
Act
.
(enum value) app.main.Act.dismiss = 2
dismiss
:
dismissAll(d, "auto"); break; case
(enum) app.main.Act
Act
.
(enum value) app.main.Act.edgeOpen = 3
edgeOpen
:
openMenu(d, 0, d.
d.screenW
screenW
- 10, d.
d.screenH
screenH
- 10, "auto_edge");
break; case
(enum) app.main.Act
Act
.
(enum value) app.main.Act.grabConflict = 4
grabConflict
:
probeGrabConflict(d); break; case
(enum) app.main.Act
Act
.
(enum value) app.main.Act.quit = 5
quit
:
d.
d.running
running
= false;
break; } ++
(local variable) ulong nextStep
nextStep
;
if (
(local variable) ulong nextStep
nextStep
==
(immutable global) immutable(app.main.Step[8]) app.main.schedule
schedule
.
(constant) ulong immutable(app.main.Step[8]).length = 8LU
length
- 1)
break; // sentinel reached } if ((
(local variable) const(bool) autoExit
autoExit
||
(local variable) const(bool) driven
driven
) &&
long instrument.nowUs() nothrow @nogc

Microseconds elapsed since initInstrument.

nowUs
() >
(local variable) const(int) deadline
deadline
)
{
void instrument.emit(scope const(char)* kind) nothrow @nogc

Emit an event with no key=value payload.

emit
("auto_exit reason=deadline");
break; } pollfd[2]
(local variable) _error_ pfd
pfd
;
undefined identifier `pollfd`
pfd[0].
(__error)[0].fd
fd
= fd;
pfd[0].events = POLLIN; pfd[1].
(__error)[1].fd
fd
= fd2;
pfd[1].events = POLLIN; poll(pfd.ptr, 2, (autoExit || driven) ? 20 : -1);
undefined identifier `poll`
}
void instrument.emitf(scope const(char)* kind, scope const(char)* fmt, ...) nothrow @nogc

Emit an event with a printf-formatted key=value ... payload.

emitf
("summary", "opens=%d dismissals=%d activations=%d hover_changes=%d "
~ "second_client_events=%d popup_focus_events=%d x_errors=%d", d.
(field) _error_ d.opens
opens
, d.
(field) _error_ d.dismissals
dismissals
, d.
(field) _error_ d.activations
activations
, d.
(field) _error_ d.hoverChanges
hoverChanges
,
d.
(field) _error_ d.secondClientEvents
secondClientEvents
, d.
(field) _error_ d.popupFocusEvents
popupFocusEvents
,
(__gshared global) int app.g_xerrors
g_xerrors
);
XCloseDisplay(d.
d.dpy2
dpy2
);
undefined identifier `XCloseDisplay`
XCloseDisplay(d.
d.dpy
dpy
);
undefined identifier `XCloseDisplay`
return 0; }