Compare commits

...

1 Commits

15 changed files with 79 additions and 90 deletions

View File

@@ -0,0 +1,5 @@
---
"tauri": "minor:feat"
---
Add `Manager::run_on_main_thread` to replace the old explicit method on `App/AppHandle/WebviewWindow/Window/Webview`.

View File

@@ -0,0 +1,6 @@
---
"tauri": "minor:feat"
---
Add `Manager::run_on_main_thread_return` which uses a channel to return the result of the closure passed in.

View File

@@ -0,0 +1,6 @@
---
"tauri": "major:breaking"
---
Removed `App/AppHandle/WebviewWindow/Window/Webview::run_on_main_thread` method, just import `tauri::Manager` trait and use the new `Manager::run_on_main_thread`.

View File

@@ -387,14 +387,6 @@ impl<'de, R: Runtime> CommandArg<'de, R> for AppHandle<R> {
}
impl<R: Runtime> AppHandle<R> {
/// Runs the given closure on the main thread.
pub fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> crate::Result<()> {
self
.runtime_handle
.run_on_main_thread(f)
.map_err(Into::into)
}
/// Adds a Tauri application plugin.
/// This function can be used to register a plugin that is loaded dynamically e.g. after login.
/// For plugins that are created when the app is started, prefer [`Builder::plugin`].
@@ -994,11 +986,6 @@ impl<R: Runtime> App<R> {
Ok(())
}
/// Runs the given closure on the main thread.
pub fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> crate::Result<()> {
self.app_handle().run_on_main_thread(f)
}
/// Gets a handle to the application instance.
pub fn handle(&self) -> &AppHandle<R> {
&self.handle

View File

@@ -90,7 +90,7 @@ mod resources;
mod vibrancy;
pub mod webview;
pub mod window;
use tauri_runtime as runtime;
use tauri_runtime::{self as runtime};
pub mod image;
#[cfg(target_os = "ios")]
mod ios;
@@ -834,6 +834,36 @@ pub trait Manager<R: Runtime>: sealed::ManagerBase<R> {
.unwrap()
.add_capability(capability)
}
/// Runs the given closure on the main thread.
fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> crate::Result<()> {
use tauri_runtime::RuntimeHandle;
self
.app_handle()
.runtime_handle
.run_on_main_thread(f)
.map_err(Into::into)
}
/// Runs the given closure on the main thread and returns the result.
///
/// Uses an [`mpsc::sync_channel``](std::sync::mpsc::sync_channel) to communicate the result back to the caller.
fn run_on_main_thread_return<Ret, F>(&self, f: F) -> crate::Result<Ret>
where
F: FnOnce() -> Ret + Send + 'static,
Ret: Send + 'static,
{
let (tx, rx) = std::sync::mpsc::sync_channel(1);
self.app_handle().run_on_main_thread(move || {
let res = f();
if let Err(_e) = tx.send(res) {
#[cfg(feature = "tracing")]
tracing::error!("failed to send result back: {:?}", _e);
}
})?;
rx.recv().map_err(|_| Error::FailedToReceiveMessage)
}
}
/// Listen to events.
@@ -1089,24 +1119,6 @@ impl<T> UnsafeSend<T> {
}
}
#[allow(unused)]
macro_rules! run_main_thread {
($handle:ident, $ex:expr) => {{
use std::sync::mpsc::channel;
let (tx, rx) = channel();
let task = move || {
let f = $ex;
let _ = tx.send(f());
};
$handle
.run_on_main_thread(task)
.and_then(|_| rx.recv().map_err(|_| crate::Error::FailedToReceiveMessage))
}};
}
#[allow(unused)]
pub(crate) use run_main_thread;
#[cfg(any(test, feature = "test"))]
#[cfg_attr(docsrs, doc(cfg(feature = "test")))]
pub mod test;

View File

@@ -6,7 +6,6 @@ use std::sync::Arc;
use super::run_item_main_thread;
use crate::menu::CheckMenuItemInner;
use crate::run_main_thread;
use crate::{menu::MenuId, AppHandle, Manager, Runtime};
use super::CheckMenuItem;
@@ -34,7 +33,7 @@ impl<R: Runtime> CheckMenuItem<R> {
let text = text.as_ref().to_owned();
let accelerator = accelerator.and_then(|s| s.as_ref().parse().ok());
let item = run_main_thread!(handle, || {
let item = handle.run_on_main_thread_return(move || {
let item = muda::CheckMenuItem::new(text, enabled, checked, accelerator);
CheckMenuItemInner {
id: item.id().clone(),
@@ -71,7 +70,7 @@ impl<R: Runtime> CheckMenuItem<R> {
let text = text.as_ref().to_owned();
let accelerator = accelerator.and_then(|s| s.as_ref().parse().ok());
let item = run_main_thread!(handle, || {
let item = handle.run_on_main_thread_return(move || {
let item = muda::CheckMenuItem::with_id(id.clone(), text, enabled, checked, accelerator);
CheckMenuItemInner {
id,

View File

@@ -7,7 +7,6 @@ use std::sync::Arc;
use super::run_item_main_thread;
use super::{IconMenuItem, NativeIcon};
use crate::menu::IconMenuItemInner;
use crate::run_main_thread;
use crate::{image::Image, menu::MenuId, AppHandle, Manager, Runtime};
impl<R: Runtime> IconMenuItem<R> {
@@ -37,7 +36,7 @@ impl<R: Runtime> IconMenuItem<R> {
None => None,
};
let item = run_main_thread!(handle, || {
let item = handle.run_on_main_thread_return(move || {
let item = muda::IconMenuItem::new(text, enabled, icon, accelerator);
IconMenuItemInner {
id: item.id().clone(),
@@ -78,7 +77,7 @@ impl<R: Runtime> IconMenuItem<R> {
None => None,
};
let item = run_main_thread!(handle, || {
let item = handle.run_on_main_thread_return(move || {
let item = muda::IconMenuItem::with_id(id.clone(), text, enabled, icon, accelerator);
IconMenuItemInner {
id,
@@ -116,7 +115,7 @@ impl<R: Runtime> IconMenuItem<R> {
let icon = native_icon.map(Into::into);
let accelerator = accelerator.and_then(|s| s.as_ref().parse().ok());
let item = run_main_thread!(handle, || {
let item = handle.run_on_main_thread_return(move || {
let item = muda::IconMenuItem::with_native_icon(text, enabled, icon, accelerator);
IconMenuItemInner {
id: item.id().clone(),
@@ -157,7 +156,7 @@ impl<R: Runtime> IconMenuItem<R> {
let icon = native_icon.map(Into::into);
let accelerator = accelerator.and_then(|s| s.as_ref().parse().ok());
let item = run_main_thread!(handle, || {
let item = handle.run_on_main_thread_return(move || {
let item =
muda::IconMenuItem::with_id_and_native_icon(id.clone(), text, enabled, icon, accelerator);
IconMenuItemInner {

View File

@@ -9,7 +9,6 @@ use super::sealed::ContextMenuBase;
use super::{
AboutMetadata, IsMenuItem, Menu, MenuInner, MenuItemKind, PredefinedMenuItem, Submenu,
};
use crate::run_main_thread;
use crate::Window;
use crate::{AppHandle, Manager, Position, Runtime};
use muda::ContextMenu;
@@ -94,7 +93,7 @@ impl<R: Runtime> Menu<R> {
let handle = manager.app_handle();
let app_handle = handle.clone();
let menu = run_main_thread!(handle, || {
let menu = handle.run_on_main_thread_return(move || {
let menu = muda::Menu::new();
MenuInner {
id: menu.id().clone(),
@@ -112,7 +111,7 @@ impl<R: Runtime> Menu<R> {
let app_handle = handle.clone();
let id = id.into();
let menu = run_main_thread!(handle, || {
let menu = handle.run_on_main_thread_return(move || {
let menu = muda::Menu::with_id(id.clone());
MenuInner {
id,

View File

@@ -95,6 +95,8 @@ macro_rules! gen_wrappers {
impl<R: Runtime> Drop for $inner<R> {
fn drop(&mut self) {
use $crate::Manager;
let inner = self.inner.take();
// SAFETY: inner was created on main thread and is being dropped on main thread
let inner = $crate::UnsafeSend(inner);

View File

@@ -6,7 +6,6 @@ use std::sync::Arc;
use super::run_item_main_thread;
use crate::menu::MenuItemInner;
use crate::run_main_thread;
use crate::{menu::MenuId, AppHandle, Manager, Runtime};
use super::MenuItem;
@@ -33,7 +32,7 @@ impl<R: Runtime> MenuItem<R> {
let text = text.as_ref().to_owned();
let accelerator = accelerator.and_then(|s| s.as_ref().parse().ok());
let item = run_main_thread!(handle, || {
let item = handle.run_on_main_thread_return(move || {
let item = muda::MenuItem::new(text, enabled, accelerator);
MenuItemInner {
id: item.id().clone(),
@@ -69,7 +68,7 @@ impl<R: Runtime> MenuItem<R> {
let accelerator = accelerator.and_then(|s| s.as_ref().parse().ok());
let text = text.as_ref().to_owned();
let item = run_main_thread!(handle, || {
let item = handle.run_on_main_thread_return(move || {
let item = muda::MenuItem::with_id(id.clone(), text, enabled, accelerator);
MenuItemInner {
id,

View File

@@ -7,7 +7,6 @@ use std::sync::Arc;
use super::run_item_main_thread;
use super::{AboutMetadata, PredefinedMenuItem};
use crate::menu::PredefinedMenuItemInner;
use crate::run_main_thread;
use crate::{menu::MenuId, AppHandle, Manager, Runtime};
impl<R: Runtime> PredefinedMenuItem<R> {
@@ -16,7 +15,7 @@ impl<R: Runtime> PredefinedMenuItem<R> {
let handle = manager.app_handle();
let app_handle = handle.clone();
let item = run_main_thread!(handle, || {
let item = handle.run_on_main_thread_return(move || {
let item = muda::PredefinedMenuItem::separator();
PredefinedMenuItemInner {
id: item.id().clone(),
@@ -35,7 +34,7 @@ impl<R: Runtime> PredefinedMenuItem<R> {
let text = text.map(|t| t.to_owned());
let item = run_main_thread!(handle, || {
let item = handle.run_on_main_thread_return(move || {
let item = muda::PredefinedMenuItem::copy(text.as_deref());
PredefinedMenuItemInner {
id: item.id().clone(),
@@ -54,7 +53,7 @@ impl<R: Runtime> PredefinedMenuItem<R> {
let text = text.map(|t| t.to_owned());
let item = run_main_thread!(handle, || {
let item = handle.run_on_main_thread_return(move || {
let item = muda::PredefinedMenuItem::cut(text.as_deref());
PredefinedMenuItemInner {
id: item.id().clone(),
@@ -73,7 +72,7 @@ impl<R: Runtime> PredefinedMenuItem<R> {
let text = text.map(|t| t.to_owned());
let item = run_main_thread!(handle, || {
let item = handle.run_on_main_thread_return(move || {
let item = muda::PredefinedMenuItem::paste(text.as_deref());
PredefinedMenuItemInner {
id: item.id().clone(),
@@ -92,7 +91,7 @@ impl<R: Runtime> PredefinedMenuItem<R> {
let text = text.map(|t| t.to_owned());
let item = run_main_thread!(handle, || {
let item = handle.run_on_main_thread_return(move || {
let item = muda::PredefinedMenuItem::select_all(text.as_deref());
PredefinedMenuItemInner {
id: item.id().clone(),
@@ -115,7 +114,7 @@ impl<R: Runtime> PredefinedMenuItem<R> {
let text = text.map(|t| t.to_owned());
let item = run_main_thread!(handle, || {
let item = handle.run_on_main_thread_return(move || {
let item = muda::PredefinedMenuItem::undo(text.as_deref());
PredefinedMenuItemInner {
id: item.id().clone(),
@@ -137,7 +136,7 @@ impl<R: Runtime> PredefinedMenuItem<R> {
let text = text.map(|t| t.to_owned());
let item = run_main_thread!(handle, || {
let item = handle.run_on_main_thread_return(move || {
let item = muda::PredefinedMenuItem::redo(text.as_deref());
PredefinedMenuItemInner {
id: item.id().clone(),
@@ -160,7 +159,7 @@ impl<R: Runtime> PredefinedMenuItem<R> {
let text = text.map(|t| t.to_owned());
let item = run_main_thread!(handle, || {
let item = handle.run_on_main_thread_return(move || {
let item = muda::PredefinedMenuItem::minimize(text.as_deref());
PredefinedMenuItemInner {
id: item.id().clone(),
@@ -183,7 +182,7 @@ impl<R: Runtime> PredefinedMenuItem<R> {
let text = text.map(|t| t.to_owned());
let item = run_main_thread!(handle, || {
let item = handle.run_on_main_thread_return(move || {
let item = muda::PredefinedMenuItem::maximize(text.as_deref());
PredefinedMenuItemInner {
id: item.id().clone(),
@@ -206,7 +205,7 @@ impl<R: Runtime> PredefinedMenuItem<R> {
let text = text.map(|t| t.to_owned());
let item = run_main_thread!(handle, || {
let item = handle.run_on_main_thread_return(move || {
let item = muda::PredefinedMenuItem::fullscreen(text.as_deref());
PredefinedMenuItemInner {
id: item.id().clone(),
@@ -229,7 +228,7 @@ impl<R: Runtime> PredefinedMenuItem<R> {
let text = text.map(|t| t.to_owned());
let item = run_main_thread!(handle, || {
let item = handle.run_on_main_thread_return(move || {
let item = muda::PredefinedMenuItem::hide(text.as_deref());
PredefinedMenuItemInner {
id: item.id().clone(),
@@ -252,7 +251,7 @@ impl<R: Runtime> PredefinedMenuItem<R> {
let text = text.map(|t| t.to_owned());
let item = run_main_thread!(handle, || {
let item = handle.run_on_main_thread_return(move || {
let item = muda::PredefinedMenuItem::hide_others(text.as_deref());
PredefinedMenuItemInner {
id: item.id().clone(),
@@ -275,7 +274,7 @@ impl<R: Runtime> PredefinedMenuItem<R> {
let text = text.map(|t| t.to_owned());
let item = run_main_thread!(handle, || {
let item = handle.run_on_main_thread_return(move || {
let item = muda::PredefinedMenuItem::show_all(text.as_deref());
PredefinedMenuItemInner {
id: item.id().clone(),
@@ -298,7 +297,7 @@ impl<R: Runtime> PredefinedMenuItem<R> {
let text = text.map(|t| t.to_owned());
let item = run_main_thread!(handle, || {
let item = handle.run_on_main_thread_return(move || {
let item = muda::PredefinedMenuItem::close_window(text.as_deref());
PredefinedMenuItemInner {
id: item.id().clone(),
@@ -321,7 +320,7 @@ impl<R: Runtime> PredefinedMenuItem<R> {
let text = text.map(|t| t.to_owned());
let item = run_main_thread!(handle, || {
let item = handle.run_on_main_thread_return(move || {
let item = muda::PredefinedMenuItem::quit(text.as_deref());
PredefinedMenuItemInner {
id: item.id().clone(),
@@ -349,7 +348,7 @@ impl<R: Runtime> PredefinedMenuItem<R> {
None => None,
};
let item = run_main_thread!(handle, || {
let item = handle.run_on_main_thread_return(move || {
let item = muda::PredefinedMenuItem::about(text.as_deref(), metadata);
PredefinedMenuItemInner {
id: item.id().clone(),
@@ -372,7 +371,7 @@ impl<R: Runtime> PredefinedMenuItem<R> {
let text = text.map(|t| t.to_owned());
let item = run_main_thread!(handle, || {
let item = handle.run_on_main_thread_return(move || {
let item = muda::PredefinedMenuItem::services(text.as_deref());
PredefinedMenuItemInner {
id: item.id().clone(),

View File

@@ -8,7 +8,6 @@ use super::run_item_main_thread;
use super::Submenu;
use super::{sealed::ContextMenuBase, IsMenuItem, MenuItemKind};
use crate::menu::SubmenuInner;
use crate::run_main_thread;
use crate::{AppHandle, Manager, Position, Runtime, Window};
use muda::{ContextMenu, MenuId};
@@ -93,7 +92,7 @@ impl<R: Runtime> Submenu<R> {
let text = text.as_ref().to_owned();
let submenu = run_main_thread!(handle, || {
let submenu = handle.run_on_main_thread_return(move || {
let submenu = muda::Submenu::new(text, enabled);
SubmenuInner {
id: submenu.id().clone(),
@@ -118,7 +117,7 @@ impl<R: Runtime> Submenu<R> {
let id = id.into();
let text = text.as_ref().to_owned();
let submenu = run_main_thread!(handle, || {
let submenu = handle.run_on_main_thread_return(move || {
let submenu = muda::Submenu::with_id(id.clone(), text, enabled);
SubmenuInner {
id,

View File

@@ -982,15 +982,6 @@ impl<R: Runtime> Webview<R> {
WebviewBuilder::new(label.into(), url)
}
/// Runs the given closure on the main thread.
pub fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> crate::Result<()> {
self
.webview
.dispatcher
.run_on_main_thread(f)
.map_err(Into::into)
}
/// The webview label.
pub fn label(&self) -> &str {
&self.webview.label

View File

@@ -1087,11 +1087,6 @@ impl<R: Runtime> WebviewWindow<R> {
WebviewWindowBuilder::new(manager, label, url)
}
/// Runs the given closure on the main thread.
pub fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> crate::Result<()> {
self.webview.run_on_main_thread(f)
}
/// The webview label.
pub fn label(&self) -> &str {
self.webview.label()

View File

@@ -1037,15 +1037,6 @@ impl<R: Runtime> Window<R> {
self.webviews().iter().all(|w| w.label() == self.label())
}
/// Runs the given closure on the main thread.
pub fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> crate::Result<()> {
self
.window
.dispatcher
.run_on_main_thread(f)
.map_err(Into::into)
}
/// The label of this window.
pub fn label(&self) -> &str {
&self.window.label