Skip to content

Conversation

@redstrate
Copy link
Contributor

@redstrate redstrate commented Dec 5, 2025

We had the raw_window_handle_06 feature and functions in Rust, but there wasn't an easy way to do the same in C++. This is especially useful for embedding windows (such as browsers, 3D views, etc.) or just wanting to access the platform's handles for other reasons.

Similar to Rust, you need to enable a specific non-default feature for this API. I re-used the existing NativeWindowHandle struct for this, moving it out of slint-platform.h and adding getters to it.

Examples

void print_native_handles(slint::Window& window)
{
	auto native_handle = window.native_window_handle();

	// Wayland
	std::cout << "- wl_display = " << native_handle.wayland_display() << std::endl;
	std::cout << "- wl_surface = " << native_handle.wayland_surface() << std::endl;

	// Win32
	std::cout << "- hwnd = " << native_handle.win32_hwnd() << std::endl;
	std::cout << "- hinstance = " << native_handle.win32_instance() << std::endl;
}

TODO

  • See if there's an existing issue (currently I only came across C++ Raw Window Handle #6248)
  • Double-check if this is an API break, I don't think so since slint-window.h/slint-platform.h should be interchangeable.
  • Test on macOS/Windows
  • Add/expand the documentation
  • Do we need a way to check the underlying window handle type? But this can probably be answered later.
  • Outside of this PR, some improvements that can be upstreamed now: Maybe moving NativeWindowHandle, disabling Win32 properly on Linux

Notes

I intentionally only added getters for Wayland/Appkit/Win32 since that's the only platforms that currently matter to me. Since we didn't have a C++ API at all before that's still a net positive, and this can be easily extended later.

It should be safe to call this even if the window isn't initialized, or on the wrong platform.

@redstrate redstrate force-pushed the work/josh/raw-window-handle-api branch from 862992e to 0f5b956 Compare December 5, 2025 13:57
We had the raw_window_handle_06 feature and functions in Rust, but there
wasn't an easy way to do the same in C++. This is especially useful for
embedding windows (such as browsers, 3D views, etc.) or just wanting to
access the platform's handles for other reasons.

Similar to Rust, you need to enable a specific non-default feature for
this API. I re-used the existing NativeWindowHandle struct for this,
moving it out of slint-platform.h and adding getters to it.\
@redstrate redstrate force-pushed the work/josh/raw-window-handle-api branch from d542c70 to 53f2142 Compare December 5, 2025 14:12
Copy link
Member

@ogoffart ogoffart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the contribution. I think it indeed make sense to expose that, and it could be exposed to C++ without a feature.

define_cargo_dependent_feature(testing "Enable support for testing API (experimental)" ON "NOT SLINT_FEATURE_FREESTANDING")
define_cargo_feature(experimental "Enable experimental features. (No backward compatibility guarantees)" OFF)
define_cargo_dependent_feature(system-testing "Enable system testing support (experimental)" OFF "SLINT_FEATURE_EXPERIMENTAL AND NOT SLINT_FEATURE_FREESTANDING")
define_cargo_feature(raw-window-handle-06 "Enable integration with raw-window-handle." OFF)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason it is a feature in Rust is because it is dependent of a specific Rust crate (raw-window-handle) and a specific version (0.6) and that in the future, Rust users may opt for a newer version of raw-window-handle and so wouldn't enable this feature anymore.

In C++ we don't have this as we'd have to re-expose the API anyway, so IMHO it shouldn't need to be a feature and it can be enabled by default

}

/// Returns the NSView from this NativeWindowHandle.
NSView *appkit_view() const
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we also need a getter for the NSWindow?

}
}

#[cfg(feature = "raw-window-handle-06")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(maybe put things in a module to avoid repeating this too often?)

}

#[cfg(feature = "raw-window-handle-06")]
unsafe impl std::marker::Send for RawHandlePair {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could get safety comment. There was a comment before

}
}

NativeWindowHandle native_window_handle() const
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, looking again at my comment in #6248 (comment) , I wonder if we really need this NativeWindowHandle indirection and can just have things like win32_handle() directly on the Window.

@tronical: opinions?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're right. That would make for a simpler API. Just one function per platform (two for linux).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants