#[cfg(all(feature = "webview-system", not(hydrolysis_macos_system_webview)))]
compile_error!(
"the `webview-system` feature selects the macOS WKWebView bridge, which needs \
`target_os = \"macos\"` and the `winit` feature (WKWebView is composed into the \
winit window's AppKit view). Enable `winit`, build for macOS, or link a browser \
engine crate (`waterui-browser-cef`, `waterui-browser-wpe`) in the application \
instead."
);
use std::cell::RefCell;
use std::rc::Rc;
use waterui_core::Environment;
use waterui_core::layout::{ProposalSize, Size as LayoutSize, ViewDimensions};
use waterui_webview::WebView;
#[cfg(hydrolysis_macos_system_webview)]
mod macos;
#[cfg(hydrolysis_macos_system_webview)]
pub use macos::MacSystemWebViewController;
use crate::renderer::{HydroNativeView, HydroState, HydrolysisRenderer, WidgetRenderContext};
pub(crate) struct WebViewRenderState {
_source: WebView,
#[cfg(hydrolysis_macos_system_webview)]
native: macos::MacSystemWebViewHandle,
#[cfg(hydrolysis_macos_system_webview)]
occlusion: Rc<RefCell<Vec<vello::kurbo::Rect>>>,
}
impl WebViewRenderState {
#[cfg(hydrolysis_macos_system_webview)]
pub(crate) fn from_view(view: WebView, env: &Environment) -> Self {
let _ = env;
let native = view
.handle()
.downcast_ref::<macos::MacSystemWebViewHandle>()
.unwrap_or_else(|| {
panic!("Hydrolysis macOS WebView handle does not use the selected system backend")
})
.clone();
Self {
_source: view,
native,
occlusion: Rc::new(RefCell::new(Vec::new())),
}
}
#[cfg(not(hydrolysis_macos_system_webview))]
pub(crate) fn from_view(view: WebView, env: &Environment) -> Self {
let _ = env;
Self { _source: view }
}
pub(crate) fn prebuild(&mut self, renderer: &mut HydrolysisRenderer, env: &Environment) {
let _ = (renderer, env);
}
}
impl HydroNativeView for WebView {
fn intrinsic(state: &mut HydroState, view: &Self, env: &Environment) -> LayoutSize {
let _ = (state, view, env);
LayoutSize::zero()
}
fn dimensions(
state: &mut HydroState,
view: &Self,
env: &Environment,
proposal: ProposalSize,
) -> ViewDimensions {
let _ = (state, view, env);
ViewDimensions::new(LayoutSize::new(
proposal.width.unwrap_or(0.0),
proposal.height.unwrap_or(0.0),
))
}
}
pub(crate) fn measure_webview_node(
state: &WebViewRenderState,
proposal: ProposalSize,
hydro: &mut HydroState,
_env: &Environment,
) -> ViewDimensions {
let _ = (state, hydro);
ViewDimensions::new(LayoutSize::new(
proposal.width.unwrap_or(0.0),
proposal.height.unwrap_or(0.0),
))
}
pub(crate) fn render_webview_node(
ctx: &mut WidgetRenderContext<'_>,
state: &Rc<RefCell<WebViewRenderState>>,
env: &Environment,
) {
super::register_web_surface_accessibility(ctx, env);
#[cfg(hydrolysis_macos_system_webview)]
{
use crate::renderer::transformed_rect;
let _ = env;
let bounds = ctx.bounds;
let transform = ctx.render_context().transform;
let hit_transform = ctx.hit_transform;
let (native, occlusion) = {
let state = state.borrow();
(state.native.native_view(), Rc::clone(&state.occlusion))
};
let renderer = ctx.renderer_mut();
renderer.register_native_view_occlusion(
transformed_rect(hit_transform, bounds),
Rc::clone(&occlusion),
);
renderer.record_native_view_layer(native, transform, bounds, occlusion);
}
#[cfg(not(hydrolysis_macos_system_webview))]
let _ = state;
}
#[cfg(hydrolysis_macos_system_webview)]
pub(crate) fn install_controller(env: &mut Environment) {
macos::install(env);
}