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 a50cf739e1b06a82487b494c52029048f9440936..3ff519804da47b3567b4aa5d28ec181395a510b6 100644 |
--- a/ui/events/platform/x11/x11_event_source.cc |
+++ b/ui/events/platform/x11/x11_event_source.cc |
@@ -4,10 +4,12 @@ |
#include "ui/events/platform/x11/x11_event_source.h" |
+#include <X11/Xatom.h> |
#include <X11/XKBlib.h> |
#include <X11/Xlib.h> |
#include "base/logging.h" |
+#include "base/metrics/histogram_macros.h" |
#include "ui/events/devices/x11/device_data_manager_x11.h" |
#include "ui/events/devices/x11/touch_factory_x11.h" |
#include "ui/events/event_utils.h" |
@@ -78,6 +80,13 @@ void UpdateDeviceList() { |
DeviceDataManagerX11::GetInstance()->UpdateDeviceList(display); |
} |
+Bool IsPropertyNotifyForTimestamp(Display* display, |
+ XEvent* event, |
+ XPointer arg) { |
+ return event->type == PropertyNotify && |
+ event->xproperty.window == *(Window*)arg; |
danakj
2016/05/12 23:35:48
C++ style casts please
Tom (Use chromium acct)
2016/05/13 17:21:25
Done.
|
+} |
+ |
} // namespace |
X11EventSource* X11EventSource::instance_ = nullptr; |
@@ -87,6 +96,7 @@ X11EventSource::X11EventSource(X11EventSourceDelegate* delegate, |
: delegate_(delegate), |
display_(display), |
last_seen_server_time_(CurrentTime), |
+ dummy_initialized_(false), |
continue_stream_(true) { |
DCHECK(!instance_); |
instance_ = this; |
@@ -100,6 +110,8 @@ X11EventSource::X11EventSource(X11EventSourceDelegate* delegate, |
X11EventSource::~X11EventSource() { |
DCHECK_EQ(this, instance_); |
instance_ = nullptr; |
+ if (dummy_initialized_) |
+ XDestroyWindow(display_, dummy_window_); |
} |
// static |
@@ -134,6 +146,38 @@ void X11EventSource::BlockUntilWindowMapped(XID window) { |
} while (event.type != MapNotify); |
} |
+Time X11EventSource::UpdateLastSeenServerTime() { |
+ base::TimeTicks start = base::TimeTicks::Now(); |
+ |
+ DCHECK(display_); |
+ |
+ if (!dummy_initialized_) { |
+ // Create a new Window and Atom that will be used for the property change. |
+ dummy_data_ = 0; |
+ dummy_window_ = XCreateSimpleWindow(display_, DefaultRootWindow(display_), |
+ 0, 0, 1, 1, 0, 0, 0); |
+ dummy_atom_ = XInternAtom(display_, "TIMESTAMP", False); |
danakj
2016/05/12 23:33:26
Can you namespace this like CHROMIUM_TIMESTAMP
Tom (Use chromium acct)
2016/05/13 17:21:25
Done.
|
+ XSelectInput(display_, dummy_window_, PropertyChangeMask); |
+ dummy_initialized_ = true; |
+ } |
+ |
+ // Make a no-op property change on |dummy_window_|. |
+ dummy_data_++; |
+ XChangeProperty(display_, dummy_window_, dummy_atom_, XA_INTEGER, 8, |
danakj
2016/05/12 23:33:26
I believe you can do this and avoid the need for d
Tom (Use chromium acct)
2016/05/13 17:21:25
Done. Also, cool!
|
+ PropModeReplace, &dummy_data_, 1); |
+ |
+ // Observe the resulting PropertyNotify event to obtain the timestamp. |
+ XEvent event; |
+ XIfEvent(display_, &event, IsPropertyNotifyForTimestamp, |
+ (XPointer)&dummy_window_); |
danakj
2016/05/12 23:35:48
Oh, c++-style casts please.
|
+ |
+ last_seen_server_time_ = event.xproperty.time; |
+ |
+ UMA_HISTOGRAM_TIMES("Event.Latency.X11EventSource.UpdateServerTime", |
+ base::TimeTicks::Now() - start); |
+ return last_seen_server_time_; |
+} |
+ |
//////////////////////////////////////////////////////////////////////////////// |
// X11EventSource, protected |