Skip to content

Commit

Permalink
feat(windows): Fix inconsistency in mouse button device events, add h…
Browse files Browse the repository at this point in the history
…wheel 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.
  • Loading branch information
valaphee authored and kchibisov committed Oct 21, 2023
1 parent 0656c54 commit 40ba9a7
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 35 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,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

Expand Down
38 changes: 21 additions & 17 deletions src/platform_impl/windows/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -1542,7 +1542,6 @@ unsafe fn public_window_callback_inner<T: 'static>(
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);
Expand All @@ -1563,7 +1562,6 @@ unsafe fn public_window_callback_inner<T: 'static>(
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);
Expand Down Expand Up @@ -2450,30 +2448,36 @@ unsafe fn handle_raw_input<T: 'static>(userdata: &ThreadMsgTargetData<T>, 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 {
delta: LineDelta(0.0, delta),
},
});
}
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,
},
});
}
}
Expand Down
28 changes: 10 additions & 18 deletions src/platform_impl/windows/raw_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
},
};
Expand Down Expand Up @@ -209,22 +211,12 @@ fn button_flags_to_element_state(
}
}

pub fn get_raw_mouse_button_state(button_flags: u32) -> [Option<ElementState>; 3] {
pub fn get_raw_mouse_button_state(button_flags: u32) -> [Option<ElementState>; 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),
]
}

0 comments on commit 40ba9a7

Please sign in to comment.