mirror of
https://github.com/rust-windowing/winit.git
synced 2026-08-31 05:40:04 -04:00
win32: account for mouse wheel speed setting
Also adds a method to toggle this behavior during runtime.
This commit is contained in:
@@ -42,22 +42,23 @@ use windows_sys::Win32::UI::Input::{
|
||||
use windows_sys::Win32::UI::WindowsAndMessaging::{
|
||||
CreateWindowExW, DefWindowProcW, DestroyWindow, DispatchMessageW, GetClientRect, GetCursorPos,
|
||||
GetMenu, LoadCursorW, MsgWaitForMultipleObjectsEx, PeekMessageW, PostMessageW,
|
||||
RegisterClassExW, RegisterWindowMessageA, SetCursor, SetWindowPos, TranslateMessage,
|
||||
CREATESTRUCTW, GWL_STYLE, GWL_USERDATA, HTCAPTION, HTCLIENT, MINMAXINFO, MNC_CLOSE, MSG,
|
||||
MWMO_INPUTAVAILABLE, NCCALCSIZE_PARAMS, PM_REMOVE, PT_TOUCH, QS_ALLINPUT, RI_MOUSE_HWHEEL,
|
||||
RI_MOUSE_WHEEL, SC_MINIMIZE, SC_RESTORE, SIZE_MAXIMIZED, SWP_NOACTIVATE, SWP_NOMOVE,
|
||||
SWP_NOSIZE, SWP_NOZORDER, WHEEL_DELTA, WINDOWPOS, WMSZ_BOTTOM, WMSZ_BOTTOMLEFT,
|
||||
WMSZ_BOTTOMRIGHT, WMSZ_LEFT, WMSZ_RIGHT, WMSZ_TOP, WMSZ_TOPLEFT, WMSZ_TOPRIGHT,
|
||||
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_KEYDOWN, WM_KEYUP, WM_KILLFOCUS,
|
||||
WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN, WM_MBUTTONUP, WM_MENUCHAR, WM_MOUSEHWHEEL,
|
||||
WM_MOUSEMOVE, WM_MOUSEWHEEL, WM_NCACTIVATE, WM_NCCALCSIZE, WM_NCCREATE, WM_NCDESTROY,
|
||||
WM_NCLBUTTONDOWN, WM_PAINT, WM_POINTERDOWN, WM_POINTERUP, WM_POINTERUPDATE, WM_RBUTTONDOWN,
|
||||
WM_RBUTTONUP, WM_SETCURSOR, WM_SETFOCUS, WM_SETTINGCHANGE, WM_SIZE, WM_SIZING, WM_SYSCOMMAND,
|
||||
WM_SYSKEYDOWN, WM_SYSKEYUP, WM_TOUCH, WM_WINDOWPOSCHANGED, WM_WINDOWPOSCHANGING,
|
||||
WM_XBUTTONDOWN, WM_XBUTTONUP, WNDCLASSEXW, WS_EX_LAYERED, WS_EX_NOACTIVATE, WS_EX_TOOLWINDOW,
|
||||
WS_EX_TRANSPARENT, WS_OVERLAPPED, WS_POPUP, WS_VISIBLE,
|
||||
RegisterClassExW, RegisterWindowMessageA, SetCursor, SetWindowPos, SystemParametersInfoW,
|
||||
TranslateMessage, CREATESTRUCTW, GWL_STYLE, GWL_USERDATA, HTCAPTION, HTCLIENT, MINMAXINFO,
|
||||
MNC_CLOSE, MSG, MWMO_INPUTAVAILABLE, NCCALCSIZE_PARAMS, PM_REMOVE, PT_TOUCH, QS_ALLINPUT,
|
||||
RI_MOUSE_HWHEEL, RI_MOUSE_WHEEL, SC_MINIMIZE, SC_RESTORE, SIZE_MAXIMIZED,
|
||||
SPI_GETWHEELSCROLLCHARS, SPI_GETWHEELSCROLLLINES, SWP_NOACTIVATE, SWP_NOMOVE, SWP_NOSIZE,
|
||||
SWP_NOZORDER, WHEEL_DELTA, WINDOWPOS, WMSZ_BOTTOM, WMSZ_BOTTOMLEFT, WMSZ_BOTTOMRIGHT,
|
||||
WMSZ_LEFT, WMSZ_RIGHT, WMSZ_TOP, WMSZ_TOPLEFT, WMSZ_TOPRIGHT, 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_KEYDOWN, WM_KEYUP, WM_KILLFOCUS, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN,
|
||||
WM_MBUTTONUP, WM_MENUCHAR, WM_MOUSEHWHEEL, WM_MOUSEMOVE, WM_MOUSEWHEEL, WM_NCACTIVATE,
|
||||
WM_NCCALCSIZE, WM_NCCREATE, WM_NCDESTROY, WM_NCLBUTTONDOWN, WM_PAINT, WM_POINTERDOWN,
|
||||
WM_POINTERUP, WM_POINTERUPDATE, WM_RBUTTONDOWN, WM_RBUTTONUP, WM_SETCURSOR, WM_SETFOCUS,
|
||||
WM_SETTINGCHANGE, WM_SIZE, WM_SIZING, WM_SYSCOMMAND, WM_SYSKEYDOWN, WM_SYSKEYUP, WM_TOUCH,
|
||||
WM_WINDOWPOSCHANGED, WM_WINDOWPOSCHANGING, WM_XBUTTONDOWN, WM_XBUTTONUP, WNDCLASSEXW,
|
||||
WS_EX_LAYERED, WS_EX_NOACTIVATE, WS_EX_TOOLWINDOW, WS_EX_TRANSPARENT, WS_OVERLAPPED, WS_POPUP,
|
||||
WS_VISIBLE,
|
||||
};
|
||||
use winit_core::application::ApplicationHandler;
|
||||
use winit_core::cursor::{CustomCursor, CustomCursorSource};
|
||||
@@ -92,6 +93,13 @@ use crate::window::{InitData, Window};
|
||||
use crate::window_state::{CursorFlags, ImeState, WindowFlags, WindowState};
|
||||
use crate::{raw_input, util};
|
||||
|
||||
// This is defined in `winuser.h` as a macro that expands to `UINT_MAX`
|
||||
const WHEEL_PAGESCROLL: u32 = u32::MAX;
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-systemparametersinfoa#:~:text=SPI_GETWHEELSCROLLLINES
|
||||
const DEFAULT_SCROLL_LINES_PER_WHEEL_DELTA: isize = 3;
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-systemparametersinfoa#:~:text=SPI_GETWHEELSCROLLCHARS
|
||||
const DEFAULT_SCROLL_CHARACTERS_PER_WHEEL_DELTA: isize = 3;
|
||||
|
||||
pub(crate) struct WindowData {
|
||||
pub window_state: Arc<Mutex<WindowState>>,
|
||||
pub event_loop_runner: Rc<EventLoopRunner>,
|
||||
@@ -1636,9 +1644,26 @@ unsafe fn public_window_callback_inner(
|
||||
|
||||
update_modifiers(window, userdata);
|
||||
|
||||
let scroll_lines_multiplier = if userdata.window_state_lock().use_system_wheel_speed {
|
||||
let mut scroll_lines = DEFAULT_SCROLL_LINES_PER_WHEEL_DELTA;
|
||||
let _ = SystemParametersInfoW(
|
||||
SPI_GETWHEELSCROLLLINES,
|
||||
0,
|
||||
&mut scroll_lines as *mut isize as *mut c_void,
|
||||
0,
|
||||
);
|
||||
if scroll_lines as u32 == WHEEL_PAGESCROLL {
|
||||
// TODO: figure out how to handle page scrolls
|
||||
scroll_lines = DEFAULT_SCROLL_LINES_PER_WHEEL_DELTA;
|
||||
}
|
||||
scroll_lines
|
||||
} else {
|
||||
1
|
||||
};
|
||||
|
||||
userdata.send_window_event(window, WindowEvent::MouseWheel {
|
||||
device_id: None,
|
||||
delta: LineDelta(0.0, value),
|
||||
delta: LineDelta(0.0, value * scroll_lines_multiplier as f32),
|
||||
phase: TouchPhase::Moved,
|
||||
});
|
||||
|
||||
@@ -1653,9 +1678,23 @@ unsafe fn public_window_callback_inner(
|
||||
|
||||
update_modifiers(window, userdata);
|
||||
|
||||
let scroll_characters_multiplier =
|
||||
if userdata.window_state_lock().use_system_wheel_speed {
|
||||
let mut scroll_characters = DEFAULT_SCROLL_CHARACTERS_PER_WHEEL_DELTA;
|
||||
let _ = SystemParametersInfoW(
|
||||
SPI_GETWHEELSCROLLCHARS,
|
||||
0,
|
||||
&mut scroll_characters as *mut isize as *mut c_void,
|
||||
0,
|
||||
);
|
||||
scroll_characters
|
||||
} else {
|
||||
1
|
||||
};
|
||||
|
||||
userdata.send_window_event(window, WindowEvent::MouseWheel {
|
||||
device_id: None,
|
||||
delta: LineDelta(value, 0.0),
|
||||
delta: LineDelta(value * scroll_characters_multiplier as f32, 0.0),
|
||||
phase: TouchPhase::Moved,
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user