Răsfoiți Sursa

feat: adds monitor_from_point method (#9770)

Siddharth 1 an în urmă
părinte
comite
ec0e092ecd

+ 5 - 0
.changes/monitor-from-point-js.md

@@ -0,0 +1,5 @@
+---
+'@tauri-apps/api': 'patch:feat'
+---
+
+Add `monitorFromPoint` function in `window` module to get the monitor from a given point.

+ 5 - 0
.changes/monitor-from-point.md

@@ -0,0 +1,5 @@
+---
+'tauri': 'patch:feat'
+---
+
+Add `App/AppHandle/Window/Webview/WebviewWindow::monitor_from_point(x, y)` getter to get the monitor from a given point.

+ 37 - 0
core/tauri-runtime-wry/src/lib.rs

@@ -1092,6 +1092,7 @@ pub enum WindowMessage {
   Title(Sender<String>),
   CurrentMonitor(Sender<Option<MonitorHandle>>),
   PrimaryMonitor(Sender<Option<MonitorHandle>>),
+  MonitorFromPoint(Sender<Option<MonitorHandle>>, (f64, f64)),
   AvailableMonitors(Sender<Vec<MonitorHandle>>),
   #[cfg(any(
     target_os = "linux",
@@ -1578,6 +1579,21 @@ impl<T: UserEvent> WindowDispatch<T> for WryWindowDispatcher<T> {
     Ok(window_getter!(self, WindowMessage::PrimaryMonitor)?.map(|m| MonitorHandleWrapper(m).into()))
   }
 
+  fn monitor_from_point(&self, x: f64, y: f64) -> Result<Option<Monitor>> {
+    let (tx, rx) = channel();
+
+    let _ = send_user_message(
+      &self.context,
+      Message::Window(self.window_id, WindowMessage::MonitorFromPoint(tx, (x, y))),
+    );
+
+    Ok(
+      rx.recv()
+        .map_err(|_| crate::Error::FailedToReceiveMessage)?
+        .map(|m| MonitorHandleWrapper(m).into()),
+    )
+  }
+
   fn available_monitors(&self) -> Result<Vec<Monitor>> {
     Ok(
       window_getter!(self, WindowMessage::AvailableMonitors)?
@@ -2149,6 +2165,15 @@ impl<T: UserEvent> RuntimeHandle<T> for WryHandle<T> {
       .map(|m| MonitorHandleWrapper(m).into())
   }
 
+  fn monitor_from_point(&self, x: f64, y: f64) -> Option<Monitor> {
+    self
+      .context
+      .main_thread
+      .window_target
+      .monitor_from_point(x, y)
+      .map(|m| MonitorHandleWrapper(m).into())
+  }
+
   fn available_monitors(&self) -> Vec<Monitor> {
     self
       .context
@@ -2407,6 +2432,15 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
       .map(|m| MonitorHandleWrapper(m).into())
   }
 
+  fn monitor_from_point(&self, x: f64, y: f64) -> Option<Monitor> {
+    self
+      .context
+      .main_thread
+      .window_target
+      .monitor_from_point(x, y)
+      .map(|m| MonitorHandleWrapper(m).into())
+  }
+
   fn available_monitors(&self) -> Vec<Monitor> {
     self
       .context
@@ -2643,6 +2677,9 @@ fn handle_user_message<T: UserEvent>(
           WindowMessage::Title(tx) => tx.send(window.title()).unwrap(),
           WindowMessage::CurrentMonitor(tx) => tx.send(window.current_monitor()).unwrap(),
           WindowMessage::PrimaryMonitor(tx) => tx.send(window.primary_monitor()).unwrap(),
+          WindowMessage::MonitorFromPoint(tx, (x, y)) => {
+            tx.send(window.monitor_from_point(x, y)).unwrap()
+          }
           WindowMessage::AvailableMonitors(tx) => {
             tx.send(window.available_monitors().collect()).unwrap()
           }

+ 5 - 0
core/tauri-runtime/src/lib.rs

@@ -300,6 +300,7 @@ pub trait RuntimeHandle<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'st
   fn display_handle(&self) -> std::result::Result<DisplayHandle, raw_window_handle::HandleError>;
 
   fn primary_monitor(&self) -> Option<Monitor>;
+  fn monitor_from_point(&self, x: f64, y: f64) -> Option<Monitor>;
   fn available_monitors(&self) -> Vec<Monitor>;
 
   fn cursor_position(&self) -> Result<PhysicalPosition<f64>>;
@@ -382,6 +383,7 @@ pub trait Runtime<T: UserEvent>: Debug + Sized + 'static {
   ) -> Result<DetachedWebview<T, Self>>;
 
   fn primary_monitor(&self) -> Option<Monitor>;
+  fn monitor_from_point(&self, x: f64, y: f64) -> Option<Monitor>;
   fn available_monitors(&self) -> Vec<Monitor>;
 
   fn cursor_position(&self) -> Result<PhysicalPosition<f64>>;
@@ -587,6 +589,9 @@ pub trait WindowDispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 's
   /// Returns None if it can't identify any monitor as a primary one.
   fn primary_monitor(&self) -> Result<Option<Monitor>>;
 
+  /// Returns the monitor that contains the given point.
+  fn monitor_from_point(&self, x: f64, y: f64) -> Result<Option<Monitor>>;
+
   /// Returns the list of all the monitors available on the system.
   fn available_monitors(&self) -> Result<Vec<Monitor>>;
 

+ 1 - 0
core/tauri/build.rs

@@ -63,6 +63,7 @@ const PLUGINS: &[(&str, &[(&str, bool)])] = &[
       ("title", true),
       ("current_monitor", true),
       ("primary_monitor", true),
+      ("monitor_from_point", true),
       ("available_monitors", true),
       ("cursor_position", true),
       ("theme", true),

+ 2 - 0
core/tauri/permissions/window/autogenerated/reference.md

@@ -46,6 +46,8 @@
 |`deny-maximize`|Denies the maximize command without any pre-configured scope.|
 |`allow-minimize`|Enables the minimize command without any pre-configured scope.|
 |`deny-minimize`|Denies the minimize command without any pre-configured scope.|
+|`allow-monitor-from-point`|Enables the monitor_from_point command without any pre-configured scope.|
+|`deny-monitor-from-point`|Denies the monitor_from_point command without any pre-configured scope.|
 |`allow-outer-position`|Enables the outer_position command without any pre-configured scope.|
 |`deny-outer-position`|Denies the outer_position command without any pre-configured scope.|
 |`allow-outer-size`|Enables the outer_size command without any pre-configured scope.|

Fișier diff suprimat deoarece este prea mare
+ 0 - 0
core/tauri/scripts/bundle.global.js


+ 9 - 0
core/tauri/src/app.rs

@@ -592,6 +592,15 @@ macro_rules! shared_app_impl {
         })
       }
 
+      /// Returns the monitor that contains the given point.
+      pub fn monitor_from_point(&self, x: f64, y: f64) -> crate::Result<Option<Monitor>> {
+        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),
+          _ => unreachable!(),
+        })
+      }
+
       /// Returns the list of all the monitors available on the system.
       pub fn available_monitors(&self) -> crate::Result<Vec<Monitor>> {
         Ok(match self.runtime() {

+ 12 - 0
core/tauri/src/test/mock_runtime.rs

@@ -235,6 +235,10 @@ impl<T: UserEvent> RuntimeHandle<T> for MockRuntimeHandle {
     unimplemented!()
   }
 
+  fn monitor_from_point(&self, x: f64, y: f64) -> Option<Monitor> {
+    unimplemented!()
+  }
+
   fn available_monitors(&self) -> Vec<Monitor> {
     unimplemented!()
   }
@@ -650,6 +654,10 @@ impl<T: UserEvent> WindowDispatch<T> for MockWindowDispatcher {
     Ok(None)
   }
 
+  fn monitor_from_point(&self, x: f64, y: f64) -> Result<Option<Monitor>> {
+    Ok(None)
+  }
+
   fn available_monitors(&self) -> Result<Vec<Monitor>> {
     Ok(Vec::new())
   }
@@ -1054,6 +1062,10 @@ impl<T: UserEvent> Runtime<T> for MockRuntime {
     unimplemented!()
   }
 
+  fn monitor_from_point(&self, x: f64, y: f64) -> Option<Monitor> {
+    unimplemented!()
+  }
+
   fn available_monitors(&self) -> Vec<Monitor> {
     unimplemented!()
   }

+ 5 - 0
core/tauri/src/webview/webview_window.rs

@@ -1160,6 +1160,11 @@ impl<R: Runtime> WebviewWindow<R> {
     self.webview.window().primary_monitor()
   }
 
+  /// Returns the monitor that contains the given point.
+  pub fn monitor_from_point(&self, x: f64, y: f64) -> crate::Result<Option<Monitor>> {
+    self.webview.window().monitor_from_point(x, y)
+  }
+
   /// Returns the list of all the monitors available on the system.
   pub fn available_monitors(&self) -> crate::Result<Vec<Monitor>> {
     self.webview.window().available_monitors()

+ 10 - 0
core/tauri/src/window/mod.rs

@@ -1437,6 +1437,16 @@ impl<R: Runtime> Window<R> {
       .map_err(Into::into)
   }
 
+  /// Returns the monitor that contains the given point.
+  pub fn monitor_from_point(&self, x: f64, y: f64) -> crate::Result<Option<Monitor>> {
+    self
+      .window
+      .dispatcher
+      .monitor_from_point(x, y)
+      .map(|m| m.map(Into::into))
+      .map_err(Into::into)
+  }
+
   /// Returns the primary monitor of the system.
   ///
   /// Returns None if it can't identify any monitor as a primary one.

+ 12 - 0
core/tauri/src/window/plugin.rs

@@ -172,6 +172,17 @@ mod desktop_commands {
     }
     Ok(())
   }
+
+  #[command(root = "crate")]
+  pub async fn monitor_from_point<R: Runtime>(
+    window: Window<R>,
+    label: Option<String>,
+    x: f64,
+    y: f64,
+  ) -> crate::Result<Option<Monitor>> {
+    let window = get_window(window, label)?;
+    window.monitor_from_point(x, y)
+  }
 }
 
 /// Initializes the plugin.
@@ -222,6 +233,7 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
             desktop_commands::title,
             desktop_commands::current_monitor,
             desktop_commands::primary_monitor,
+            desktop_commands::monitor_from_point,
             desktop_commands::available_monitors,
             desktop_commands::cursor_position,
             desktop_commands::theme,

+ 18 - 0
tooling/api/src/window.ts

@@ -2240,6 +2240,23 @@ async function primaryMonitor(): Promise<Monitor | null> {
   )
 }
 
+/**
+ * Returns the monitor that contains the given point. Returns `null` if can't find any.
+ * @example
+ * ```typescript
+ * import { monitorFromPoint } from '@tauri-apps/api/window';
+ * const monitor = monitorFromPoint();
+ * ```
+ *
+ * @since 1.0.0
+ */
+async function monitorFromPoint(x: number, y: number): Promise<Monitor | null> {
+  return invoke<Monitor | null>('plugin:window|monitor_from_point', {
+    x,
+    y
+  }).then(mapMonitor)
+}
+
 /**
  * Returns the list of all the monitors available on the system.
  * @example
@@ -2285,6 +2302,7 @@ export {
   Effect,
   EffectState,
   currentMonitor,
+  monitorFromPoint,
   primaryMonitor,
   availableMonitors,
   cursorPosition

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff