X11: Avoid round-tripping to get the cursor position
This is a performance optimization which avoids calling XQueryPointer when we're dispatching a mouse event. It's become a convenience to call GetCursorScreenPoint() all over the place in Chrome, even when an event which has the cursor position is available. R=sadrul@chromium.org Review-Url: https://codereview.chromium.org/2398343002 Cr-Commit-Position: refs/heads/master@{#424645}
This commit is contained in:

committed by
Commit bot

parent
77097e7075
commit
6753a182d5
ui
@ -96,7 +96,6 @@ X11EventSource::X11EventSource(X11EventSourceDelegate* delegate,
|
||||
XDisplay* display)
|
||||
: delegate_(delegate),
|
||||
display_(display),
|
||||
event_timestamp_(CurrentTime),
|
||||
dummy_initialized_(false),
|
||||
continue_stream_(true) {
|
||||
DCHECK(!instance_);
|
||||
@ -184,13 +183,43 @@ Time X11EventSource::GetCurrentServerTime() {
|
||||
}
|
||||
|
||||
Time X11EventSource::GetTimestamp() {
|
||||
if (event_timestamp_ != CurrentTime) {
|
||||
return event_timestamp_;
|
||||
if (!dispatching_events_.empty()) {
|
||||
DCHECK(dispatching_events_.top());
|
||||
Time timestamp = ExtractTimeFromXEvent(*dispatching_events_.top());
|
||||
if (timestamp != CurrentTime)
|
||||
return timestamp;
|
||||
}
|
||||
DVLOG(1) << "Making a round trip to get a recent server timestamp.";
|
||||
return GetCurrentServerTime();
|
||||
}
|
||||
|
||||
base::Optional<gfx::Point>
|
||||
X11EventSource::GetRootCursorLocationFromCurrentEvent() const {
|
||||
if (dispatching_events_.empty())
|
||||
return base::nullopt;
|
||||
|
||||
XEvent* event = dispatching_events_.top();
|
||||
DCHECK(event);
|
||||
bool is_valid_event = false;
|
||||
switch (event->type) {
|
||||
case ButtonPress:
|
||||
case ButtonRelease:
|
||||
case MotionNotify:
|
||||
case EnterNotify:
|
||||
case LeaveNotify:
|
||||
is_valid_event = true;
|
||||
break;
|
||||
case GenericEvent:
|
||||
if (!ui::TouchFactory::GetInstance()->ShouldProcessXI2Event(event))
|
||||
break;
|
||||
is_valid_event = true;
|
||||
}
|
||||
|
||||
if (is_valid_event)
|
||||
return ui::EventSystemLocationFromNative(event);
|
||||
return base::nullopt;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// X11EventSource, protected
|
||||
|
||||
@ -201,12 +230,12 @@ void X11EventSource::ExtractCookieDataDispatchEvent(XEvent* xevent) {
|
||||
have_cookie = true;
|
||||
}
|
||||
|
||||
event_timestamp_ = ExtractTimeFromXEvent(*xevent);
|
||||
dispatching_events_.push(xevent);
|
||||
|
||||
delegate_->ProcessXEvent(xevent);
|
||||
PostDispatchEvent(xevent);
|
||||
|
||||
event_timestamp_ = CurrentTime;
|
||||
dispatching_events_.pop();
|
||||
|
||||
if (have_cookie)
|
||||
XFreeEventData(xevent->xgeneric.display, &xevent->xcookie);
|
||||
|
@ -8,8 +8,10 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include <memory>
|
||||
#include <stack>
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "base/optional.h"
|
||||
#include "ui/events/events_export.h"
|
||||
#include "ui/gfx/x/x11_types.h"
|
||||
|
||||
@ -18,6 +20,10 @@ using XEvent = union _XEvent;
|
||||
using XID = unsigned long;
|
||||
using XWindow = unsigned long;
|
||||
|
||||
namespace gfx {
|
||||
class Point;
|
||||
}
|
||||
|
||||
namespace ui {
|
||||
|
||||
class X11HotplugEventHandler;
|
||||
@ -77,6 +83,10 @@ class EVENTS_EXPORT X11EventSource {
|
||||
// current event does not have a timestamp.
|
||||
Time GetTimestamp();
|
||||
|
||||
// Returns the root pointer location only if there is an event being
|
||||
// dispatched that contains that information.
|
||||
base::Optional<gfx::Point> GetRootCursorLocationFromCurrentEvent() const;
|
||||
|
||||
void StopCurrentEventStream();
|
||||
void OnDispatcherListChanged();
|
||||
|
||||
@ -105,8 +115,9 @@ class EVENTS_EXPORT X11EventSource {
|
||||
// The connection to the X11 server used to receive the events.
|
||||
XDisplay* display_;
|
||||
|
||||
// The timestamp of the event being dispatched.
|
||||
Time event_timestamp_;
|
||||
// Events currently being dispatched. The topmost event in this stack
|
||||
// corresponds to the deepest-nested message loop.
|
||||
std::stack<XEvent*> dispatching_events_;
|
||||
|
||||
// State necessary for UpdateLastSeenServerTime
|
||||
bool dummy_initialized_;
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "ui/display/util/display_util.h"
|
||||
#include "ui/display/util/x11/edid_parser_x11.h"
|
||||
#include "ui/events/platform/platform_event_source.h"
|
||||
#include "ui/events/platform/x11/x11_event_source.h"
|
||||
#include "ui/gfx/font_render_params.h"
|
||||
#include "ui/gfx/geometry/point_conversions.h"
|
||||
#include "ui/gfx/geometry/size_conversions.h"
|
||||
@ -133,20 +134,18 @@ DesktopScreenX11::~DesktopScreenX11() {
|
||||
gfx::Point DesktopScreenX11::GetCursorScreenPoint() {
|
||||
TRACE_EVENT0("views", "DesktopScreenX11::GetCursorScreenPoint()");
|
||||
|
||||
XDisplay* display = gfx::GetXDisplay();
|
||||
if (ui::X11EventSource::HasInstance()) {
|
||||
auto point = ui::X11EventSource::GetInstance()
|
||||
->GetRootCursorLocationFromCurrentEvent();
|
||||
if (point)
|
||||
return point.value();
|
||||
}
|
||||
|
||||
::Window root, child;
|
||||
int root_x, root_y, win_x, win_y;
|
||||
unsigned int mask;
|
||||
XQueryPointer(display,
|
||||
DefaultRootWindow(display),
|
||||
&root,
|
||||
&child,
|
||||
&root_x,
|
||||
&root_y,
|
||||
&win_x,
|
||||
&win_y,
|
||||
&mask);
|
||||
XQueryPointer(xdisplay_, x_root_window_, &root, &child, &root_x, &root_y,
|
||||
&win_x, &win_y, &mask);
|
||||
|
||||
return PixelToDIPPoint(gfx::Point(root_x, root_y));
|
||||
}
|
||||
|
Reference in New Issue
Block a user