slint-ui/slint · error

C++: NativeWindowHandle created with null xcb window handle

Error message

C++: NativeWindowHandle created with null xcb window handle

What it means

When wrapping an XCB window for the C++ API, the u32 window id is converted into raw-window-handle's XcbWindowHandle whose NonNull window field rejects 0 via try_into().expect(...). A zero window id is not a valid X window, so the library panics with this message. It enforces the invariant that a handle references a real X server window.

Solutions

  1. Verify the window id is non-zero before constructing the handle.
  2. Check xcb_create_window's xcb_generic_error_t result to ensure the window was actually created.
  3. Reorder code so the X window is created and flushed before Slint's NativeWindowHandle is built.
  4. Re-query the valid window id from your windowing layer instead of reusing a stale one.

Example fix

// before (C++)
uint32_t window = 0;
auto handle = slint::NativeWindowHandle::from_xcb(connection, window, visual_id);
// after
if (window == 0) throw std::runtime_error("no xcb window created yet");
auto handle = slint::NativeWindowHandle::from_xcb(connection, window, visual_id);
Defensive patterns

Strategy: validation

Validate before calling

// C++ caller, before constructing the handle
if (window == 0) {
    throw std::invalid_argument("cannot create NativeWindowHandle: null xcb window id");
}
// also check xcb errors after window creation
if (xcb_connection_has_error(connection)) { /* reconnect */ }

Type guard

// C++ helper
bool is_valid_xcb_window(xcb_connection_t *c, uint32_t w) {
    return w != 0 && xcb_connection_has_error(c) == 0;
}

Prevention

When it happens

Trigger: Passing window=0 (uninitialized or disconnected xcb_connection state) to slint_new_raw_window_handle_xcb from C++, e.g. before xcb_create_window completed or after the window was destroyed.

Common situations: X11 apps that call the Slint interop before their xcb window exists, stale window ids after window teardown, or errors from xcb_create_window ignored so the id remains 0.

Related errors


AI-assisted analysis of slint-ui/slint@bb937076de (2026-09-16). Data as JSON: /api/errors/c44009771938f226. Report an issue: GitHub.

Appendix: source

Thrown at api/cpp/platform.rs:814

            RawDisplayHandle::Windows(raw_window_handle::WindowsDisplayHandle::new()),
        ));
        Box::into_raw(Box::new(handle)) as CppRawHandleOpaque
    }

    #[unsafe(no_mangle)]
    pub unsafe extern "C" fn slint_new_raw_window_handle_x11_xcb(
        window: u32,
        visual_id: u32,
        connection: *mut c_void,
        screen: core::ffi::c_int,
    ) -> CppRawHandleOpaque {
        use raw_window_handle::{XcbDisplayHandle, XcbWindowHandle};
        let handle = CppRawHandle::from((
            RawWindowHandle::Xcb({
                let mut hnd = XcbWindowHandle::new(
                    window
                        .try_into()
                        .expect("C++: NativeWindowHandle created with null xcb window handle"),
                );
                hnd.visual_id = visual_id.try_into().ok();
                hnd
            }),
            RawDisplayHandle::Xcb(XcbDisplayHandle::new(
                core::ptr::NonNull::new(connection),
                screen,
            )),
        ));
        Box::into_raw(Box::new(handle)) as CppRawHandleOpaque
    }

    #[unsafe(no_mangle)]
    pub unsafe extern "C" fn slint_new_raw_window_handle_x11_xlib(
        window: core::ffi::c_ulong,
        visual_id: core::ffi::c_ulong,
        display: *mut c_void,
        screen: core::ffi::c_int,

View on GitHub (pinned to bb937076de)