Skip to content

feat(core): add Manager::run_on_main_thread/run_on_main_thread_return, remove old explicit methods #12893

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changes/manager-run_on_main_thread.md
Original file line number Diff line number Diff line change
@@ -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`.
6 changes: 6 additions & 0 deletions .changes/manager-run_on_main_thread_return.md
Original file line number Diff line number Diff line change
@@ -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.

6 changes: 6 additions & 0 deletions .changes/run_on_main_thread_explicit-removed.md
Original file line number Diff line number Diff line change
@@ -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`.

13 changes: 0 additions & 13 deletions crates/tauri/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`].
Expand Down Expand Up @@ -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
Expand Down
50 changes: 31 additions & 19 deletions crates/tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand Down
5 changes: 2 additions & 3 deletions crates/tauri/src/menu/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -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,
Expand Down
9 changes: 4 additions & 5 deletions crates/tauri/src/menu/icon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -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 {
Expand Down
5 changes: 2 additions & 3 deletions crates/tauri/src/menu/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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(),
Expand All @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions crates/tauri/src/menu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 2 additions & 3 deletions crates/tauri/src/menu/normal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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(),
Expand Down Expand Up @@ -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,
Expand Down
Loading
Loading