diff --git a/.changes/android-target-sdk-37.md b/.changes/android-target-sdk-37.md new file mode 100644 index 000000000000..beac94f8411a --- /dev/null +++ b/.changes/android-target-sdk-37.md @@ -0,0 +1,6 @@ +--- +"tauri-cli": patch:enhance +"@tauri-apps/cli": patch:enhance +--- + +Update template to use `targetSdk = 37` diff --git a/.changes/fix-monitor-queries-off-thread.md b/.changes/fix-monitor-queries-off-thread.md new file mode 100644 index 000000000000..30f4f4811afa --- /dev/null +++ b/.changes/fix-monitor-queries-off-thread.md @@ -0,0 +1,6 @@ +--- +'tauri': 'patch:bug' +'tauri-runtime-wry': 'patch:bug' +--- + +Query monitor information (`primary_monitor`, `monitor_from_point`, `available_monitors`) on the main thread from the app-level runtime handle instead of touching the event loop's window target directly. diff --git a/.changes/runtime-handle-monitor-fns.md b/.changes/runtime-handle-monitor-fns.md new file mode 100644 index 000000000000..36e6ccfa4666 --- /dev/null +++ b/.changes/runtime-handle-monitor-fns.md @@ -0,0 +1,6 @@ +--- +'tauri-runtime': 'minor:breaking' +'tauri-runtime-wry': 'minor:breaking' +--- + +Changed `RuntimeHandle::primary_monitor`, `RuntimeHandle::monitor_from_point`, `RuntimeHandle::available_monitors` to return `Result`s diff --git a/crates/tauri-cli/templates/mobile/android/app/build.gradle.kts b/crates/tauri-cli/templates/mobile/android/app/build.gradle.kts index b4864e2d321c..e871e162a66e 100644 --- a/crates/tauri-cli/templates/mobile/android/app/build.gradle.kts +++ b/crates/tauri-cli/templates/mobile/android/app/build.gradle.kts @@ -17,13 +17,13 @@ val tauriProperties = Properties().apply { } android { - compileSdk = 36 + compileSdk = 37 namespace = "{{app.identifier}}" defaultConfig { manifestPlaceholders["usesCleartextTraffic"] = "false" applicationId = "{{app.identifier}}" minSdk = {{android.min-sdk-version}} - targetSdk = 36 + targetSdk = 37 versionCode = tauriProperties.getProperty("tauri.android.versionCode", "1").toInt() versionName = tauriProperties.getProperty("tauri.android.versionName", "1.0") } diff --git a/crates/tauri-runtime-wry/src/lib.rs b/crates/tauri-runtime-wry/src/lib.rs index f92fd48e28e1..d14f6570ded6 100644 --- a/crates/tauri-runtime-wry/src/lib.rs +++ b/crates/tauri-runtime-wry/src/lib.rs @@ -1478,6 +1478,9 @@ pub enum WebviewMessage { pub enum EventLoopWindowTargetMessage { CursorPosition(Sender>>), + PrimaryMonitor(Sender>), + MonitorFromPoint(Sender>, (f64, f64)), + AvailableMonitors(Sender>), SetTheme(Option), SetDeviceEventFilter(DeviceEventFilter), } @@ -2735,32 +2738,31 @@ impl RuntimeHandle for WryHandle { self.context.main_thread.window_target.display_handle() } - fn primary_monitor(&self) -> Option { - self - .context - .main_thread - .window_target - .primary_monitor() - .map(|m| MonitorHandleWrapper(m).into()) + fn primary_monitor(&self) -> Result> { + Ok( + event_loop_window_getter!(self, EventLoopWindowTargetMessage::PrimaryMonitor)? + .map(|m| MonitorHandleWrapper(m).into()), + ) } - fn monitor_from_point(&self, x: f64, y: f64) -> Option { - self - .context - .main_thread - .window_target - .monitor_from_point(x, y) - .map(|m| MonitorHandleWrapper(m).into()) + fn monitor_from_point(&self, x: f64, y: f64) -> Result> { + let (tx, rx) = channel(); + send_user_message( + &self.context, + Message::EventLoopWindowTarget(EventLoopWindowTargetMessage::MonitorFromPoint(tx, (x, y))), + )?; + Ok(rx.recv().unwrap().map(|m| MonitorHandleWrapper(m).into())) } - fn available_monitors(&self) -> Vec { - self - .context - .main_thread - .window_target - .available_monitors() - .map(|m| MonitorHandleWrapper(m).into()) - .collect() + fn available_monitors(&self) -> Result> { + event_loop_window_getter!(self, EventLoopWindowTargetMessage::AvailableMonitors).map( + |monitors| { + monitors + .into_iter() + .map(|m| MonitorHandleWrapper(m).into()) + .collect() + }, + ) } fn cursor_position(&self) -> Result> { @@ -4084,6 +4086,17 @@ fn handle_user_message( .map_err(|_| Error::FailedToSendMessage); sender.send(pos).unwrap(); } + EventLoopWindowTargetMessage::PrimaryMonitor(sender) => { + sender.send(event_loop.primary_monitor()).unwrap(); + } + EventLoopWindowTargetMessage::MonitorFromPoint(sender, (x, y)) => { + sender.send(event_loop.monitor_from_point(x, y)).unwrap(); + } + EventLoopWindowTargetMessage::AvailableMonitors(sender) => { + sender + .send(event_loop.available_monitors().collect()) + .unwrap(); + } EventLoopWindowTargetMessage::SetTheme(theme) => { event_loop.set_theme(to_tao_theme(theme)); } diff --git a/crates/tauri-runtime/src/lib.rs b/crates/tauri-runtime/src/lib.rs index af811c20e7f0..3465c514b159 100644 --- a/crates/tauri-runtime/src/lib.rs +++ b/crates/tauri-runtime/src/lib.rs @@ -315,13 +315,13 @@ pub trait RuntimeHandle: Debug + Clone + Send + Sync + Sized + 'st /// Returns the primary monitor of the system. /// /// Returns None if it can't identify any monitor as a primary one. - fn primary_monitor(&self) -> Option; + fn primary_monitor(&self) -> Result>; /// Returns the monitor that contains the given point. - fn monitor_from_point(&self, x: f64, y: f64) -> Option; + fn monitor_from_point(&self, x: f64, y: f64) -> Result>; /// Returns the list of all the monitors available on the system. - fn available_monitors(&self) -> Vec; + fn available_monitors(&self) -> Result>; /// Get the cursor position relative to the top-left hand corner of the desktop. fn cursor_position(&self) -> Result>; diff --git a/crates/tauri/src/app.rs b/crates/tauri/src/app.rs index 244ca3234be6..ea93715344c0 100644 --- a/crates/tauri/src/app.rs +++ b/crates/tauri/src/app.rs @@ -870,7 +870,7 @@ macro_rules! shared_app_impl { pub fn primary_monitor(&self) -> crate::Result> { Ok(match self.runtime() { RuntimeOrDispatch::Runtime(h) => h.primary_monitor().map(Into::into), - RuntimeOrDispatch::RuntimeHandle(h) => h.primary_monitor().map(Into::into), + RuntimeOrDispatch::RuntimeHandle(h) => h.primary_monitor()?.map(Into::into), _ => unreachable!(), }) } @@ -879,7 +879,7 @@ macro_rules! shared_app_impl { pub fn monitor_from_point(&self, x: f64, y: f64) -> crate::Result> { Ok(match self.runtime() { RuntimeOrDispatch::Runtime(h) => h.monitor_from_point(x, y).map(Into::into), - RuntimeOrDispatch::RuntimeHandle(h) => h.monitor_from_point(x, y).map(Into::into), + RuntimeOrDispatch::RuntimeHandle(h) => h.monitor_from_point(x, y)?.map(Into::into), _ => unreachable!(), }) } @@ -890,9 +890,11 @@ macro_rules! shared_app_impl { RuntimeOrDispatch::Runtime(h) => { h.available_monitors().into_iter().map(Into::into).collect() } - RuntimeOrDispatch::RuntimeHandle(h) => { - h.available_monitors().into_iter().map(Into::into).collect() - } + RuntimeOrDispatch::RuntimeHandle(h) => h + .available_monitors()? + .into_iter() + .map(Into::into) + .collect(), _ => unreachable!(), }) } diff --git a/crates/tauri/src/test/mock_runtime.rs b/crates/tauri/src/test/mock_runtime.rs index a1f4c88745c9..0aeeb54799d8 100644 --- a/crates/tauri/src/test/mock_runtime.rs +++ b/crates/tauri/src/test/mock_runtime.rs @@ -249,15 +249,15 @@ impl RuntimeHandle for MockRuntimeHandle { unimplemented!(); } - fn primary_monitor(&self) -> Option { + fn primary_monitor(&self) -> Result> { unimplemented!() } - fn monitor_from_point(&self, x: f64, y: f64) -> Option { + fn monitor_from_point(&self, x: f64, y: f64) -> Result> { unimplemented!() } - fn available_monitors(&self) -> Vec { + fn available_monitors(&self) -> Result> { unimplemented!() }