OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ash/sticky_keys/sticky_keys_controller.h" | 5 #include "ash/sticky_keys/sticky_keys_controller.h" |
6 | 6 |
7 #if defined(USE_X11) | |
8 #include <X11/extensions/XInput2.h> | |
9 #include <X11/Xlib.h> | |
10 #undef RootWindow | |
11 #endif | |
12 | |
13 #include "ash/sticky_keys/sticky_keys_overlay.h" | 7 #include "ash/sticky_keys/sticky_keys_overlay.h" |
14 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
15 #include "base/debug/stack_trace.h" | 9 #include "base/debug/stack_trace.h" |
16 #include "ui/aura/window.h" | 10 #include "ui/aura/window.h" |
17 #include "ui/aura/window_tracker.h" | 11 #include "ui/aura/window_tracker.h" |
18 #include "ui/aura/window_tree_host.h" | 12 #include "ui/aura/window_tree_host.h" |
19 #include "ui/events/event.h" | 13 #include "ui/events/event.h" |
20 #include "ui/events/event_processor.h" | 14 #include "ui/events/event_processor.h" |
21 #include "ui/events/keycodes/keyboard_code_conversion.h" | 15 #include "ui/events/keycodes/keyboard_code_conversion.h" |
22 | 16 |
23 namespace ash { | 17 namespace ash { |
24 | 18 |
25 namespace { | 19 namespace { |
26 | 20 |
27 // Returns true if the type of mouse event should be modified by sticky keys. | 21 // Returns true if the type of mouse event should be modified by sticky keys. |
28 bool ShouldModifyMouseEvent(ui::MouseEvent* event) { | 22 bool ShouldModifyMouseEvent(const ui::MouseEvent& event) { |
29 ui::EventType type = event->type(); | 23 ui::EventType type = event.type(); |
30 return type == ui::ET_MOUSE_PRESSED || type == ui::ET_MOUSE_RELEASED || | 24 return type == ui::ET_MOUSE_PRESSED || type == ui::ET_MOUSE_RELEASED || |
31 type == ui::ET_MOUSEWHEEL; | 25 type == ui::ET_MOUSEWHEEL; |
32 } | 26 } |
33 | 27 |
34 // An implementation of StickyKeysHandler::StickyKeysHandlerDelegate. | |
35 class StickyKeysHandlerDelegateImpl : | |
36 public StickyKeysHandler::StickyKeysHandlerDelegate { | |
37 public: | |
38 StickyKeysHandlerDelegateImpl(); | |
39 virtual ~StickyKeysHandlerDelegateImpl(); | |
40 | |
41 // StickyKeysHandlerDelegate overrides. | |
42 virtual void DispatchKeyEvent(ui::KeyEvent* event, | |
43 aura::Window* target) OVERRIDE; | |
44 | |
45 virtual void DispatchMouseEvent(ui::MouseEvent* event, | |
46 aura::Window* target) OVERRIDE; | |
47 | |
48 virtual void DispatchScrollEvent(ui::ScrollEvent* event, | |
49 aura::Window* target) OVERRIDE; | |
50 private: | |
51 void DispatchEvent(ui::Event* event, aura::Window* target); | |
52 | |
53 DISALLOW_COPY_AND_ASSIGN(StickyKeysHandlerDelegateImpl); | |
54 }; | |
55 | |
56 StickyKeysHandlerDelegateImpl::StickyKeysHandlerDelegateImpl() { | |
57 } | |
58 | |
59 StickyKeysHandlerDelegateImpl::~StickyKeysHandlerDelegateImpl() { | |
60 } | |
61 | |
62 void StickyKeysHandlerDelegateImpl::DispatchKeyEvent(ui::KeyEvent* event, | |
63 aura::Window* target) { | |
64 DispatchEvent(event, target); | |
65 } | |
66 | |
67 void StickyKeysHandlerDelegateImpl::DispatchMouseEvent(ui::MouseEvent* event, | |
68 aura::Window* target) { | |
69 DCHECK(target); | |
70 // We need to send a new, untransformed mouse event to the host. | |
71 if (event->IsMouseWheelEvent()) { | |
72 aura::Window* source = static_cast<aura::Window*>(event->target()); | |
73 ui::MouseWheelEvent new_event(*static_cast<ui::MouseWheelEvent*>(event), | |
74 source, | |
75 source->GetRootWindow()); | |
76 // Transform the location back to host coordinates before dispatching. | |
77 new_event.UpdateForRootTransform(source->GetHost()->GetRootTransform()); | |
78 DispatchEvent(&new_event, target); | |
79 } else { | |
80 aura::Window* source = static_cast<aura::Window*>(event->target()); | |
81 ui::MouseEvent new_event(*event, source, source->GetRootWindow()); | |
82 // Transform the location back to host coordinates before dispatching. | |
83 new_event.UpdateForRootTransform(source->GetHost()->GetRootTransform()); | |
84 DispatchEvent(&new_event, target); | |
85 } | |
86 } | |
87 | |
88 void StickyKeysHandlerDelegateImpl::DispatchScrollEvent( | |
89 ui::ScrollEvent* event, | |
90 aura::Window* target) { | |
91 DispatchEvent(event, target); | |
92 } | |
93 | |
94 void StickyKeysHandlerDelegateImpl::DispatchEvent(ui::Event* event, | |
95 aura::Window* target) { | |
96 DCHECK(target); | |
97 ui::EventDispatchDetails details = | |
98 target->GetHost()->event_processor()->OnEventFromSource(event); | |
99 if (details.dispatcher_destroyed) | |
100 return; | |
101 } | |
102 | |
103 } // namespace | 28 } // namespace |
104 | 29 |
105 /////////////////////////////////////////////////////////////////////////////// | 30 /////////////////////////////////////////////////////////////////////////////// |
106 // StickyKeys | 31 // StickyKeys |
107 StickyKeysController::StickyKeysController() | 32 StickyKeysController::StickyKeysController() |
108 : enabled_(false), | 33 : enabled_(false), |
109 mod3_enabled_(false), | 34 mod3_enabled_(false), |
110 altgr_enabled_(false) { | 35 altgr_enabled_(false) { |
111 } | 36 } |
112 | 37 |
113 StickyKeysController::~StickyKeysController() { | 38 StickyKeysController::~StickyKeysController() { |
114 } | 39 } |
115 | 40 |
116 void StickyKeysController::Enable(bool enabled) { | 41 void StickyKeysController::Enable(bool enabled) { |
117 if (enabled_ != enabled) { | 42 if (enabled_ != enabled) { |
118 enabled_ = enabled; | 43 enabled_ = enabled; |
119 | 44 |
120 // Reset key handlers when activating sticky keys to ensure all | 45 // Reset key handlers when activating sticky keys to ensure all |
121 // the handlers' states are reset. | 46 // the handlers' states are reset. |
122 if (enabled_) { | 47 if (enabled_) { |
123 shift_sticky_key_.reset( | 48 shift_sticky_key_.reset(new StickyKeysHandler(ui::EF_SHIFT_DOWN)); |
124 new StickyKeysHandler(ui::EF_SHIFT_DOWN, | 49 alt_sticky_key_.reset(new StickyKeysHandler(ui::EF_ALT_DOWN)); |
125 new StickyKeysHandlerDelegateImpl())); | 50 altgr_sticky_key_.reset(new StickyKeysHandler(ui::EF_ALTGR_DOWN)); |
126 alt_sticky_key_.reset( | 51 ctrl_sticky_key_.reset(new StickyKeysHandler(ui::EF_CONTROL_DOWN)); |
127 new StickyKeysHandler(ui::EF_ALT_DOWN, | 52 mod3_sticky_key_.reset(new StickyKeysHandler(ui::EF_MOD3_DOWN)); |
128 new StickyKeysHandlerDelegateImpl())); | |
129 altgr_sticky_key_.reset( | |
130 new StickyKeysHandler(ui::EF_ALTGR_DOWN, | |
131 new StickyKeysHandlerDelegateImpl())); | |
132 ctrl_sticky_key_.reset( | |
133 new StickyKeysHandler(ui::EF_CONTROL_DOWN, | |
134 new StickyKeysHandlerDelegateImpl())); | |
135 mod3_sticky_key_.reset( | |
136 new StickyKeysHandler(ui::EF_MOD3_DOWN, | |
137 new StickyKeysHandlerDelegateImpl())); | |
138 | 53 |
139 overlay_.reset(new StickyKeysOverlay()); | 54 overlay_.reset(new StickyKeysOverlay()); |
140 overlay_->SetModifierVisible(ui::EF_ALTGR_DOWN, altgr_enabled_); | 55 overlay_->SetModifierVisible(ui::EF_ALTGR_DOWN, altgr_enabled_); |
141 overlay_->SetModifierVisible(ui::EF_MOD3_DOWN, mod3_enabled_); | 56 overlay_->SetModifierVisible(ui::EF_MOD3_DOWN, mod3_enabled_); |
142 } else if (overlay_) { | 57 } else if (overlay_) { |
143 overlay_->Show(false); | 58 overlay_->Show(false); |
144 } | 59 } |
145 } | 60 } |
146 } | 61 } |
147 | 62 |
148 void StickyKeysController::SetModifiersEnabled(bool mod3_enabled, | 63 void StickyKeysController::SetModifiersEnabled(bool mod3_enabled, |
149 bool altgr_enabled) { | 64 bool altgr_enabled) { |
150 mod3_enabled_ = mod3_enabled; | 65 mod3_enabled_ = mod3_enabled; |
151 altgr_enabled_ = altgr_enabled; | 66 altgr_enabled_ = altgr_enabled; |
152 if (overlay_) { | 67 if (overlay_) { |
153 overlay_->SetModifierVisible(ui::EF_ALTGR_DOWN, altgr_enabled_); | 68 overlay_->SetModifierVisible(ui::EF_ALTGR_DOWN, altgr_enabled_); |
154 overlay_->SetModifierVisible(ui::EF_MOD3_DOWN, mod3_enabled_); | 69 overlay_->SetModifierVisible(ui::EF_MOD3_DOWN, mod3_enabled_); |
155 } | 70 } |
156 } | 71 } |
157 | 72 |
158 bool StickyKeysController::HandleKeyEvent(ui::KeyEvent* event) { | 73 bool StickyKeysController::HandleKeyEvent(const ui::KeyEvent& event, |
159 return shift_sticky_key_->HandleKeyEvent(event) || | 74 ui::KeyboardCode key_code, |
160 alt_sticky_key_->HandleKeyEvent(event) || | 75 int* mod_down_flags, |
161 altgr_sticky_key_->HandleKeyEvent(event) || | 76 int* mod_up_flags) { |
162 ctrl_sticky_key_->HandleKeyEvent(event) || | 77 return shift_sticky_key_->HandleKeyEvent( |
163 mod3_sticky_key_->HandleKeyEvent(event); | 78 event, key_code, mod_down_flags, mod_up_flags) || |
79 alt_sticky_key_->HandleKeyEvent( | |
80 event, key_code, mod_down_flags, mod_up_flags) || | |
81 altgr_sticky_key_->HandleKeyEvent( | |
82 event, key_code, mod_down_flags, mod_up_flags) || | |
83 ctrl_sticky_key_->HandleKeyEvent( | |
84 event, key_code, mod_down_flags, mod_up_flags) || | |
85 mod3_sticky_key_->HandleKeyEvent( | |
86 event, key_code, mod_down_flags, mod_up_flags); | |
164 } | 87 } |
165 | 88 |
166 bool StickyKeysController::HandleMouseEvent(ui::MouseEvent* event) { | 89 bool StickyKeysController::HandleMouseEvent(const ui::MouseEvent& event, |
167 return shift_sticky_key_->HandleMouseEvent(event) || | 90 int* mod_down_flags, |
168 alt_sticky_key_->HandleMouseEvent(event) || | 91 int* mod_up_flags) { |
169 altgr_sticky_key_->HandleMouseEvent(event) || | 92 return shift_sticky_key_->HandleMouseEvent( |
170 ctrl_sticky_key_->HandleMouseEvent(event) || | 93 event, mod_down_flags, mod_up_flags) || |
171 mod3_sticky_key_->HandleMouseEvent(event); | 94 alt_sticky_key_->HandleMouseEvent( |
95 event, mod_down_flags, mod_up_flags) || | |
96 altgr_sticky_key_->HandleMouseEvent( | |
97 event, mod_down_flags, mod_up_flags) || | |
98 ctrl_sticky_key_->HandleMouseEvent( | |
99 event, mod_down_flags, mod_up_flags) || | |
100 mod3_sticky_key_->HandleMouseEvent( | |
101 event, mod_down_flags, mod_up_flags); | |
172 } | 102 } |
173 | 103 |
174 bool StickyKeysController::HandleScrollEvent(ui::ScrollEvent* event) { | 104 bool StickyKeysController::HandleScrollEvent(const ui::ScrollEvent& event, |
175 return shift_sticky_key_->HandleScrollEvent(event) || | 105 int* mod_down_flags, |
176 alt_sticky_key_->HandleScrollEvent(event) || | 106 int* mod_up_flags) { |
177 altgr_sticky_key_->HandleScrollEvent(event) || | 107 return shift_sticky_key_->HandleScrollEvent( |
178 ctrl_sticky_key_->HandleScrollEvent(event) || | 108 event, mod_down_flags, mod_up_flags) || |
179 mod3_sticky_key_->HandleScrollEvent(event); | 109 alt_sticky_key_->HandleScrollEvent( |
110 event, mod_down_flags, mod_up_flags) || | |
111 altgr_sticky_key_->HandleScrollEvent( | |
112 event, mod_down_flags, mod_up_flags) || | |
113 ctrl_sticky_key_->HandleScrollEvent( | |
114 event, mod_down_flags, mod_up_flags) || | |
115 mod3_sticky_key_->HandleScrollEvent( | |
116 event, mod_down_flags, mod_up_flags); | |
180 } | 117 } |
181 | 118 |
182 void StickyKeysController::OnKeyEvent(ui::KeyEvent* event) { | 119 ui::EventRewriteStatus StickyKeysController::RewriteKeyEvent( |
183 // Do not consume a translated key event which is generated by an IME. | 120 const ui::KeyEvent& event, |
184 if (event->IsTranslated()) | 121 ui::KeyboardCode key_code, |
185 return; | 122 int* flags) { |
186 | 123 if (!enabled_) |
187 if (enabled_) { | 124 return ui::EVENT_REWRITE_CONTINUE; |
188 if (HandleKeyEvent(event)) | 125 int mod_down_flags = 0; |
189 event->StopPropagation(); | 126 int mod_up_flags = 0; |
190 UpdateOverlay(); | 127 bool consumed = |
191 } | 128 HandleKeyEvent(event, key_code, &mod_down_flags, &mod_up_flags); |
129 int changed_flags = mod_down_flags & ~*flags; | |
130 *flags |= mod_down_flags; | |
131 UpdateOverlay(); | |
132 return consumed ? ui::EVENT_REWRITE_DISCARD | |
Daniel Erat
2014/06/05 23:16:10
this looks like it's duplicated a few times. mind
kpschoedel
2014/06/06 17:53:22
Done.
| |
133 : mod_up_flags ? ui::EVENT_REWRITE_DISPATCH_ANOTHER | |
134 : changed_flags ? ui::EVENT_REWRITE_REWRITTEN | |
135 : ui::EVENT_REWRITE_CONTINUE; | |
192 } | 136 } |
193 | 137 |
194 void StickyKeysController::OnMouseEvent(ui::MouseEvent* event) { | 138 ui::EventRewriteStatus StickyKeysController::RewriteMouseEvent( |
195 if (enabled_) { | 139 const ui::MouseEvent& event, |
196 if (HandleMouseEvent(event)) | 140 int* flags) { |
197 event->StopPropagation(); | 141 if (!enabled_) |
198 UpdateOverlay(); | 142 return ui::EVENT_REWRITE_CONTINUE; |
199 } | 143 int mod_down_flags = 0; |
144 int mod_up_flags = 0; | |
145 bool consumed = HandleMouseEvent(event, &mod_down_flags, &mod_up_flags); | |
146 int changed_flags = mod_down_flags & ~*flags; | |
147 *flags |= mod_down_flags; | |
148 UpdateOverlay(); | |
149 return consumed ? ui::EVENT_REWRITE_DISCARD | |
150 : mod_up_flags ? ui::EVENT_REWRITE_DISPATCH_ANOTHER | |
151 : changed_flags ? ui::EVENT_REWRITE_REWRITTEN | |
152 : ui::EVENT_REWRITE_CONTINUE; | |
200 } | 153 } |
201 | 154 |
202 void StickyKeysController::OnScrollEvent(ui::ScrollEvent* event) { | 155 ui::EventRewriteStatus StickyKeysController::RewriteScrollEvent( |
203 if (enabled_) { | 156 const ui::ScrollEvent& event, |
204 if (HandleScrollEvent(event)) | 157 int* flags) { |
205 event->StopPropagation(); | 158 if (!enabled_) |
206 UpdateOverlay(); | 159 return ui::EVENT_REWRITE_CONTINUE; |
207 } | 160 int mod_down_flags = 0; |
161 int mod_up_flags = 0; | |
162 bool consumed = HandleScrollEvent(event, &mod_down_flags, &mod_up_flags); | |
163 int changed_flags = mod_down_flags & ~*flags; | |
164 *flags |= mod_down_flags; | |
165 UpdateOverlay(); | |
166 return consumed ? ui::EVENT_REWRITE_DISCARD | |
167 : mod_up_flags ? ui::EVENT_REWRITE_DISPATCH_ANOTHER | |
168 : changed_flags ? ui::EVENT_REWRITE_REWRITTEN | |
169 : ui::EVENT_REWRITE_CONTINUE; | |
170 } | |
171 | |
172 ui::EventRewriteStatus StickyKeysController::NextDispatchEvent( | |
173 scoped_ptr<ui::Event>* new_event) { | |
174 new_event->reset(); | |
175 int remaining = shift_sticky_key_->GetModifierUpEvent(new_event) + | |
176 alt_sticky_key_->GetModifierUpEvent(new_event) + | |
177 altgr_sticky_key_->GetModifierUpEvent(new_event) + | |
178 ctrl_sticky_key_->GetModifierUpEvent(new_event) + | |
179 mod3_sticky_key_->GetModifierUpEvent(new_event); | |
180 return remaining ? ui::EVENT_REWRITE_DISPATCH_ANOTHER | |
181 : ui::EVENT_REWRITE_REWRITTEN; | |
208 } | 182 } |
209 | 183 |
210 void StickyKeysController::UpdateOverlay() { | 184 void StickyKeysController::UpdateOverlay() { |
211 overlay_->SetModifierKeyState( | 185 overlay_->SetModifierKeyState( |
212 ui::EF_SHIFT_DOWN, shift_sticky_key_->current_state()); | 186 ui::EF_SHIFT_DOWN, shift_sticky_key_->current_state()); |
213 overlay_->SetModifierKeyState( | 187 overlay_->SetModifierKeyState( |
214 ui::EF_CONTROL_DOWN, ctrl_sticky_key_->current_state()); | 188 ui::EF_CONTROL_DOWN, ctrl_sticky_key_->current_state()); |
215 overlay_->SetModifierKeyState( | 189 overlay_->SetModifierKeyState( |
216 ui::EF_ALT_DOWN, alt_sticky_key_->current_state()); | 190 ui::EF_ALT_DOWN, alt_sticky_key_->current_state()); |
217 overlay_->SetModifierKeyState( | 191 overlay_->SetModifierKeyState( |
(...skipping 10 matching lines...) Expand all Loading... | |
228 | 202 |
229 overlay_->Show(enabled_ && key_in_use); | 203 overlay_->Show(enabled_ && key_in_use); |
230 } | 204 } |
231 | 205 |
232 StickyKeysOverlay* StickyKeysController::GetOverlayForTest() { | 206 StickyKeysOverlay* StickyKeysController::GetOverlayForTest() { |
233 return overlay_.get(); | 207 return overlay_.get(); |
234 } | 208 } |
235 | 209 |
236 /////////////////////////////////////////////////////////////////////////////// | 210 /////////////////////////////////////////////////////////////////////////////// |
237 // StickyKeysHandler | 211 // StickyKeysHandler |
238 StickyKeysHandler::StickyKeysHandler(ui::EventFlags modifier_flag, | 212 StickyKeysHandler::StickyKeysHandler(ui::EventFlags modifier_flag) |
239 StickyKeysHandlerDelegate* delegate) | |
240 : modifier_flag_(modifier_flag), | 213 : modifier_flag_(modifier_flag), |
241 current_state_(STICKY_KEY_STATE_DISABLED), | 214 current_state_(STICKY_KEY_STATE_DISABLED), |
242 event_from_myself_(false), | |
243 preparing_to_enable_(false), | 215 preparing_to_enable_(false), |
244 scroll_delta_(0), | 216 scroll_delta_(0) { |
245 delegate_(delegate) { | |
246 } | 217 } |
247 | 218 |
248 StickyKeysHandler::~StickyKeysHandler() { | 219 StickyKeysHandler::~StickyKeysHandler() { |
249 } | 220 } |
250 | 221 |
251 StickyKeysHandler::StickyKeysHandlerDelegate::StickyKeysHandlerDelegate() { | 222 bool StickyKeysHandler::HandleKeyEvent(const ui::KeyEvent& event, |
252 } | 223 ui::KeyboardCode key_code, |
253 | 224 int* mod_down_flags, |
254 StickyKeysHandler::StickyKeysHandlerDelegate::~StickyKeysHandlerDelegate() { | 225 int* mod_up_flags) { |
255 } | |
256 | |
257 bool StickyKeysHandler::HandleKeyEvent(ui::KeyEvent* event) { | |
258 if (event_from_myself_) | |
259 return false; // Do not handle self-generated key event. | |
260 switch (current_state_) { | 226 switch (current_state_) { |
261 case STICKY_KEY_STATE_DISABLED: | 227 case STICKY_KEY_STATE_DISABLED: |
262 return HandleDisabledState(event); | 228 return HandleDisabledState(event, key_code); |
263 case STICKY_KEY_STATE_ENABLED: | 229 case STICKY_KEY_STATE_ENABLED: |
264 return HandleEnabledState(event); | 230 return HandleEnabledState(event, key_code, mod_down_flags, mod_up_flags); |
265 case STICKY_KEY_STATE_LOCKED: | 231 case STICKY_KEY_STATE_LOCKED: |
266 return HandleLockedState(event); | 232 return HandleLockedState(event, key_code, mod_down_flags, mod_up_flags); |
267 } | 233 } |
268 NOTREACHED(); | 234 NOTREACHED(); |
269 return false; | 235 return false; |
270 } | 236 } |
271 | 237 |
272 bool StickyKeysHandler::HandleMouseEvent(ui::MouseEvent* event) { | 238 bool StickyKeysHandler::HandleMouseEvent( |
239 const ui::MouseEvent& event, | |
240 int* mod_down_flags, | |
241 int* mod_up_flags) { | |
273 if (ShouldModifyMouseEvent(event)) | 242 if (ShouldModifyMouseEvent(event)) |
274 preparing_to_enable_ = false; | 243 preparing_to_enable_ = false; |
275 | 244 |
276 if (event_from_myself_ || current_state_ == STICKY_KEY_STATE_DISABLED | 245 if (current_state_ == STICKY_KEY_STATE_DISABLED || |
277 || !ShouldModifyMouseEvent(event)) { | 246 !ShouldModifyMouseEvent(event)) { |
278 return false; | 247 return false; |
279 } | 248 } |
280 DCHECK(current_state_ == STICKY_KEY_STATE_ENABLED || | 249 DCHECK(current_state_ == STICKY_KEY_STATE_ENABLED || |
281 current_state_ == STICKY_KEY_STATE_LOCKED); | 250 current_state_ == STICKY_KEY_STATE_LOCKED); |
282 | 251 |
283 AppendModifier(event); | 252 *mod_down_flags |= modifier_flag_; |
284 // Only disable on the mouse released event in normal, non-locked mode. | 253 // Only disable on the mouse released event in normal, non-locked mode. |
285 if (current_state_ == STICKY_KEY_STATE_ENABLED && | 254 if (current_state_ == STICKY_KEY_STATE_ENABLED && |
286 event->type() != ui::ET_MOUSE_PRESSED) { | 255 event.type() != ui::ET_MOUSE_PRESSED) { |
287 current_state_ = STICKY_KEY_STATE_DISABLED; | 256 current_state_ = STICKY_KEY_STATE_DISABLED; |
288 DispatchEventAndReleaseModifier(event); | 257 *mod_up_flags |= modifier_flag_; |
289 return true; | 258 return false; |
290 } | 259 } |
291 | 260 |
292 return false; | 261 return false; |
293 } | 262 } |
294 | 263 |
295 bool StickyKeysHandler::HandleScrollEvent(ui::ScrollEvent* event) { | 264 bool StickyKeysHandler::HandleScrollEvent( |
265 const ui::ScrollEvent& event, | |
266 int* mod_down_flags, | |
267 int* mod_up_flags) { | |
296 preparing_to_enable_ = false; | 268 preparing_to_enable_ = false; |
297 if (event_from_myself_ || current_state_ == STICKY_KEY_STATE_DISABLED) | 269 if (current_state_ == STICKY_KEY_STATE_DISABLED) |
298 return false; | 270 return false; |
299 DCHECK(current_state_ == STICKY_KEY_STATE_ENABLED || | 271 DCHECK(current_state_ == STICKY_KEY_STATE_ENABLED || |
300 current_state_ == STICKY_KEY_STATE_LOCKED); | 272 current_state_ == STICKY_KEY_STATE_LOCKED); |
301 | 273 |
302 // We detect a direction change if the current |scroll_delta_| is assigned | 274 // We detect a direction change if the current |scroll_delta_| is assigned |
303 // and the offset of the current scroll event has the opposing sign. | 275 // and the offset of the current scroll event has the opposing sign. |
304 bool direction_changed = false; | 276 bool direction_changed = false; |
305 if (current_state_ == STICKY_KEY_STATE_ENABLED && | 277 if (current_state_ == STICKY_KEY_STATE_ENABLED && |
306 event->type() == ui::ET_SCROLL) { | 278 event.type() == ui::ET_SCROLL) { |
307 int offset = event->y_offset(); | 279 int offset = event.y_offset(); |
308 if (scroll_delta_) | 280 if (scroll_delta_) |
309 direction_changed = offset * scroll_delta_ <= 0; | 281 direction_changed = offset * scroll_delta_ <= 0; |
310 scroll_delta_ = offset; | 282 scroll_delta_ = offset; |
311 } | 283 } |
312 | 284 |
313 if (!direction_changed) | 285 if (!direction_changed) |
314 AppendModifier(event); | 286 *mod_down_flags |= modifier_flag_; |
315 | 287 |
316 // We want to modify all the scroll events in the scroll sequence, which ends | 288 // We want to modify all the scroll events in the scroll sequence, which ends |
317 // with a fling start event. We also stop when the scroll sequence changes | 289 // with a fling start event. We also stop when the scroll sequence changes |
318 // direction. | 290 // direction. |
319 if (current_state_ == STICKY_KEY_STATE_ENABLED && | 291 if (current_state_ == STICKY_KEY_STATE_ENABLED && |
320 (event->type() == ui::ET_SCROLL_FLING_START || direction_changed)) { | 292 (event.type() == ui::ET_SCROLL_FLING_START || direction_changed)) { |
321 current_state_ = STICKY_KEY_STATE_DISABLED; | 293 current_state_ = STICKY_KEY_STATE_DISABLED; |
322 scroll_delta_ = 0; | 294 scroll_delta_ = 0; |
323 DispatchEventAndReleaseModifier(event); | 295 *mod_up_flags |= modifier_flag_; |
324 return true; | 296 return false; |
325 } | 297 } |
326 | 298 |
327 return false; | 299 return false; |
328 } | 300 } |
329 | 301 |
330 StickyKeysHandler::KeyEventType | 302 int StickyKeysHandler::GetModifierUpEvent(scoped_ptr<ui::Event>* new_event) { |
331 StickyKeysHandler::TranslateKeyEvent(ui::KeyEvent* event) { | 303 if (current_state_ != STICKY_KEY_STATE_DISABLED || !modifier_up_event_) |
304 return 0; | |
305 DCHECK(new_event); | |
306 if (*new_event) | |
307 return 1; | |
308 new_event->reset(modifier_up_event_.release()); | |
309 return 0; | |
310 } | |
311 | |
312 StickyKeysHandler::KeyEventType StickyKeysHandler::TranslateKeyEvent( | |
313 ui::EventType type, | |
314 ui::KeyboardCode key_code) { | |
332 bool is_target_key = false; | 315 bool is_target_key = false; |
333 if (event->key_code() == ui::VKEY_SHIFT || | 316 if (key_code == ui::VKEY_SHIFT || |
334 event->key_code() == ui::VKEY_LSHIFT || | 317 key_code == ui::VKEY_LSHIFT || |
335 event->key_code() == ui::VKEY_RSHIFT) { | 318 key_code == ui::VKEY_RSHIFT) { |
336 is_target_key = (modifier_flag_ == ui::EF_SHIFT_DOWN); | 319 is_target_key = (modifier_flag_ == ui::EF_SHIFT_DOWN); |
337 } else if (event->key_code() == ui::VKEY_CONTROL || | 320 } else if (key_code == ui::VKEY_CONTROL || |
338 event->key_code() == ui::VKEY_LCONTROL || | 321 key_code == ui::VKEY_LCONTROL || |
339 event->key_code() == ui::VKEY_RCONTROL) { | 322 key_code == ui::VKEY_RCONTROL) { |
340 is_target_key = (modifier_flag_ == ui::EF_CONTROL_DOWN); | 323 is_target_key = (modifier_flag_ == ui::EF_CONTROL_DOWN); |
341 } else if (event->key_code() == ui::VKEY_MENU || | 324 } else if (key_code == ui::VKEY_MENU || |
342 event->key_code() == ui::VKEY_LMENU || | 325 key_code == ui::VKEY_LMENU || |
343 event->key_code() == ui::VKEY_RMENU) { | 326 key_code == ui::VKEY_RMENU) { |
344 is_target_key = (modifier_flag_ == ui::EF_ALT_DOWN); | 327 is_target_key = (modifier_flag_ == ui::EF_ALT_DOWN); |
345 } else if (event->key_code() == ui::VKEY_ALTGR) { | 328 } else if (key_code == ui::VKEY_ALTGR) { |
346 is_target_key = (modifier_flag_ == ui::EF_ALTGR_DOWN); | 329 is_target_key = (modifier_flag_ == ui::EF_ALTGR_DOWN); |
347 } else if (event->key_code() == ui::VKEY_OEM_8) { | 330 } else if (key_code == ui::VKEY_OEM_8) { |
348 is_target_key = (modifier_flag_ == ui::EF_MOD3_DOWN); | 331 is_target_key = (modifier_flag_ == ui::EF_MOD3_DOWN); |
349 } else { | 332 } else { |
350 return event->type() == ui::ET_KEY_PRESSED ? | 333 return type == ui::ET_KEY_PRESSED ? |
351 NORMAL_KEY_DOWN : NORMAL_KEY_UP; | 334 NORMAL_KEY_DOWN : NORMAL_KEY_UP; |
352 } | 335 } |
353 | 336 |
354 if (is_target_key) { | 337 if (is_target_key) { |
355 return event->type() == ui::ET_KEY_PRESSED ? | 338 return type == ui::ET_KEY_PRESSED ? |
356 TARGET_MODIFIER_DOWN : TARGET_MODIFIER_UP; | 339 TARGET_MODIFIER_DOWN : TARGET_MODIFIER_UP; |
357 } | 340 } |
358 return event->type() == ui::ET_KEY_PRESSED ? | 341 return type == ui::ET_KEY_PRESSED ? |
359 OTHER_MODIFIER_DOWN : OTHER_MODIFIER_UP; | 342 OTHER_MODIFIER_DOWN : OTHER_MODIFIER_UP; |
360 } | 343 } |
361 | 344 |
362 bool StickyKeysHandler::HandleDisabledState(ui::KeyEvent* event) { | 345 bool StickyKeysHandler::HandleDisabledState(const ui::KeyEvent& event, |
363 switch (TranslateKeyEvent(event)) { | 346 ui::KeyboardCode key_code) { |
347 switch (TranslateKeyEvent(event.type(), key_code)) { | |
364 case TARGET_MODIFIER_UP: | 348 case TARGET_MODIFIER_UP: |
365 if (preparing_to_enable_) { | 349 if (preparing_to_enable_) { |
366 preparing_to_enable_ = false; | 350 preparing_to_enable_ = false; |
367 scroll_delta_ = 0; | 351 scroll_delta_ = 0; |
368 current_state_ = STICKY_KEY_STATE_ENABLED; | 352 current_state_ = STICKY_KEY_STATE_ENABLED; |
369 modifier_up_event_.reset(new ui::KeyEvent(*event)); | 353 modifier_up_event_.reset(new ui::KeyEvent(event)); |
370 return true; | 354 return true; |
371 } | 355 } |
372 return false; | 356 return false; |
373 case TARGET_MODIFIER_DOWN: | 357 case TARGET_MODIFIER_DOWN: |
374 preparing_to_enable_ = true; | 358 preparing_to_enable_ = true; |
375 return false; | 359 return false; |
376 case NORMAL_KEY_DOWN: | 360 case NORMAL_KEY_DOWN: |
377 preparing_to_enable_ = false; | 361 preparing_to_enable_ = false; |
378 return false; | 362 return false; |
379 case NORMAL_KEY_UP: | 363 case NORMAL_KEY_UP: |
380 case OTHER_MODIFIER_DOWN: | 364 case OTHER_MODIFIER_DOWN: |
381 case OTHER_MODIFIER_UP: | 365 case OTHER_MODIFIER_UP: |
382 return false; | 366 return false; |
383 } | 367 } |
384 NOTREACHED(); | 368 NOTREACHED(); |
385 return false; | 369 return false; |
386 } | 370 } |
387 | 371 |
388 bool StickyKeysHandler::HandleEnabledState(ui::KeyEvent* event) { | 372 bool StickyKeysHandler::HandleEnabledState(const ui::KeyEvent& event, |
389 switch (TranslateKeyEvent(event)) { | 373 ui::KeyboardCode key_code, |
374 int* mod_down_flags, | |
375 int* mod_up_flags) { | |
376 switch (TranslateKeyEvent(event.type(), key_code)) { | |
390 case NORMAL_KEY_UP: | 377 case NORMAL_KEY_UP: |
391 case TARGET_MODIFIER_DOWN: | 378 case TARGET_MODIFIER_DOWN: |
392 return true; | 379 return false; |
Daniel Erat
2014/06/05 23:16:10
what's the reason for this change? (just asking be
kpschoedel
2014/06/06 17:53:22
Short answer is that these functions are defined t
| |
393 case TARGET_MODIFIER_UP: | 380 case TARGET_MODIFIER_UP: |
394 current_state_ = STICKY_KEY_STATE_LOCKED; | 381 current_state_ = STICKY_KEY_STATE_LOCKED; |
395 modifier_up_event_.reset(); | 382 modifier_up_event_.reset(); |
396 return true; | 383 return true; |
397 case NORMAL_KEY_DOWN: { | 384 case NORMAL_KEY_DOWN: { |
398 current_state_ = STICKY_KEY_STATE_DISABLED; | 385 current_state_ = STICKY_KEY_STATE_DISABLED; |
399 AppendModifier(event); | 386 *mod_down_flags |= modifier_flag_; |
400 DispatchEventAndReleaseModifier(event); | 387 *mod_up_flags |= modifier_flag_; |
401 return true; | 388 return false; |
402 } | 389 } |
403 case OTHER_MODIFIER_DOWN: | 390 case OTHER_MODIFIER_DOWN: |
404 case OTHER_MODIFIER_UP: | 391 case OTHER_MODIFIER_UP: |
405 return false; | 392 return false; |
406 } | 393 } |
407 NOTREACHED(); | 394 NOTREACHED(); |
408 return false; | 395 return false; |
409 } | 396 } |
410 | 397 |
411 bool StickyKeysHandler::HandleLockedState(ui::KeyEvent* event) { | 398 bool StickyKeysHandler::HandleLockedState(const ui::KeyEvent& event, |
412 switch (TranslateKeyEvent(event)) { | 399 ui::KeyboardCode key_code, |
400 int* mod_down_flags, | |
401 int* mod_up_flags) { | |
402 switch (TranslateKeyEvent(event.type(), key_code)) { | |
413 case TARGET_MODIFIER_DOWN: | 403 case TARGET_MODIFIER_DOWN: |
414 return true; | 404 return true; |
415 case TARGET_MODIFIER_UP: | 405 case TARGET_MODIFIER_UP: |
416 current_state_ = STICKY_KEY_STATE_DISABLED; | 406 current_state_ = STICKY_KEY_STATE_DISABLED; |
417 return false; | 407 return false; |
418 case NORMAL_KEY_DOWN: | 408 case NORMAL_KEY_DOWN: |
419 case NORMAL_KEY_UP: | 409 case NORMAL_KEY_UP: |
420 AppendModifier(event); | 410 *mod_down_flags |= modifier_flag_; |
421 return false; | 411 return false; |
422 case OTHER_MODIFIER_DOWN: | 412 case OTHER_MODIFIER_DOWN: |
423 case OTHER_MODIFIER_UP: | 413 case OTHER_MODIFIER_UP: |
424 return false; | 414 return false; |
425 } | 415 } |
426 NOTREACHED(); | 416 NOTREACHED(); |
427 return false; | 417 return false; |
428 } | 418 } |
429 | 419 |
430 void StickyKeysHandler::DispatchEventAndReleaseModifier(ui::Event* event) { | |
431 DCHECK(event->IsKeyEvent() || | |
432 event->IsMouseEvent() || | |
433 event->IsScrollEvent()); | |
434 DCHECK(modifier_up_event_.get()); | |
435 aura::Window* target = static_cast<aura::Window*>(event->target()); | |
436 DCHECK(target); | |
437 aura::Window* root_window = target->GetRootWindow(); | |
438 DCHECK(root_window); | |
439 | |
440 aura::WindowTracker window_tracker; | |
441 window_tracker.Add(target); | |
442 | |
443 event_from_myself_ = true; | |
444 if (event->IsKeyEvent()) { | |
445 delegate_->DispatchKeyEvent(static_cast<ui::KeyEvent*>(event), target); | |
446 } else if (event->IsMouseEvent()) { | |
447 delegate_->DispatchMouseEvent(static_cast<ui::MouseEvent*>(event), target); | |
448 } else { | |
449 delegate_->DispatchScrollEvent( | |
450 static_cast<ui::ScrollEvent*>(event), target); | |
451 } | |
452 | |
453 // The action triggered above may have destroyed the event target, in which | |
454 // case we will dispatch the modifier up event to the root window instead. | |
455 aura::Window* modifier_up_target = | |
456 window_tracker.Contains(target) ? target : root_window; | |
457 delegate_->DispatchKeyEvent(modifier_up_event_.get(), modifier_up_target); | |
458 event_from_myself_ = false; | |
459 } | |
460 | |
461 void StickyKeysHandler::AppendNativeEventMask(unsigned int* state) { | |
462 #if defined(USE_X11) | |
463 unsigned int& state_ref = *state; | |
464 switch (modifier_flag_) { | |
465 case ui::EF_CONTROL_DOWN: | |
466 state_ref |= ControlMask; | |
467 break; | |
468 case ui::EF_ALT_DOWN: | |
469 state_ref |= Mod1Mask; | |
470 break; | |
471 case ui::EF_ALTGR_DOWN: | |
472 state_ref |= Mod5Mask; | |
473 break; | |
474 case ui::EF_SHIFT_DOWN: | |
475 state_ref |= ShiftMask; | |
476 break; | |
477 case ui::EF_MOD3_DOWN: | |
478 state_ref |= Mod3Mask; | |
479 break; | |
480 default: | |
481 NOTREACHED(); | |
482 } | |
483 #endif | |
484 } | |
485 | |
486 void StickyKeysHandler::AppendModifier(ui::KeyEvent* event) { | |
487 #if defined(USE_X11) | |
488 XEvent* xev = event->native_event(); | |
489 if (xev) { | |
490 XKeyEvent* xkey = &(xev->xkey); | |
491 AppendNativeEventMask(&xkey->state); | |
492 } | |
493 #elif defined(USE_OZONE) | |
494 NOTIMPLEMENTED() << "Modifier key is not handled"; | |
495 #endif | |
496 event->set_flags(event->flags() | modifier_flag_); | |
497 event->set_character(ui::GetCharacterFromKeyCode(event->key_code(), | |
498 event->flags())); | |
499 event->NormalizeFlags(); | |
500 } | |
501 | |
502 void StickyKeysHandler::AppendModifier(ui::MouseEvent* event) { | |
503 #if defined(USE_X11) | |
504 // The native mouse event can either be a classic X button event or an | |
505 // XInput2 button event. | |
506 XEvent* xev = event->native_event(); | |
507 if (xev) { | |
508 switch (xev->type) { | |
509 case ButtonPress: | |
510 case ButtonRelease: { | |
511 XButtonEvent* xkey = &(xev->xbutton); | |
512 AppendNativeEventMask(&xkey->state); | |
513 break; | |
514 } | |
515 case GenericEvent: { | |
516 XIDeviceEvent* xievent = | |
517 static_cast<XIDeviceEvent*>(xev->xcookie.data); | |
518 CHECK(xievent->evtype == XI_ButtonPress || | |
519 xievent->evtype == XI_ButtonRelease); | |
520 AppendNativeEventMask( | |
521 reinterpret_cast<unsigned int*>(&xievent->mods.effective)); | |
522 break; | |
523 } | |
524 default: | |
525 NOTREACHED(); | |
526 } | |
527 } | |
528 #elif defined(USE_OZONE) | |
529 NOTIMPLEMENTED() << "Modifier key is not handled"; | |
530 #endif | |
531 event->set_flags(event->flags() | modifier_flag_); | |
532 } | |
533 | |
534 void StickyKeysHandler::AppendModifier(ui::ScrollEvent* event) { | |
535 #if defined(USE_X11) | |
536 XEvent* xev = event->native_event(); | |
537 if (xev) { | |
538 XIDeviceEvent* xievent = | |
539 static_cast<XIDeviceEvent*>(xev->xcookie.data); | |
540 if (xievent) { | |
541 AppendNativeEventMask(reinterpret_cast<unsigned int*>( | |
542 &xievent->mods.effective)); | |
543 } | |
544 } | |
545 #elif defined(USE_OZONE) | |
546 NOTIMPLEMENTED() << "Modifier key is not handled"; | |
547 #endif | |
548 event->set_flags(event->flags() | modifier_flag_); | |
549 } | |
550 | |
551 } // namespace ash | 420 } // namespace ash |
OLD | NEW |