Skip to content

Commit f79e9d9

Browse files
committed
improve event loop
1 parent 342cf09 commit f79e9d9

File tree

1 file changed

+43
-21
lines changed
  • crates/tauri-runtime-cef/src

1 file changed

+43
-21
lines changed

crates/tauri-runtime-cef/src/lib.rs

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,6 @@ pub struct RuntimeContext<T: UserEvent> {
274274
main_thread_task_runner: cef::TaskRunner,
275275
main_thread_id: ThreadId,
276276
cef_context: cef_impl::Context<T>,
277-
event_queue: Arc<RefCell<Vec<RunEvent<T>>>>,
278277
}
279278

280279
// SAFETY: we ensure this type is only used on the main thread.
@@ -1779,6 +1778,8 @@ impl<T: UserEvent> EventLoopProxy<T> for EventProxy<T> {
17791778
#[derive(Debug)]
17801779
pub struct CefRuntime<T: UserEvent> {
17811780
pub context: RuntimeContext<T>,
1781+
event_tx: std::sync::mpsc::Sender<RunEvent<T>>,
1782+
event_rx: std::sync::mpsc::Receiver<RunEvent<T>>,
17821783
}
17831784

17841785
#[cfg(target_os = "macos")]
@@ -1832,25 +1833,26 @@ impl<T: UserEvent> CefRuntime<T> {
18321833

18331834
let _ = cef::api_hash(cef::sys::CEF_API_VERSION_LAST, 0);
18341835

1835-
let event_queue = Arc::new(RefCell::new(Vec::new()));
1836-
let event_queue_ = event_queue.clone();
1836+
let (event_tx, event_rx) = channel();
18371837

18381838
let cache_base = dirs::cache_dir().unwrap_or_else(|| std::env::temp_dir());
18391839
let cache_path = cache_base.join(&runtime_args.identifier).join("cef");
18401840

18411841
// Ensure the cache directory exists
18421842
let _ = create_dir_all(&cache_path);
18431843

1844+
let event_tx_ = event_tx.clone();
18441845
let cef_context = cef_impl::Context {
18451846
windows: Default::default(),
18461847
callback: Arc::new(RefCell::new(Box::new(move |event| {
1847-
event_queue_.borrow_mut().push(event);
1848+
event_tx_.send(event).unwrap();
18481849
}))),
18491850
next_webview_event_id: Default::default(),
18501851
next_webview_id: Default::default(),
18511852
next_window_id: Default::default(),
18521853
next_window_event_id: Default::default(),
18531854
};
1855+
18541856
let mut app = cef_impl::TauriApp::new(cef_context.clone(), runtime_args.custom_schemes);
18551857

18561858
let cmd = args.as_cmd_line().unwrap();
@@ -1892,9 +1894,12 @@ impl<T: UserEvent> CefRuntime<T> {
18921894
main_thread_task_runner: cef::task_runner_get_for_current_thread().expect("null task runner"),
18931895
main_thread_id,
18941896
cef_context,
1895-
event_queue,
18961897
};
1897-
Self { context }
1898+
Self {
1899+
context,
1900+
event_tx,
1901+
event_rx,
1902+
}
18981903
}
18991904
}
19001905

@@ -2048,22 +2053,38 @@ impl<T: UserEvent> Runtime<T> for CefRuntime<T> {
20482053

20492054
fn run<F: FnMut(RunEvent<T>) + 'static>(self, callback: F) {
20502055
let callback = Arc::new(RefCell::new(callback));
2056+
let event_tx_ = self.event_tx.clone();
2057+
let _ = self.context.cef_context.callback.replace(Box::new(move |event| {
2058+
if let RunEvent::Exit = event {
2059+
// notify the event loop to exit
2060+
let _ = event_tx_.send(RunEvent::Exit);
2061+
} else {
2062+
// Try to call callback directly, if busy queue to channel
2063+
if let Ok(mut cb) = callback.try_borrow_mut() {
2064+
cb(event);
2065+
} else {
2066+
let _ = event_tx_.send(event);
2067+
}
2068+
}
2069+
}));
20512070

2052-
let callback_ = callback.clone();
2053-
let _ = self
2054-
.context
2055-
.cef_context
2056-
.callback
2057-
.replace(Box::new(move |event| {
2058-
(callback_.borrow_mut())(event);
2059-
}));
2060-
2061-
// clear event queue
2062-
for event in self.context.event_queue.replace(Vec::new()) {
2063-
(callback.borrow_mut())(event);
2064-
}
2071+
'main_loop: loop {
2072+
while let Ok(event) = self.event_rx.try_recv() {
2073+
if matches!(&event, RunEvent::Exit) {
2074+
// Exit event is triggered when we break out of the loop
2075+
break 'main_loop;
2076+
}
2077+
2078+
(self.context.cef_context.callback.borrow())(event);
2079+
}
20652080

2066-
cef::run_message_loop();
2081+
// Do CEF message loop work
2082+
// This processes one iteration of the message loop
2083+
cef::do_message_loop_work();
2084+
2085+
// Emit MainEventsCleared event
2086+
(self.context.cef_context.callback.borrow())(RunEvent::MainEventsCleared);
2087+
}
20672088

20682089
let windows = self.context.windows.borrow();
20692090
for window in windows.values() {
@@ -2072,7 +2093,8 @@ impl<T: UserEvent> Runtime<T> for CefRuntime<T> {
20722093

20732094
cef::shutdown();
20742095

2075-
(callback.borrow_mut())(RunEvent::Exit);
2096+
// Final Exit event
2097+
(self.context.cef_context.callback.borrow())(RunEvent::Exit);
20762098
}
20772099

20782100
fn cursor_position(&self) -> Result<PhysicalPosition<f64>> {

0 commit comments

Comments
 (0)