tauri_runtime_cef/
offscreen.rs1use std::sync::{
6 Arc, Mutex, Weak,
7 atomic::{AtomicBool, Ordering},
8};
9
10use tauri_runtime::dpi::Rect;
11
12pub type CursorHandler = dyn Fn(cef::CursorType, Option<&cef::CursorInfo>) + Send + Sync;
15
16#[derive(Clone)]
27pub struct Offscreen {
28 pub shared_texture_enabled: bool,
31 pub external_begin_frame_enabled: bool,
33 pub cursor_handler: Option<Arc<CursorHandler>>,
35 pub(crate) render_handler: Arc<dyn Fn(OffscreenView) -> cef::RenderHandler + Send + Sync>,
36}
37
38impl Offscreen {
39 pub fn new<F: Fn(OffscreenView) -> cef::RenderHandler + Send + Sync + 'static>(
46 handler: F,
47 ) -> Self {
48 Self {
49 shared_texture_enabled: false,
50 external_begin_frame_enabled: false,
51 cursor_handler: None,
52 render_handler: Arc::new(handler),
53 }
54 }
55
56 pub(crate) fn window_info(&self, parent: cef::sys::cef_window_handle_t) -> cef::WindowInfo {
57 let mut info = cef::WindowInfo::default().set_as_windowless(parent);
58 info.shared_texture_enabled = i32::from(self.shared_texture_enabled);
59 info.external_begin_frame_enabled = i32::from(self.external_begin_frame_enabled);
60 info
61 }
62}
63
64#[derive(Clone)]
66pub struct OffscreenView {
67 pub(crate) window: Weak<dyn winit::window::Window>,
69 pub(crate) bounds: Arc<Mutex<Rect>>,
70 pub(crate) visible: Arc<AtomicBool>,
71}
72
73impl OffscreenView {
74 pub fn window(&self) -> Option<Arc<dyn winit::window::Window>> {
78 self.window.upgrade()
79 }
80
81 pub fn request_redraw(&self) {
83 if let Some(window) = self.window.upgrade() {
84 window.request_redraw();
85 }
86 }
87
88 pub fn bounds(&self) -> Rect {
90 *self.bounds.lock().unwrap_or_else(|e| e.into_inner())
91 }
92
93 pub fn is_visible(&self) -> bool {
95 self.visible.load(Ordering::Relaxed)
96 }
97}
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102
103 #[test]
104 fn offscreen_options_select_alloy_and_the_requested_paint_mode() {
105 let mut options = Offscreen::new(|_| unreachable!());
106 let software = options.window_info(Default::default());
107 assert_eq!(software.windowless_rendering_enabled, 1);
108 assert_eq!(software.runtime_style, cef::RuntimeStyle::ALLOY);
109 assert_eq!(software.shared_texture_enabled, 0);
110 assert_eq!(software.external_begin_frame_enabled, 0);
111
112 options.shared_texture_enabled = true;
113 options.external_begin_frame_enabled = true;
114 let accelerated = options.window_info(Default::default());
115 assert_eq!(accelerated.shared_texture_enabled, 1);
116 assert_eq!(accelerated.external_begin_frame_enabled, 1);
117 }
118}