mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-04-01 10:01:07 +02:00
refactor(core): add RunEvent::WindowEvent (#3793)
This commit is contained in:
committed by
GitHub
parent
d5c06f0240
commit
edad9f4f55
6
.changes/refactor-runtime-window-event.md
Normal file
6
.changes/refactor-runtime-window-event.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"tauri-runtime": minor
|
||||
"tauri-runtime-wry": minor
|
||||
---
|
||||
|
||||
**Breaking change:** Use the dedicated `WindowEvent` enum on `RunEvent`.
|
||||
5
.changes/refactor-window-event.md
Normal file
5
.changes/refactor-window-event.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"tauri": patch
|
||||
---
|
||||
|
||||
**Breaking change:** Removed `RunEvent::CloseRequested` and `RunEvent::WindowClosed` and added `RunEvent::WindowEvent`.
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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>,
|
||||
},
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user