diff options
author | erg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-17 13:18:17 +0000 |
---|---|---|
committer | erg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-17 13:18:17 +0000 |
commit | eaafeb2ad48870ccd5e891a6266dabd3ee6afd53 (patch) | |
tree | 942312bcfdb2e8b0e66a8bc0147b0008c1cdc09c /ui/base/x | |
parent | 612a1cb1f2e9328dc81e1556c576a6fb1c73b8c8 (diff) | |
download | chromium_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.cc | 85 | ||||
-rw-r--r-- | ui/base/x/x11_util.h | 6 |
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); |