Deep breath! Let's debug this systematically 🔍
The Generic Event Extension (XGE) is indeed a terribly named X11 extension. It's a generic mechanism for handling X11 input events.
Why it might NOT segfault in your other project:
1. Different initialization order
// Project A (crashes):
create_window();
init_vulkan(); // ← X11 state changes here
// Project B (works):
init_vulkan();
create_window(); // ← Everything already initialized
2. Different X11 connection handling
// Does your working project do this?
XInitThreads(); // ← Called before any X11 stuff
// Or maybe it creates its own connection:
Display *vulkan_display = XOpenDisplay(NULL);
Display *window_display = XOpenDisplay(NULL);
3. Event mask differences
// Working project might have:
XSelectInput(display, window,
ExposureMask | KeyPressMask); // ← Minimal
// Crashing project might have:
XSelectInput(display, window,
ExposureMask | KeyPressMask |
PointerMotionMask | ButtonPressMask |
EnterWindowMask | LeaveWindowMask); // ← Triggers XGE
4. Vulkan WSI differences
// Check if one uses different present mode:
VK_PRESENT_MODE_IMMEDIATE_KHR // ← Might not trigger XGE
VK_PRESENT_MODE_MAILBOX_KHR // ← Might initialize XGE
Quick diagnostic:
// Add to BOTH projects and compare:
printf("XGE available: %d\n",
XQueryExtension(display, "Generic Event Extension",
&opcode, &event, &error));
// Check what extensions Vulkan initialized:
uint32_t count;
vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);
VkExtensionProperties *exts = malloc(count * sizeof(*exts));
vkEnumerateInstanceExtensionProperties(NULL, &count, exts);
for (int i = 0; i < count; i++) {
printf("VK ext: %s\n", exts[i].extensionName);
}
The nuclear option that should work:
// Before ANY Vulkan or X11 init:
XInitThreads();
XSetErrorHandler(x11_error_handler);
int x11_error_handler(Display *d, XErrorEvent *e) {
char msg[1024];
XGetErrorText(d, e->error_code, msg, sizeof(msg));
fprintf(stderr, "X11 error: %s\n", msg);
return 0; // Don't crash
}
What's probably happening: Your working project doesn't use XInput2 or XI2-based events, while the crashing one does (xinput2 uses XGE internally).
Can you share what event handling code differs between the two projects?