Commit 90d19302 authored by Peter Hutterer's avatar Peter Hutterer

eventcomm: ensure we're on the same clock as the server

Default on evdev devices is CLOCK_REALTIME. If that clock falls behind the
server's CLOCK_MONOTONIC, motion after a clickpad click may be delayed by the
difference in the clocks.

In detail:
When the timer func is triggered, GetTimeInMillis() which is CLOCK_MONOTONIC,
is stored as hwState->millis. The eventcomm backend uses struct
input_event time (CLOCK_REALTIME).

When we read events from the device, if the evdev time is less than the server
time, the fix for (#48777) sets the current event time to hwState->millis.
Until the evdev time overtakes that stored time, all events have the
hwState->millis time.

If during that time a clickpad triggers a physical click,
clickpad_click_millis is set to hwState->millis + the ignore-motion timeout.
Thus, all motion is ignored until the event time overtakes that stored

The whole issue is further enhanced by us unconditionally setting the timer
func if we get any events, which is a separate issue anyway.
Signed-off-by: Peter Hutterer's avatarPeter Hutterer <>
Reviewed-by: default avatarHans de Goede <>
parent 96e60a4e
......@@ -39,6 +39,7 @@
#include <dirent.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include "synproto.h"
#include "synapticsstr.h"
#include <xf86.h>
......@@ -88,6 +89,8 @@ struct eventcomm_proto_data {
struct libevdev *evdev;
enum libevdev_read_flag read_flag;
int have_monotonic_clock;
......@@ -234,6 +237,7 @@ EventDeviceOnHook(InputInfoPtr pInfo, SynapticsParameters * para)
SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
struct eventcomm_proto_data *proto_data =
(struct eventcomm_proto_data *) priv->proto_data;
int ret;
if (libevdev_get_fd(proto_data->evdev) != -1) {
struct input_event ev;
......@@ -253,7 +257,6 @@ EventDeviceOnHook(InputInfoPtr pInfo, SynapticsParameters * para)
if (para->grab_event_device) {
/* Try to grab the event device so that data don't leak to /dev/input/mice */
int ret;
ret = libevdev_grab(proto_data->evdev, LIBEVDEV_GRAB);
if (ret < 0) {
......@@ -265,6 +268,9 @@ EventDeviceOnHook(InputInfoPtr pInfo, SynapticsParameters * para)
proto_data->need_grab = FALSE;
ret = libevdev_set_clock_id(proto_data->evdev, CLOCK_MONOTONIC);
proto_data->have_monotonic_clock = (ret == 0);
return TRUE;
......@@ -682,7 +688,10 @@ EventReadHwState(InputInfoPtr pInfo,
switch (ev.code) {
hw->numFingers = count_fingers(pInfo, comm);
hw->millis = 1000 * ev.time.tv_sec + ev.time.tv_usec / 1000;
if (proto_data->have_monotonic_clock)
hw->millis = 1000 * ev.time.tv_sec + ev.time.tv_usec / 1000;
hw->millis = GetTimeInMillis();
SynapticsCopyHwState(hwRet, hw);
return TRUE;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment