On Windows, add opt-in function for device events (#2409)

This commit is contained in:
ajtribick 2022-08-11 15:17:46 +02:00 committed by GitHub
parent b1c9e4a6fa
commit 9b71df9f97
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 32 additions and 10 deletions

View file

@ -11,6 +11,7 @@ And please only add new entries to the top of this list, right below the `# Unre
- On macOS, fixed touch phase reporting when scrolling. - On macOS, fixed touch phase reporting when scrolling.
- On X11, fix min, max and resize increment hints not persisting for resizable windows (e.g. on DPI change). - On X11, fix min, max and resize increment hints not persisting for resizable windows (e.g. on DPI change).
- On Windows, respect min/max inner sizes when creating the window. - On Windows, respect min/max inner sizes when creating the window.
- **Breaking:** On Windows, device events are now ignored for unfocused windows by default, use `EventLoopWindowTarget::set_device_event_filter` to set the filter level.
# 0.27.1 (2022-07-30) # 0.27.1 (2022-07-30)

View file

@ -323,7 +323,7 @@ impl<T> EventLoopWindowTarget<T> {
/// ///
/// ## Platform-specific /// ## Platform-specific
/// ///
/// - **Wayland / Windows / macOS / iOS / Android / Web:** Unsupported. /// - **Wayland / macOS / iOS / Android / Web:** Unsupported.
/// ///
/// [`DeviceEvent`]: crate::event::DeviceEvent /// [`DeviceEvent`]: crate::event::DeviceEvent
pub fn set_device_event_filter(&self, _filter: DeviceEventFilter) { pub fn set_device_event_filter(&self, _filter: DeviceEventFilter) {
@ -332,7 +332,8 @@ impl<T> EventLoopWindowTarget<T> {
target_os = "dragonfly", target_os = "dragonfly",
target_os = "freebsd", target_os = "freebsd",
target_os = "netbsd", target_os = "netbsd",
target_os = "openbsd" target_os = "openbsd",
target_os = "windows"
))] ))]
self.p.set_device_event_filter(_filter); self.p.set_device_event_filter(_filter);
} }

View file

@ -77,7 +77,9 @@ use windows_sys::Win32::{
use crate::{ use crate::{
dpi::{PhysicalPosition, PhysicalSize}, dpi::{PhysicalPosition, PhysicalSize},
event::{DeviceEvent, Event, Force, Ime, KeyboardInput, Touch, TouchPhase, WindowEvent}, event::{DeviceEvent, Event, Force, Ime, KeyboardInput, Touch, TouchPhase, WindowEvent},
event_loop::{ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootELW}, event_loop::{
ControlFlow, DeviceEventFilter, EventLoopClosed, EventLoopWindowTarget as RootELW,
},
monitor::MonitorHandle as RootMonitorHandle, monitor::MonitorHandle as RootMonitorHandle,
platform_impl::platform::{ platform_impl::platform::{
dark_mode::try_theme, dark_mode::try_theme,
@ -207,7 +209,10 @@ impl<T: 'static> EventLoop<T> {
let thread_msg_sender = let thread_msg_sender =
insert_event_target_window_data::<T>(thread_msg_target, runner_shared.clone()); insert_event_target_window_data::<T>(thread_msg_target, runner_shared.clone());
raw_input::register_all_mice_and_keyboards_for_raw_input(thread_msg_target); raw_input::register_all_mice_and_keyboards_for_raw_input(
thread_msg_target,
Default::default(),
);
EventLoop { EventLoop {
thread_msg_sender, thread_msg_sender,
@ -322,6 +327,10 @@ impl<T> EventLoopWindowTarget<T> {
pub fn raw_display_handle(&self) -> RawDisplayHandle { pub fn raw_display_handle(&self) -> RawDisplayHandle {
RawDisplayHandle::Windows(WindowsDisplayHandle::empty()) 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);
}
} }
/// Returns the id of the main thread. /// Returns the id of the main thread.

View file

@ -12,9 +12,9 @@ use windows_sys::Win32::{
Input::{ Input::{
GetRawInputData, GetRawInputDeviceInfoW, GetRawInputDeviceList, GetRawInputData, GetRawInputDeviceInfoW, GetRawInputDeviceList,
RegisterRawInputDevices, HRAWINPUT, RAWINPUT, RAWINPUTDEVICE, RAWINPUTDEVICELIST, RegisterRawInputDevices, HRAWINPUT, RAWINPUT, RAWINPUTDEVICE, RAWINPUTDEVICELIST,
RAWINPUTHEADER, RIDEV_DEVNOTIFY, RIDEV_INPUTSINK, RIDI_DEVICEINFO, RIDI_DEVICENAME, RAWINPUTHEADER, RIDEV_DEVNOTIFY, RIDEV_INPUTSINK, RIDEV_REMOVE, RIDI_DEVICEINFO,
RID_DEVICE_INFO, RID_DEVICE_INFO_HID, RID_DEVICE_INFO_KEYBOARD, RID_DEVICE_INFO_MOUSE, RIDI_DEVICENAME, RID_DEVICE_INFO, RID_DEVICE_INFO_HID, RID_DEVICE_INFO_KEYBOARD,
RID_INPUT, RIM_TYPEHID, RIM_TYPEKEYBOARD, RIM_TYPEMOUSE, RID_DEVICE_INFO_MOUSE, RID_INPUT, RIM_TYPEHID, RIM_TYPEKEYBOARD, RIM_TYPEMOUSE,
}, },
WindowsAndMessaging::{ WindowsAndMessaging::{
RI_MOUSE_LEFT_BUTTON_DOWN, RI_MOUSE_LEFT_BUTTON_UP, RI_MOUSE_MIDDLE_BUTTON_DOWN, RI_MOUSE_LEFT_BUTTON_DOWN, RI_MOUSE_LEFT_BUTTON_UP, RI_MOUSE_MIDDLE_BUTTON_DOWN,
@ -23,7 +23,7 @@ use windows_sys::Win32::{
}, },
}; };
use crate::{event::ElementState, platform_impl::platform::util}; use crate::{event::ElementState, event_loop::DeviceEventFilter, platform_impl::platform::util};
#[allow(dead_code)] #[allow(dead_code)]
pub fn get_raw_input_device_list() -> Option<Vec<RAWINPUTDEVICELIST>> { pub fn get_raw_input_device_list() -> Option<Vec<RAWINPUTDEVICELIST>> {
@ -138,10 +138,21 @@ pub fn register_raw_input_devices(devices: &[RAWINPUTDEVICE]) -> bool {
} }
} }
pub fn register_all_mice_and_keyboards_for_raw_input(window_handle: HWND) -> bool { pub fn register_all_mice_and_keyboards_for_raw_input(
mut window_handle: HWND,
filter: DeviceEventFilter,
) -> bool {
// RIDEV_DEVNOTIFY: receive hotplug events // RIDEV_DEVNOTIFY: receive hotplug events
// RIDEV_INPUTSINK: receive events even if we're not in the foreground // RIDEV_INPUTSINK: receive events even if we're not in the foreground
let flags = RIDEV_DEVNOTIFY | RIDEV_INPUTSINK; // RIDEV_REMOVE: don't receive device events (requires NULL hwndTarget)
let flags = match filter {
DeviceEventFilter::Always => {
window_handle = 0;
RIDEV_REMOVE
}
DeviceEventFilter::Unfocused => RIDEV_DEVNOTIFY,
DeviceEventFilter::Never => RIDEV_DEVNOTIFY | RIDEV_INPUTSINK,
};
let devices: [RAWINPUTDEVICE; 2] = [ let devices: [RAWINPUTDEVICE; 2] = [
RAWINPUTDEVICE { RAWINPUTDEVICE {