winit-core:winit: add tablet input support

The API is integrated into the `WindowEvent::Pointer*` API and is
present in form of `TabletTool` variant on corresponding data entries.

For now implemented for Web, Windows, and with limitations for Wayland.

Fixes #99.

Co-authored-by: daxpedda <daxpedda@gmail.com>
This commit is contained in:
Kirill Chibisov
2025-10-07 21:42:36 +09:00
committed by GitHub
parent ffcdf80192
commit f046e778aa
23 changed files with 1206 additions and 204 deletions

View File

@@ -33,8 +33,8 @@ use xkbcommon_dl::xkb_mod_mask_t;
use crate::atoms::*;
use crate::dnd::{Dnd, DndState};
use crate::event_loop::{
mkdid, mkwid, ActiveEventLoop, CookieResultExt, Device, DeviceInfo, ScrollOrientation,
ALL_DEVICES,
mkdid, mkwid, ActiveEventLoop, CookieResultExt, Device, DeviceInfo, DeviceType,
ScrollOrientation, ALL_DEVICES,
};
use crate::ime::{ImeEvent, ImeEventReceiver, ImeReceiver, ImeRequest};
use crate::util;
@@ -323,8 +323,10 @@ impl EventProcessor {
pub fn init_device(&self, device: xinput::DeviceId) {
let mut devices = self.devices.borrow_mut();
if let Some(info) = DeviceInfo::get(&self.target.xconn, device as _) {
let atoms = self.target.x_connection().atoms();
for info in info.iter() {
devices.insert(mkdid(info.deviceid as xinput::DeviceId), Device::new(info));
devices.insert(mkdid(info.deviceid as xinput::DeviceId), Device::new(info, atoms));
}
}
}
@@ -974,6 +976,15 @@ impl EventProcessor {
// Set the timestamp.
self.target.xconn.set_timestamp(event.time as xproto::Timestamp);
let Some(DeviceType::Mouse) = self
.devices
.borrow()
.get(&mkdid(event.sourceid as xinput::DeviceId))
.map(|device| device.r#type)
else {
return;
};
// Deliver multi-touch events instead of emulated mouse events.
if (event.flags & xinput2::XIPointerEmulated) != 0 {
return;
@@ -1051,6 +1062,15 @@ impl EventProcessor {
// Set the timestamp.
self.target.xconn.set_timestamp(event.time as xproto::Timestamp);
let Some(DeviceType::Mouse) = self
.devices
.borrow()
.get(&mkdid(event.sourceid as xinput::DeviceId))
.map(|device| device.r#type)
else {
return;
};
let device_id = Some(mkdid(event.deviceid as xinput::DeviceId));
let window = event.event as xproto::Window;
let window_id = mkwid(window);
@@ -1376,7 +1396,6 @@ impl EventProcessor {
self.target.xconn.set_timestamp(xev.time as xproto::Timestamp);
let did = Some(mkdid(xev.deviceid as xinput::DeviceId));
let mask =
unsafe { slice::from_raw_parts(xev.valuators.mask, xev.valuators.mask_len as usize) };
let mut value = xev.raw_values;
@@ -1401,6 +1420,15 @@ impl EventProcessor {
value = unsafe { value.offset(1) };
}
let Some(DeviceType::Mouse) = self
.devices
.borrow()
.get(&mkdid(xev.sourceid as xinput::DeviceId))
.map(|device| device.r#type)
else {
return;
};
if let Some(mouse_delta) = mouse_delta.consume() {
app.device_event(&self.target, did, DeviceEvent::PointerMotion { delta: mouse_delta });
}