mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-24 06:11:30 +11:00
Add touch pressure information for touch events on Windows (#1134)
* Add touch pressure information for touch events on Windows * Modified CHANGELOG.md and FEATURES.md to reflect changes * Updated documentation of struct Touch to reflect changes * Replaced mem::uninitalized() with mem::MaybeUninit Fixed warnings in platform_impl/windows/dpi.rs
This commit is contained in:
parent
3273c14dea
commit
068d114740
|
@ -5,6 +5,7 @@
|
||||||
- On X11, performance is improved when rapidly calling `Window::set_cursor_icon`.
|
- On X11, performance is improved when rapidly calling `Window::set_cursor_icon`.
|
||||||
- On iOS, fix improper `msg_send` usage that was UB and/or would break if `!` is stabilized.
|
- On iOS, fix improper `msg_send` usage that was UB and/or would break if `!` is stabilized.
|
||||||
- On Windows, unset `maximized` when manually changing the window's position or size.
|
- On Windows, unset `maximized` when manually changing the window's position or size.
|
||||||
|
- On Windows, add touch pressure information for touch events.
|
||||||
|
|
||||||
# 0.20.0 Alpha 3 (2019-08-14)
|
# 0.20.0 Alpha 3 (2019-08-14)
|
||||||
|
|
||||||
|
|
|
@ -194,7 +194,7 @@ Legend:
|
||||||
|Cursor grab |✔️ |▢[#165] |▢[#242] |❌[#306] |**N/A**|**N/A**|✔️ |
|
|Cursor grab |✔️ |▢[#165] |▢[#242] |❌[#306] |**N/A**|**N/A**|✔️ |
|
||||||
|Cursor icon |✔️ |✔️ |✔️ |❌[#306] |**N/A**|**N/A**|❌ |
|
|Cursor icon |✔️ |✔️ |✔️ |❌[#306] |**N/A**|**N/A**|❌ |
|
||||||
|Touch events |✔️ |❌ |✔️ |✔️ |✔️ |✔️ |✔️ |
|
|Touch events |✔️ |❌ |✔️ |✔️ |✔️ |✔️ |✔️ |
|
||||||
|Touch pressure |❌ |❌ |❌ |❌ |❌ |✔️ |❌ |
|
|Touch pressure |✔️ |❌ |❌ |❌ |❌ |✔️ |❌ |
|
||||||
|Multitouch |✔️ |❌ |✔️ |✔️ |❓ |✔️ |❌ |
|
|Multitouch |✔️ |❌ |✔️ |✔️ |❓ |✔️ |❌ |
|
||||||
|Keyboard events |✔️ |✔️ |✔️ |✔️ |❓ |❌ |✔️ |
|
|Keyboard events |✔️ |✔️ |✔️ |✔️ |❓ |❌ |✔️ |
|
||||||
|Drag & Drop |▢[#720] |▢[#720] |▢[#720] |❌[#306] |**N/A**|**N/A**|❓ |
|
|Drag & Drop |▢[#720] |▢[#720] |▢[#720] |❌[#306] |**N/A**|**N/A**|❓ |
|
||||||
|
|
|
@ -333,7 +333,7 @@ pub struct Touch {
|
||||||
///
|
///
|
||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
/// - Only available on **iOS** 9.0+.
|
/// - Only available on **iOS** 9.0+ and **Windows** 8+.
|
||||||
pub force: Option<Force>,
|
pub force: Option<Force>,
|
||||||
/// Unique identifier of a finger.
|
/// Unique identifier of a finger.
|
||||||
pub id: u64,
|
pub id: u64,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#![allow(non_snake_case, unused_unsafe)]
|
#![allow(non_snake_case, unused_unsafe)]
|
||||||
|
|
||||||
use std::{mem, os::raw::c_void, sync::Once};
|
use std::sync::Once;
|
||||||
|
|
||||||
use winapi::{
|
use winapi::{
|
||||||
shared::{
|
shared::{
|
||||||
|
|
|
@ -46,7 +46,7 @@ use winapi::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
dpi::{LogicalPosition, LogicalSize, PhysicalSize},
|
dpi::{LogicalPosition, LogicalSize, PhysicalSize},
|
||||||
event::{DeviceEvent, Event, KeyboardInput, StartCause, Touch, TouchPhase, WindowEvent},
|
event::{DeviceEvent, Event, Force, KeyboardInput, StartCause, Touch, TouchPhase, WindowEvent},
|
||||||
event_loop::{ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootELW},
|
event_loop::{ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootELW},
|
||||||
platform_impl::platform::{
|
platform_impl::platform::{
|
||||||
dpi::{
|
dpi::{
|
||||||
|
@ -77,6 +77,12 @@ type GetPointerDeviceRects = unsafe extern "system" fn(
|
||||||
displayRect: *mut RECT,
|
displayRect: *mut RECT,
|
||||||
) -> BOOL;
|
) -> BOOL;
|
||||||
|
|
||||||
|
type GetPointerTouchInfo =
|
||||||
|
unsafe extern "system" fn(pointerId: UINT, touchInfo: *mut winuser::POINTER_TOUCH_INFO) -> BOOL;
|
||||||
|
|
||||||
|
type GetPointerPenInfo =
|
||||||
|
unsafe extern "system" fn(pointId: UINT, penInfo: *mut winuser::POINTER_PEN_INFO) -> BOOL;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref GET_POINTER_FRAME_INFO_HISTORY: Option<GetPointerFrameInfoHistory> =
|
static ref GET_POINTER_FRAME_INFO_HISTORY: Option<GetPointerFrameInfoHistory> =
|
||||||
get_function!("user32.dll", GetPointerFrameInfoHistory);
|
get_function!("user32.dll", GetPointerFrameInfoHistory);
|
||||||
|
@ -84,6 +90,10 @@ lazy_static! {
|
||||||
get_function!("user32.dll", SkipPointerFrameMessages);
|
get_function!("user32.dll", SkipPointerFrameMessages);
|
||||||
static ref GET_POINTER_DEVICE_RECTS: Option<GetPointerDeviceRects> =
|
static ref GET_POINTER_DEVICE_RECTS: Option<GetPointerDeviceRects> =
|
||||||
get_function!("user32.dll", GetPointerDeviceRects);
|
get_function!("user32.dll", GetPointerDeviceRects);
|
||||||
|
static ref GET_POINTER_TOUCH_INFO: Option<GetPointerTouchInfo> =
|
||||||
|
get_function!("user32.dll", GetPointerTouchInfo);
|
||||||
|
static ref GET_POINTER_PEN_INFO: Option<GetPointerPenInfo> =
|
||||||
|
get_function!("user32.dll", GetPointerPenInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct SubclassInput<T> {
|
pub(crate) struct SubclassInput<T> {
|
||||||
|
@ -852,6 +862,13 @@ pub(crate) fn subclass_window<T>(window: HWND, subclass_input: SubclassInput<T>)
|
||||||
assert_eq!(subclass_result, 1);
|
assert_eq!(subclass_result, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn normalize_pointer_pressure(pressure: u32) -> Option<Force> {
|
||||||
|
match pressure {
|
||||||
|
1..=1024 => Some(Force::Normalized(pressure as f64 / 1024.0)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Any window whose callback is configured to this function will have its events propagated
|
/// Any window whose callback is configured to this function will have its events propagated
|
||||||
/// through the events loop of the thread the window was created in.
|
/// through the events loop of the thread the window was created in.
|
||||||
//
|
//
|
||||||
|
@ -1499,7 +1516,7 @@ unsafe extern "system" fn public_window_callback<T>(
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
location,
|
location,
|
||||||
force: None, // TODO
|
force: None, // WM_TOUCH doesn't support pressure information
|
||||||
id: input.dwID as u64,
|
id: input.dwID as u64,
|
||||||
device_id: DEVICE_ID,
|
device_id: DEVICE_ID,
|
||||||
}),
|
}),
|
||||||
|
@ -1551,18 +1568,21 @@ unsafe extern "system" fn public_window_callback<T>(
|
||||||
// The information retrieved appears in reverse chronological order, with the most recent entry in the first
|
// The information retrieved appears in reverse chronological order, with the most recent entry in the first
|
||||||
// row of the returned array
|
// row of the returned array
|
||||||
for pointer_info in pointer_infos.iter().rev() {
|
for pointer_info in pointer_infos.iter().rev() {
|
||||||
let mut device_rect: RECT = mem::uninitialized();
|
let mut device_rect = mem::MaybeUninit::uninit();
|
||||||
let mut display_rect: RECT = mem::uninitialized();
|
let mut display_rect = mem::MaybeUninit::uninit();
|
||||||
|
|
||||||
if (GetPointerDeviceRects(
|
if (GetPointerDeviceRects(
|
||||||
pointer_info.sourceDevice,
|
pointer_info.sourceDevice,
|
||||||
&mut device_rect as *mut _,
|
device_rect.as_mut_ptr(),
|
||||||
&mut display_rect as *mut _,
|
display_rect.as_mut_ptr(),
|
||||||
)) == 0
|
)) == 0
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let device_rect = device_rect.assume_init();
|
||||||
|
let display_rect = display_rect.assume_init();
|
||||||
|
|
||||||
// For the most precise himetric to pixel conversion we calculate the ratio between the resolution
|
// For the most precise himetric to pixel conversion we calculate the ratio between the resolution
|
||||||
// of the display device (pixel) and the touch device (himetric).
|
// of the display device (pixel) and the touch device (himetric).
|
||||||
let himetric_to_pixel_ratio_x = (display_rect.right - display_rect.left) as f64
|
let himetric_to_pixel_ratio_x = (display_rect.right - display_rect.left) as f64
|
||||||
|
@ -1587,6 +1607,38 @@ unsafe extern "system" fn public_window_callback<T>(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let force = match pointer_info.pointerType {
|
||||||
|
winuser::PT_TOUCH => {
|
||||||
|
let mut touch_info = mem::MaybeUninit::uninit();
|
||||||
|
GET_POINTER_TOUCH_INFO.and_then(|GetPointerTouchInfo| {
|
||||||
|
match GetPointerTouchInfo(
|
||||||
|
pointer_info.pointerId,
|
||||||
|
touch_info.as_mut_ptr(),
|
||||||
|
) {
|
||||||
|
0 => None,
|
||||||
|
_ => normalize_pointer_pressure(
|
||||||
|
touch_info.assume_init().pressure,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
winuser::PT_PEN => {
|
||||||
|
let mut pen_info = mem::MaybeUninit::uninit();
|
||||||
|
GET_POINTER_PEN_INFO.and_then(|GetPointerPenInfo| {
|
||||||
|
match GetPointerPenInfo(
|
||||||
|
pointer_info.pointerId,
|
||||||
|
pen_info.as_mut_ptr(),
|
||||||
|
) {
|
||||||
|
0 => None,
|
||||||
|
_ => {
|
||||||
|
normalize_pointer_pressure(pen_info.assume_init().pressure)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
|
||||||
let x = location.x as f64 + x.fract();
|
let x = location.x as f64 + x.fract();
|
||||||
let y = location.y as f64 + y.fract();
|
let y = location.y as f64 + y.fract();
|
||||||
let location = LogicalPosition::from_physical((x, y), dpi_factor);
|
let location = LogicalPosition::from_physical((x, y), dpi_factor);
|
||||||
|
@ -1604,7 +1656,7 @@ unsafe extern "system" fn public_window_callback<T>(
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
location,
|
location,
|
||||||
force: None, // TODO
|
force,
|
||||||
id: pointer_info.pointerId as u64,
|
id: pointer_info.pointerId as u64,
|
||||||
device_id: DEVICE_ID,
|
device_id: DEVICE_ID,
|
||||||
}),
|
}),
|
||||||
|
|
Loading…
Reference in a new issue