slint-ui/slint · error

C++: NativeWindowHandle created with null hwnd

Error message

C++: NativeWindowHandle created with null hwnd

What it means

The C++ API's slint_new_raw_window_handle_win32 converts a raw HWND pointer into a raw-window-handle Win32WindowHandle, whose NonNull HWND field is constructed via isize::try_into().expect(...). A null HWND (0) cannot be converted to NonNull, so the library panics with this message rather than producing an invalid window handle. It is a hard invariant: a window handle wrapper is meaningless without a valid window.

Solutions

  1. Check the HWND is non-null before calling the Slint API that wraps it.
  2. Fix the window-creation path so a valid HWND exists before registering it (verify CreateWindowEx returned non-null).
  3. Reorder initialization: create the native window first, then construct Slint's NativeWindowHandle.
  4. If the window was destroyed, recreate it and re-create the handle instead of reusing a stale pointer.

Example fix

// before (C++)
HWND hwnd = nullptr; // not yet created
auto handle = slint::NativeWindowHandle::from_win32(hwnd, hinstance);
// after
HWND hwnd = create_native_window();
if (!hwnd) throw std::runtime_error("window creation failed");
auto handle = slint::NativeWindowHandle::from_win32(hwnd, hinstance);
Defensive patterns

Strategy: validation

Validate before calling

// C++ caller, before constructing the handle
if (hwnd == nullptr) {
    throw std::invalid_argument("cannot create NativeWindowHandle: null HWND");
}

Type guard

// C++ helper
bool is_valid_hwnd(HWND hwnd) { return hwnd != nullptr && IsWindow(hwnd) == TRUE; }

Prevention

When it happens

Trigger: Calling slint_native_window_handle_from_raw / the C++ NativeWindowHandle constructor with an uninitialized or already-destroyed Win32 window's HWND (nullptr), or default-constructed zero handle passed from C++ code.

Common situations: Passing a window handle captured before CreateWindow completed, using an HWND after the window was destroyed, or wiring up Win32 interop where the platform layer returned nullptr (e.g. failed window creation).

Related errors


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

Appendix: source

Thrown at api/cpp/platform.rs:794

    struct CppRawHandle(Arc<RawHandlePair>);

    impl From<(RawWindowHandle, RawDisplayHandle)> for CppRawHandle {
        fn from(pair: (RawWindowHandle, RawDisplayHandle)) -> Self {
            Self(Arc::new(RawHandlePair(pair)))
        }
    }

    type CppRawHandleOpaque = *const c_void;

    #[unsafe(no_mangle)]
    pub unsafe extern "C" fn slint_new_raw_window_handle_win32(
        hwnd: *mut c_void,
        _hinstance: *mut c_void,
    ) -> CppRawHandleOpaque {
        let handle = CppRawHandle::from((
            RawWindowHandle::Win32(raw_window_handle::Win32WindowHandle::new(
                (hwnd as isize).try_into().expect("C++: NativeWindowHandle created with null hwnd"),
            )),
            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

View on GitHub (pinned to bb937076de)