diff --git a/CHANGELOG.md b/CHANGELOG.md index 29d2dd80..82901a82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ And please only add new entries to the top of this list, right below the `# Unre # Unreleased +- **Breaking** Rename `DeviceEventFilter` to `DeviceEvents` reversing the behavior of variants. +- **Breaking** Rename `EventLoopWindowTarget::set_device_event_filter` to `listen_device_events`. +- On X11, fix `EventLoopWindowTarget::listen_device_events` effect being reversed. - **Breaking:** Remove all deprecated `modifiers` fields. - **Breaking:** Overhaul keyboard input handling. - Replace `KeyboardInput` with `KeyEvent` and `RawKeyEvent`. diff --git a/examples/window_buttons.rs b/examples/window_buttons.rs index b7245f5a..b8f435cd 100644 --- a/examples/window_buttons.rs +++ b/examples/window_buttons.rs @@ -6,7 +6,7 @@ use simple_logger::SimpleLogger; use winit::{ dpi::LogicalSize, event::{ElementState, Event, KeyEvent, WindowEvent}, - event_loop::{DeviceEventFilter, EventLoop}, + event_loop::{DeviceEvents, EventLoop}, keyboard::Key, window::{WindowBuilder, WindowButtons}, }; @@ -26,7 +26,7 @@ fn main() { eprintln!(" (G) Toggle maximize button"); eprintln!(" (H) Toggle minimize button"); - event_loop.set_device_event_filter(DeviceEventFilter::Never); + event_loop.listen_device_events(DeviceEvents::Always); event_loop.run(move |event, _, control_flow| { control_flow.set_wait(); diff --git a/examples/window_debug.rs b/examples/window_debug.rs index 1a16f513..def104b6 100644 --- a/examples/window_debug.rs +++ b/examples/window_debug.rs @@ -6,7 +6,7 @@ use simple_logger::SimpleLogger; use winit::{ dpi::{LogicalSize, PhysicalSize}, event::{DeviceEvent, ElementState, Event, KeyEvent, RawKeyEvent, WindowEvent}, - event_loop::{DeviceEventFilter, EventLoop}, + event_loop::{DeviceEvents, EventLoop}, keyboard::{Key, KeyCode}, window::{Fullscreen, WindowBuilder}, }; @@ -33,7 +33,7 @@ fn main() { let mut minimized = false; let mut visible = true; - event_loop.set_device_event_filter(DeviceEventFilter::Never); + event_loop.listen_device_events(DeviceEvents::Always); event_loop.run(move |event, _, control_flow| { control_flow.set_wait(); diff --git a/src/event_loop.rs b/src/event_loop.rs index 1f00f7d7..effbd15c 100644 --- a/src/event_loop.rs +++ b/src/event_loop.rs @@ -352,20 +352,20 @@ impl EventLoopWindowTarget { .map(|inner| MonitorHandle { inner }) } - /// Change [`DeviceEvent`] filter mode. + /// Change if or when [`DeviceEvent`]s are captured. /// /// Since the [`DeviceEvent`] capture can lead to high CPU usage for unfocused windows, winit /// will ignore them by default for unfocused windows on Linux/BSD. This method allows changing - /// this filter at runtime to explicitly capture them again. + /// this at runtime to explicitly capture them again. /// /// ## Platform-specific /// /// - **Wayland / macOS / iOS / Android / Web / Orbital:** Unsupported. /// /// [`DeviceEvent`]: crate::event::DeviceEvent - pub fn set_device_event_filter(&self, _filter: DeviceEventFilter) { + pub fn listen_device_events(&self, _allowed: DeviceEvents) { #[cfg(any(x11_platform, wayland_platform, windows))] - self.p.set_device_event_filter(_filter); + self.p.listen_device_events(_allowed); } } @@ -423,19 +423,14 @@ impl fmt::Display for EventLoopClosed { impl error::Error for EventLoopClosed {} -/// Filter controlling the propagation of device events. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -pub enum DeviceEventFilter { - /// Always filter out device events. +/// Control when device events are captured. +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)] +pub enum DeviceEvents { + /// Report device events regardless of window focus. Always, - /// Filter out device events while the window is not focused. - Unfocused, - /// Report all device events regardless of window focus. + /// Only capture device events while the window is focused. + #[default] + WhenFocused, + /// Never capture device events. Never, } - -impl Default for DeviceEventFilter { - fn default() -> Self { - Self::Unfocused - } -} diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index 5fdc22f5..03db21ed 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -30,9 +30,7 @@ use crate::{ dpi::{PhysicalPosition, PhysicalSize, Position, Size}, error::{ExternalError, NotSupportedError, OsError as RootOsError}, event::{Event, KeyEvent}, - event_loop::{ - ControlFlow, DeviceEventFilter, EventLoopClosed, EventLoopWindowTarget as RootELW, - }, + event_loop::{ControlFlow, DeviceEvents, EventLoopClosed, EventLoopWindowTarget as RootELW}, icon::Icon, keyboard::{Key, KeyCode}, platform::{modifier_supplement::KeyEventExtModifierSupplement, scancode::KeyCodeExtScancode}, @@ -894,12 +892,12 @@ impl EventLoopWindowTarget { } #[inline] - pub fn set_device_event_filter(&self, _filter: DeviceEventFilter) { + pub fn listen_device_events(&self, _allowed: DeviceEvents) { match *self { #[cfg(wayland_platform)] EventLoopWindowTarget::Wayland(_) => (), #[cfg(x11_platform)] - EventLoopWindowTarget::X(ref evlp) => evlp.set_device_event_filter(_filter), + EventLoopWindowTarget::X(ref evlp) => evlp.set_listen_device_events(_allowed), } } diff --git a/src/platform_impl/linux/x11/event_processor.rs b/src/platform_impl/linux/x11/event_processor.rs index 16380754..a32f3d9e 100644 --- a/src/platform_impl/linux/x11/event_processor.rs +++ b/src/platform_impl/linux/x11/event_processor.rs @@ -813,7 +813,7 @@ impl EventProcessor { if self.active_window != Some(xev.event) { self.active_window = Some(xev.event); - wt.update_device_event_filter(true); + wt.update_listen_device_events(true); let window_id = mkwid(xev.event); let position = PhysicalPosition::new(xev.event_x, xev.event_y); @@ -877,7 +877,7 @@ impl EventProcessor { if self.active_window.take() == Some(xev.event) { let window_id = mkwid(xev.event); - wt.update_device_event_filter(false); + wt.update_listen_device_events(false); // Issue key release events for all pressed keys Self::handle_pressed_keys( diff --git a/src/platform_impl/linux/x11/mod.rs b/src/platform_impl/linux/x11/mod.rs index 51b8fce0..5f2ed0af 100644 --- a/src/platform_impl/linux/x11/mod.rs +++ b/src/platform_impl/linux/x11/mod.rs @@ -46,9 +46,7 @@ use super::common::xkb_state::KbdState; use crate::{ error::OsError as RootOsError, event::{Event, StartCause}, - event_loop::{ - ControlFlow, DeviceEventFilter, EventLoopClosed, EventLoopWindowTarget as RootELW, - }, + event_loop::{ControlFlow, DeviceEvents, EventLoopClosed, EventLoopWindowTarget as RootELW}, platform_impl::{ platform::{sticky_exit_callback, WindowId}, PlatformSpecificWindowBuilderAttributes, @@ -107,7 +105,7 @@ pub struct EventLoopWindowTarget { ime: RefCell, windows: RefCell>>, redraw_sender: WakeSender, - device_event_filter: Cell, + device_events: Cell, _marker: ::std::marker::PhantomData, } @@ -266,11 +264,11 @@ impl EventLoop { sender: redraw_sender, // not used again so no clone waker: waker.clone(), }, - device_event_filter: Default::default(), + device_events: Default::default(), }; // Set initial device event filter. - window_target.update_device_event_filter(true); + window_target.update_listen_device_events(true); let target = Rc::new(RootELW { p: super::EventLoopWindowTarget::X(window_target), @@ -573,17 +571,17 @@ impl EventLoopWindowTarget { &self.xconn } - pub fn set_device_event_filter(&self, filter: DeviceEventFilter) { - self.device_event_filter.set(filter); + pub fn set_listen_device_events(&self, allowed: DeviceEvents) { + self.device_events.set(allowed); } - /// Update the device event filter based on window focus. - pub fn update_device_event_filter(&self, focus: bool) { - let filter_events = self.device_event_filter.get() == DeviceEventFilter::Never - || (self.device_event_filter.get() == DeviceEventFilter::Unfocused && !focus); + /// Update the device event based on window focus. + pub fn update_listen_device_events(&self, focus: bool) { + let device_events = self.device_events.get() == DeviceEvents::Always + || (focus && self.device_events.get() == DeviceEvents::WhenFocused); let mut mask = 0; - if !filter_events { + if device_events { mask = ffi::XI_RawMotionMask | ffi::XI_RawButtonPressMask | ffi::XI_RawButtonReleaseMask diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index f5a3d005..fd9a87f1 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -76,9 +76,7 @@ use windows_sys::Win32::{ use crate::{ dpi::{PhysicalPosition, PhysicalSize}, event::{DeviceEvent, Event, Force, Ime, RawKeyEvent, Touch, TouchPhase, WindowEvent}, - event_loop::{ - ControlFlow, DeviceEventFilter, EventLoopClosed, EventLoopWindowTarget as RootELW, - }, + event_loop::{ControlFlow, DeviceEvents, EventLoopClosed, EventLoopWindowTarget as RootELW}, keyboard::{KeyCode, ModifiersState}, platform::scancode::KeyCodeExtScancode, platform_impl::platform::{ @@ -344,8 +342,8 @@ impl EventLoopWindowTarget { RawDisplayHandle::Windows(WindowsDisplayHandle::empty()) } - pub fn set_device_event_filter(&self, filter: DeviceEventFilter) { - raw_input::register_all_mice_and_keyboards_for_raw_input(self.thread_msg_target, filter); + pub fn listen_device_events(&self, allowed: DeviceEvents) { + raw_input::register_all_mice_and_keyboards_for_raw_input(self.thread_msg_target, allowed); } } diff --git a/src/platform_impl/windows/raw_input.rs b/src/platform_impl/windows/raw_input.rs index c8d9a8b2..69f2d035 100644 --- a/src/platform_impl/windows/raw_input.rs +++ b/src/platform_impl/windows/raw_input.rs @@ -23,7 +23,7 @@ use windows_sys::Win32::{ }, }; -use crate::{event::ElementState, event_loop::DeviceEventFilter, platform_impl::platform::util}; +use crate::{event::ElementState, event_loop::DeviceEvents, platform_impl::platform::util}; #[allow(dead_code)] pub fn get_raw_input_device_list() -> Option> { @@ -140,18 +140,18 @@ pub fn register_raw_input_devices(devices: &[RAWINPUTDEVICE]) -> bool { pub fn register_all_mice_and_keyboards_for_raw_input( mut window_handle: HWND, - filter: DeviceEventFilter, + filter: DeviceEvents, ) -> bool { // RIDEV_DEVNOTIFY: receive hotplug events // RIDEV_INPUTSINK: receive events even if we're not in the foreground // RIDEV_REMOVE: don't receive device events (requires NULL hwndTarget) let flags = match filter { - DeviceEventFilter::Always => { + DeviceEvents::Never => { window_handle = 0; RIDEV_REMOVE } - DeviceEventFilter::Unfocused => RIDEV_DEVNOTIFY, - DeviceEventFilter::Never => RIDEV_DEVNOTIFY | RIDEV_INPUTSINK, + DeviceEvents::WhenFocused => RIDEV_DEVNOTIFY, + DeviceEvents::Always => RIDEV_DEVNOTIFY | RIDEV_INPUTSINK, }; let devices: [RAWINPUTDEVICE; 2] = [