[PATCH xserver] dix: Don't update current time in the middle of input event processing

Keith Packard keithp at keithp.com
Sat May 28 00:49:52 UTC 2016

In patch 137ac094e7ab8c871f3b36e40ad826ac797f0e26, Adam moved an
expensive call to UpdateCurrentTime out of the main dispatch
loop. That's a good change as the original fix from Chase was a bit
expensive. However, it breaks grab processing and so a couple of the
calls to UpdateCurrenTime need to be removed.

Input event processing can generate a stream of events; a button press
that activates a grab will send a press followed by a sequence of
enter/leave events. All of these should have the same time stamp on
the wire as they occur at the 'same' time.

More importantly, the grab time recorded in the device is pulled from
currentTime after all of the events are delivered, so if currentTime
doesn't match the time in the device event, then future grab
modifications will fail as the time marked in the device will be
'later' than the grab time known to the client (which is defined as
the timestamp from the activating input event).

A bit of history here -- it used to be that currentTime was driven
*entirely* by input events; those timestamps didn't even have to be
related to the system time in any way. Then we started doing ICCCM
stuff and people got confused when PropertyNotify events would have
the same timestamp even when delivered minutes apart because no input
events were delivered.

We added code in the server to go update the time, but only if no
input events were pending (so that the clock "wouldn't" go
backwards). The only places where this is necessary is in request
processing which may generate an event with a timestamp, and there
only at the very top of the request processing code so that the whole
request would be processed at the 'same time', just like events.

cc: Chase Douglas <chase.douglas at canonical.com>
cc: Peter Hutterer <peter.hutterer at who-t.net>
cc: Adam Jackson <ajax at redhat.com>
Signed-off-by: Keith Packard <keithp at keithp.com>
 dix/enterleave.c | 1 -
 dix/events.c     | 1 -
 2 files changed, 2 deletions(-)

diff --git a/dix/enterleave.c b/dix/enterleave.c
index 0c6c616..1b341f2 100644
--- a/dix/enterleave.c
+++ b/dix/enterleave.c
@@ -782,7 +782,6 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
     DeviceIntPtr mouse;
     int btlen, len, i;
-    UpdateCurrentTimeIf();
     mouse = IsFloating(dev) ? dev : GetMaster(dev, MASTER_POINTER);
     /* XI 2 event */
diff --git a/dix/events.c b/dix/events.c
index 0404eba..8efdf18 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2242,7 +2242,6 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
                                    this mask is the mask of the grab. */
     int type = pEvents->u.u.type;
-    UpdateCurrentTimeIf();
     /* Deliver to window owner */
     if ((filter == CantBeFiltered) || core_get_type(pEvents) != 0) {
         enum EventDeliveryState rc;

More information about the xorg-devel mailing list