From 89a184ed848ad42d431f7efc2dd6c120bbaedc1e Mon Sep 17 00:00:00 2001 From: Valaphee The Meerkat <32491319+valaphee@users.noreply.github.com> Date: Fri, 20 Oct 2023 19:03:05 +0200 Subject: [PATCH] feat(windows): Fix inconsistency in mouse button device events, add hwheel device event on Windows While working with device events, I noticed that there was an inconsistency in the mouse button device events between Windows/X11 and for example web, because web uses the same ids/order as the MouseButton enum, and Windows/X11 are using the X11 ids, and hwheel device event was ignored on Windows. Mouse button device events are now using the same order as the MouseButton enum, and I also added hwheel device events for Windows. --- CHANGELOG.md | 1 + src/platform_impl/windows/event_loop.rs | 38 ++++++++++++++----------- src/platform_impl/windows/raw_input.rs | 28 +++++++----------- 3 files changed, 32 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 28da7ec0..0be030ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ And please only add new entries to the top of this list, right below the `# Unre - On macOS, fix crash when accessing tabbing APIs. - On Windows, fix `RedrawRequested` not being delivered when calling `Window::request_redraw` from `RedrawRequested`. - On Windows, fix IME APIs not working when from non event loop thread. +- Add horizontal MouseWheel DeviceEvent on Windows # 0.29.1-beta diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 7cc105a3..59e5c9d5 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -54,10 +54,10 @@ use windows_sys::Win32::{ RegisterClassExW, RegisterWindowMessageA, SetCursor, SetTimer, SetWindowPos, TranslateMessage, CREATESTRUCTW, GIDC_ARRIVAL, GIDC_REMOVAL, GWL_STYLE, GWL_USERDATA, HTCAPTION, HTCLIENT, MINMAXINFO, MNC_CLOSE, MSG, NCCALCSIZE_PARAMS, PM_REMOVE, PT_PEN, - PT_TOUCH, RI_KEY_E0, RI_KEY_E1, RI_MOUSE_WHEEL, SC_MINIMIZE, SC_RESTORE, - SIZE_MAXIMIZED, SWP_NOACTIVATE, SWP_NOMOVE, SWP_NOSIZE, SWP_NOZORDER, WHEEL_DELTA, - WINDOWPOS, WM_CAPTURECHANGED, WM_CLOSE, WM_CREATE, WM_DESTROY, WM_DPICHANGED, - WM_ENTERSIZEMOVE, WM_EXITSIZEMOVE, WM_GETMINMAXINFO, WM_IME_COMPOSITION, + PT_TOUCH, RI_KEY_E0, RI_KEY_E1, RI_MOUSE_HWHEEL, RI_MOUSE_WHEEL, SC_MINIMIZE, + SC_RESTORE, SIZE_MAXIMIZED, SWP_NOACTIVATE, SWP_NOMOVE, SWP_NOSIZE, SWP_NOZORDER, + WHEEL_DELTA, WINDOWPOS, WM_CAPTURECHANGED, WM_CLOSE, WM_CREATE, WM_DESTROY, + WM_DPICHANGED, WM_ENTERSIZEMOVE, WM_EXITSIZEMOVE, WM_GETMINMAXINFO, WM_IME_COMPOSITION, WM_IME_ENDCOMPOSITION, WM_IME_SETCONTEXT, WM_IME_STARTCOMPOSITION, WM_INPUT, WM_INPUT_DEVICE_CHANGE, WM_KEYDOWN, WM_KEYUP, WM_KILLFOCUS, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN, WM_MBUTTONUP, WM_MENUCHAR, WM_MOUSEHWHEEL, WM_MOUSEMOVE, @@ -1542,7 +1542,6 @@ unsafe fn public_window_callback_inner( use crate::event::MouseScrollDelta::LineDelta; let value = (wparam >> 16) as i16; - let value = value as i32; let value = value as f32 / WHEEL_DELTA as f32; update_modifiers(window, userdata); @@ -1563,7 +1562,6 @@ unsafe fn public_window_callback_inner( use crate::event::MouseScrollDelta::LineDelta; let value = (wparam >> 16) as i16; - let value = value as i32; let value = -value as f32 / WHEEL_DELTA as f32; // NOTE: inverted! See https://github.com/rust-windowing/winit/pull/2105/ update_modifiers(window, userdata); @@ -2450,11 +2448,9 @@ unsafe fn handle_raw_input(userdata: &ThreadMsgTargetData, data: } let button_flags = unsafe { mouse.Anonymous.Anonymous.usButtonFlags }; - if util::has_flag(button_flags as u32, RI_MOUSE_WHEEL) { - let button_data = unsafe { mouse.Anonymous.Anonymous.usButtonData }; - // We must cast to i16 first, becaues `usButtonData` must be interpreted as signed. - let delta = button_data as i16 as f32 / WHEEL_DELTA as f32; + let button_data = unsafe { mouse.Anonymous.Anonymous.usButtonData } as i16; + let delta = button_data as f32 / WHEEL_DELTA as f32; userdata.send_event(Event::DeviceEvent { device_id, event: MouseWheel { @@ -2462,18 +2458,26 @@ unsafe fn handle_raw_input(userdata: &ThreadMsgTargetData, data: }, }); } + if util::has_flag(button_flags as u32, RI_MOUSE_HWHEEL) { + let button_data = unsafe { mouse.Anonymous.Anonymous.usButtonData } as i16; + let delta = -button_data as f32 / WHEEL_DELTA as f32; + userdata.send_event(Event::DeviceEvent { + device_id, + event: MouseWheel { + delta: LineDelta(delta, 0.0), + }, + }); + } let button_state = raw_input::get_raw_mouse_button_state(button_flags as u32); - // Left, middle, and right, respectively. - for (index, state) in button_state.iter().enumerate() { + for (button, state) in button_state.iter().enumerate() { if let Some(state) = *state { - // This gives us consistency with X11, since there doesn't - // seem to be anything else reasonable to do for a mouse - // button ID. - let button = (index + 1) as _; userdata.send_event(Event::DeviceEvent { device_id, - event: Button { button, state }, + event: Button { + button: button as _, + state, + }, }); } } diff --git a/src/platform_impl/windows/raw_input.rs b/src/platform_impl/windows/raw_input.rs index 69f2d035..eeec93e7 100644 --- a/src/platform_impl/windows/raw_input.rs +++ b/src/platform_impl/windows/raw_input.rs @@ -17,8 +17,10 @@ use windows_sys::Win32::{ RID_DEVICE_INFO_MOUSE, RID_INPUT, RIM_TYPEHID, RIM_TYPEKEYBOARD, RIM_TYPEMOUSE, }, WindowsAndMessaging::{ - RI_MOUSE_LEFT_BUTTON_DOWN, RI_MOUSE_LEFT_BUTTON_UP, RI_MOUSE_MIDDLE_BUTTON_DOWN, - RI_MOUSE_MIDDLE_BUTTON_UP, RI_MOUSE_RIGHT_BUTTON_DOWN, RI_MOUSE_RIGHT_BUTTON_UP, + RI_MOUSE_BUTTON_1_DOWN, RI_MOUSE_BUTTON_1_UP, RI_MOUSE_BUTTON_2_DOWN, + RI_MOUSE_BUTTON_2_UP, RI_MOUSE_BUTTON_3_DOWN, RI_MOUSE_BUTTON_3_UP, + RI_MOUSE_BUTTON_4_DOWN, RI_MOUSE_BUTTON_4_UP, RI_MOUSE_BUTTON_5_DOWN, + RI_MOUSE_BUTTON_5_UP, }, }, }; @@ -209,22 +211,12 @@ fn button_flags_to_element_state( } } -pub fn get_raw_mouse_button_state(button_flags: u32) -> [Option; 3] { +pub fn get_raw_mouse_button_state(button_flags: u32) -> [Option; 5] { [ - button_flags_to_element_state( - button_flags, - RI_MOUSE_LEFT_BUTTON_DOWN, - RI_MOUSE_LEFT_BUTTON_UP, - ), - button_flags_to_element_state( - button_flags, - RI_MOUSE_MIDDLE_BUTTON_DOWN, - RI_MOUSE_MIDDLE_BUTTON_UP, - ), - button_flags_to_element_state( - button_flags, - RI_MOUSE_RIGHT_BUTTON_DOWN, - RI_MOUSE_RIGHT_BUTTON_UP, - ), + button_flags_to_element_state(button_flags, RI_MOUSE_BUTTON_1_DOWN, RI_MOUSE_BUTTON_1_UP), + button_flags_to_element_state(button_flags, RI_MOUSE_BUTTON_2_DOWN, RI_MOUSE_BUTTON_2_UP), + button_flags_to_element_state(button_flags, RI_MOUSE_BUTTON_3_DOWN, RI_MOUSE_BUTTON_3_UP), + button_flags_to_element_state(button_flags, RI_MOUSE_BUTTON_4_DOWN, RI_MOUSE_BUTTON_4_UP), + button_flags_to_element_state(button_flags, RI_MOUSE_BUTTON_5_DOWN, RI_MOUSE_BUTTON_5_UP), ] }