From 8c6d1e8e6c852667bb223b5f4823948868c26d98 Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Tue, 22 Oct 2024 15:59:21 +0300 Subject: [PATCH] fix(runtime-wry): run `cursor_position` getter on main thread (#11401) * fix(runtime-wry): run `cursor_position` getter on main thread closes #10340 * clippy * clippy --------- Co-authored-by: Lucas Nogueira --- .changes/curosr-position-gtk.md | 6 ++++++ crates/tauri-cli/src/mobile/init.rs | 14 +++---------- crates/tauri-runtime-wry/src/lib.rs | 32 ++++++++++++++++++++--------- 3 files changed, 31 insertions(+), 21 deletions(-) create mode 100644 .changes/curosr-position-gtk.md diff --git a/.changes/curosr-position-gtk.md b/.changes/curosr-position-gtk.md new file mode 100644 index 000000000000..4bc87b6bb9c6 --- /dev/null +++ b/.changes/curosr-position-gtk.md @@ -0,0 +1,6 @@ +--- +"tauri": "patch:bug" +"tauri-runtime-wry": "patch:bug" +--- + +Fix `App/AppHandle/Window/Webview/WebviewWindow::cursor_position` getter method failing on Linux with `GDK may only be used from the main thread`. diff --git a/crates/tauri-cli/src/mobile/init.rs b/crates/tauri-cli/src/mobile/init.rs index 0539935e3d25..c24ddbe84408 100644 --- a/crates/tauri-cli/src/mobile/init.rs +++ b/crates/tauri-cli/src/mobile/init.rs @@ -198,17 +198,9 @@ fn get_str<'a>(helper: &'a Helper) -> &'a str { fn get_str_array(helper: &Helper, formatter: impl Fn(&str) -> String) -> Option> { helper.param(0).and_then(|v| { - v.value().as_array().and_then(|arr| { - arr - .iter() - .map(|val| { - val.as_str().map( - #[allow(clippy::redundant_closure)] - &formatter, - ) - }) - .collect() - }) + v.value() + .as_array() + .and_then(|arr| arr.iter().map(|val| val.as_str().map(&formatter)).collect()) }) } diff --git a/crates/tauri-runtime-wry/src/lib.rs b/crates/tauri-runtime-wry/src/lib.rs index 0f05dd8cc8f2..4dd17d494910 100644 --- a/crates/tauri-runtime-wry/src/lib.rs +++ b/crates/tauri-runtime-wry/src/lib.rs @@ -181,6 +181,13 @@ macro_rules! window_getter { }}; } +macro_rules! event_loop_window_getter { + ($self: ident, $message: expr) => {{ + let (tx, rx) = channel(); + getter!($self, rx, Message::EventLoopWindowTarget($message(tx))) + }}; +} + macro_rules! webview_getter { ($self: ident, $message: expr) => {{ let (tx, rx) = channel(); @@ -1268,6 +1275,10 @@ pub enum WebviewMessage { IsDevToolsOpen(Sender), } +pub enum EventLoopWindowTargetMessage { + CursorPosition(Sender>>), +} + pub type CreateWindowClosure = Box>) -> Result + Send>; @@ -1282,6 +1293,7 @@ pub enum Message { Application(ApplicationMessage), Window(WindowId, WindowMessage), Webview(WindowId, WebviewId, WebviewMessage), + EventLoopWindowTarget(EventLoopWindowTargetMessage), CreateWebview(WindowId, CreateWebviewClosure), CreateWindow(WindowId, CreateWindowClosure), CreateRawWindow( @@ -2325,11 +2337,7 @@ impl RuntimeHandle for WryHandle { } fn cursor_position(&self) -> Result> { - self - .context - .main_thread - .window_target - .cursor_position() + event_loop_window_getter!(self, EventLoopWindowTargetMessage::CursorPosition)? .map(PhysicalPositionWrapper) .map(Into::into) .map_err(|_| Error::FailedToGetCursorPosition) @@ -2616,11 +2624,7 @@ impl Runtime for Wry { } fn cursor_position(&self) -> Result> { - self - .context - .main_thread - .window_target - .cursor_position() + event_loop_window_getter!(self, EventLoopWindowTargetMessage::CursorPosition)? .map(PhysicalPositionWrapper) .map(Into::into) .map_err(|_| Error::FailedToGetCursorPosition) @@ -3452,6 +3456,14 @@ fn handle_user_message( } Message::UserEvent(_) => (), + Message::EventLoopWindowTarget(message) => match message { + EventLoopWindowTargetMessage::CursorPosition(sender) => { + let pos = event_loop + .cursor_position() + .map_err(|_| Error::FailedToSendMessage); + sender.send(pos).unwrap(); + } + }, } }