diff options
author | sheckylin@chromium.org <sheckylin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-05 15:00:14 +0000 |
---|---|---|
committer | sheckylin@chromium.org <sheckylin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-05 15:00:14 +0000 |
commit | 33f0eccc6c8fa1616e19fbceeac51c7aed67c9e5 (patch) | |
tree | 3e3c88cc99e675dd55f98bdb95fdc17a6db80307 /ui/base/x | |
parent | 681739f982a5e4fb720959a5ffb44980253106dc (diff) | |
download | chromium_src-33f0eccc6c8fa1616e19fbceeac51c7aed67c9e5.zip chromium_src-33f0eccc6c8fa1616e19fbceeac51c7aed67c9e5.tar.gz chromium_src-33f0eccc6c8fa1616e19fbceeac51c7aed67c9e5.tar.bz2 |
Handling cursor visibility changing events for ChromeOS
The CL does 5 things:
1. A handler in RootWindowHost that will be called whenever cursor
visibility is changed.
2. An utility function in RootWindowHostLinux that can be used to
set XInput device properties.
3. Use 1) and 2) to temporarily pause trackpad tap-to-click feature
when the cursor is hidden.
4. Add a cache class that caches X input device lists to minimize
round-trip time to X server for device list queries.
5. 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
Review URL: https://chromiumcodereview.appspot.com/11316074
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@171223 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 |