C++: Expose raw window handle API

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.

ChangeLog: It's now possible to access platform native window handles
from C++, like a HWND.
This commit is contained in:
Joshua Goins 2025-12-05 08:46:26 -05:00 committed by Olivier Goffart
parent d6f494bd6e
commit f015cbe3ee
4 changed files with 223 additions and 0 deletions

View file

@ -51,6 +51,8 @@ std = [
"i-slint-core/image-default-formats",
"i-slint-backend-selector",
"i-slint-renderer-software?/std",
"i-slint-core/raw-window-handle-06",
"i-slint-backend-selector/raw-window-handle-06",
]
freestanding = ["i-slint-core/libm", "i-slint-core/unsafe-single-threaded"]
experimental = ["i-slint-renderer-software?/experimental"]

View file

@ -579,6 +579,11 @@ fn gen_corelib(
"slint_windowrc_is_minimized",
"slint_windowrc_is_maximized",
"slint_windowrc_take_snapshot",
"slint_windowrc_hwnd_win32",
"slint_windowrc_hinstance_win32",
"slint_windowrc_wlsurface_wayland",
"slint_windowrc_wldisplay_wayland",
"slint_windowrc_nsview_appkit",
"GradientStop",
"ConicGradientBrush",
"slint_conic_gradient_normalize_stops",

View file

@ -5,6 +5,37 @@
#include "slint_internal.h"
#if (!defined(__APPLE__) && !defined(_WIN32) && !defined(_WIN64) \
&& !defined(SLINT_FEATURE_FREESTANDING)) \
|| defined(DOXYGEN)
struct wl_surface;
struct wl_display;
#endif
#if (defined(__APPLE__) && !defined(_WIN32) && !defined(_WIN64) \
&& !defined(SLINT_FEATURE_FREESTANDING)) \
|| defined(DOXYGEN)
# ifdef __OBJC__
@class NSView;
# else
typedef struct objc_object NSView;
# endif
#endif
#if (!defined(__APPLE__) && (defined(_WIN32) || defined(_WIN64)) \
&& !defined(SLINT_FEATURE_FREESTANDING)) \
|| defined(DOXYGEN)
class HINSTANCE__;
typedef HINSTANCE__ *HINSTANCE;
class HWND__;
typedef HWND__ *HWND;
#endif
namespace slint {
#if !defined(DOXYGEN)
namespace platform {
@ -637,6 +668,71 @@ public:
}
}
#if (!defined(__APPLE__) && !defined(_WIN32) && !defined(_WIN64) \
&& !defined(SLINT_FEATURE_FREESTANDING)) \
|| defined(DOXYGEN)
/// Returns the wl_surface for this window.
///
/// If the underlying window handle hasn't been created yet or isn't applicable for the
/// platform, this will return nullptr.
wl_surface *wayland_surface() const
{
return static_cast<wl_surface *>(
cbindgen_private::slint_windowrc_wlsurface_wayland(&inner.handle()));
}
/// Returns the wl_display for this window.
///
/// If the underlying window handle hasn't been created yet or isn't applicable for the
/// platform, this will return nullptr.
wl_display *wayland_display() const
{
return static_cast<wl_display *>(
cbindgen_private::slint_windowrc_wldisplay_wayland(&inner.handle()));
}
#endif
#if (defined(__APPLE__) && !defined(_WIN32) && !defined(_WIN64) \
&& !defined(SLINT_FEATURE_FREESTANDING)) \
|| defined(DOXYGEN)
/// Returns the NSView for this window.
///
/// If the underlying window handle hasn't been created yet or isn't applicable for the
/// platform, this will return nullptr.
NSView *appkit_view() const
{
return static_cast<NSView *>(
cbindgen_private::slint_windowrc_nsview_appkit(&inner.handle()));
}
#endif
#if (!defined(__APPLE__) && (defined(_WIN32) || defined(_WIN64)) \
&& !defined(SLINT_FEATURE_FREESTANDING)) \
|| defined(DOXYGEN)
/// Returns the HINSTANCE for this window.
///
/// If the underlying window handle hasn't been created yet or isn't applicable for the
/// platform, this will return nullptr.
HWND win32_hwnd() const
{
return static_cast<HWND>(cbindgen_private::slint_windowrc_hwnd_win32(&inner.handle()));
}
/// Returns the HINSTANCE for this window.
///
/// If the underlying window handle hasn't been created yet or isn't applicable for the
/// platform, this will return nullptr.
HINSTANCE win32_hinstance() const
{
return static_cast<HINSTANCE>(
cbindgen_private::slint_windowrc_hinstance_win32(&inner.handle()));
}
#endif
/// \private
private_api::WindowAdapterRc &window_handle() { return inner; }
/// \private