Skip to content

Commit

Permalink
Workaround for hovering pens and touch rejection
Browse files Browse the repository at this point in the history
Some browsers do not send a pointer event to indicate that a hovering
pen has left the hovering range. This results in the pen still being
active, even if there are touch events and the pen is lifted. In this
case we manually remove the pen to prevent touch rejection.
  • Loading branch information
H-M-H committed Oct 18, 2024
1 parent 296d5de commit d2cdd2c
Showing 1 changed file with 26 additions and 0 deletions.
26 changes: 26 additions & 0 deletions src/input/uinput_device.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::cmp::Ordering;
use std::ffi::CString;
use std::os::raw::{c_char, c_int};
use std::time::{Duration, Instant};

use crate::capturable::x11::X11Context;
use crate::capturable::{Capturable, Geometry};
Expand Down Expand Up @@ -35,6 +36,7 @@ pub struct UInputDevice {
touches: [Option<MultiTouch>; 5],
tool_pen_active: bool,
pen_touching: bool,
last_pen_event: Instant,
capturable: Box<dyn Capturable>,
geometry: Rect,
name_mouse_device: String,
Expand Down Expand Up @@ -99,6 +101,7 @@ impl UInputDevice {
touches: Default::default(),
tool_pen_active: false,
pen_touching: false,
last_pen_event: Instant::now(),
capturable,
geometry: Rect::default(),
name_mouse_device: name_mouse,
Expand Down Expand Up @@ -304,6 +307,28 @@ impl InputDevice for UInputDevice {
}
self.num_touch_mapping_tries += 1;
}

// This is a workaround for browsers that send events when the pen is hovering but
// do not send an event when the pen leaves the hovering range. If the pen is left
// in this state touch rejection may stay active and touch won't work.
// Therefore, we manually remove the pen after a short delay.
if self.tool_pen_active
&& !self.pen_touching
&& (Instant::now() - self.last_pen_event) > Duration::from_millis(50)
{
self.tool_pen_active = false;
self.send(self.stylus_fd, ET_KEY, EC_KEY_TOUCH, 0);
self.send(self.stylus_fd, ET_KEY, EC_KEY_TOOL_PEN, 0);
self.send(self.stylus_fd, ET_KEY, EC_KEY_TOOL_RUBBER, 0);
self.send(self.stylus_fd, ET_ABSOLUTE, EC_ABSOLUTE_PRESSURE, 0);
self.send(
self.stylus_fd,
ET_MSC,
EC_MSC_TIMESTAMP,
(event.timestamp % (i32::MAX as u64 + 1)) as i32,
);
self.send(self.stylus_fd, ET_SYNC, EC_SYNC_REPORT, 0);
}
match event.event_type {
PointerEventType::DOWN
| PointerEventType::MOVE
Expand Down Expand Up @@ -446,6 +471,7 @@ impl InputDevice for UInputDevice {
};
}
PointerType::Pen => {
self.last_pen_event = Instant::now();
if self.num_stylus_mapping_tries < MAX_SCREEN_MAPPING_TRIES {
if let Some(x11ctx) = &mut self.x11ctx {
// Mapping input does not work on XWayland as xinput list does not expose
Expand Down

0 comments on commit d2cdd2c

Please sign in to comment.