Эх сурвалжийг харах

refactor(core): add `RunEvent::WindowEvent` (#3793)

Lucas Fernandes Nogueira 3 жил өмнө
parent
commit
edad9f4f55

+ 6 - 0
.changes/refactor-runtime-window-event.md

@@ -0,0 +1,6 @@
+---
+"tauri-runtime": minor
+"tauri-runtime-wry": minor
+---
+
+**Breaking change:** Use the dedicated `WindowEvent` enum on `RunEvent`.

+ 5 - 0
.changes/refactor-window-event.md

@@ -0,0 +1,5 @@
+---
+"tauri": patch
+---
+
+**Breaking change:** Removed `RunEvent::CloseRequested` and `RunEvent::WindowClosed` and added `RunEvent::WindowEvent`.

+ 12 - 11
core/tauri-runtime-wry/src/lib.rs

@@ -2458,9 +2458,16 @@ fn handle_event_loop<T: UserEvent>(
 
       {
         let windows_lock = windows.lock().expect("poisoned webview collection");
-        if let Some(window_handle) = windows_lock.get(&window_id).map(|w| &w.inner) {
+        if let Some((label, window_handle)) =
+          windows_lock.get(&window_id).map(|w| (&w.label, &w.inner))
+        {
           if let Some(event) = WindowEventWrapper::parse(window_handle, &event).0 {
+            let label = label.clone();
             drop(windows_lock);
+            callback(RunEvent::WindowEvent {
+              label,
+              event: event.clone(),
+            });
             for handler in window_event_listeners
               .lock()
               .unwrap()
@@ -2519,7 +2526,6 @@ fn handle_event_loop<T: UserEvent>(
     Event::UserEvent(message) => match message {
       Message::Window(id, WindowMessage::Close) => {
         on_window_close(
-          callback,
           id,
           windows.lock().expect("poisoned webview collection"),
           menu_event_listeners.clone(),
@@ -2574,19 +2580,17 @@ fn on_close_requested<'a, T: UserEvent>(
       .values()
     {
       handler(&WindowEvent::CloseRequested {
-        label: label.clone(),
         signal_tx: tx.clone(),
       });
     }
-    callback(RunEvent::CloseRequested {
+    callback(RunEvent::WindowEvent {
       label,
-      signal_tx: tx,
+      event: WindowEvent::CloseRequested { signal_tx: tx },
     });
     if let Ok(true) = rx.try_recv() {
       None
     } else {
       on_window_close(
-        callback,
         window_id,
         windows.lock().expect("poisoned webview collection"),
         menu_event_listeners,
@@ -2597,17 +2601,14 @@ fn on_close_requested<'a, T: UserEvent>(
   }
 }
 
-fn on_window_close<'a, T: UserEvent>(
-  callback: &'a mut (dyn FnMut(RunEvent<T>) + 'static),
+fn on_window_close(
   window_id: WebviewId,
-  mut windows: MutexGuard<'a, HashMap<WebviewId, WindowWrapper>>,
+  mut windows: MutexGuard<'_, HashMap<WebviewId, WindowWrapper>>,
   menu_event_listeners: MenuEventListeners,
 ) -> Option<WindowWrapper> {
   #[allow(unused_mut)]
   let w = if let Some(mut webview) = windows.remove(&window_id) {
-    drop(windows);
     menu_event_listeners.lock().unwrap().remove(&window_id);
-    callback(RunEvent::WindowClose(webview.label.clone()));
     Some(webview)
   } else {
     None

+ 4 - 6
core/tauri-runtime/src/lib.rs

@@ -208,15 +208,13 @@ pub enum RunEvent<T: UserEvent> {
   ExitRequested {
     tx: Sender<ExitRequestedEventAction>,
   },
-  /// Window close was requested by the user.
-  CloseRequested {
+  /// An event associated with a window.
+  WindowEvent {
     /// The window label.
     label: String,
-    /// A signal sender. If a `true` value is emitted, the window won't be closed.
-    signal_tx: Sender<bool>,
+    /// The detailed event.
+    event: WindowEvent,
   },
-  /// Window closed.
-  WindowClose(String),
   /// Application ready.
   Ready,
   /// Sent if the event loop is being resumed.

+ 0 - 3
core/tauri-runtime/src/window.rs

@@ -28,7 +28,6 @@ pub mod dpi;
 
 /// An event from a window.
 #[derive(Debug, Clone)]
-#[non_exhaustive]
 pub enum WindowEvent {
   /// The size of the window has changed. Contains the client area's new dimensions.
   Resized(dpi::PhysicalSize<u32>),
@@ -36,8 +35,6 @@ pub enum WindowEvent {
   Moved(dpi::PhysicalPosition<i32>),
   /// The window has been requested to close.
   CloseRequested {
-    /// The window label.
-    label: String,
     /// A signal sender. If a `true` value is emitted, the window won't be closed.
     signal_tx: Sender<bool>,
   },

+ 77 - 12
core/tauri/src/app.rs

@@ -16,7 +16,7 @@ use crate::{
   runtime::{
     http::{Request as HttpRequest, Response as HttpResponse},
     webview::{WebviewAttributes, WindowBuilder as _},
-    window::{PendingWindow, WindowEvent},
+    window::{PendingWindow, WindowEvent as RuntimeWindowEvent},
     Dispatch, ExitRequestedEventAction, RunEvent as RuntimeRunEvent,
   },
   scope::FsScope,
@@ -32,6 +32,10 @@ use crate::{
 use crate::scope::ShellScope;
 
 use tauri_macros::default_runtime;
+use tauri_runtime::window::{
+  dpi::{PhysicalPosition, PhysicalSize},
+  FileDropEvent,
+};
 use tauri_utils::PackageInfo;
 
 use std::{
@@ -69,7 +73,7 @@ impl ExitRequestApi {
 }
 
 /// Api exposed on the `CloseRequested` event.
-#[derive(Debug)]
+#[derive(Debug, Clone)]
 pub struct CloseRequestApi(Sender<bool>);
 
 impl CloseRequestApi {
@@ -79,6 +83,66 @@ impl CloseRequestApi {
   }
 }
 
+/// An event from a window.
+#[derive(Debug, Clone)]
+#[non_exhaustive]
+pub enum WindowEvent {
+  /// The size of the window has changed. Contains the client area's new dimensions.
+  Resized(PhysicalSize<u32>),
+  /// The position of the window has changed. Contains the window's new position.
+  Moved(PhysicalPosition<i32>),
+  /// The window has been requested to close.
+  #[non_exhaustive]
+  CloseRequested {
+    /// An API modify the behavior of the close requested event.
+    api: CloseRequestApi,
+  },
+  /// The window has been destroyed.
+  Destroyed,
+  /// The window gained or lost focus.
+  ///
+  /// The parameter is true if the window has gained focus, and false if it has lost focus.
+  Focused(bool),
+  /// The window's scale factor has changed.
+  ///
+  /// The following user actions can cause DPI changes:
+  ///
+  /// - Changing the display's resolution.
+  /// - Changing the display's scale factor (e.g. in Control Panel on Windows).
+  /// - Moving the window to a display with a different scale factor.
+  #[non_exhaustive]
+  ScaleFactorChanged {
+    /// The new scale factor.
+    scale_factor: f64,
+    /// The window inner size.
+    new_inner_size: PhysicalSize<u32>,
+  },
+  /// An event associated with the file drop action.
+  FileDrop(FileDropEvent),
+}
+
+impl From<RuntimeWindowEvent> for WindowEvent {
+  fn from(event: RuntimeWindowEvent) -> Self {
+    match event {
+      RuntimeWindowEvent::Resized(size) => Self::Resized(size),
+      RuntimeWindowEvent::Moved(position) => Self::Moved(position),
+      RuntimeWindowEvent::CloseRequested { signal_tx } => Self::CloseRequested {
+        api: CloseRequestApi(signal_tx),
+      },
+      RuntimeWindowEvent::Destroyed => Self::Destroyed,
+      RuntimeWindowEvent::Focused(flag) => Self::Focused(flag),
+      RuntimeWindowEvent::ScaleFactorChanged {
+        scale_factor,
+        new_inner_size,
+      } => Self::ScaleFactorChanged {
+        scale_factor,
+        new_inner_size,
+      },
+      RuntimeWindowEvent::FileDrop(event) => Self::FileDrop(event),
+    }
+  }
+}
+
 /// An application event, triggered from the event loop.
 #[derive(Debug)]
 #[non_exhaustive]
@@ -91,16 +155,14 @@ pub enum RunEvent {
     /// Event API
     api: ExitRequestApi,
   },
-  /// Window close was requested by the user.
+  /// An event associated with a window.
   #[non_exhaustive]
-  CloseRequested {
+  WindowEvent {
     /// The window label.
     label: String,
-    /// Event API.
-    api: CloseRequestApi,
+    /// The detailed event.
+    event: WindowEvent,
   },
-  /// Window closed.
-  WindowClosed(String),
   /// Application ready.
   Ready,
   /// Sent if the event loop is being resumed.
@@ -1428,7 +1490,11 @@ fn on_event_loop_event<R: Runtime, F: FnMut(&AppHandle<R>, RunEvent) + 'static>(
   manager: &WindowManager<R>,
   callback: Option<&mut F>,
 ) {
-  if let RuntimeRunEvent::WindowClose(label) = &event {
+  if let RuntimeRunEvent::WindowEvent {
+    label,
+    event: RuntimeWindowEvent::Destroyed,
+  } = &event
+  {
     manager.on_window_close(label);
   }
 
@@ -1437,11 +1503,10 @@ fn on_event_loop_event<R: Runtime, F: FnMut(&AppHandle<R>, RunEvent) + 'static>(
     RuntimeRunEvent::ExitRequested { tx } => RunEvent::ExitRequested {
       api: ExitRequestApi(tx),
     },
-    RuntimeRunEvent::CloseRequested { label, signal_tx } => RunEvent::CloseRequested {
+    RuntimeRunEvent::WindowEvent { label, event } => RunEvent::WindowEvent {
       label,
-      api: CloseRequestApi(signal_tx),
+      event: event.into(),
     },
-    RuntimeRunEvent::WindowClose(label) => RunEvent::WindowClosed(label),
     RuntimeRunEvent::Ready => RunEvent::Ready,
     RuntimeRunEvent::Resumed => RunEvent::Resumed,
     RuntimeRunEvent::MainEventsCleared => RunEvent::MainEventsCleared,

+ 2 - 2
core/tauri/src/lib.rs

@@ -203,7 +203,7 @@ pub use {
 pub use {
   self::app::{
     App, AppHandle, AssetResolver, Builder, CloseRequestApi, GlobalWindowEvent, PathResolver,
-    RunEvent,
+    RunEvent, WindowEvent,
   },
   self::hooks::{
     Invoke, InvokeError, InvokeHandler, InvokeMessage, InvokePayload, InvokeResolver,
@@ -214,7 +214,7 @@ pub use {
     webview::{WebviewAttributes, WindowBuilder},
     window::{
       dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Pixel, Position, Size},
-      FileDropEvent, WindowEvent,
+      FileDropEvent,
     },
     ClipboardManager, GlobalShortcutManager, RunIteration, TrayIcon, UserAttentionType,
   },

+ 2 - 6
core/tauri/src/manager.rs

@@ -1147,7 +1147,7 @@ impl<R: Runtime> WindowManager<R> {
       for handler in window_event_listeners.iter() {
         handler(GlobalWindowEvent {
           window: window_.clone(),
-          event: event.clone(),
+          event: event.clone().into(),
         });
       }
     });
@@ -1274,10 +1274,7 @@ fn on_window_event<R: Runtime>(
   match event {
     WindowEvent::Resized(size) => window.emit(WINDOW_RESIZED_EVENT, size)?,
     WindowEvent::Moved(position) => window.emit(WINDOW_MOVED_EVENT, position)?,
-    WindowEvent::CloseRequested {
-      label: _,
-      signal_tx,
-    } => {
+    WindowEvent::CloseRequested { signal_tx } => {
       if window.has_js_listener(Some(window.label().into()), WINDOW_CLOSE_REQUESTED_EVENT) {
         signal_tx.send(true).unwrap();
       }
@@ -1328,7 +1325,6 @@ fn on_window_event<R: Runtime>(
       FileDropEvent::Cancelled => window.emit("tauri://file-drop-cancelled", ())?,
       _ => unimplemented!(),
     },
-    _ => unimplemented!(),
   }
   Ok(())
 }

+ 7 - 2
examples/api/src-tauri/src/main.rs

@@ -17,7 +17,8 @@ use std::sync::atomic::{AtomicBool, Ordering};
 use serde::{Deserialize, Serialize};
 use tauri::{
   api::dialog::ask, http::ResponseBuilder, window::WindowBuilder, CustomMenuItem,
-  GlobalShortcutManager, Manager, RunEvent, SystemTray, SystemTrayEvent, SystemTrayMenu, WindowUrl,
+  GlobalShortcutManager, Manager, RunEvent, SystemTray, SystemTrayEvent, SystemTrayMenu,
+  WindowEvent, WindowUrl,
 };
 
 #[derive(Clone, Serialize)]
@@ -227,7 +228,11 @@ fn main() {
     }
 
     // Triggered when a window is trying to close
-    RunEvent::CloseRequested { label, api, .. } => {
+    RunEvent::WindowEvent {
+      label,
+      event: WindowEvent::CloseRequested { api, .. },
+      ..
+    } => {
       let app_handle = app_handle.clone();
       let window = app_handle.get_window(&label).unwrap();
       // use the exposed close api, and prevent the event loop to close