Skip to content

Merge RawWindowHandle and WindowHandle<'_>? #178

Description

@madsmtm

I don't recall the reasoning for keeping RawWindowHandle around, is there ever a case where it's useful? And wouldn't WindowHandle<'static> be able to serve that same purpose?

I propose we change our API to merge these, so that it's instead something like:

#[non_exhaustive]
enum WindowHandle<'window> {
    AppKit(AppKitWindowHandle<'window>),
    UIKit(UIKitWindowHandle<'window>),
    AndroidNDK(AndroidNDKWindowHandle<'window>),
    // ... etc.
}

This means that instead of a three-step process for making safe handles (create raw platform handle + wrap in RawWindowHandle + call WindowHandle::borrow_raw), it's now only two steps (create raw platform handle with lifetime + wrap it in WindowHandle).

One reason to not do this would be to mirror the std::os::fd API (RawFd vs BorrowedFd<'_>), but we already can't do that, because we can't provide a mirror of OwnedFd.

Activity

  1. madsmtm commented on Feb 6, 2026

    @madsmtm
    MemberAuthor

    I guess another downside is that we'd no longer be able to make fields public (at least not before RFC 3458 is stable and in our MSRV), because then users might assign a NonNull::dangling() into one of the fields.

  2. madsmtm commented on Feb 6, 2026

    @madsmtm
    MemberAuthor

    Another option to simplify things would perhaps be to get rid of the platform-specific wrappers? Something like:

    #[non_exhaustive]
    enum RawWindowHandle {
        #[non_exhaustive]
        AppKit {
            ns_view: NonNull<c_void>,
        },
        #[non_exhaustive]
        UIKit {
            ui_view: NonNull<c_void>,
        },
        #[non_exhaustive]
        AndroidNDK {
            a_native_window: NonNull<c_void>,
        },
        // ... etc.
    }
    
    impl RawWindowHandle {
        pub fn new_appkit(ns_view: NonNull<c_void>) -> Self {
            Self::AppKit { ns_view }
        }
    
        pub fn new_uikit(ui_view: NonNull<c_void>) -> Self { ... }
    
        // ... etc.
    }
    
    // Keep this
    impl WindowHandle<'_> {
        fn borrow_raw(...)
    }

    This has the downside that fields have to be public, because enums have no visibility rules. But if our fields are public anyhow, we might as well IMO.

  3. notgull commented on Feb 6, 2026

    @notgull
    Contributor

    I'm fine with getting rid of raw window handles entirely, assuming we can't come up with a better use case. As an added bonus, it lets us have more granular safety rules for each window handle. For example, we can make it safe to construct an XCB window handle, but not a Win32 window handle.

    One argument for raw handles is it lets us have a raw pointer equivalent for window handles.

  4. notgull commented on Mar 14, 2026

    @notgull
    Contributor

    Two points from today's meeting:

    • It's good to have a RawWindowHandle that represents plain old data, compared to a BorrowedWindowHandle<'static> that represents a valid live window handle.
    • We should move forwards with getting rid of the subtypes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions