| Index: ui/events/platform/x11/x11_event_source.cc
|
| diff --git a/ui/events/platform/x11/x11_event_source.cc b/ui/events/platform/x11/x11_event_source.cc
|
| index e1bc15ecc3176812a5d161a07b252fb666514853..0319da91b56843494f6c487d3876f316098142fd 100644
|
| --- a/ui/events/platform/x11/x11_event_source.cc
|
| +++ b/ui/events/platform/x11/x11_event_source.cc
|
| @@ -40,13 +40,46 @@ bool InitializeXkb(XDisplay* display) {
|
| return true;
|
| }
|
|
|
| +Time ExtractTimeFromXEvent(const XEvent& xevent) {
|
| + switch (xevent.type) {
|
| + case KeyPress:
|
| + case KeyRelease:
|
| + return xevent.xkey.time;
|
| + case ButtonPress:
|
| + case ButtonRelease:
|
| + return xevent.xbutton.time;
|
| + case MotionNotify:
|
| + return xevent.xmotion.time;
|
| + case EnterNotify:
|
| + case LeaveNotify:
|
| + return xevent.xcrossing.time;
|
| + case PropertyNotify:
|
| + return xevent.xproperty.time;
|
| + case SelectionClear:
|
| + return xevent.xselectionclear.time;
|
| + case SelectionRequest:
|
| + return xevent.xselectionrequest.time;
|
| + case SelectionNotify:
|
| + return xevent.xselection.time;
|
| + case GenericEvent:
|
| + if (DeviceDataManagerX11::GetInstance()->IsXIDeviceEvent(xevent))
|
| + return static_cast<XIDeviceEvent*>(xevent.xcookie.data)->time;
|
| + else
|
| + break;
|
| + }
|
| + return CurrentTime;
|
| +}
|
| +
|
| } // namespace
|
|
|
| X11EventSource* X11EventSource::instance_ = nullptr;
|
|
|
| X11EventSource::X11EventSource(X11EventSourceDelegate* delegate,
|
| XDisplay* display)
|
| - : delegate_(delegate), display_(display), continue_stream_(true) {
|
| + : delegate_(delegate),
|
| + display_(display),
|
| + last_seen_server_time_(CurrentTime),
|
| + continue_stream_(true) {
|
| DCHECK(!instance_);
|
| instance_ = this;
|
|
|
| @@ -102,6 +135,16 @@ void X11EventSource::ExtractCookieDataDispatchEvent(XEvent* xevent) {
|
| XGetEventData(xevent->xgeneric.display, &xevent->xcookie)) {
|
| have_cookie = true;
|
| }
|
| + Time event_time = ExtractTimeFromXEvent(*xevent);
|
| + if (event_time != CurrentTime) {
|
| + int64_t event_time_64 = event_time;
|
| + int64_t time_difference = last_seen_server_time_ - event_time_64;
|
| + // Ignore timestamps that go backwards. However, X server time is a 32-bit
|
| + // millisecond counter, so if the time goes backwards by more than half the
|
| + // range of the 32-bit counter, treat it as a rollover.
|
| + if (time_difference < 0 || time_difference > (UINT32_MAX >> 1))
|
| + last_seen_server_time_ = event_time;
|
| + }
|
| delegate_->ProcessXEvent(xevent);
|
| PostDispatchEvent(xevent);
|
| if (have_cookie)
|
|
|