-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
feat: add Builder::on_device_event
#13396
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
Package Changes Through 3292bbeThere are 8 changes which include tauri-bundler with patch, tauri with minor, tauri-runtime with minor, tauri-runtime-wry with minor, @tauri-apps/api with minor, tauri-cli with patch, @tauri-apps/cli with patch, tauri-utils with minor Planned Package VersionsThe following package releases are the planned based on the context of changes in this pull request.
Add another change file through the GitHub UI by following this link. Read about change files or the docs at github.com/jbolda/covector |
Why hasn't this PR been merged? |
no idea guess it was forgotten about. its just waiting for a review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we have the RunEvent enum that should be used to dispatch this sort of event (instead of creating dedicated functions)
something like this:
diff --git a/.changes/feat-device-events.md b/.changes/feat-device-events.md
index 13852dfe3..b2b9567ba 100644
--- a/.changes/feat-device-events.md
+++ b/.changes/feat-device-events.md
@@ -1,9 +1,7 @@
---
+"tauri": "minor:feat"
"tauri-runtime": "minor:feat"
"tauri-runtime-wry": "minor:feat"
-"tauri": "minor:feat"
---
-Adds a callback method to App builder that is called with device events and Apphandle.
-Update Runtime Trait to add a device event callback method
-Update wry and mock runtime with this method
+Added `RunEvent::DeviceEvent`.
diff --git a/crates/tauri-runtime-wry/src/lib.rs b/crates/tauri-runtime-wry/src/lib.rs
index efb218f1a..0dd7e3edf 100644
--- a/crates/tauri-runtime-wry/src/lib.rs
+++ b/crates/tauri-runtime-wry/src/lib.rs
@@ -21,7 +21,7 @@ use raw_window_handle::{DisplayHandle, HasDisplayHandle, HasWindowHandle};
#[cfg(windows)]
use tauri_runtime::webview::ScrollBarStyle;
use tauri_runtime::{
- device_events::DeviceEventFilter,
+ device_events::{DeviceEventFilter, DeviceId},
dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Position, Size},
monitor::Monitor,
webview::{DetachedWebview, DownloadEvent, PendingWebview, WebviewIpcHandler},
@@ -70,16 +70,19 @@ use tauri_utils::{
Theme,
};
use url::Url;
+
#[cfg(windows)]
-use webview2_com::FocusChangedEventHandler;
+use webview2_com::{ContainsFullScreenElementChangedEventHandler, FocusChangedEventHandler};
#[cfg(windows)]
use windows::Win32::Foundation::HWND;
+#[cfg(windows)]
+use wry::ScrollBarStyle as WryScrollBarStyle;
#[cfg(target_os = "ios")]
use wry::WebViewBuilderExtIos;
+#[cfg(target_os = "macos")]
+use wry::WebViewBuilderExtMacos;
#[cfg(windows)]
use wry::WebViewBuilderExtWindows;
-#[cfg(windows)]
-use wry::ScrollBarStyle as WryScrollBarStyle;
use wry::{
DragDropEvent as WryDragDropEvent, ProxyConfig, ProxyEndpoint, WebContext as WryWebContext,
WebView, WebViewBuilder,
@@ -137,9 +140,9 @@ use std::{
pub type WebviewId = u32;
type IpcHandler = dyn Fn(Request<String>) + 'static;
+mod device_event;
#[cfg(not(debug_assertions))]
mod dialog;
-mod map_device_event;
mod monitor;
#[cfg(any(
windows,
@@ -246,22 +249,6 @@ pub(crate) fn send_user_message<T: UserEvent>(
.map_err(|_| Error::FailedToSendMessage)
}
}
-#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-/// A unique identifier for a device.
-/// There is no meaning to the value of this identifier, it is just a unique identifier.
-pub struct DeviceId(tao::event::DeviceId);
-
-impl tauri_runtime::device_events::DeviceId for DeviceId {
- unsafe fn dummy() -> Self {
- DeviceId(unsafe { tao::event::DeviceId::dummy() })
- }
-}
-
-type DeviceEventCallback = Arc<
- Mutex<
- Option<Box<dyn FnMut(DeviceId, tauri_runtime::device_events::DeviceEvent) + Send + 'static>>,
- >,
->;
#[derive(Clone)]
pub struct Context<T: UserEvent> {
@@ -270,7 +257,6 @@ pub struct Context<T: UserEvent> {
pub proxy: TaoEventLoopProxy<Message<T>>,
main_thread: DispatcherMainThreadContext<T>,
plugins: Arc<Mutex<Vec<Box<dyn Plugin<T> + Send>>>>,
- device_event_callback: DeviceEventCallback,
next_window_id: Arc<AtomicU32>,
next_webview_id: Arc<AtomicU32>,
next_window_event_id: Arc<AtomicU32>,
@@ -2795,7 +2781,6 @@ impl<T: UserEvent> Wry<T> {
#[cfg(feature = "tracing")]
active_tracing_spans: Default::default(),
},
- device_event_callback: Default::default(),
plugins: Default::default(),
next_window_id: Default::default(),
next_webview_id: Default::default(),
@@ -3043,20 +3028,6 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
.set_device_event_filter(DeviceEventFilterWrapper::from(filter).0);
}
- type DeviceId = DeviceId;
-
- fn set_device_event_callback<F>(&self, callback: F)
- where
- F: FnMut(Self::DeviceId, tauri_runtime::device_events::DeviceEvent) + Send + 'static,
- {
- self
- .context
- .device_event_callback
- .lock()
- .unwrap()
- .replace(Box::new(callback));
- }
-
#[cfg(desktop)]
fn run_iteration<F: FnMut(RunEvent<T>) + 'static>(&mut self, mut callback: F) {
use tao::platform::run_return::EventLoopExtRunReturn;
@@ -3064,7 +3035,6 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
let window_id_map = self.context.window_id_map.clone();
let web_context = &self.context.main_thread.web_context;
let plugins = self.context.plugins.clone();
- let device_event_callback = self.context.device_event_callback.clone();
#[cfg(feature = "tracing")]
let active_tracing_spans = self.context.main_thread.active_tracing_spans.clone();
@@ -3103,7 +3073,6 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
event,
event_loop,
control_flow,
- device_event_callback.clone(),
EventLoopIterationContext {
callback: &mut callback,
windows: windows.clone(),
@@ -3149,7 +3118,6 @@ where
let window_id_map = runtime.context.window_id_map.clone();
let web_context = runtime.context.main_thread.web_context.clone();
let plugins = runtime.context.plugins.clone();
- let device_event_callback = runtime.context.device_event_callback.clone();
#[cfg(feature = "tracing")]
let active_tracing_spans = runtime.context.main_thread.active_tracing_spans.clone();
@@ -3183,7 +3151,6 @@ where
event,
event_loop,
control_flow,
- device_event_callback.clone(),
EventLoopIterationContext {
callback: &mut callback,
window_id_map: window_id_map.clone(),
@@ -4019,7 +3986,6 @@ fn handle_event_loop<T: UserEvent>(
event: Event<'_, Message<T>>,
event_loop: &EventLoopWindowTarget<Message<T>>,
control_flow: &mut ControlFlow,
- device_event_callback: DeviceEventCallback,
context: EventLoopIterationContext<'_, T>,
) {
let EventLoopIterationContext {
@@ -4037,10 +4003,11 @@ fn handle_event_loop<T: UserEvent>(
Event::DeviceEvent {
device_id, event, ..
} => {
- if let Some(device_event_function) = device_event_callback.lock().unwrap().as_mut() {
- if let Some(mapped_event) = map_device_event::map_device_event(event) {
- device_event_function(DeviceId(device_id), mapped_event);
- }
+ if let Some(event) = device_event::map(event) {
+ callback(RunEvent::DeviceEvent {
+ id: DeviceId::new(device_id),
+ event,
+ });
}
}
Event::NewEvents(StartCause::Init) => {
diff --git a/crates/tauri-runtime-wry/src/map_device_event.rs b/crates/tauri-runtime-wry/src/map_device_event.rs
deleted file mode 100644
index 6a5c21fd7..000000000
--- a/crates/tauri-runtime-wry/src/map_device_event.rs
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
-// SPDX-License-Identifier: Apache-2.0
-// SPDX-License-Identifier: MIT
-
-use tauri_runtime::device_events::{Code, DeviceEvent, MouseScrollDelta};
-
-pub fn map_device_event(event: tao::event::DeviceEvent) -> Option<DeviceEvent> {
- match event {
- tao::event::DeviceEvent::Added => Some(DeviceEvent::Added),
- tao::event::DeviceEvent::Removed => Some(DeviceEvent::Removed),
- tao::event::DeviceEvent::MouseMotion { delta, .. } => Some(DeviceEvent::MouseMotion { delta }),
- tao::event::DeviceEvent::MouseWheel { delta, .. } => match delta {
- tao::event::MouseScrollDelta::LineDelta(x, y) => Some(DeviceEvent::MouseWheel {
- delta: MouseScrollDelta::LineDelta(x, y),
- }),
- tao::event::MouseScrollDelta::PixelDelta(pos) => Some(DeviceEvent::MouseWheel {
- delta: MouseScrollDelta::PixelDelta(pos),
- }),
- _ => None,
- },
- tao::event::DeviceEvent::Motion { axis, value, .. } => {
- Some(DeviceEvent::Motion { axis, value })
- }
- tao::event::DeviceEvent::Button { button, state, .. } => Some(DeviceEvent::Button {
- button,
- state: map_element_state(state)?,
- }),
- tao::event::DeviceEvent::Key(raw_key_event) => {
- let physical_key = raw_key_event.physical_key;
- let state = map_element_state(raw_key_event.state)?;
- Some(DeviceEvent::Key {
- pysical_key: map_physical_key(physical_key)?,
- state,
- })
- }
- tao::event::DeviceEvent::Text { codepoint, .. } => Some(DeviceEvent::Text { codepoint }),
- _ => None,
- }
-}
-
-fn map_element_state(
- state: tao::event::ElementState,
-) -> Option<tauri_runtime::device_events::KeyState> {
- match state {
- tao::event::ElementState::Pressed => Some(tauri_runtime::device_events::KeyState::Down),
- tao::event::ElementState::Released => Some(tauri_runtime::device_events::KeyState::Up),
- _ => None,
- }
-}
-
-fn map_physical_key(event: tao::keyboard::KeyCode) -> Option<Code> {
- match event {
- tao::keyboard::KeyCode::Unidentified(_) => None,
- tao::keyboard::KeyCode::Backquote => Some(Code::Backquote),
- tao::keyboard::KeyCode::Backslash => Some(Code::Backslash),
- tao::keyboard::KeyCode::BracketLeft => Some(Code::BracketLeft),
- tao::keyboard::KeyCode::BracketRight => Some(Code::BracketRight),
- tao::keyboard::KeyCode::Comma => Some(Code::Comma),
- tao::keyboard::KeyCode::Digit0 => Some(Code::Digit0),
- tao::keyboard::KeyCode::Digit1 => Some(Code::Digit1),
- tao::keyboard::KeyCode::Digit2 => Some(Code::Digit2),
- tao::keyboard::KeyCode::Digit3 => Some(Code::Digit3),
- tao::keyboard::KeyCode::Digit4 => Some(Code::Digit4),
- tao::keyboard::KeyCode::Digit5 => Some(Code::Digit5),
- tao::keyboard::KeyCode::Digit6 => Some(Code::Digit6),
- tao::keyboard::KeyCode::Digit7 => Some(Code::Digit7),
- tao::keyboard::KeyCode::Digit8 => Some(Code::Digit8),
- tao::keyboard::KeyCode::Digit9 => Some(Code::Digit9),
- tao::keyboard::KeyCode::Equal => Some(Code::Equal),
- tao::keyboard::KeyCode::IntlBackslash => Some(Code::IntlBackslash),
- tao::keyboard::KeyCode::IntlRo => Some(Code::IntlRo),
- tao::keyboard::KeyCode::IntlYen => Some(Code::IntlYen),
- tao::keyboard::KeyCode::KeyA => Some(Code::KeyA),
- tao::keyboard::KeyCode::KeyB => Some(Code::KeyB),
- tao::keyboard::KeyCode::KeyC => Some(Code::KeyC),
- tao::keyboard::KeyCode::KeyD => Some(Code::KeyD),
- tao::keyboard::KeyCode::KeyE => Some(Code::KeyE),
- tao::keyboard::KeyCode::KeyF => Some(Code::KeyF),
- tao::keyboard::KeyCode::KeyG => Some(Code::KeyG),
- tao::keyboard::KeyCode::KeyH => Some(Code::KeyH),
- tao::keyboard::KeyCode::KeyI => Some(Code::KeyI),
- tao::keyboard::KeyCode::KeyJ => Some(Code::KeyJ),
- tao::keyboard::KeyCode::KeyK => Some(Code::KeyK),
- tao::keyboard::KeyCode::KeyL => Some(Code::KeyL),
- tao::keyboard::KeyCode::KeyM => Some(Code::KeyM),
- tao::keyboard::KeyCode::KeyN => Some(Code::KeyN),
- tao::keyboard::KeyCode::KeyO => Some(Code::KeyO),
- tao::keyboard::KeyCode::KeyP => Some(Code::KeyP),
- tao::keyboard::KeyCode::KeyQ => Some(Code::KeyQ),
- tao::keyboard::KeyCode::KeyR => Some(Code::KeyR),
- tao::keyboard::KeyCode::KeyS => Some(Code::KeyS),
- tao::keyboard::KeyCode::KeyT => Some(Code::KeyT),
- tao::keyboard::KeyCode::KeyU => Some(Code::KeyU),
- tao::keyboard::KeyCode::KeyV => Some(Code::KeyV),
- tao::keyboard::KeyCode::KeyW => Some(Code::KeyW),
- tao::keyboard::KeyCode::KeyX => Some(Code::KeyX),
- tao::keyboard::KeyCode::KeyY => Some(Code::KeyY),
- tao::keyboard::KeyCode::KeyZ => Some(Code::KeyZ),
- tao::keyboard::KeyCode::Minus => Some(Code::Minus),
- // could be wrong convertion??
- tao::keyboard::KeyCode::Plus => Some(Code::Equal),
- tao::keyboard::KeyCode::Period => Some(Code::Period),
- tao::keyboard::KeyCode::Quote => Some(Code::Quote),
- tao::keyboard::KeyCode::Semicolon => Some(Code::Semicolon),
- tao::keyboard::KeyCode::Slash => Some(Code::Slash),
- tao::keyboard::KeyCode::AltLeft => Some(Code::AltLeft),
- tao::keyboard::KeyCode::AltRight => Some(Code::AltRight),
- tao::keyboard::KeyCode::Backspace => Some(Code::Backspace),
- tao::keyboard::KeyCode::CapsLock => Some(Code::CapsLock),
- tao::keyboard::KeyCode::ContextMenu => Some(Code::ContextMenu),
- tao::keyboard::KeyCode::ControlLeft => Some(Code::ControlLeft),
- tao::keyboard::KeyCode::ControlRight => Some(Code::ControlRight),
- tao::keyboard::KeyCode::Enter => Some(Code::Enter),
- tao::keyboard::KeyCode::SuperLeft => Some(Code::MetaLeft),
- tao::keyboard::KeyCode::SuperRight => Some(Code::MetaRight),
- tao::keyboard::KeyCode::ShiftLeft => Some(Code::ShiftLeft),
- tao::keyboard::KeyCode::ShiftRight => Some(Code::ShiftRight),
- tao::keyboard::KeyCode::Space => Some(Code::Space),
- tao::keyboard::KeyCode::Tab => Some(Code::Tab),
- tao::keyboard::KeyCode::Convert => Some(Code::Convert),
- tao::keyboard::KeyCode::KanaMode => Some(Code::KanaMode),
- tao::keyboard::KeyCode::Lang1 => Some(Code::Lang1),
- tao::keyboard::KeyCode::Lang2 => Some(Code::Lang2),
- tao::keyboard::KeyCode::Lang3 => Some(Code::Lang3),
- tao::keyboard::KeyCode::Lang4 => Some(Code::Lang4),
- tao::keyboard::KeyCode::Lang5 => Some(Code::Lang5),
- tao::keyboard::KeyCode::NonConvert => Some(Code::NonConvert),
- tao::keyboard::KeyCode::Delete => Some(Code::Delete),
- tao::keyboard::KeyCode::End => Some(Code::End),
- tao::keyboard::KeyCode::Help => Some(Code::Help),
- tao::keyboard::KeyCode::Home => Some(Code::Home),
- tao::keyboard::KeyCode::Insert => Some(Code::Insert),
- tao::keyboard::KeyCode::PageDown => Some(Code::PageDown),
- tao::keyboard::KeyCode::PageUp => Some(Code::PageUp),
- tao::keyboard::KeyCode::ArrowDown => Some(Code::ArrowDown),
- tao::keyboard::KeyCode::ArrowLeft => Some(Code::ArrowLeft),
- tao::keyboard::KeyCode::ArrowRight => Some(Code::ArrowRight),
- tao::keyboard::KeyCode::ArrowUp => Some(Code::ArrowUp),
- tao::keyboard::KeyCode::NumLock => Some(Code::NumLock),
- tao::keyboard::KeyCode::Numpad0 => Some(Code::Numpad0),
- tao::keyboard::KeyCode::Numpad1 => Some(Code::Numpad1),
- tao::keyboard::KeyCode::Numpad2 => Some(Code::Numpad2),
- tao::keyboard::KeyCode::Numpad3 => Some(Code::Numpad3),
- tao::keyboard::KeyCode::Numpad4 => Some(Code::Numpad4),
- tao::keyboard::KeyCode::Numpad5 => Some(Code::Numpad5),
- tao::keyboard::KeyCode::Numpad6 => Some(Code::Numpad6),
- tao::keyboard::KeyCode::Numpad7 => Some(Code::Numpad7),
- tao::keyboard::KeyCode::Numpad8 => Some(Code::Numpad8),
- tao::keyboard::KeyCode::Numpad9 => Some(Code::Numpad9),
- tao::keyboard::KeyCode::NumpadAdd => Some(Code::NumpadAdd),
- tao::keyboard::KeyCode::NumpadBackspace => Some(Code::NumpadBackspace),
- tao::keyboard::KeyCode::NumpadClear => Some(Code::NumpadClear),
- tao::keyboard::KeyCode::NumpadClearEntry => Some(Code::NumpadClearEntry),
- tao::keyboard::KeyCode::NumpadComma => Some(Code::NumpadComma),
- tao::keyboard::KeyCode::NumpadDecimal => Some(Code::NumpadDecimal),
- tao::keyboard::KeyCode::NumpadDivide => Some(Code::NumpadDivide),
- tao::keyboard::KeyCode::NumpadEnter => Some(Code::NumpadEnter),
- tao::keyboard::KeyCode::NumpadEqual => Some(Code::NumpadEqual),
- tao::keyboard::KeyCode::NumpadHash => Some(Code::NumpadHash),
- tao::keyboard::KeyCode::NumpadMemoryAdd => Some(Code::NumpadMemoryAdd),
- tao::keyboard::KeyCode::NumpadMemoryClear => Some(Code::NumpadMemoryClear),
- tao::keyboard::KeyCode::NumpadMemoryRecall => Some(Code::NumpadMemoryRecall),
- tao::keyboard::KeyCode::NumpadMemoryStore => Some(Code::NumpadMemoryStore),
- tao::keyboard::KeyCode::NumpadMemorySubtract => Some(Code::NumpadMemorySubtract),
- tao::keyboard::KeyCode::NumpadMultiply => Some(Code::NumpadMultiply),
- tao::keyboard::KeyCode::NumpadParenLeft => Some(Code::NumpadParenLeft),
- tao::keyboard::KeyCode::NumpadParenRight => Some(Code::NumpadParenRight),
- tao::keyboard::KeyCode::NumpadStar => Some(Code::NumpadStar),
- tao::keyboard::KeyCode::NumpadSubtract => Some(Code::NumpadSubtract),
- tao::keyboard::KeyCode::Escape => Some(Code::Escape),
- tao::keyboard::KeyCode::Fn => Some(Code::Fn),
- tao::keyboard::KeyCode::FnLock => Some(Code::FnLock),
- tao::keyboard::KeyCode::PrintScreen => Some(Code::PrintScreen),
- tao::keyboard::KeyCode::ScrollLock => Some(Code::ScrollLock),
- tao::keyboard::KeyCode::Pause => Some(Code::Pause),
- tao::keyboard::KeyCode::BrowserBack => Some(Code::BrowserBack),
- tao::keyboard::KeyCode::BrowserFavorites => Some(Code::BrowserFavorites),
- tao::keyboard::KeyCode::BrowserForward => Some(Code::BrowserForward),
- tao::keyboard::KeyCode::BrowserHome => Some(Code::BrowserHome),
- tao::keyboard::KeyCode::BrowserRefresh => Some(Code::BrowserRefresh),
- tao::keyboard::KeyCode::BrowserSearch => Some(Code::BrowserSearch),
- tao::keyboard::KeyCode::BrowserStop => Some(Code::BrowserStop),
- tao::keyboard::KeyCode::Eject => Some(Code::Eject),
- tao::keyboard::KeyCode::LaunchApp1 => Some(Code::LaunchApp1),
- tao::keyboard::KeyCode::LaunchApp2 => Some(Code::LaunchApp2),
- tao::keyboard::KeyCode::LaunchMail => Some(Code::LaunchMail),
- tao::keyboard::KeyCode::MediaPlayPause => Some(Code::MediaPlayPause),
- tao::keyboard::KeyCode::MediaSelect => Some(Code::MediaSelect),
- tao::keyboard::KeyCode::MediaStop => Some(Code::MediaStop),
- tao::keyboard::KeyCode::MediaTrackNext => Some(Code::MediaTrackNext),
- tao::keyboard::KeyCode::MediaTrackPrevious => Some(Code::MediaTrackPrevious),
- tao::keyboard::KeyCode::Power => Some(Code::Power),
- tao::keyboard::KeyCode::Sleep => Some(Code::Sleep),
- tao::keyboard::KeyCode::AudioVolumeDown => Some(Code::AudioVolumeDown),
- tao::keyboard::KeyCode::AudioVolumeMute => Some(Code::AudioVolumeMute),
- tao::keyboard::KeyCode::AudioVolumeUp => Some(Code::AudioVolumeUp),
- tao::keyboard::KeyCode::WakeUp => Some(Code::WakeUp),
- // maybe needs to be changed but [`Code::Hyper`] is deprecated
- tao::keyboard::KeyCode::Hyper => Some(Code::MetaLeft),
- // maybe needs to be changed but [`Code::Super`] is deprecated
- tao::keyboard::KeyCode::Turbo => Some(Code::MetaLeft),
- tao::keyboard::KeyCode::Abort => Some(Code::Abort),
- tao::keyboard::KeyCode::Resume => Some(Code::Resume),
- tao::keyboard::KeyCode::Suspend => Some(Code::Suspend),
- tao::keyboard::KeyCode::Again => Some(Code::Again),
- tao::keyboard::KeyCode::Copy => Some(Code::Copy),
- tao::keyboard::KeyCode::Cut => Some(Code::Cut),
- tao::keyboard::KeyCode::Find => Some(Code::Find),
- tao::keyboard::KeyCode::Open => Some(Code::Open),
- tao::keyboard::KeyCode::Paste => Some(Code::Paste),
- tao::keyboard::KeyCode::Props => Some(Code::Props),
- tao::keyboard::KeyCode::Select => Some(Code::Select),
- tao::keyboard::KeyCode::Undo => Some(Code::Undo),
- tao::keyboard::KeyCode::Hiragana => Some(Code::Hiragana),
- tao::keyboard::KeyCode::Katakana => Some(Code::Katakana),
- tao::keyboard::KeyCode::F1 => Some(Code::F1),
- tao::keyboard::KeyCode::F2 => Some(Code::F2),
- tao::keyboard::KeyCode::F3 => Some(Code::F3),
- tao::keyboard::KeyCode::F4 => Some(Code::F4),
- tao::keyboard::KeyCode::F5 => Some(Code::F5),
- tao::keyboard::KeyCode::F6 => Some(Code::F6),
- tao::keyboard::KeyCode::F7 => Some(Code::F7),
- tao::keyboard::KeyCode::F8 => Some(Code::F8),
- tao::keyboard::KeyCode::F9 => Some(Code::F9),
- tao::keyboard::KeyCode::F10 => Some(Code::F10),
- tao::keyboard::KeyCode::F11 => Some(Code::F11),
- tao::keyboard::KeyCode::F12 => Some(Code::F12),
- tao::keyboard::KeyCode::F13 => Some(Code::F13),
- tao::keyboard::KeyCode::F14 => Some(Code::F14),
- tao::keyboard::KeyCode::F15 => Some(Code::F15),
- tao::keyboard::KeyCode::F16 => Some(Code::F16),
- tao::keyboard::KeyCode::F17 => Some(Code::F17),
- tao::keyboard::KeyCode::F18 => Some(Code::F18),
- tao::keyboard::KeyCode::F19 => Some(Code::F19),
- tao::keyboard::KeyCode::F20 => Some(Code::F20),
- tao::keyboard::KeyCode::F21 => Some(Code::F21),
- tao::keyboard::KeyCode::F22 => Some(Code::F22),
- tao::keyboard::KeyCode::F23 => Some(Code::F23),
- tao::keyboard::KeyCode::F24 => Some(Code::F24),
- tao::keyboard::KeyCode::F25 => Some(Code::F25),
- tao::keyboard::KeyCode::F26 => Some(Code::F26),
- tao::keyboard::KeyCode::F27 => Some(Code::F27),
- tao::keyboard::KeyCode::F28 => Some(Code::F28),
- tao::keyboard::KeyCode::F29 => Some(Code::F29),
- tao::keyboard::KeyCode::F30 => Some(Code::F30),
- tao::keyboard::KeyCode::F31 => Some(Code::F31),
- tao::keyboard::KeyCode::F32 => Some(Code::F32),
- tao::keyboard::KeyCode::F33 => Some(Code::F33),
- tao::keyboard::KeyCode::F34 => Some(Code::F34),
- tao::keyboard::KeyCode::F35 => Some(Code::F35),
- _ => None,
- }
-}
diff --git a/crates/tauri-runtime/src/device_events.rs b/crates/tauri-runtime/src/device_events.rs
index 38c02b68f..2f73bb687 100644
--- a/crates/tauri-runtime/src/device_events.rs
+++ b/crates/tauri-runtime/src/device_events.rs
@@ -2,6 +2,8 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
+use std::hash::{DefaultHasher, Hash, Hasher};
+
use dpi::PhysicalPosition;
pub use keyboard_types::{Code, KeyState};
use serde::{Deserialize, Serialize};
@@ -23,14 +25,21 @@ impl Default for DeviceEventFilter {
}
}
-pub trait DeviceId: Copy + Clone + PartialEq + Eq + PartialOrd + Ord + std::hash::Hash {
- /// # Safety
- /// Returns a dummy `DeviceId`, useful for unit testing. The only guarantee made about the return
- /// value of this function is that it will always be equal to itself and to future values returned
- /// by this function. No other guarantees are made. This may be equal to a real `DeviceId`.
- ///
- /// **Passing this id to any real device will result in undefined behavior.**
- unsafe fn dummy() -> Self;
+/// Identifier of an input device.
+///
+/// Whenever you receive an event arising from a particular input device, this event contains a `DeviceId` which
+/// identifies its origin. Note that devices may be virtual (representing an on-screen cursor and keyboard focus) or
+/// physical. Virtual devices typically aggregate inputs from multiple physical devices.
+#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub struct DeviceId(u64);
+
+impl DeviceId {
+ #[doc(hidden)]
+ pub fn new<T: Hash>(id: T) -> Self {
+ let mut hasher = DefaultHasher::new();
+ id.hash(&mut hasher);
+ Self(hasher.finish())
+ }
}
#[derive(Clone, Debug, PartialEq)]
diff --git a/crates/tauri-runtime/src/lib.rs b/crates/tauri-runtime/src/lib.rs
index 946848bef..125b12fec 100644
--- a/crates/tauri-runtime/src/lib.rs
+++ b/crates/tauri-runtime/src/lib.rs
@@ -223,6 +223,11 @@ pub enum RunEvent<T: UserEvent> {
},
/// A custom event defined by the user.
UserEvent(T),
+ /// Emitted when the OS sends an event to a device.
+ DeviceEvent {
+ id: device_events::DeviceId,
+ event: device_events::DeviceEvent,
+ },
}
/// Action to take when the event loop is about to exit
@@ -450,8 +455,6 @@ pub trait Runtime<T: UserEvent>: Debug + Sized + 'static {
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
fn hide(&self);
- type DeviceId: device_events::DeviceId;
-
/// Change the device event filter mode.
///
/// Since the DeviceEvent capture can lead to high CPU usage for unfocused windows, [`tao`]
@@ -465,20 +468,6 @@ pub trait Runtime<T: UserEvent>: Debug + Sized + 'static {
/// [`tao`]: https://crates.io/crates/tao
fn set_device_event_filter(&self, filter: DeviceEventFilter);
- /// Set a callback to be called when a device event is received.
- ///
- /// By default, the device events are filtered out when the window is not focused.
- /// To change this behavior, use [`set_device_event_filter`](Runtime::set_device_event_filter).
- ///
- /// ## Platform-specific
- ///
- /// - ** Wayland / macOS / iOS / Android**: Unsupported.
- ///
- /// [`tao`]: https://crates.io/crates/tao
- fn set_device_event_callback<F>(&self, callback: F)
- where
- F: FnMut(Self::DeviceId, device_events::DeviceEvent) + Send + 'static;
-
/// Runs an iteration of the runtime event loop and returns control flow to the caller.
#[cfg(desktop)]
fn run_iteration<F: FnMut(RunEvent<T>) + 'static>(&mut self, callback: F);
diff --git a/crates/tauri/src/app.rs b/crates/tauri/src/app.rs
index 2629a80b8..b3327bcb0 100644
--- a/crates/tauri/src/app.rs
+++ b/crates/tauri/src/app.rs
@@ -32,7 +32,7 @@ use tauri_macros::default_runtime;
#[cfg(desktop)]
use tauri_runtime::EventLoopProxy;
use tauri_runtime::{
- device_events::DeviceEvent,
+ device_events::{DeviceEvent, DeviceId},
dpi::{PhysicalPosition, PhysicalSize},
window::DragDropEvent,
RuntimeInitArgs,
@@ -253,6 +253,13 @@ pub enum RunEvent {
/// Indicates whether the NSApplication object found any visible windows in your application.
has_visible_windows: bool,
},
+ /// Emitted when the OS sends an event to a device.
+ DeviceEvent {
+ /// Unique identifier for the device.
+ id: DeviceId,
+ /// The event that was sent by the device.
+ event: DeviceEvent,
+ },
}
impl From<EventLoopMessage> for RunEvent {
@@ -1427,10 +1434,6 @@ pub struct Builder<R: Runtime> {
/// The device event filter.
device_event_filter: DeviceEventFilter,
- /// device event callback
- device_event_callback:
- Option<Box<dyn FnMut(&AppHandle<R>, R::DeviceId, DeviceEvent) + Send + 'static>>,
-
pub(crate) invoke_key: String,
}
@@ -1496,7 +1499,6 @@ impl<R: Runtime> Builder<R> {
window_event_listeners: Vec::new(),
webview_event_listeners: Vec::new(),
device_event_filter: Default::default(),
- device_event_callback: None,
invoke_key,
}
}
@@ -2079,7 +2081,7 @@ tauri::Builder::default()
///
/// ## Platform-specific
///
- /// - ** Wayland / macOS / iOS / Android**: Unsupported.
+ /// - ** Linux / macOS / iOS / Android**: Unsupported.
///
/// # Example
/// ```,no_run
@@ -2093,35 +2095,6 @@ tauri::Builder::default()
self
}
- /// Registers a device event callback.
- ///
- /// if [`DeviceEventFilter`] is set to [`DeviceEventFilter::Always`], this callback will be called for all device events.
- /// This leads to high CPU usage for unfocused windows, so it is recommended to use [`DeviceEventFilter::FocusedOnly`] unless nessary and keep processing to a minimum.
- ///
- /// ## Platform-specific
- ///
- /// - ** Wayland / macOS / iOS / Android**: Unsupported.
- ///
- /// # Example
- /// ```
- /// tauri::Builder::default().on_device_event(|_app, _device_id, event| match event {
- /// tauri::DeviceEvent::MouseMotion { delta } => {
- /// println!("Mouse moved: {:?}", delta);
- /// }
- /// tauri::DeviceEvent::MouseWheel { delta } => {
- /// println!("Mouse wheel: {:?}", delta);
- /// }
- /// _ => {}
- /// });
- /// ```
- pub fn on_device_event<F>(mut self, callback: F) -> Self
- where
- F: FnMut(&AppHandle<R>, R::DeviceId, DeviceEvent) + Send + 'static,
- {
- self.device_event_callback = Some(Box::new(callback));
- self
- }
-
/// Builds the application.
#[allow(clippy::type_complexity, unused_mut)]
#[cfg_attr(
@@ -2259,13 +2232,6 @@ tauri::Builder::default()
})),
};
- if let Some(mut device_event_callback) = self.device_event_callback {
- let app_handle_clone = app_handle.clone();
- runtime.set_device_event_callback(move |id, event| {
- device_event_callback(&app_handle_clone, id, event);
- });
- }
-
#[allow(unused_mut)]
let mut app = App {
runtime: Some(runtime),
@@ -2529,6 +2495,7 @@ fn on_event_loop_event<R: Runtime>(
} => RunEvent::Reopen {
has_visible_windows,
},
+ RuntimeRunEvent::DeviceEvent { id, event } => RunEvent::DeviceEvent { id, event },
_ => unimplemented!(),
};
diff --git a/crates/tauri/src/test/mock_runtime.rs b/crates/tauri/src/test/mock_runtime.rs
index 2c861cc05..a37dedee6 100644
--- a/crates/tauri/src/test/mock_runtime.rs
+++ b/crates/tauri/src/test/mock_runtime.rs
@@ -1137,14 +1137,6 @@ impl MockRuntime {
}
}
-#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct DeviceId(u32);
-impl tauri_runtime::device_events::DeviceId for DeviceId {
- unsafe fn dummy() -> Self {
- Self(0)
- }
-}
-
impl<T: UserEvent> Runtime<T> for MockRuntime {
type WindowDispatcher = MockWindowDispatcher;
type WebviewDispatcher = MockWebviewDispatcher;
@@ -1271,14 +1263,6 @@ impl<T: UserEvent> Runtime<T> for MockRuntime {
fn set_device_event_filter(&self, filter: DeviceEventFilter) {}
- type DeviceId = DeviceId;
-
- fn set_device_event_callback<F>(&self, callback: F)
- where
- F: FnMut(Self::DeviceId, tauri_runtime::device_events::DeviceEvent) + Send + 'static,
- {
- }
-
#[cfg(any(
target_os = "macos",
windows,
diff --git a/examples/helloworld/main.rs b/examples/helloworld/main.rs
index ee822803b..f110b2adc 100644
--- a/examples/helloworld/main.rs
+++ b/examples/helloworld/main.rs
@@ -12,8 +12,14 @@ fn greet(name: &str) -> String {
fn main() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![greet])
- .run(tauri::generate_context!(
+ .build(tauri::generate_context!(
"../../examples/helloworld/tauri.conf.json"
))
- .expect("error while running tauri application");
+ .expect("error while running tauri application")
+ .run(|_app_handle, event| match event {
+ tauri::RunEvent::DeviceEvent { id, event } => {
+ println!("Device event: {id:?} {:?}", event);
+ }
+ _ => {}
+ });
}
(the helloworld example diff is just a test)
i don't have access to push to your fork unfortunately :)
@lucasfernog you almost certainly don't want it in the RunEvent. The issue is that device events can be enabled to run all the time not just when the window is focused. There can be a huge number of events to process if the hot path is not short it can end up burning significant cpu time even while running in the background. if its in RunEvent you end up doing alot more processing then necessary as all plugins all have to process the message as well. just moving your cursor from 1 corner of the screen to the other can produce hundreds of events to process |
Maybe we could provide both listening methods, just like we do for WindowEvent and WebviewEvent? |
ok i'll take another look later.. |
Adds a callback method to App builder that is called with device events and Apphandle.
Update Runtime Trait to add a device event callback method
Update wry and mock runtime with this method
closes #7393 maybe #11671 as welll