OLD | NEW |
| (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 #ifndef CHROME_BROWSER_CHROMEOS_EVENTS_EVENT_REWRITER_H_ | |
6 #define CHROME_BROWSER_CHROMEOS_EVENTS_EVENT_REWRITER_H_ | |
7 | |
8 #include <map> | |
9 #include <memory> | |
10 #include <set> | |
11 #include <string> | |
12 | |
13 #include "base/compiler_specific.h" | |
14 #include "base/containers/hash_tables.h" | |
15 #include "base/macros.h" | |
16 #include "ui/events/event.h" | |
17 #include "ui/events/event_rewriter.h" | |
18 #include "ui/events/keycodes/dom/dom_key.h" | |
19 | |
20 class PrefService; | |
21 | |
22 namespace ash { | |
23 class StickyKeysController; | |
24 } | |
25 | |
26 namespace ui { | |
27 enum class DomCode; | |
28 }; | |
29 | |
30 namespace chromeos { | |
31 namespace input_method { | |
32 class ImeKeyboard; | |
33 } | |
34 | |
35 // EventRewriter makes various changes to keyboard-related events, | |
36 // including KeyEvents and some other events with keyboard modifier flags: | |
37 // - maps certain non-character keys according to user preferences | |
38 // (Control, Alt, Search, Caps Lock, Escape, Backspace, Diamond); | |
39 // - maps Command to Control on Apple keyboards; | |
40 // - converts numeric pad editing keys to their numeric forms; | |
41 // - converts top-row function keys to special keys where necessary; | |
42 // - handles various key combinations like Search+Backspace -> Delete | |
43 // and Search+number to Fnumber; | |
44 // - handles key/pointer combinations like Alt+Button1 -> Button3. | |
45 class EventRewriter : public ui::EventRewriter { | |
46 public: | |
47 enum DeviceType { | |
48 kDeviceUnknown = 0, | |
49 kDeviceAppleKeyboard, | |
50 kDeviceHotrodRemote, | |
51 kDeviceVirtualCoreKeyboard, // X-server generated events. | |
52 }; | |
53 | |
54 // Things that keyboard-related rewriter phases can change about an Event. | |
55 struct MutableKeyState { | |
56 int flags; | |
57 ui::DomCode code; | |
58 ui::DomKey::Base key; | |
59 ui::KeyboardCode key_code; | |
60 }; | |
61 | |
62 // Does not take ownership of the |sticky_keys_controller|, which may also | |
63 // be NULL (for testing without ash), in which case sticky key operations | |
64 // don't happen. | |
65 explicit EventRewriter(ash::StickyKeysController* sticky_keys_controller); | |
66 ~EventRewriter() override; | |
67 | |
68 // Calls KeyboardDeviceAddedInternal. | |
69 DeviceType KeyboardDeviceAddedForTesting(int device_id, | |
70 const std::string& device_name); | |
71 | |
72 // Calls RewriteMouseEvent(). | |
73 void RewriteMouseButtonEventForTesting( | |
74 const ui::MouseEvent& event, | |
75 std::unique_ptr<ui::Event>* rewritten_event); | |
76 | |
77 const std::map<int, DeviceType>& device_id_to_type_for_testing() const { | |
78 return device_id_to_type_; | |
79 } | |
80 void set_last_keyboard_device_id_for_testing(int device_id) { | |
81 last_keyboard_device_id_ = device_id; | |
82 } | |
83 void set_pref_service_for_testing(const PrefService* pref_service) { | |
84 pref_service_for_testing_ = pref_service; | |
85 } | |
86 void set_ime_keyboard_for_testing( | |
87 chromeos::input_method::ImeKeyboard* ime_keyboard) { | |
88 ime_keyboard_for_testing_ = ime_keyboard; | |
89 } | |
90 | |
91 // EventRewriter overrides: | |
92 ui::EventRewriteStatus RewriteEvent( | |
93 const ui::Event& event, | |
94 std::unique_ptr<ui::Event>* rewritten_event) override; | |
95 ui::EventRewriteStatus NextDispatchEvent( | |
96 const ui::Event& last_event, | |
97 std::unique_ptr<ui::Event>* new_event) override; | |
98 | |
99 // Generate a new key event from an original key event and the replacement | |
100 // state determined by a key rewriter. | |
101 static void BuildRewrittenKeyEvent( | |
102 const ui::KeyEvent& key_event, | |
103 const MutableKeyState& state, | |
104 std::unique_ptr<ui::Event>* rewritten_event); | |
105 | |
106 private: | |
107 void DeviceKeyPressedOrReleased(int device_id); | |
108 | |
109 // Returns the PrefService that should be used. | |
110 const PrefService* GetPrefService() const; | |
111 | |
112 // Adds a device to |device_id_to_type_|. | |
113 DeviceType KeyboardDeviceAdded(int device_id); | |
114 | |
115 // Checks the type of the |device_name|, |vendor_id| and |product_id|, and | |
116 // inserts a new entry to |device_id_to_type_|. | |
117 DeviceType KeyboardDeviceAddedInternal(int device_id, | |
118 const std::string& device_name, | |
119 int vendor_id, | |
120 int product_id); | |
121 | |
122 // Returns true if |last_keyboard_device_id_| is Apple's. | |
123 bool IsAppleKeyboard() const; | |
124 // Returns true if |last_keyboard_device_id_| is Hotrod remote. | |
125 bool IsHotrodRemote() const; | |
126 // Returns true if |last_keyboard_device_id_| is of given |device_type|. | |
127 bool IsLastKeyboardOfType(DeviceType device_type) const; | |
128 | |
129 // Returns true if the target for |event| would prefer to receive raw function | |
130 // keys instead of having them rewritten into back, forward, brightness, | |
131 // volume, etc. or if the user has specified that they desire top-row keys to | |
132 // be treated as function keys globally. | |
133 bool TopRowKeysAreFunctionKeys(const ui::KeyEvent& event) const; | |
134 | |
135 // Given modifier flags |original_flags|, returns the remapped modifiers | |
136 // according to user preferences and/or event properties. | |
137 int GetRemappedModifierMasks(const PrefService& pref_service, | |
138 const ui::Event& event, | |
139 int original_flags) const; | |
140 | |
141 // Rewrite a particular kind of event. | |
142 ui::EventRewriteStatus RewriteKeyEvent( | |
143 const ui::KeyEvent& key_event, | |
144 std::unique_ptr<ui::Event>* rewritten_event); | |
145 ui::EventRewriteStatus RewriteMouseButtonEvent( | |
146 const ui::MouseEvent& mouse_event, | |
147 std::unique_ptr<ui::Event>* rewritten_event); | |
148 ui::EventRewriteStatus RewriteMouseWheelEvent( | |
149 const ui::MouseWheelEvent& mouse_event, | |
150 std::unique_ptr<ui::Event>* rewritten_event); | |
151 ui::EventRewriteStatus RewriteTouchEvent( | |
152 const ui::TouchEvent& touch_event, | |
153 std::unique_ptr<ui::Event>* rewritten_event); | |
154 ui::EventRewriteStatus RewriteScrollEvent( | |
155 const ui::ScrollEvent& scroll_event, | |
156 std::unique_ptr<ui::Event>* rewritten_event); | |
157 | |
158 // Rewriter phases. These can inspect the original |event|, but operate using | |
159 // the current |state|, which may have been modified by previous phases. | |
160 bool RewriteModifierKeys(const ui::KeyEvent& event, MutableKeyState* state); | |
161 void RewriteNumPadKeys(const ui::KeyEvent& event, MutableKeyState* state); | |
162 void RewriteExtendedKeys(const ui::KeyEvent& event, MutableKeyState* state); | |
163 void RewriteFunctionKeys(const ui::KeyEvent& event, MutableKeyState* state); | |
164 void RewriteLocatedEvent(const ui::Event& event, int* flags); | |
165 int RewriteModifierClick(const ui::MouseEvent& event, int* flags); | |
166 | |
167 // A set of device IDs whose press event has been rewritten. | |
168 // This is to ensure that press and release events are rewritten consistently. | |
169 std::set<int> pressed_device_ids_; | |
170 | |
171 std::map<int, DeviceType> device_id_to_type_; | |
172 | |
173 // The |source_device_id()| of the most recent keyboard event, | |
174 // used to interpret modifiers on pointer events. | |
175 int last_keyboard_device_id_; | |
176 | |
177 chromeos::input_method::ImeKeyboard* ime_keyboard_for_testing_; | |
178 const PrefService* pref_service_for_testing_; | |
179 | |
180 // The sticky keys controller is not owned here; | |
181 // at time of writing it is a singleton in ash::Shell. | |
182 ash::StickyKeysController* sticky_keys_controller_; | |
183 | |
184 // Some keyboard layouts have 'latching' keys, which either apply | |
185 // a modifier while held down (like normal modifiers), or, if no | |
186 // non-modifier is pressed while the latching key is down, apply the | |
187 // modifier to the next non-modifier keypress. Under Ozone the stateless | |
188 // layout model requires this to be handled explicitly. See crbug.com/518237 | |
189 // Pragmatically this, like the Diamond key, is handled here in | |
190 // EventRewriter, but modifier state management is scattered between | |
191 // here, sticky keys, and the system layer (X11 or Ozone), and could | |
192 // do with refactoring. | |
193 // - |pressed_modifier_latches_| records the latching keys currently pressed. | |
194 // It also records the active modifier flags for non-modifier keys that are | |
195 // remapped to modifiers, e.g. Diamond/F15. | |
196 // - |latched_modifier_latches_| records the latching keys just released, | |
197 // to be applied to the next non-modifier key. | |
198 // - |used_modifier_latches_| records the latching keys applied to a non- | |
199 // modifier while pressed, so that they do not get applied after release. | |
200 int pressed_modifier_latches_; | |
201 int latched_modifier_latches_; | |
202 int used_modifier_latches_; | |
203 | |
204 DISALLOW_COPY_AND_ASSIGN(EventRewriter); | |
205 }; | |
206 | |
207 } // namespace chromeos | |
208 | |
209 #endif // CHROME_BROWSER_CHROMEOS_EVENTS_EVENT_REWRITER_H_ | |
OLD | NEW |