Skip to content

Commit 73fd60e

Browse files
cymruulucasfernog
andauthored
expose set_device_event_filter in tauri (#5562)
Co-authored-by: Lucas Nogueira <lucas@tauri.studio> Closes #5496
1 parent 5fd4d20 commit 73fd60e

File tree

6 files changed

+125
-11
lines changed

6 files changed

+125
-11
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"tauri-runtime-wry": minor
3+
"tauri-runtime": minor
4+
"tauri": minor
5+
---
6+
7+
Added `Builder::device_event_filter` and `App::set_device_event_filter` methods.

core/tauri-runtime-wry/src/lib.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ use tauri_runtime::{
1414
dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Position, Size},
1515
CursorIcon, DetachedWindow, FileDropEvent, JsEventListenerKey, PendingWindow, WindowEvent,
1616
},
17-
Dispatch, Error, EventLoopProxy, ExitRequestedEventAction, Icon, Result, RunEvent, RunIteration,
18-
Runtime, RuntimeHandle, UserAttentionType, UserEvent,
17+
DeviceEventFilter, Dispatch, Error, EventLoopProxy, ExitRequestedEventAction, Icon, Result,
18+
RunEvent, RunIteration, Runtime, RuntimeHandle, UserAttentionType, UserEvent,
1919
};
2020

2121
use tauri_runtime::window::MenuEvent;
@@ -47,7 +47,8 @@ use wry::{
4747
},
4848
event::{Event, StartCause, WindowEvent as WryWindowEvent},
4949
event_loop::{
50-
ControlFlow, EventLoop, EventLoopProxy as WryEventLoopProxy, EventLoopWindowTarget,
50+
ControlFlow, DeviceEventFilter as WryDeviceEventFilter, EventLoop,
51+
EventLoopProxy as WryEventLoopProxy, EventLoopWindowTarget,
5152
},
5253
menu::{
5354
AboutMetadata as WryAboutMetadata, CustomMenuItem as WryCustomMenuItem, MenuBar,
@@ -64,7 +65,6 @@ use wry::{
6465
webview::{FileDropEvent as WryFileDropEvent, WebContext, WebView, WebViewBuilder},
6566
};
6667

67-
pub use wry;
6868
pub use wry::application::window::{Window, WindowBuilder as WryWindowBuilder, WindowId};
6969

7070
#[cfg(windows)]
@@ -364,6 +364,18 @@ impl From<MenuItem> for MenuItemWrapper {
364364
}
365365
}
366366

367+
pub struct DeviceEventFilterWrapper(pub WryDeviceEventFilter);
368+
369+
impl From<DeviceEventFilter> for DeviceEventFilterWrapper {
370+
fn from(item: DeviceEventFilter) -> Self {
371+
match item {
372+
DeviceEventFilter::Always => Self(WryDeviceEventFilter::Always),
373+
DeviceEventFilter::Never => Self(WryDeviceEventFilter::Never),
374+
DeviceEventFilter::Unfocused => Self(WryDeviceEventFilter::Unfocused),
375+
}
376+
}
377+
}
378+
367379
#[cfg(target_os = "macos")]
368380
pub struct NativeImageWrapper(pub WryNativeImage);
369381

@@ -2055,6 +2067,12 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
20552067
self.event_loop.hide_application();
20562068
}
20572069

2070+
fn set_device_event_filter(&mut self, filter: DeviceEventFilter) {
2071+
self
2072+
.event_loop
2073+
.set_device_event_filter(DeviceEventFilterWrapper::from(filter).0);
2074+
}
2075+
20582076
#[cfg(desktop)]
20592077
fn run_iteration<F: FnMut(RunEvent<T>) + 'static>(&mut self, mut callback: F) -> RunIteration {
20602078
use wry::application::platform::run_return::EventLoopExtRunReturn;

core/tauri-runtime/src/lib.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,23 @@ pub enum UserAttentionType {
184184
Informational,
185185
}
186186

187+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
188+
#[serde(tag = "type")]
189+
pub enum DeviceEventFilter {
190+
/// Always filter out device events.
191+
Always,
192+
/// Filter out device events while the window is not focused.
193+
Unfocused,
194+
/// Report all device events regardless of window focus.
195+
Never,
196+
}
197+
198+
impl Default for DeviceEventFilter {
199+
fn default() -> Self {
200+
Self::Unfocused
201+
}
202+
}
203+
187204
#[derive(Debug, thiserror::Error)]
188205
#[non_exhaustive]
189206
pub enum Error {
@@ -461,6 +478,19 @@ pub trait Runtime<T: UserEvent>: Debug + Sized + 'static {
461478
#[cfg_attr(doc_cfg, doc(cfg(target_os = "macos")))]
462479
fn hide(&self);
463480

481+
/// Change the device event filter mode.
482+
///
483+
/// Since the DeviceEvent capture can lead to high CPU usage for unfocused windows, [`tao`]
484+
/// will ignore them by default for unfocused windows on Windows. This method allows changing
485+
/// the filter to explicitly capture them again.
486+
///
487+
/// ## Platform-specific
488+
///
489+
/// - ** Linux / macOS / iOS / Android**: Unsupported.
490+
///
491+
/// [`tao`]: https://crates.io/crates/tao
492+
fn set_device_event_filter(&mut self, filter: DeviceEventFilter);
493+
464494
/// Runs the one step of the webview runtime event loop and returns control flow to the caller.
465495
#[cfg(desktop)]
466496
fn run_iteration<F: Fn(RunEvent<T>) + 'static>(&mut self, callback: F) -> RunIteration;

core/tauri/src/app.rs

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ use crate::{
2323
sealed::{ManagerBase, RuntimeOrDispatch},
2424
utils::config::Config,
2525
utils::{assets::Assets, resources::resource_relpath, Env},
26-
Context, EventLoopMessage, Invoke, InvokeError, InvokeResponse, Manager, Runtime, Scopes,
27-
StateManager, Theme, Window,
26+
Context, DeviceEventFilter, EventLoopMessage, Invoke, InvokeError, InvokeResponse, Manager,
27+
Runtime, Scopes, StateManager, Theme, Window,
2828
};
2929

3030
#[cfg(shell_scope)]
@@ -805,6 +805,35 @@ impl<R: Runtime> App<R> {
805805
.set_activation_policy(activation_policy);
806806
}
807807

808+
/// Change the device event filter mode.
809+
///
810+
/// Since the DeviceEvent capture can lead to high CPU usage for unfocused windows, [`tao`]
811+
/// will ignore them by default for unfocused windows on Windows. This method allows changing
812+
/// the filter to explicitly capture them again.
813+
///
814+
/// ## Platform-specific
815+
///
816+
/// - ** Linux / macOS / iOS / Android**: Unsupported.
817+
///
818+
/// # Examples
819+
/// ```,no_run
820+
/// let mut app = tauri::Builder::default()
821+
/// // on an actual app, remove the string argument
822+
/// .build(tauri::generate_context!("test/fixture/src-tauri/tauri.conf.json"))
823+
/// .expect("error while building tauri application");
824+
/// app.set_device_event_filter(tauri::DeviceEventFilter::Always);
825+
/// app.run(|_app_handle, _event| {});
826+
/// ```
827+
///
828+
/// [`tao`]: https://crates.io/crates/tao
829+
pub fn set_device_event_filter(&mut self, filter: DeviceEventFilter) {
830+
self
831+
.runtime
832+
.as_mut()
833+
.unwrap()
834+
.set_device_event_filter(filter);
835+
}
836+
808837
/// Gets the argument matches of the CLI definition configured in `tauri.conf.json`.
809838
///
810839
/// # Examples
@@ -1008,6 +1037,9 @@ pub struct Builder<R: Runtime> {
10081037
/// The updater configuration.
10091038
#[cfg(updater)]
10101039
updater_settings: UpdaterSettings,
1040+
1041+
/// The device event filter.
1042+
device_event_filter: DeviceEventFilter,
10111043
}
10121044

10131045
impl<R: Runtime> Builder<R> {
@@ -1036,6 +1068,7 @@ impl<R: Runtime> Builder<R> {
10361068
system_tray_event_listeners: Vec::new(),
10371069
#[cfg(updater)]
10381070
updater_settings: Default::default(),
1071+
device_event_filter: Default::default(),
10391072
}
10401073
}
10411074

@@ -1486,6 +1519,28 @@ impl<R: Runtime> Builder<R> {
14861519
self
14871520
}
14881521

1522+
/// Change the device event filter mode.
1523+
///
1524+
/// Since the DeviceEvent capture can lead to high CPU usage for unfocused windows, [`tao`]
1525+
/// will ignore them by default for unfocused windows on Windows. This method allows changing
1526+
/// the filter to explicitly capture them again.
1527+
///
1528+
/// ## Platform-specific
1529+
///
1530+
/// - ** Linux / macOS / iOS / Android**: Unsupported.
1531+
///
1532+
/// # Examples
1533+
/// ```,no_run
1534+
/// tauri::Builder::default()
1535+
/// .device_event_filter(tauri::DeviceEventFilter::Always);
1536+
/// ```
1537+
///
1538+
/// [`tao`]: https://crates.io/crates/tao
1539+
pub fn device_event_filter(mut self, filter: DeviceEventFilter) -> Self {
1540+
self.device_event_filter = filter;
1541+
self
1542+
}
1543+
14891544
/// Builds the application.
14901545
#[allow(clippy::type_complexity)]
14911546
pub fn build<A: Assets>(mut self, context: Context<A>) -> crate::Result<App<R>> {
@@ -1531,13 +1586,15 @@ impl<R: Runtime> Builder<R> {
15311586
}
15321587

15331588
#[cfg(any(windows, target_os = "linux"))]
1534-
let runtime = if self.runtime_any_thread {
1589+
let mut runtime = if self.runtime_any_thread {
15351590
R::new_any_thread()?
15361591
} else {
15371592
R::new()?
15381593
};
15391594
#[cfg(not(any(windows, target_os = "linux")))]
1540-
let runtime = R::new()?;
1595+
let mut runtime = R::new()?;
1596+
1597+
runtime.set_device_event_filter(self.device_event_filter);
15411598

15421599
let runtime_handle = runtime.handle();
15431600

core/tauri/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ pub use {
244244
dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Pixel, Position, Size},
245245
CursorIcon, FileDropEvent,
246246
},
247-
RunIteration, UserAttentionType,
247+
DeviceEventFilter, RunIteration, UserAttentionType,
248248
},
249249
self::state::{State, StateManager},
250250
self::utils::{

core/tauri/src/test/mock_runtime.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ use tauri_runtime::{
1212
dpi::{PhysicalPosition, PhysicalSize, Position, Size},
1313
CursorIcon, DetachedWindow, MenuEvent, PendingWindow, WindowEvent,
1414
},
15-
Dispatch, EventLoopProxy, Icon, Result, RunEvent, Runtime, RuntimeHandle, UserAttentionType,
16-
UserEvent,
15+
DeviceEventFilter, Dispatch, EventLoopProxy, Icon, Result, RunEvent, Runtime, RuntimeHandle,
16+
UserAttentionType, UserEvent,
1717
};
1818
#[cfg(all(desktop, feature = "system-tray"))]
1919
use tauri_runtime::{
@@ -711,6 +711,8 @@ impl<T: UserEvent> Runtime<T> for MockRuntime {
711711
#[cfg_attr(doc_cfg, doc(cfg(target_os = "macos")))]
712712
fn hide(&self) {}
713713

714+
fn set_device_event_filter(&mut self, filter: DeviceEventFilter) {}
715+
714716
#[cfg(any(
715717
target_os = "macos",
716718
windows,

0 commit comments

Comments
 (0)