use std::sync::{
Arc, Mutex, Weak,
atomic::{AtomicBool, Ordering},
};
use tauri_runtime::dpi::Rect;
pub type CursorHandler = dyn Fn(cef::CursorType, Option<&cef::CursorInfo>) + Send + Sync;
#[derive(Clone)]
pub struct Offscreen {
pub shared_texture_enabled: bool,
pub external_begin_frame_enabled: bool,
pub cursor_handler: Option<Arc<CursorHandler>>,
pub(crate) render_handler: Arc<dyn Fn(OffscreenView) -> cef::RenderHandler + Send + Sync>,
}
impl Offscreen {
pub fn new<F: Fn(OffscreenView) -> cef::RenderHandler + Send + Sync + 'static>(
handler: F,
) -> Self {
Self {
shared_texture_enabled: false,
external_begin_frame_enabled: false,
cursor_handler: None,
render_handler: Arc::new(handler),
}
}
pub(crate) fn window_info(&self, parent: cef::sys::cef_window_handle_t) -> cef::WindowInfo {
let mut info = cef::WindowInfo::default().set_as_windowless(parent);
info.shared_texture_enabled = i32::from(self.shared_texture_enabled);
info.external_begin_frame_enabled = i32::from(self.external_begin_frame_enabled);
info
}
}
#[derive(Clone)]
pub struct OffscreenView {
pub(crate) window: Weak<dyn winit::window::Window>,
pub(crate) bounds: Arc<Mutex<Rect>>,
pub(crate) visible: Arc<AtomicBool>,
}
impl OffscreenView {
pub fn window(&self) -> Option<Arc<dyn winit::window::Window>> {
self.window.upgrade()
}
pub fn request_redraw(&self) {
if let Some(window) = self.window.upgrade() {
window.request_redraw();
}
}
pub fn bounds(&self) -> Rect {
*self.bounds.lock().unwrap_or_else(|e| e.into_inner())
}
pub fn is_visible(&self) -> bool {
self.visible.load(Ordering::Relaxed)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn offscreen_options_select_alloy_and_the_requested_paint_mode() {
let mut options = Offscreen::new(|_| unreachable!());
let software = options.window_info(Default::default());
assert_eq!(software.windowless_rendering_enabled, 1);
assert_eq!(software.runtime_style, cef::RuntimeStyle::ALLOY);
assert_eq!(software.shared_texture_enabled, 0);
assert_eq!(software.external_begin_frame_enabled, 0);
options.shared_texture_enabled = true;
options.external_begin_frame_enabled = true;
let accelerated = options.window_info(Default::default());
assert_eq!(accelerated.shared_texture_enabled, 1);
assert_eq!(accelerated.external_begin_frame_enabled, 1);
}
}