kovidgoyal/kitty · error

Failed to load glfwGetX11Display

Error message

Failed to load glfwGetX11Display

What it means

kitty's x11_display() Python binding tried to use glfwGetX11Display but the function pointer is NULL — meaning GLFW was not built with X11 support or the current session is not X11 (e.g. running under Wayland). The function pointer is resolved at load time; NULL means the X11 code path is unavailable, so Py_None is returned instead of the Display pointer.

Source

Thrown at kitty/glfw.c:2996

        PyTuple_SET_ITEM(result, i, x);
    }
    return Py_NewRef(result);
}


static PyObject *
primary_monitor_content_scale(PYNOARG) {
    GLFWmonitor *monitor = glfwGetPrimaryMonitor();
    float xscale = 1.0, yscale = 1.0;
    if (monitor) glfwGetMonitorContentScale(monitor, &xscale, &yscale);
    return Py_BuildValue("ff", xscale, yscale);
}

static PyObject *
x11_display(PYNOARG) {
    if (glfwGetX11Display) {
        return PyLong_FromVoidPtr(glfwGetX11Display());
    } else log_error("Failed to load glfwGetX11Display");
    Py_RETURN_NONE;
}

static PyObject *
wayland_compositor_data(PYNOARG) {
    pid_t pid = -1;
    const char *missing_capabilities = NULL;
    if (global_state.is_wayland && glfwWaylandCompositorPID) {
        pid = glfwWaylandCompositorPID();
        missing_capabilities = glfwWaylandMissingCapabilities();
    }
    return Py_BuildValue("Ls", (long long)pid, missing_capabilities);
}

static PyObject *
x11_window_id(PyObject UNUSED *self, PyObject *os_wid) {
    OSWindow *w = os_window_for_id(PyLong_AsUnsignedLongLong(os_wid));
    if (!w) {

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Verify the session type: echo $XDG_SESSION_TYPE — if wayland, use Wayland equivalents (wayland_compositor_data) instead of x11_display()
  2. If X11 is required, run kitty under XWayland/X11: env GLFW_PLATFORM=x11 kitty or launch from an X11 session
  3. Rebuild kitty/glfw with X11 support if it was disabled at compile time

Example fix

# before
import kitty.fast_data_types as fdt
display = fdt.x11_display()
# after
import os
if os.environ.get('XDG_SESSION_TYPE') == 'x11':
    display = fdt.x11_display()
else:
    display = None  # use wayland APIs instead
Defensive patterns

Strategy: type-guard

Validate before calling

import os

def get_x11_display():
    if os.environ.get('XDG_SESSION_TYPE') != 'x11':
        return None
    import kitty.fast_data_types as fdt
    return fdt.x11_display()  # may still be None if built without X11

Type guard

def has_x11() -> bool:
    return os.environ.get('XDG_SESSION_TYPE') == 'x11' and os.environ.get('DISPLAY') is not None

Prevention

When it happens

Trigger: Calling kitty's x11_display() Python/C API (used by window management helpers like gl_x11_window / x11 display queries) while running under Wayland, or with a GLFW build compiled without X11 backends.

Common situations: Running kitty on Wayland ($XDG_SESSION_TYPE=wayland) and scripts/kittens that assume X11; custom kitty builds with GLFW X11 support disabled; SSH into a headless box.

Related errors


AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27). Data as JSON: /api/errors/531ae4d0fa208d63. Report an issue: GitHub.