Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(253)

Unified Diff: ui/events/platform/x11/x11_event_source.cc

Issue 2177823002: X11: Add window cache Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix test compilation Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« ui/base/x/x11_window_cache.cc ('K') | « ui/events/platform/x11/x11_event_source.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1923e95fa14dbb8d97d401201129b4d8ad1dc355..afc77eb45f444cef61bc0dc99e7edda613ecbf94 100644
--- a/ui/events/platform/x11/x11_event_source.cc
+++ b/ui/events/platform/x11/x11_event_source.cc
@@ -7,6 +7,8 @@
#include <X11/Xatom.h>
#include <X11/XKBlib.h>
#include <X11/Xlib.h>
+#include <X11/Xlib-xcb.h>
+#include <xcb/xcbext.h>
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
@@ -16,6 +18,8 @@
#include "ui/events/platform/platform_event_dispatcher.h"
#include "ui/events/platform/x11/x11_hotplug_event_handler.h"
+#define XLIB_SEQUENCE_COMPARE(a, op, b) (((int64_t)(a) - (int64_t)(b)) op 0)
+
namespace ui {
namespace {
@@ -91,12 +95,18 @@ Bool IsPropertyNotifyForTimestamp(Display* display,
X11EventSource* X11EventSource::instance_ = nullptr;
+X11EventSource::Request::Request(uint32_t sequence) : sequence_(sequence) {}
+X11EventSource::Request::~Request() {}
+
X11EventSource::X11EventSource(X11EventSourceDelegate* delegate,
XDisplay* display)
: delegate_(delegate),
display_(display),
+ connection_(XGetXCBConnection(display_)),
event_timestamp_(CurrentTime),
dummy_initialized_(false),
+ next_reply_(nullptr),
+ next_error_(nullptr),
continue_stream_(true) {
DCHECK(!instance_);
instance_ = this;
@@ -109,6 +119,7 @@ X11EventSource::X11EventSource(X11EventSourceDelegate* delegate,
X11EventSource::~X11EventSource() {
DCHECK_EQ(this, instance_);
+ DCHECK(!next_reply_ && !next_error_);
instance_ = nullptr;
if (dummy_initialized_)
XDestroyWindow(display_, dummy_window_);
@@ -133,11 +144,22 @@ void X11EventSource::DispatchXEvents() {
// It may be useful to eventually align this event dispatch with vsync, but
// not yet.
continue_stream_ = true;
- while (XPending(display_) && continue_stream_) {
- XEvent xevent;
- XNextEvent(display_, &xevent);
- ExtractCookieDataDispatchEvent(&xevent);
+
+ // Read all available data.
+ XEventsQueued(display_, QueuedAfterReading);
+
+ while (HasNextReply() && HasNextEvent() && continue_stream_) {
+ if (XLIB_SEQUENCE_COMPARE(NextReplySequence(), <=, NextEventSequence()))
+ ProcessNextReply();
+ else
+ ProcessNextEvent();
}
+
+ while (HasNextReply() && continue_stream_)
+ ProcessNextReply();
+
+ while (HasNextEvent() && continue_stream_)
+ ProcessNextEvent();
}
void X11EventSource::DispatchXEventNow(XEvent* event) {
@@ -189,6 +211,18 @@ Time X11EventSource::GetTimestamp() {
return GetCurrentServerTime();
}
+void X11EventSource::EnqueueRequest(Request* request) {
+ DCHECK(request);
+ request_queue_.emplace_back(request);
+ request->it_ = --request_queue_.end();
+}
+
+void X11EventSource::DiscardRequest(Request* request) {
+ DCHECK(connection_);
+ xcb_discard_reply(connection_, request->sequence());
+ request_queue_.erase(request->it_);
+}
+
////////////////////////////////////////////////////////////////////////////////
// X11EventSource, protected
@@ -252,6 +286,56 @@ void X11EventSource::BlockOnWindowStructureEvent(XID window, int type) {
} while (event.type != type);
}
+bool X11EventSource::HasNextReply() {
+ if (request_queue_.empty() || xcb_connection_has_error(connection_))
+ return false;
+ if (next_reply_ || next_error_)
+ return true;
+
+ return xcb_poll_for_reply(connection_, request_queue_.front()->sequence(),
+ &next_reply_, &next_error_);
+}
+
+uint32_t X11EventSource::NextReplySequence() {
+ DCHECK(HasNextReply());
+ return request_queue_.front()->sequence();
+}
+
+void X11EventSource::ProcessNextReply() {
+ DCHECK(HasNextReply());
+
+ uint32_t sequence = request_queue_.front()->sequence();
+ request_queue_.front()->OnReply(
+ reinterpret_cast<xcb_generic_reply_t*>(next_reply_), next_error_);
+
+ free(next_reply_);
+ free(next_error_);
+ next_reply_ = nullptr;
+ next_error_ = nullptr;
+
+ // OnReply() may have already discarded this event.
+ if (!request_queue_.empty() && request_queue_.front()->sequence() == sequence)
+ request_queue_.pop_front();
+}
+
+bool X11EventSource::HasNextEvent() {
+ return XEventsQueued(display_, QueuedAlready);
+}
+
+uint32_t X11EventSource::NextEventSequence() {
+ DCHECK(HasNextEvent());
+ XEvent event;
+ XPeekEvent(display_, &event);
+ return event.xany.serial;
+}
+
+void X11EventSource::ProcessNextEvent() {
+ DCHECK(HasNextEvent());
+ XEvent event;
+ XNextEvent(display_, &event);
+ ExtractCookieDataDispatchEvent(&event);
+}
+
void X11EventSource::StopCurrentEventStream() {
continue_stream_ = false;
}
« ui/base/x/x11_window_cache.cc ('K') | « ui/events/platform/x11/x11_event_source.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698