mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-11-28 12:27:16 +03:00
feat(core): panic when a dispatcher getter is used on the main thread (#2455)
This commit is contained in:
parent
c76f4b7d39
commit
50ffdc06fb
7
.changes/panic-dispatcher-getter-main-thread.md
Normal file
7
.changes/panic-dispatcher-getter-main-thread.md
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
"tauri": patch
|
||||
"tauri-runtime": patch
|
||||
"tauri-runtime-wry": patch
|
||||
---
|
||||
|
||||
Panic when a dispatcher getter method (`Window`, `GlobalShortcutHandle`, `ClipboardManager` and `MenuHandle` APIs) is called on the main thread.
|
@ -112,10 +112,11 @@ pub type WindowMenuEventListeners = Arc<Mutex<HashMap<Uuid, MenuEventHandler>>>;
|
||||
|
||||
macro_rules! dispatcher_getter {
|
||||
($self: ident, $message: expr) => {{
|
||||
if current_thread().id() == $self.context.main_thread_id
|
||||
&& !$self.context.is_event_loop_running.load(Ordering::Relaxed)
|
||||
{
|
||||
panic!("This API cannot be called when the event loop is not running");
|
||||
if current_thread().id() == $self.context.main_thread_id {
|
||||
panic!("This API cannot be called on the main thread. Try using `std::thread::spawn` or `tauri::async_runtime::spawn`.");
|
||||
}
|
||||
if !$self.context.is_event_loop_running.load(Ordering::Relaxed) {
|
||||
panic!("This API cannot be called when the event loop is not running. Try using `std::thread::spawn` or `tauri::async_runtime::spawn`.");
|
||||
}
|
||||
let (tx, rx) = channel();
|
||||
$self
|
||||
@ -129,10 +130,11 @@ macro_rules! dispatcher_getter {
|
||||
|
||||
macro_rules! getter {
|
||||
($self: ident, $rx: expr, $message: expr) => {{
|
||||
if current_thread().id() == $self.context.main_thread_id
|
||||
&& !$self.context.is_event_loop_running.load(Ordering::Relaxed)
|
||||
{
|
||||
panic!("This API cannot be called when the event loop is not running");
|
||||
if current_thread().id() == $self.context.main_thread_id {
|
||||
panic!("This API cannot be called on the main thread. Try using `std::thread::spawn` or `tauri::async_runtime::spawn`.");
|
||||
}
|
||||
if !$self.context.is_event_loop_running.load(Ordering::Relaxed) {
|
||||
panic!("This API cannot be called when the event loop is not running. Try using `std::thread::spawn` or `tauri::async_runtime::spawn`.");
|
||||
}
|
||||
$self
|
||||
.context
|
||||
|
@ -258,16 +258,20 @@ pub trait GlobalShortcutManager: Debug {
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the app is not running yet, usually when called on the `tauri::Builder#setup` closure.
|
||||
/// You can spawn a task to use the API using the `tauri::async_runtime` to prevent the panic.
|
||||
/// - Panics if the event loop is not running yet, usually when called on the `tauri::Builder#setup` closure.
|
||||
/// - Panics when called on the main thread, usually on the `tauri::App#run`closure.
|
||||
///
|
||||
/// You can spawn a task to use the API using `tauri::async_runtime::spawn` or [`std::thread::spawn`] to prevent the panic.
|
||||
fn is_registered(&self, accelerator: &str) -> crate::Result<bool>;
|
||||
|
||||
/// Register a global shortcut of `accelerator`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the app is not running yet, usually when called on the `tauri::Builder#setup` closure.
|
||||
/// You can spawn a task to use the API using the `tauri::async_runtime` to prevent the panic.
|
||||
/// - Panics if the event loop is not running yet, usually when called on the `tauri::Builder#setup` closure.
|
||||
/// - Panics when called on the main thread, usually on the `tauri::App#run`closure.
|
||||
///
|
||||
/// You can spawn a task to use the API using `tauri::async_runtime::spawn` or [`std::thread::spawn`] to prevent the panic.
|
||||
fn register<F: Fn() + Send + 'static>(
|
||||
&mut self,
|
||||
accelerator: &str,
|
||||
@ -278,16 +282,20 @@ pub trait GlobalShortcutManager: Debug {
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the app is not running yet, usually when called on the `tauri::Builder#setup` closure.
|
||||
/// You can spawn a task to use the API using the `tauri::async_runtime` to prevent the panic.
|
||||
/// - Panics if the event loop is not running yet, usually when called on the `tauri::Builder#setup` closure.
|
||||
/// - Panics when called on the main thread, usually on the `tauri::App#run`closure.
|
||||
///
|
||||
/// You can spawn a task to use the API using `tauri::async_runtime::spawn` or [`std::thread::spawn`] to prevent the panic.
|
||||
fn unregister_all(&mut self) -> crate::Result<()>;
|
||||
|
||||
/// Unregister the provided `accelerator`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the app is not running yet, usually when called on the `tauri::Builder#setup` closure.
|
||||
/// You can spawn a task to use the API using the `tauri::async_runtime` to prevent the panic.
|
||||
/// - Panics if the event loop is not running yet, usually when called on the `tauri::Builder#setup` closure.
|
||||
/// - Panics when called on the main thread, usually on the `tauri::App#run`closure.
|
||||
///
|
||||
/// You can spawn a task to use the API using `tauri::async_runtime::spawn` or [`std::thread::spawn`] to prevent the panic.
|
||||
fn unregister(&mut self, accelerator: &str) -> crate::Result<()>;
|
||||
}
|
||||
|
||||
@ -297,16 +305,19 @@ pub trait ClipboardManager: Debug {
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the app is not running yet, usually when called on the `tauri::Builder#setup` closure.
|
||||
/// You can spawn a task to use the API using the `tauri::async_runtime` to prevent the panic.
|
||||
|
||||
/// - Panics if the event loop is not running yet, usually when called on the `tauri::Builder#setup` closure.
|
||||
/// - Panics when called on the main thread, usually on the `tauri::App#run`closure.
|
||||
///
|
||||
/// You can spawn a task to use the API using `tauri::async_runtime::spawn` or [`std::thread::spawn`] to prevent the panic.
|
||||
fn write_text<T: Into<String>>(&mut self, text: T) -> Result<()>;
|
||||
/// Read the content in the clipboard as plain text.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the app is not running yet, usually when called on the `tauri::Builder#setup` closure.
|
||||
/// You can spawn a task to use the API using the `tauri::async_runtime` to prevent the panic.
|
||||
/// - Panics if the event loop is not running yet, usually when called on the `tauri::Builder#setup` closure.
|
||||
/// - Panics when called on the main thread, usually on the `tauri::App#run`closure.
|
||||
///
|
||||
/// You can spawn a task to use the API using `tauri::async_runtime::spawn` or [`std::thread::spawn`] to prevent the panic.
|
||||
fn read_text(&self) -> Result<Option<String>>;
|
||||
}
|
||||
|
||||
|
@ -313,8 +313,10 @@ impl<R: Runtime> Window<R> {
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the app is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// You can spawn a task to use the API using the [`async_runtime`](crate::async_runtime) to prevent the panic.
|
||||
/// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure.
|
||||
///
|
||||
/// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic.
|
||||
pub fn scale_factor(&self) -> crate::Result<f64> {
|
||||
self.window.dispatcher.scale_factor().map_err(Into::into)
|
||||
}
|
||||
@ -323,8 +325,10 @@ impl<R: Runtime> Window<R> {
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the app is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// You can spawn a task to use the API using the [`async_runtime`](crate::async_runtime) to prevent the panic.
|
||||
/// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure.
|
||||
///
|
||||
/// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic.
|
||||
pub fn inner_position(&self) -> crate::Result<PhysicalPosition<i32>> {
|
||||
self.window.dispatcher.inner_position().map_err(Into::into)
|
||||
}
|
||||
@ -333,8 +337,10 @@ impl<R: Runtime> Window<R> {
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the app is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// You can spawn a task to use the API using the [`async_runtime`](crate::async_runtime) to prevent the panic.
|
||||
/// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure.
|
||||
///
|
||||
/// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic.
|
||||
pub fn outer_position(&self) -> crate::Result<PhysicalPosition<i32>> {
|
||||
self.window.dispatcher.outer_position().map_err(Into::into)
|
||||
}
|
||||
@ -345,8 +351,10 @@ impl<R: Runtime> Window<R> {
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the app is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// You can spawn a task to use the API using the [`async_runtime`](crate::async_runtime) to prevent the panic.
|
||||
/// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure.
|
||||
///
|
||||
/// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic.
|
||||
pub fn inner_size(&self) -> crate::Result<PhysicalSize<u32>> {
|
||||
self.window.dispatcher.inner_size().map_err(Into::into)
|
||||
}
|
||||
@ -357,8 +365,10 @@ impl<R: Runtime> Window<R> {
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the app is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// You can spawn a task to use the API using the [`async_runtime`](crate::async_runtime) to prevent the panic.
|
||||
/// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure.
|
||||
///
|
||||
/// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic.
|
||||
pub fn outer_size(&self) -> crate::Result<PhysicalSize<u32>> {
|
||||
self.window.dispatcher.outer_size().map_err(Into::into)
|
||||
}
|
||||
@ -367,8 +377,10 @@ impl<R: Runtime> Window<R> {
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the app is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// You can spawn a task to use the API using the [`async_runtime`](crate::async_runtime) to prevent the panic.
|
||||
/// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure.
|
||||
///
|
||||
/// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic.
|
||||
pub fn is_fullscreen(&self) -> crate::Result<bool> {
|
||||
self.window.dispatcher.is_fullscreen().map_err(Into::into)
|
||||
}
|
||||
@ -377,8 +389,10 @@ impl<R: Runtime> Window<R> {
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the app is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// You can spawn a task to use the API using the [`async_runtime`](crate::async_runtime) to prevent the panic.
|
||||
/// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure.
|
||||
///
|
||||
/// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic.
|
||||
pub fn is_maximized(&self) -> crate::Result<bool> {
|
||||
self.window.dispatcher.is_maximized().map_err(Into::into)
|
||||
}
|
||||
@ -387,8 +401,10 @@ impl<R: Runtime> Window<R> {
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the app is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// You can spawn a task to use the API using the [`async_runtime`](crate::async_runtime) to prevent the panic.
|
||||
/// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure.
|
||||
///
|
||||
/// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic.
|
||||
pub fn is_decorated(&self) -> crate::Result<bool> {
|
||||
self.window.dispatcher.is_decorated().map_err(Into::into)
|
||||
}
|
||||
@ -397,8 +413,10 @@ impl<R: Runtime> Window<R> {
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the app is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// You can spawn a task to use the API using the [`async_runtime`](crate::async_runtime) to prevent the panic.
|
||||
/// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure.
|
||||
///
|
||||
/// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic.
|
||||
pub fn is_resizable(&self) -> crate::Result<bool> {
|
||||
self.window.dispatcher.is_resizable().map_err(Into::into)
|
||||
}
|
||||
@ -407,8 +425,10 @@ impl<R: Runtime> Window<R> {
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the app is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// You can spawn a task to use the API using the [`async_runtime`](crate::async_runtime) to prevent the panic.
|
||||
/// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure.
|
||||
///
|
||||
/// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic.
|
||||
pub fn is_visible(&self) -> crate::Result<bool> {
|
||||
self.window.dispatcher.is_visible().map_err(Into::into)
|
||||
}
|
||||
@ -423,8 +443,10 @@ impl<R: Runtime> Window<R> {
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the app is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// You can spawn a task to use the API using the [`async_runtime`](crate::async_runtime) to prevent the panic.
|
||||
/// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure.
|
||||
///
|
||||
/// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic.
|
||||
pub fn current_monitor(&self) -> crate::Result<Option<Monitor>> {
|
||||
self
|
||||
.window
|
||||
@ -444,8 +466,10 @@ impl<R: Runtime> Window<R> {
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the app is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// You can spawn a task to use the API using the [`async_runtime`](crate::async_runtime) to prevent the panic.
|
||||
/// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure.
|
||||
///
|
||||
/// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic.
|
||||
pub fn primary_monitor(&self) -> crate::Result<Option<Monitor>> {
|
||||
self
|
||||
.window
|
||||
@ -463,8 +487,10 @@ impl<R: Runtime> Window<R> {
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the app is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// You can spawn a task to use the API using the [`async_runtime`](crate::async_runtime) to prevent the panic.
|
||||
/// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure.
|
||||
///
|
||||
/// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic.
|
||||
pub fn available_monitors(&self) -> crate::Result<Vec<Monitor>> {
|
||||
self
|
||||
.window
|
||||
@ -478,8 +504,10 @@ impl<R: Runtime> Window<R> {
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the app is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// You can spawn a task to use the API using the [`async_runtime`](crate::async_runtime) to prevent the panic.
|
||||
/// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure.
|
||||
///
|
||||
/// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic.
|
||||
#[cfg(target_os = "macos")]
|
||||
pub fn ns_window(&self) -> crate::Result<*mut std::ffi::c_void> {
|
||||
self.window.dispatcher.ns_window().map_err(Into::into)
|
||||
@ -488,8 +516,10 @@ impl<R: Runtime> Window<R> {
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the app is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// You can spawn a task to use the API using the [`async_runtime`](crate::async_runtime) to prevent the panic.
|
||||
/// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure.
|
||||
///
|
||||
/// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic.
|
||||
#[cfg(windows)]
|
||||
pub fn hwnd(&self) -> crate::Result<*mut std::ffi::c_void> {
|
||||
self
|
||||
|
@ -86,8 +86,10 @@ impl<R: Runtime> MenuHandle<R> {
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the app is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// You can spawn a task to use the API using the [`async_runtime`](crate::async_runtime) to prevent the panic.
|
||||
/// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure.
|
||||
///
|
||||
/// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic.
|
||||
pub fn is_visible(&self) -> crate::Result<bool> {
|
||||
self.dispatcher.is_menu_visible().map_err(Into::into)
|
||||
}
|
||||
@ -96,8 +98,10 @@ impl<R: Runtime> MenuHandle<R> {
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the app is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// You can spawn a task to use the API using the [`async_runtime`](crate::async_runtime) to prevent the panic.
|
||||
/// - Panics if the event loop is not running yet, usually when called on the [`setup`](crate::Builder#method.setup) closure.
|
||||
/// - Panics when called on the main thread, usually on the [`run`](crate::App#method.run) closure.
|
||||
///
|
||||
/// You can spawn a task to use the API using [`crate::async_runtime::spawn`] or [`std::thread::spawn`] to prevent the panic.
|
||||
pub fn toggle(&self) -> crate::Result<()> {
|
||||
if self.is_visible()? {
|
||||
self.hide()
|
||||
|
Loading…
Reference in New Issue
Block a user