Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(558)

Side by Side Diff: ash/wm/maximize_mode/scoped_disable_internal_mouse_and_keyboard_x11.cc

Issue 2906803002: Rename MaximizeMode to TabletMode (Closed)
Patch Set: updated filter Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "ash/wm/maximize_mode/scoped_disable_internal_mouse_and_keyboard_x11.h"
6
7 #include <X11/extensions/XInput2.h>
8 #include <X11/Xlib.h>
9
10 #include <memory>
11 #include <set>
12 #include <utility>
13
14 #include "ash/display/window_tree_host_manager.h"
15 #include "ash/shell.h"
16 #include "base/strings/string_util.h"
17 #include "ui/aura/client/cursor_client.h"
18 #include "ui/aura/client/screen_position_client.h"
19 #include "ui/aura/env.h"
20 #include "ui/aura/window.h"
21 #include "ui/aura/window_event_dispatcher.h"
22 #include "ui/aura/window_tree_host.h"
23 #include "ui/events/devices/input_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"
31
32 namespace ash {
33
34 namespace {
35
36 // The name of the xinput device corresponding to the internal touchpad.
37 const char kInternalTouchpadName[] = "Elan Touchpad";
38
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";
42
43 // Device id used to indicate that a device has not been detected.
44 const int kDeviceIdNone = -1;
45
46 gfx::Point GetMouseLocationInScreen() {
47 return aura::Env::GetInstance()->last_mouse_location();
48 }
49
50 void SetMouseLocationInScreen(const gfx::Point& screen_location) {
51 const display::Display& display =
52 Shell::Get()->display_manager()->FindDisplayContainingPoint(
53 screen_location);
54 if (!display.is_valid())
55 return;
56 aura::Window* root_window =
57 Shell::Get()->window_tree_host_manager()->GetRootWindowForDisplayId(
58 display.id());
59 gfx::Point host_location(screen_location);
60 aura::client::ScreenPositionClient* client =
61 aura::client::GetScreenPositionClient(root_window);
62 if (client)
63 client->ConvertPointFromScreen(root_window, &host_location);
64 root_window->GetHost()->MoveCursorToLocationInDIP(host_location);
65 }
66
67 } // namespace
68
69 ScopedDisableInternalMouseAndKeyboardX11::
70 ScopedDisableInternalMouseAndKeyboardX11()
71 : touchpad_device_id_(kDeviceIdNone),
72 keyboard_device_id_(kDeviceIdNone),
73 core_keyboard_device_id_(kDeviceIdNone),
74 last_mouse_location_(GetMouseLocationInScreen()) {
75 ui::DeviceDataManagerX11* device_data_manager =
76 ui::DeviceDataManagerX11::GetInstance();
77 if (device_data_manager->IsXInput2Available()) {
78 const XIDeviceList& xi_dev_list =
79 ui::DeviceListCacheX11::GetInstance()->GetXI2DeviceList(
80 gfx::GetXDisplay());
81 for (int i = 0; i < xi_dev_list.count; ++i) {
82 std::string device_name(xi_dev_list[i].name);
83 base::TrimWhitespaceASCII(device_name, base::TRIM_TRAILING, &device_name);
84 if (device_name == kInternalTouchpadName) {
85 if (device_data_manager->IsDeviceEnabled(xi_dev_list[i].deviceid)) {
86 // If the touchpad is already disabled we will do nothing about it.
87 // This will result in doing nothing in the destructor as well since
88 // |touchpad_device_id_| will remain |kDeviceIdNone|.
89 touchpad_device_id_ = xi_dev_list[i].deviceid;
90 device_data_manager->DisableDevice(touchpad_device_id_);
91 Shell::Get()->cursor_manager()->HideCursor();
92 }
93 } else if (device_name == kCoreKeyboardName) {
94 core_keyboard_device_id_ = xi_dev_list[i].deviceid;
95 device_data_manager->DisableDevice(core_keyboard_device_id_);
96 }
97 }
98
99 for (const ui::InputDevice& device :
100 device_data_manager->GetKeyboardDevices()) {
101 if (device.type == ui::InputDeviceType::INPUT_DEVICE_INTERNAL) {
102 keyboard_device_id_ = device.id;
103 device_data_manager->DisableDevice(keyboard_device_id_);
104 break;
105 }
106 }
107 }
108 // Allow the accessible keys present on the side of some devices to continue
109 // working.
110 std::unique_ptr<std::set<ui::KeyboardCode>> excepted_keys(
111 new std::set<ui::KeyboardCode>);
112 excepted_keys->insert(ui::VKEY_VOLUME_DOWN);
113 excepted_keys->insert(ui::VKEY_VOLUME_UP);
114 excepted_keys->insert(ui::VKEY_POWER);
115 device_data_manager->SetDisabledKeyboardAllowedKeys(std::move(excepted_keys));
116 ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
117 }
118
119 ScopedDisableInternalMouseAndKeyboardX11::
120 ~ScopedDisableInternalMouseAndKeyboardX11() {
121 ui::DeviceDataManagerX11* device_data_manager =
122 static_cast<ui::DeviceDataManagerX11*>(
123 ui::DeviceDataManager::GetInstance());
124 if (touchpad_device_id_ != kDeviceIdNone) {
125 device_data_manager->EnableDevice(touchpad_device_id_);
126 Shell::Get()->cursor_manager()->ShowCursor();
127 }
128 if (keyboard_device_id_ != kDeviceIdNone)
129 device_data_manager->EnableDevice(keyboard_device_id_);
130 if (core_keyboard_device_id_ != kDeviceIdNone)
131 device_data_manager->EnableDevice(core_keyboard_device_id_);
132 device_data_manager->SetDisabledKeyboardAllowedKeys(
133 std::unique_ptr<std::set<ui::KeyboardCode>>());
134 ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
135 }
136
137 void ScopedDisableInternalMouseAndKeyboardX11::WillProcessEvent(
138 const ui::PlatformEvent& event) {}
139
140 void ScopedDisableInternalMouseAndKeyboardX11::DidProcessEvent(
141 const ui::PlatformEvent& event) {
142 if (event->type != GenericEvent)
143 return;
144 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(event->xcookie.data);
145 ui::DeviceDataManagerX11* device_data_manager =
146 static_cast<ui::DeviceDataManagerX11*>(
147 ui::DeviceDataManager::GetInstance());
148 if (xievent->evtype != XI_Motion ||
149 device_data_manager->IsFlingEvent(*event) ||
150 device_data_manager->IsScrollEvent(*event) ||
151 device_data_manager->IsCMTMetricsEvent(*event)) {
152 return;
153 }
154 if (xievent->sourceid == touchpad_device_id_) {
155 // The cursor will have already moved even though the move event will be
156 // blocked. Move the mouse cursor back to its last known location resulting
157 // from an external mouse to prevent the internal touchpad from moving it.
158 SetMouseLocationInScreen(last_mouse_location_);
159 } else {
160 // Track the last location seen from an external mouse event.
161 last_mouse_location_ = GetMouseLocationInScreen();
162 }
163 }
164
165 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698