Revert "Reland c91b178b07b0d - Delete dead signin code (SigninGlobalError)"
[chromium-blink-merge.git] / ash / wm / maximize_mode / scoped_disable_internal_mouse_and_keyboard_x11.cc
blob77043942b6dfd89c4c7bb3ee546f0db331b47c41
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ash/wm/maximize_mode/scoped_disable_internal_mouse_and_keyboard_x11.h"
7 #include <set>
8 #include <X11/extensions/XInput2.h>
9 #include <X11/Xlib.h>
11 #include "ash/display/window_tree_host_manager.h"
12 #include "ash/screen_util.h"
13 #include "ash/shell.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/strings/string_util.h"
16 #include "ui/aura/client/cursor_client.h"
17 #include "ui/aura/client/screen_position_client.h"
18 #include "ui/aura/env.h"
19 #include "ui/aura/window.h"
20 #include "ui/aura/window_event_dispatcher.h"
21 #include "ui/aura/window_tree_host.h"
22 #include "ui/events/devices/input_device.h"
23 #include "ui/events/devices/keyboard_device.h"
24 #include "ui/events/devices/x11/device_data_manager_x11.h"
25 #include "ui/events/devices/x11/device_list_cache_x11.h"
26 #include "ui/events/event.h"
27 #include "ui/events/event_utils.h"
28 #include "ui/events/keycodes/keyboard_codes_posix.h"
29 #include "ui/events/platform/platform_event_source.h"
30 #include "ui/gfx/x/x11_types.h"
32 namespace ash {
34 namespace {
36 // The name of the xinput device corresponding to the internal touchpad.
37 const char kInternalTouchpadName[] = "Elan Touchpad";
39 // Repeated key events have their source set to the core keyboard device.
40 // These must be disabled also until http://crbug.com/402898 is resolved.
41 const char kCoreKeyboardName[] = "Virtual core keyboard";
43 // Device id used to indicate that a device has not been detected.
44 const int kDeviceIdNone = -1;
46 gfx::Point GetMouseLocationInScreen() {
47 return aura::Env::GetInstance()->last_mouse_location();
50 void SetMouseLocationInScreen(const gfx::Point& screen_location) {
51 gfx::Display display = ash::ScreenUtil::FindDisplayContainingPoint(
52 screen_location);
53 if (!display.is_valid())
54 return;
55 aura::Window* root_window = Shell::GetInstance()
56 ->window_tree_host_manager()
57 ->GetRootWindowForDisplayId(display.id());
58 gfx::Point host_location(screen_location);
59 aura::client::ScreenPositionClient* client =
60 aura::client::GetScreenPositionClient(root_window);
61 if (client)
62 client->ConvertPointFromScreen(root_window, &host_location);
63 root_window->GetHost()->MoveCursorTo(host_location);
66 } // namespace
68 ScopedDisableInternalMouseAndKeyboardX11::
69 ScopedDisableInternalMouseAndKeyboardX11()
70 : touchpad_device_id_(kDeviceIdNone),
71 keyboard_device_id_(kDeviceIdNone),
72 core_keyboard_device_id_(kDeviceIdNone),
73 last_mouse_location_(GetMouseLocationInScreen()) {
75 ui::DeviceDataManagerX11* device_data_manager =
76 static_cast<ui::DeviceDataManagerX11*>(
77 ui::DeviceDataManager::GetInstance());
78 if (device_data_manager->IsXInput2Available()) {
79 const XIDeviceList& xi_dev_list =
80 ui::DeviceListCacheX11::GetInstance()->GetXI2DeviceList(
81 gfx::GetXDisplay());
82 for (int i = 0; i < xi_dev_list.count; ++i) {
83 std::string device_name(xi_dev_list[i].name);
84 base::TrimWhitespaceASCII(device_name, base::TRIM_TRAILING, &device_name);
85 if (device_name == kInternalTouchpadName) {
86 touchpad_device_id_ = xi_dev_list[i].deviceid;
87 device_data_manager->DisableDevice(touchpad_device_id_);
88 aura::client::GetCursorClient(
89 Shell::GetInstance()->GetPrimaryRootWindow())->HideCursor();
90 } else if (device_name == kCoreKeyboardName) {
91 core_keyboard_device_id_ = xi_dev_list[i].deviceid;
92 device_data_manager->DisableDevice(core_keyboard_device_id_);
96 for (const ui::KeyboardDevice& device :
97 device_data_manager->keyboard_devices()) {
98 if (device.type == ui::InputDeviceType::INPUT_DEVICE_INTERNAL) {
99 keyboard_device_id_ = device.id;
100 device_data_manager->DisableDevice(keyboard_device_id_);
101 break;
105 // Allow the accessible keys present on the side of some devices to continue
106 // working.
107 scoped_ptr<std::set<ui::KeyboardCode> > excepted_keys(
108 new std::set<ui::KeyboardCode>);
109 excepted_keys->insert(ui::VKEY_VOLUME_DOWN);
110 excepted_keys->insert(ui::VKEY_VOLUME_UP);
111 excepted_keys->insert(ui::VKEY_POWER);
112 device_data_manager->SetDisabledKeyboardAllowedKeys(excepted_keys.Pass());
113 ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
116 ScopedDisableInternalMouseAndKeyboardX11::
117 ~ScopedDisableInternalMouseAndKeyboardX11() {
118 ui::DeviceDataManagerX11* device_data_manager =
119 static_cast<ui::DeviceDataManagerX11*>(
120 ui::DeviceDataManager::GetInstance());
121 if (touchpad_device_id_ != kDeviceIdNone)
122 device_data_manager->EnableDevice(touchpad_device_id_);
123 if (keyboard_device_id_ != kDeviceIdNone)
124 device_data_manager->EnableDevice(keyboard_device_id_);
125 if (core_keyboard_device_id_ != kDeviceIdNone)
126 device_data_manager->EnableDevice(core_keyboard_device_id_);
127 device_data_manager->SetDisabledKeyboardAllowedKeys(
128 scoped_ptr<std::set<ui::KeyboardCode> >());
129 ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
132 void ScopedDisableInternalMouseAndKeyboardX11::WillProcessEvent(
133 const ui::PlatformEvent& event) {
136 void ScopedDisableInternalMouseAndKeyboardX11::DidProcessEvent(
137 const ui::PlatformEvent& event) {
138 if (event->type != GenericEvent)
139 return;
140 XIDeviceEvent* xievent =
141 static_cast<XIDeviceEvent*>(event->xcookie.data);
142 ui::DeviceDataManagerX11* device_data_manager =
143 static_cast<ui::DeviceDataManagerX11*>(
144 ui::DeviceDataManager::GetInstance());
145 if (xievent->evtype != XI_Motion ||
146 device_data_manager->IsFlingEvent(event) ||
147 device_data_manager->IsScrollEvent(event) ||
148 device_data_manager->IsCMTMetricsEvent(event)) {
149 return;
151 if (xievent->sourceid == touchpad_device_id_) {
152 // The cursor will have already moved even though the move event will be
153 // blocked. Move the mouse cursor back to its last known location resulting
154 // from an external mouse to prevent the internal touchpad from moving it.
155 SetMouseLocationInScreen(last_mouse_location_);
156 } else {
157 // Track the last location seen from an external mouse event.
158 last_mouse_location_ = GetMouseLocationInScreen();
162 } // namespace ash