diff options
author | sheckylin@chromium.org <sheckylin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-08 03:39:41 +0000 |
---|---|---|
committer | sheckylin@chromium.org <sheckylin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-08 03:39:41 +0000 |
commit | 726f07569f1cce45d08367f7365c5be0693a849e (patch) | |
tree | a40c35044f6058dfbc666ad7c92c3390e6316104 /ui/base/x | |
parent | ea9d8f2728ab88307a58b8bb5e7b690a55f75862 (diff) | |
download | chromium_src-726f07569f1cce45d08367f7365c5be0693a849e.zip chromium_src-726f07569f1cce45d08367f7365c5be0693a849e.tar.gz chromium_src-726f07569f1cce45d08367f7365c5be0693a849e.tar.bz2 |
Handling cursor visibility changing events for ChromeOS
The CL does 4 things:
1. A handler in RootWindowHost that will be called whenever cursor
visibility is changed.
2. Temporarily pause trackpad tap-to-click feature when the cursor
is hidden.
3. Add a cache class that caches X input device lists to minimize
round-trip time to X server for device list queries.
4. Refactor around the places where XListInputDevices/XIQueryDevice
queries are used.
Contributed by sheckylin@chromium.org
BUG=chromium:156697,chrome-os-partner:14085
TEST=Tested on link. "Tap paused" was successfully set when visibility
changed.
Change-Id: Ia5c62f821c80efc973e3b1ce54a467b674b466a4
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=171223
Reverted: https://codereview.chromium.org/11454002/
Review URL: https://chromiumcodereview.appspot.com/11316074
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@171928 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/base/x')
-rw-r--r-- | ui/base/x/device_list_cache_x.cc | 61 | ||||
-rw-r--r-- | ui/base/x/device_list_cache_x.h | 63 | ||||
-rw-r--r-- | ui/base/x/events_x.cc | 24 | ||||
-rw-r--r-- | ui/base/x/valuators.cc | 12 |
4 files changed, 139 insertions, 21 deletions
diff --git a/ui/base/x/device_list_cache_x.cc b/ui/base/x/device_list_cache_x.cc new file mode 100644 index 0000000..9fcb9db --- /dev/null +++ b/ui/base/x/device_list_cache_x.cc @@ -0,0 +1,61 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/base/x/device_list_cache_x.h" + +#include <algorithm> + +#include "base/memory/singleton.h" +#include "ui/base/x/x11_util.h" + +namespace ui { + +DeviceListCacheX::DeviceListCacheX() { +} + +DeviceListCacheX::~DeviceListCacheX() { + std::map<Display*, XDeviceList>::iterator xp; + for (xp = x_dev_list_map_.begin(); xp != x_dev_list_map_.end(); xp++) + XFreeDeviceList(xp->second.devices); + std::map<Display*, XIDeviceList>::iterator xip; + for (xip = xi_dev_list_map_.begin(); xip != xi_dev_list_map_.end(); xip++) + XIFreeDeviceInfo(xip->second.devices); +} + +DeviceListCacheX* DeviceListCacheX::GetInstance() { + return Singleton<DeviceListCacheX>::get(); +} + +void DeviceListCacheX::UpdateDeviceList(Display* display) { + XDeviceList& new_x_dev_list = x_dev_list_map_[display]; + if (new_x_dev_list.devices) + XFreeDeviceList(new_x_dev_list.devices); + new_x_dev_list.devices = XListInputDevices(display, &new_x_dev_list.count); + + XIDeviceList& new_xi_dev_list = xi_dev_list_map_[display]; + if (new_xi_dev_list.devices) + XIFreeDeviceInfo(new_xi_dev_list.devices); + new_xi_dev_list.devices = XIQueryDevice(display, XIAllDevices, + &new_xi_dev_list.count); +} + +const XDeviceList& DeviceListCacheX::GetXDeviceList(Display* display) { + XDeviceList& x_dev_list = x_dev_list_map_[display]; + // Note that the function can be called before any update has taken place. + if (!x_dev_list.devices && !x_dev_list.count) + x_dev_list.devices = XListInputDevices(display, &x_dev_list.count); + return x_dev_list; +} + +const XIDeviceList& DeviceListCacheX::GetXI2DeviceList(Display* display) { + XIDeviceList& xi_dev_list = xi_dev_list_map_[display]; + if (!xi_dev_list.devices && !xi_dev_list.count) { + xi_dev_list.devices = XIQueryDevice(display, XIAllDevices, + &xi_dev_list.count); + } + return xi_dev_list; +} + +} // namespace ui + diff --git a/ui/base/x/device_list_cache_x.h b/ui/base/x/device_list_cache_x.h new file mode 100644 index 0000000..2b3cefa --- /dev/null +++ b/ui/base/x/device_list_cache_x.h @@ -0,0 +1,63 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_BASE_X_DEVICE_LIST_CACHE_X_H_ +#define UI_BASE_X_DEVICE_LIST_CACHE_X_H_ + +#include <X11/extensions/XInput.h> +#include <X11/extensions/XInput2.h> + +#include <map> + +#include "base/basictypes.h" +#include "ui/base/ui_export.h" + +template <typename T> struct DefaultSingletonTraits; + +typedef struct _XDisplay Display; + +template <typename T> +struct DeviceList { + DeviceList() : devices(NULL), count(0) { + } + T& operator[] (int x) { + return devices[x]; + } + T* devices; + int count; +}; + +typedef struct DeviceList<XDeviceInfo> XDeviceList; +typedef struct DeviceList<XIDeviceInfo> XIDeviceList; + +namespace ui { + +// A class to cache the current XInput device list. This minimized the +// round-trip time to the X server whenever such a device list is needed. The +// update function will be called on each incoming XI_HierarchyChanged event. +class UI_EXPORT DeviceListCacheX { + public: + static DeviceListCacheX* GetInstance(); + + void UpdateDeviceList(Display* display); + + const XDeviceList& GetXDeviceList(Display* display); + const XIDeviceList& GetXI2DeviceList(Display* display); + + private: + friend struct DefaultSingletonTraits<DeviceListCacheX>; + + DeviceListCacheX(); + ~DeviceListCacheX(); + + std::map<Display*, XDeviceList> x_dev_list_map_; + std::map<Display*, XIDeviceList> xi_dev_list_map_; + + DISALLOW_COPY_AND_ASSIGN(DeviceListCacheX); +}; + +} // namespace ui + +#endif // UI_BASE_X_DEVICE_LIST_CACHE_X_H_ + diff --git a/ui/base/x/events_x.cc b/ui/base/x/events_x.cc index 9aa84d7..116b867 100644 --- a/ui/base/x/events_x.cc +++ b/ui/base/x/events_x.cc @@ -19,6 +19,7 @@ #include "ui/base/keycodes/keyboard_code_conversion_x.h" #include "ui/base/touch/touch_factory.h" #include "ui/base/ui_base_switches.h" +#include "ui/base/x/device_list_cache_x.h" #include "ui/base/x/valuators.h" #include "ui/base/x/x11_atom_cache.h" #include "ui/base/x/x11_util.h" @@ -98,20 +99,16 @@ class CMTEventData { device_to_valuators_.clear(); #if defined(USE_XI2_MT) - int count = 0; - // Find all the touchpad devices. - XDeviceInfo* dev_list = XListInputDevices(display, &count); + XDeviceList dev_list = + ui::DeviceListCacheX::GetInstance()->GetXDeviceList(display); Atom xi_touchpad = XInternAtom(display, XI_TOUCHPAD, false); - for (int i = 0; i < count; ++i) { - XDeviceInfo* dev = dev_list + i; - if (dev->type == xi_touchpad) + for (int i = 0; i < dev_list.count; ++i) + if (dev_list[i].type == xi_touchpad) touchpads_[dev_list[i].id] = true; - } - if (dev_list) - XFreeDeviceList(dev_list); - XIDeviceInfo* info_list = XIQueryDevice(display, XIAllDevices, &count); + XIDeviceList info_list = + ui::DeviceListCacheX::GetInstance()->GetXI2DeviceList(display); Atom x_axis = atom_cache_.GetAtom(AXIS_LABEL_PROP_REL_HWHEEL); Atom y_axis = atom_cache_.GetAtom(AXIS_LABEL_PROP_REL_WHEEL); Atom start_time = atom_cache_.GetAtom(AXIS_LABEL_PROP_ABS_START_TIME); @@ -126,8 +123,8 @@ class CMTEventData { Atom fling_state = atom_cache_.GetAtom(AXIS_LABEL_PROP_ABS_FLING_STATE); Atom finger_count = atom_cache_.GetAtom(AXIS_LABEL_PROP_ABS_FINGER_COUNT); - for (int i = 0; i < count; ++i) { - XIDeviceInfo* info = info_list + i; + for (int i = 0; i < info_list.count; ++i) { + XIDeviceInfo* info = info_list.devices + i; if (info->use != XISlavePointer && info->use != XIFloatingSlave) continue; @@ -199,8 +196,6 @@ class CMTEventData { cmt_devices_[info->deviceid] = true; } } - if (info_list) - XIFreeDeviceInfo(info_list); #endif // defined(USE_XI2_MT) } @@ -704,6 +699,7 @@ namespace ui { void UpdateDeviceList() { Display* display = GetXDisplay(); + DeviceListCacheX::GetInstance()->UpdateDeviceList(display); CMTEventData::GetInstance()->UpdateDeviceList(display); TouchFactory::GetInstance()->UpdateDeviceList(display); ValuatorTracker::GetInstance()->SetupValuator(); diff --git a/ui/base/x/valuators.cc b/ui/base/x/valuators.cc index 2380d84..4008b36 100644 --- a/ui/base/x/valuators.cc +++ b/ui/base/x/valuators.cc @@ -8,6 +8,7 @@ #include "base/memory/singleton.h" #include "ui/base/touch/touch_factory.h" +#include "ui/base/x/device_list_cache_x.h" #include "ui/base/x/x11_util.h" namespace { @@ -158,12 +159,12 @@ void ValuatorTracker::SetupValuator() { memset(last_seen_valuator_, 0, sizeof(last_seen_valuator_)); Display* display = GetXDisplay(); - int ndevice; - XIDeviceInfo* info_list = XIQueryDevice(display, XIAllDevices, &ndevice); + XIDeviceList info_list = + DeviceListCacheX::GetInstance()->GetXI2DeviceList(display); TouchFactory* factory = TouchFactory::GetInstance(); - for (int i = 0; i < ndevice; i++) { - XIDeviceInfo* info = info_list + i; + for (int i = 0; i < info_list.count; i++) { + XIDeviceInfo* info = info_list.devices + i; if (!factory->IsTouchDevice(info->deviceid)) continue; @@ -178,9 +179,6 @@ void ValuatorTracker::SetupValuator() { } } } - - if (info_list) - XIFreeDeviceInfo(info_list); } } // namespace ui |