summaryrefslogtreecommitdiffstats
path: root/ui/base/x
diff options
context:
space:
mode:
authorerg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-17 13:18:17 +0000
committererg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-17 13:18:17 +0000
commiteaafeb2ad48870ccd5e891a6266dabd3ee6afd53 (patch)
tree942312bcfdb2e8b0e66a8bc0147b0008c1cdc09c /ui/base/x
parent612a1cb1f2e9328dc81e1556c576a6fb1c73b8c8 (diff)
downloadchromium_src-eaafeb2ad48870ccd5e891a6266dabd3ee6afd53.zip
chromium_src-eaafeb2ad48870ccd5e891a6266dabd3ee6afd53.tar.gz
chromium_src-eaafeb2ad48870ccd5e891a6266dabd3ee6afd53.tar.bz2
linux_aura: Fix tab dragging performance.
This shares the movement event coalescing from RootWindowHostLinux, which was disabled to make initial bringup easier. BUG=146077 Review URL: https://chromiumcodereview.appspot.com/11192009 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@162381 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/base/x')
-rw-r--r--ui/base/x/x11_util.cc85
-rw-r--r--ui/base/x/x11_util.h6
2 files changed, 91 insertions, 0 deletions
diff --git a/ui/base/x/x11_util.cc b/ui/base/x/x11_util.cc
index 05c9991..c2beafc 100644
--- a/ui/base/x/x11_util.cc
+++ b/ui/base/x/x11_util.cc
@@ -17,6 +17,7 @@
#include <utility>
#include <vector>
+#include <X11/extensions/XInput2.h>
#include <X11/extensions/Xrandr.h>
#include <X11/extensions/randr.h>
#include <X11/extensions/shape.h>
@@ -33,6 +34,7 @@
#include "base/sys_byteorder.h"
#include "base/threading/thread.h"
#include "ui/base/keycodes/keyboard_code_conversion_x.h"
+#include "ui/base/touch/touch_factory.h"
#include "ui/base/x/x11_util_internal.h"
#include "ui/gfx/point_conversions.h"
#include "ui/gfx/rect.h"
@@ -1434,6 +1436,89 @@ bool IsMotionEvent(XEvent* event) {
return type == MotionNotify;
}
+int CoalescePendingMotionEvents(const XEvent* xev,
+ XEvent* last_event) {
+ XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data);
+ int num_coalesed = 0;
+ Display* display = xev->xany.display;
+ int event_type = xev->xgeneric.evtype;
+
+#if defined(USE_XI2_MT)
+ float tracking_id = -1;
+ if (event_type == XI_TouchUpdate) {
+ if (!ui::ValuatorTracker::GetInstance()->ExtractValuator(*xev,
+ ui::ValuatorTracker::VAL_TRACKING_ID, &tracking_id))
+ tracking_id = -1;
+ }
+#endif
+
+ while (XPending(display)) {
+ XEvent next_event;
+ XPeekEvent(display, &next_event);
+
+ // If we can't get the cookie, abort the check.
+ if (!XGetEventData(next_event.xgeneric.display, &next_event.xcookie))
+ return num_coalesed;
+
+ // If this isn't from a valid device, throw the event away, as
+ // that's what the message pump would do. Device events come in pairs
+ // with one from the master and one from the slave so there will
+ // always be at least one pending.
+ if (!ui::TouchFactory::GetInstance()->ShouldProcessXI2Event(&next_event)) {
+ XFreeEventData(display, &next_event.xcookie);
+ XNextEvent(display, &next_event);
+ continue;
+ }
+
+ if (next_event.type == GenericEvent &&
+ next_event.xgeneric.evtype == event_type &&
+ !ui::GetScrollOffsets(&next_event, NULL, NULL)) {
+ XIDeviceEvent* next_xievent =
+ static_cast<XIDeviceEvent*>(next_event.xcookie.data);
+#if defined(USE_XI2_MT)
+ float next_tracking_id = -1;
+ if (event_type == XI_TouchUpdate) {
+ // If this is a touch motion event (as opposed to mouse motion event),
+ // then make sure the events are from the same touch-point.
+ if (!ui::ValuatorTracker::GetInstance()->ExtractValuator(next_event,
+ ui::ValuatorTracker::VAL_TRACKING_ID, &next_tracking_id))
+ next_tracking_id = -1;
+ }
+#endif
+ // Confirm that the motion event is targeted at the same window
+ // and that no buttons or modifiers have changed.
+ if (xievent->event == next_xievent->event &&
+ xievent->child == next_xievent->child &&
+#if defined(USE_XI2_MT)
+ (event_type == XI_Motion || tracking_id == next_tracking_id) &&
+#endif
+ xievent->buttons.mask_len == next_xievent->buttons.mask_len &&
+ (memcmp(xievent->buttons.mask,
+ next_xievent->buttons.mask,
+ xievent->buttons.mask_len) == 0) &&
+ xievent->mods.base == next_xievent->mods.base &&
+ xievent->mods.latched == next_xievent->mods.latched &&
+ xievent->mods.locked == next_xievent->mods.locked &&
+ xievent->mods.effective == next_xievent->mods.effective) {
+ XFreeEventData(display, &next_event.xcookie);
+ // Free the previous cookie.
+ if (num_coalesed > 0)
+ XFreeEventData(display, &last_event->xcookie);
+ // Get the event and its cookie data.
+ XNextEvent(display, last_event);
+ XGetEventData(display, &last_event->xcookie);
+ ++num_coalesed;
+ continue;
+ } else {
+ // This isn't an event we want so free its cookie data.
+ XFreeEventData(display, &next_event.xcookie);
+ }
+ }
+ break;
+ }
+ return num_coalesed;
+}
+
int GetMappedButton(int button) {
return XButtonMap::GetInstance()->GetMappedButton(button);
}
diff --git a/ui/base/x/x11_util.h b/ui/base/x/x11_util.h
index b1a6e4d..0b6653f 100644
--- a/ui/base/x/x11_util.h
+++ b/ui/base/x/x11_util.h
@@ -305,6 +305,12 @@ UI_EXPORT bool IsX11WindowFullScreen(XID window);
// Return true if event type is MotionNotify.
UI_EXPORT bool IsMotionEvent(XEvent* event);
+// Coalesce all pending motion events (touch or mouse) that are at the top of
+// the queue, and return the number eliminated, storing the last one in
+// |last_event|.
+UI_EXPORT int CoalescePendingMotionEvents(const XEvent* xev,
+ XEvent* last_event);
+
// Returns the mapped button.
int GetMappedButton(int button);