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

Side by Side Diff: trunk/src/ash/sticky_keys/sticky_keys_controller.cc

Issue 341923006: Revert 278342 "Convert sticky keys to a chromeos::EventRewriter ..." (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 6 years, 6 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 | Annotate | Revision Log
OLDNEW
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
7 #include "ash/sticky_keys/sticky_keys_overlay.h" 13 #include "ash/sticky_keys/sticky_keys_overlay.h"
8 #include "base/basictypes.h" 14 #include "base/basictypes.h"
9 #include "base/debug/stack_trace.h" 15 #include "base/debug/stack_trace.h"
10 #include "ui/aura/window.h" 16 #include "ui/aura/window.h"
11 #include "ui/aura/window_tracker.h" 17 #include "ui/aura/window_tracker.h"
12 #include "ui/aura/window_tree_host.h" 18 #include "ui/aura/window_tree_host.h"
13 #include "ui/events/event.h" 19 #include "ui/events/event.h"
14 #include "ui/events/event_processor.h" 20 #include "ui/events/event_processor.h"
15 #include "ui/events/keycodes/keyboard_code_conversion.h" 21 #include "ui/events/keycodes/keyboard_code_conversion.h"
16 22
17 namespace ash { 23 namespace ash {
18 24
19 namespace { 25 namespace {
20 26
21 // Returns true if the type of mouse event should be modified by sticky keys. 27 // Returns true if the type of mouse event should be modified by sticky keys.
22 bool ShouldModifyMouseEvent(const ui::MouseEvent& event) { 28 bool ShouldModifyMouseEvent(ui::MouseEvent* event) {
23 ui::EventType type = event.type(); 29 ui::EventType type = event->type();
24 return type == ui::ET_MOUSE_PRESSED || type == ui::ET_MOUSE_RELEASED || 30 return type == ui::ET_MOUSE_PRESSED || type == ui::ET_MOUSE_RELEASED ||
25 type == ui::ET_MOUSEWHEEL; 31 type == ui::ET_MOUSEWHEEL;
26 } 32 }
27 33
28 // Handle the common tail of event rewriting. 34 // An implementation of StickyKeysHandler::StickyKeysHandlerDelegate.
29 ui::EventRewriteStatus RewriteUpdate(bool consumed, 35 class StickyKeysHandlerDelegateImpl :
30 bool released, 36 public StickyKeysHandler::StickyKeysHandlerDelegate {
31 int mod_down_flags, 37 public:
32 int* flags) { 38 StickyKeysHandlerDelegateImpl();
33 int changed_down_flags = mod_down_flags & ~*flags; 39 virtual ~StickyKeysHandlerDelegateImpl();
34 *flags |= mod_down_flags; 40
35 if (consumed) 41 // StickyKeysHandlerDelegate overrides.
36 return ui::EVENT_REWRITE_DISCARD; 42 virtual void DispatchKeyEvent(ui::KeyEvent* event,
37 if (released) 43 aura::Window* target) OVERRIDE;
38 return ui::EVENT_REWRITE_DISPATCH_ANOTHER; 44
39 if (changed_down_flags) 45 virtual void DispatchMouseEvent(ui::MouseEvent* event,
40 return ui::EVENT_REWRITE_REWRITTEN; 46 aura::Window* target) OVERRIDE;
41 return ui::EVENT_REWRITE_CONTINUE; 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;
42 } 101 }
43 102
44 } // namespace 103 } // namespace
45 104
46 /////////////////////////////////////////////////////////////////////////////// 105 ///////////////////////////////////////////////////////////////////////////////
47 // StickyKeys 106 // StickyKeys
48 StickyKeysController::StickyKeysController() 107 StickyKeysController::StickyKeysController()
49 : enabled_(false), 108 : enabled_(false),
50 mod3_enabled_(false), 109 mod3_enabled_(false),
51 altgr_enabled_(false) { 110 altgr_enabled_(false) {
52 } 111 }
53 112
54 StickyKeysController::~StickyKeysController() { 113 StickyKeysController::~StickyKeysController() {
55 } 114 }
56 115
57 void StickyKeysController::Enable(bool enabled) { 116 void StickyKeysController::Enable(bool enabled) {
58 if (enabled_ != enabled) { 117 if (enabled_ != enabled) {
59 enabled_ = enabled; 118 enabled_ = enabled;
60 119
61 // Reset key handlers when activating sticky keys to ensure all 120 // Reset key handlers when activating sticky keys to ensure all
62 // the handlers' states are reset. 121 // the handlers' states are reset.
63 if (enabled_) { 122 if (enabled_) {
64 shift_sticky_key_.reset(new StickyKeysHandler(ui::EF_SHIFT_DOWN)); 123 shift_sticky_key_.reset(
65 alt_sticky_key_.reset(new StickyKeysHandler(ui::EF_ALT_DOWN)); 124 new StickyKeysHandler(ui::EF_SHIFT_DOWN,
66 altgr_sticky_key_.reset(new StickyKeysHandler(ui::EF_ALTGR_DOWN)); 125 new StickyKeysHandlerDelegateImpl()));
67 ctrl_sticky_key_.reset(new StickyKeysHandler(ui::EF_CONTROL_DOWN)); 126 alt_sticky_key_.reset(
68 mod3_sticky_key_.reset(new StickyKeysHandler(ui::EF_MOD3_DOWN)); 127 new StickyKeysHandler(ui::EF_ALT_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()));
69 138
70 overlay_.reset(new StickyKeysOverlay()); 139 overlay_.reset(new StickyKeysOverlay());
71 overlay_->SetModifierVisible(ui::EF_ALTGR_DOWN, altgr_enabled_); 140 overlay_->SetModifierVisible(ui::EF_ALTGR_DOWN, altgr_enabled_);
72 overlay_->SetModifierVisible(ui::EF_MOD3_DOWN, mod3_enabled_); 141 overlay_->SetModifierVisible(ui::EF_MOD3_DOWN, mod3_enabled_);
73 } else if (overlay_) { 142 } else if (overlay_) {
74 overlay_->Show(false); 143 overlay_->Show(false);
75 } 144 }
76 } 145 }
77 } 146 }
78 147
79 void StickyKeysController::SetModifiersEnabled(bool mod3_enabled, 148 void StickyKeysController::SetModifiersEnabled(bool mod3_enabled,
80 bool altgr_enabled) { 149 bool altgr_enabled) {
81 mod3_enabled_ = mod3_enabled; 150 mod3_enabled_ = mod3_enabled;
82 altgr_enabled_ = altgr_enabled; 151 altgr_enabled_ = altgr_enabled;
83 if (overlay_) { 152 if (overlay_) {
84 overlay_->SetModifierVisible(ui::EF_ALTGR_DOWN, altgr_enabled_); 153 overlay_->SetModifierVisible(ui::EF_ALTGR_DOWN, altgr_enabled_);
85 overlay_->SetModifierVisible(ui::EF_MOD3_DOWN, mod3_enabled_); 154 overlay_->SetModifierVisible(ui::EF_MOD3_DOWN, mod3_enabled_);
86 } 155 }
87 } 156 }
88 157
89 bool StickyKeysController::HandleKeyEvent(const ui::KeyEvent& event, 158 bool StickyKeysController::HandleKeyEvent(ui::KeyEvent* event) {
90 ui::KeyboardCode key_code, 159 return shift_sticky_key_->HandleKeyEvent(event) ||
91 int* mod_down_flags, 160 alt_sticky_key_->HandleKeyEvent(event) ||
92 bool* released) { 161 altgr_sticky_key_->HandleKeyEvent(event) ||
93 return shift_sticky_key_->HandleKeyEvent( 162 ctrl_sticky_key_->HandleKeyEvent(event) ||
94 event, key_code, mod_down_flags, released) || 163 mod3_sticky_key_->HandleKeyEvent(event);
95 alt_sticky_key_->HandleKeyEvent(
96 event, key_code, mod_down_flags, released) ||
97 altgr_sticky_key_->HandleKeyEvent(
98 event, key_code, mod_down_flags, released) ||
99 ctrl_sticky_key_->HandleKeyEvent(
100 event, key_code, mod_down_flags, released) ||
101 mod3_sticky_key_->HandleKeyEvent(
102 event, key_code, mod_down_flags, released);
103 } 164 }
104 165
105 bool StickyKeysController::HandleMouseEvent(const ui::MouseEvent& event, 166 bool StickyKeysController::HandleMouseEvent(ui::MouseEvent* event) {
106 int* mod_down_flags, 167 return shift_sticky_key_->HandleMouseEvent(event) ||
107 bool* released) { 168 alt_sticky_key_->HandleMouseEvent(event) ||
108 return shift_sticky_key_->HandleMouseEvent( 169 altgr_sticky_key_->HandleMouseEvent(event) ||
109 event, mod_down_flags, released) || 170 ctrl_sticky_key_->HandleMouseEvent(event) ||
110 alt_sticky_key_->HandleMouseEvent( 171 mod3_sticky_key_->HandleMouseEvent(event);
111 event, mod_down_flags, released) ||
112 altgr_sticky_key_->HandleMouseEvent(
113 event, mod_down_flags, released) ||
114 ctrl_sticky_key_->HandleMouseEvent(
115 event, mod_down_flags, released) ||
116 mod3_sticky_key_->HandleMouseEvent(
117 event, mod_down_flags, released);
118 } 172 }
119 173
120 bool StickyKeysController::HandleScrollEvent(const ui::ScrollEvent& event, 174 bool StickyKeysController::HandleScrollEvent(ui::ScrollEvent* event) {
121 int* mod_down_flags, 175 return shift_sticky_key_->HandleScrollEvent(event) ||
122 bool* released) { 176 alt_sticky_key_->HandleScrollEvent(event) ||
123 return shift_sticky_key_->HandleScrollEvent( 177 altgr_sticky_key_->HandleScrollEvent(event) ||
124 event, mod_down_flags, released) || 178 ctrl_sticky_key_->HandleScrollEvent(event) ||
125 alt_sticky_key_->HandleScrollEvent( 179 mod3_sticky_key_->HandleScrollEvent(event);
126 event, mod_down_flags, released) ||
127 altgr_sticky_key_->HandleScrollEvent(
128 event, mod_down_flags, released) ||
129 ctrl_sticky_key_->HandleScrollEvent(
130 event, mod_down_flags, released) ||
131 mod3_sticky_key_->HandleScrollEvent(
132 event, mod_down_flags, released);
133 } 180 }
134 181
135 ui::EventRewriteStatus StickyKeysController::RewriteKeyEvent( 182 void StickyKeysController::OnKeyEvent(ui::KeyEvent* event) {
136 const ui::KeyEvent& event, 183 // Do not consume a translated key event which is generated by an IME.
137 ui::KeyboardCode key_code, 184 if (event->IsTranslated())
138 int* flags) { 185 return;
139 if (!enabled_) 186
140 return ui::EVENT_REWRITE_CONTINUE; 187 if (enabled_) {
141 int mod_down_flags = 0; 188 if (HandleKeyEvent(event))
142 bool released = false; 189 event->StopPropagation();
143 bool consumed = HandleKeyEvent(event, key_code, &mod_down_flags, &released); 190 UpdateOverlay();
144 UpdateOverlay(); 191 }
145 return RewriteUpdate(consumed, released, mod_down_flags, flags);
146 } 192 }
147 193
148 ui::EventRewriteStatus StickyKeysController::RewriteMouseEvent( 194 void StickyKeysController::OnMouseEvent(ui::MouseEvent* event) {
149 const ui::MouseEvent& event, 195 if (enabled_) {
150 int* flags) { 196 if (HandleMouseEvent(event))
151 if (!enabled_) 197 event->StopPropagation();
152 return ui::EVENT_REWRITE_CONTINUE; 198 UpdateOverlay();
153 int mod_down_flags = 0; 199 }
154 bool released = false;
155 bool consumed = HandleMouseEvent(event, &mod_down_flags, &released);
156 UpdateOverlay();
157 return RewriteUpdate(consumed, released, mod_down_flags, flags);
158 } 200 }
159 201
160 ui::EventRewriteStatus StickyKeysController::RewriteScrollEvent( 202 void StickyKeysController::OnScrollEvent(ui::ScrollEvent* event) {
161 const ui::ScrollEvent& event, 203 if (enabled_) {
162 int* flags) { 204 if (HandleScrollEvent(event))
163 if (!enabled_) 205 event->StopPropagation();
164 return ui::EVENT_REWRITE_CONTINUE; 206 UpdateOverlay();
165 int mod_down_flags = 0; 207 }
166 bool released = false;
167 bool consumed = HandleScrollEvent(event, &mod_down_flags, &released);
168 UpdateOverlay();
169 return RewriteUpdate(consumed, released, mod_down_flags, flags);
170 }
171
172 ui::EventRewriteStatus StickyKeysController::NextDispatchEvent(
173 scoped_ptr<ui::Event>* new_event) {
174 DCHECK(new_event);
175 new_event->reset();
176 int remaining = shift_sticky_key_->GetModifierUpEvent(new_event) +
177 alt_sticky_key_->GetModifierUpEvent(new_event) +
178 altgr_sticky_key_->GetModifierUpEvent(new_event) +
179 ctrl_sticky_key_->GetModifierUpEvent(new_event) +
180 mod3_sticky_key_->GetModifierUpEvent(new_event);
181 if (!new_event)
182 return ui::EVENT_REWRITE_CONTINUE;
183 if (remaining)
184 return ui::EVENT_REWRITE_DISPATCH_ANOTHER;
185 return ui::EVENT_REWRITE_REWRITTEN;
186 } 208 }
187 209
188 void StickyKeysController::UpdateOverlay() { 210 void StickyKeysController::UpdateOverlay() {
189 overlay_->SetModifierKeyState( 211 overlay_->SetModifierKeyState(
190 ui::EF_SHIFT_DOWN, shift_sticky_key_->current_state()); 212 ui::EF_SHIFT_DOWN, shift_sticky_key_->current_state());
191 overlay_->SetModifierKeyState( 213 overlay_->SetModifierKeyState(
192 ui::EF_CONTROL_DOWN, ctrl_sticky_key_->current_state()); 214 ui::EF_CONTROL_DOWN, ctrl_sticky_key_->current_state());
193 overlay_->SetModifierKeyState( 215 overlay_->SetModifierKeyState(
194 ui::EF_ALT_DOWN, alt_sticky_key_->current_state()); 216 ui::EF_ALT_DOWN, alt_sticky_key_->current_state());
195 overlay_->SetModifierKeyState( 217 overlay_->SetModifierKeyState(
(...skipping 10 matching lines...) Expand all
206 228
207 overlay_->Show(enabled_ && key_in_use); 229 overlay_->Show(enabled_ && key_in_use);
208 } 230 }
209 231
210 StickyKeysOverlay* StickyKeysController::GetOverlayForTest() { 232 StickyKeysOverlay* StickyKeysController::GetOverlayForTest() {
211 return overlay_.get(); 233 return overlay_.get();
212 } 234 }
213 235
214 /////////////////////////////////////////////////////////////////////////////// 236 ///////////////////////////////////////////////////////////////////////////////
215 // StickyKeysHandler 237 // StickyKeysHandler
216 StickyKeysHandler::StickyKeysHandler(ui::EventFlags modifier_flag) 238 StickyKeysHandler::StickyKeysHandler(ui::EventFlags modifier_flag,
239 StickyKeysHandlerDelegate* delegate)
217 : modifier_flag_(modifier_flag), 240 : modifier_flag_(modifier_flag),
218 current_state_(STICKY_KEY_STATE_DISABLED), 241 current_state_(STICKY_KEY_STATE_DISABLED),
242 event_from_myself_(false),
219 preparing_to_enable_(false), 243 preparing_to_enable_(false),
220 scroll_delta_(0) { 244 scroll_delta_(0),
245 delegate_(delegate) {
221 } 246 }
222 247
223 StickyKeysHandler::~StickyKeysHandler() { 248 StickyKeysHandler::~StickyKeysHandler() {
224 } 249 }
225 250
226 bool StickyKeysHandler::HandleKeyEvent(const ui::KeyEvent& event, 251 StickyKeysHandler::StickyKeysHandlerDelegate::StickyKeysHandlerDelegate() {
227 ui::KeyboardCode key_code, 252 }
228 int* mod_down_flags, 253
229 bool* released) { 254 StickyKeysHandler::StickyKeysHandlerDelegate::~StickyKeysHandlerDelegate() {
255 }
256
257 bool StickyKeysHandler::HandleKeyEvent(ui::KeyEvent* event) {
258 if (event_from_myself_)
259 return false; // Do not handle self-generated key event.
230 switch (current_state_) { 260 switch (current_state_) {
231 case STICKY_KEY_STATE_DISABLED: 261 case STICKY_KEY_STATE_DISABLED:
232 return HandleDisabledState(event, key_code); 262 return HandleDisabledState(event);
233 case STICKY_KEY_STATE_ENABLED: 263 case STICKY_KEY_STATE_ENABLED:
234 return HandleEnabledState(event, key_code, mod_down_flags, released); 264 return HandleEnabledState(event);
235 case STICKY_KEY_STATE_LOCKED: 265 case STICKY_KEY_STATE_LOCKED:
236 return HandleLockedState(event, key_code, mod_down_flags, released); 266 return HandleLockedState(event);
237 } 267 }
238 NOTREACHED(); 268 NOTREACHED();
239 return false; 269 return false;
240 } 270 }
241 271
242 bool StickyKeysHandler::HandleMouseEvent( 272 bool StickyKeysHandler::HandleMouseEvent(ui::MouseEvent* event) {
243 const ui::MouseEvent& event,
244 int* mod_down_flags,
245 bool* released) {
246 if (ShouldModifyMouseEvent(event)) 273 if (ShouldModifyMouseEvent(event))
247 preparing_to_enable_ = false; 274 preparing_to_enable_ = false;
248 275
249 if (current_state_ == STICKY_KEY_STATE_DISABLED || 276 if (event_from_myself_ || current_state_ == STICKY_KEY_STATE_DISABLED
250 !ShouldModifyMouseEvent(event)) { 277 || !ShouldModifyMouseEvent(event)) {
251 return false; 278 return false;
252 } 279 }
253 DCHECK(current_state_ == STICKY_KEY_STATE_ENABLED || 280 DCHECK(current_state_ == STICKY_KEY_STATE_ENABLED ||
254 current_state_ == STICKY_KEY_STATE_LOCKED); 281 current_state_ == STICKY_KEY_STATE_LOCKED);
255 282
256 *mod_down_flags |= modifier_flag_; 283 AppendModifier(event);
257 // Only disable on the mouse released event in normal, non-locked mode. 284 // Only disable on the mouse released event in normal, non-locked mode.
258 if (current_state_ == STICKY_KEY_STATE_ENABLED && 285 if (current_state_ == STICKY_KEY_STATE_ENABLED &&
259 event.type() != ui::ET_MOUSE_PRESSED) { 286 event->type() != ui::ET_MOUSE_PRESSED) {
260 current_state_ = STICKY_KEY_STATE_DISABLED; 287 current_state_ = STICKY_KEY_STATE_DISABLED;
261 *released = true; 288 DispatchEventAndReleaseModifier(event);
262 return false; 289 return true;
263 } 290 }
264 291
265 return false; 292 return false;
266 } 293 }
267 294
268 bool StickyKeysHandler::HandleScrollEvent( 295 bool StickyKeysHandler::HandleScrollEvent(ui::ScrollEvent* event) {
269 const ui::ScrollEvent& event,
270 int* mod_down_flags,
271 bool* released) {
272 preparing_to_enable_ = false; 296 preparing_to_enable_ = false;
273 if (current_state_ == STICKY_KEY_STATE_DISABLED) 297 if (event_from_myself_ || current_state_ == STICKY_KEY_STATE_DISABLED)
274 return false; 298 return false;
275 DCHECK(current_state_ == STICKY_KEY_STATE_ENABLED || 299 DCHECK(current_state_ == STICKY_KEY_STATE_ENABLED ||
276 current_state_ == STICKY_KEY_STATE_LOCKED); 300 current_state_ == STICKY_KEY_STATE_LOCKED);
277 301
278 // We detect a direction change if the current |scroll_delta_| is assigned 302 // We detect a direction change if the current |scroll_delta_| is assigned
279 // and the offset of the current scroll event has the opposing sign. 303 // and the offset of the current scroll event has the opposing sign.
280 bool direction_changed = false; 304 bool direction_changed = false;
281 if (current_state_ == STICKY_KEY_STATE_ENABLED && 305 if (current_state_ == STICKY_KEY_STATE_ENABLED &&
282 event.type() == ui::ET_SCROLL) { 306 event->type() == ui::ET_SCROLL) {
283 int offset = event.y_offset(); 307 int offset = event->y_offset();
284 if (scroll_delta_) 308 if (scroll_delta_)
285 direction_changed = offset * scroll_delta_ <= 0; 309 direction_changed = offset * scroll_delta_ <= 0;
286 scroll_delta_ = offset; 310 scroll_delta_ = offset;
287 } 311 }
288 312
289 if (!direction_changed) 313 if (!direction_changed)
290 *mod_down_flags |= modifier_flag_; 314 AppendModifier(event);
291 315
292 // We want to modify all the scroll events in the scroll sequence, which ends 316 // We want to modify all the scroll events in the scroll sequence, which ends
293 // with a fling start event. We also stop when the scroll sequence changes 317 // with a fling start event. We also stop when the scroll sequence changes
294 // direction. 318 // direction.
295 if (current_state_ == STICKY_KEY_STATE_ENABLED && 319 if (current_state_ == STICKY_KEY_STATE_ENABLED &&
296 (event.type() == ui::ET_SCROLL_FLING_START || direction_changed)) { 320 (event->type() == ui::ET_SCROLL_FLING_START || direction_changed)) {
297 current_state_ = STICKY_KEY_STATE_DISABLED; 321 current_state_ = STICKY_KEY_STATE_DISABLED;
298 scroll_delta_ = 0; 322 scroll_delta_ = 0;
299 *released = true; 323 DispatchEventAndReleaseModifier(event);
300 return false; 324 return true;
301 } 325 }
302 326
303 return false; 327 return false;
304 } 328 }
305 329
306 int StickyKeysHandler::GetModifierUpEvent(scoped_ptr<ui::Event>* new_event) { 330 StickyKeysHandler::KeyEventType
307 if (current_state_ != STICKY_KEY_STATE_DISABLED || !modifier_up_event_) 331 StickyKeysHandler::TranslateKeyEvent(ui::KeyEvent* event) {
308 return 0;
309 DCHECK(new_event);
310 if (*new_event)
311 return 1;
312 new_event->reset(modifier_up_event_.release());
313 return 0;
314 }
315
316 StickyKeysHandler::KeyEventType StickyKeysHandler::TranslateKeyEvent(
317 ui::EventType type,
318 ui::KeyboardCode key_code) {
319 bool is_target_key = false; 332 bool is_target_key = false;
320 if (key_code == ui::VKEY_SHIFT || 333 if (event->key_code() == ui::VKEY_SHIFT ||
321 key_code == ui::VKEY_LSHIFT || 334 event->key_code() == ui::VKEY_LSHIFT ||
322 key_code == ui::VKEY_RSHIFT) { 335 event->key_code() == ui::VKEY_RSHIFT) {
323 is_target_key = (modifier_flag_ == ui::EF_SHIFT_DOWN); 336 is_target_key = (modifier_flag_ == ui::EF_SHIFT_DOWN);
324 } else if (key_code == ui::VKEY_CONTROL || 337 } else if (event->key_code() == ui::VKEY_CONTROL ||
325 key_code == ui::VKEY_LCONTROL || 338 event->key_code() == ui::VKEY_LCONTROL ||
326 key_code == ui::VKEY_RCONTROL) { 339 event->key_code() == ui::VKEY_RCONTROL) {
327 is_target_key = (modifier_flag_ == ui::EF_CONTROL_DOWN); 340 is_target_key = (modifier_flag_ == ui::EF_CONTROL_DOWN);
328 } else if (key_code == ui::VKEY_MENU || 341 } else if (event->key_code() == ui::VKEY_MENU ||
329 key_code == ui::VKEY_LMENU || 342 event->key_code() == ui::VKEY_LMENU ||
330 key_code == ui::VKEY_RMENU) { 343 event->key_code() == ui::VKEY_RMENU) {
331 is_target_key = (modifier_flag_ == ui::EF_ALT_DOWN); 344 is_target_key = (modifier_flag_ == ui::EF_ALT_DOWN);
332 } else if (key_code == ui::VKEY_ALTGR) { 345 } else if (event->key_code() == ui::VKEY_ALTGR) {
333 is_target_key = (modifier_flag_ == ui::EF_ALTGR_DOWN); 346 is_target_key = (modifier_flag_ == ui::EF_ALTGR_DOWN);
334 } else if (key_code == ui::VKEY_OEM_8) { 347 } else if (event->key_code() == ui::VKEY_OEM_8) {
335 is_target_key = (modifier_flag_ == ui::EF_MOD3_DOWN); 348 is_target_key = (modifier_flag_ == ui::EF_MOD3_DOWN);
336 } else { 349 } else {
337 return type == ui::ET_KEY_PRESSED ? 350 return event->type() == ui::ET_KEY_PRESSED ?
338 NORMAL_KEY_DOWN : NORMAL_KEY_UP; 351 NORMAL_KEY_DOWN : NORMAL_KEY_UP;
339 } 352 }
340 353
341 if (is_target_key) { 354 if (is_target_key) {
342 return type == ui::ET_KEY_PRESSED ? 355 return event->type() == ui::ET_KEY_PRESSED ?
343 TARGET_MODIFIER_DOWN : TARGET_MODIFIER_UP; 356 TARGET_MODIFIER_DOWN : TARGET_MODIFIER_UP;
344 } 357 }
345 return type == ui::ET_KEY_PRESSED ? 358 return event->type() == ui::ET_KEY_PRESSED ?
346 OTHER_MODIFIER_DOWN : OTHER_MODIFIER_UP; 359 OTHER_MODIFIER_DOWN : OTHER_MODIFIER_UP;
347 } 360 }
348 361
349 bool StickyKeysHandler::HandleDisabledState(const ui::KeyEvent& event, 362 bool StickyKeysHandler::HandleDisabledState(ui::KeyEvent* event) {
350 ui::KeyboardCode key_code) { 363 switch (TranslateKeyEvent(event)) {
351 switch (TranslateKeyEvent(event.type(), key_code)) {
352 case TARGET_MODIFIER_UP: 364 case TARGET_MODIFIER_UP:
353 if (preparing_to_enable_) { 365 if (preparing_to_enable_) {
354 preparing_to_enable_ = false; 366 preparing_to_enable_ = false;
355 scroll_delta_ = 0; 367 scroll_delta_ = 0;
356 current_state_ = STICKY_KEY_STATE_ENABLED; 368 current_state_ = STICKY_KEY_STATE_ENABLED;
357 modifier_up_event_.reset(new ui::KeyEvent(event)); 369 modifier_up_event_.reset(new ui::KeyEvent(*event));
358 return true; 370 return true;
359 } 371 }
360 return false; 372 return false;
361 case TARGET_MODIFIER_DOWN: 373 case TARGET_MODIFIER_DOWN:
362 preparing_to_enable_ = true; 374 preparing_to_enable_ = true;
363 return false; 375 return false;
364 case NORMAL_KEY_DOWN: 376 case NORMAL_KEY_DOWN:
365 preparing_to_enable_ = false; 377 preparing_to_enable_ = false;
366 return false; 378 return false;
367 case NORMAL_KEY_UP: 379 case NORMAL_KEY_UP:
368 case OTHER_MODIFIER_DOWN: 380 case OTHER_MODIFIER_DOWN:
369 case OTHER_MODIFIER_UP: 381 case OTHER_MODIFIER_UP:
370 return false; 382 return false;
371 } 383 }
372 NOTREACHED(); 384 NOTREACHED();
373 return false; 385 return false;
374 } 386 }
375 387
376 bool StickyKeysHandler::HandleEnabledState(const ui::KeyEvent& event, 388 bool StickyKeysHandler::HandleEnabledState(ui::KeyEvent* event) {
377 ui::KeyboardCode key_code, 389 switch (TranslateKeyEvent(event)) {
378 int* mod_down_flags,
379 bool* released) {
380 switch (TranslateKeyEvent(event.type(), key_code)) {
381 case NORMAL_KEY_UP: 390 case NORMAL_KEY_UP:
382 case TARGET_MODIFIER_DOWN: 391 case TARGET_MODIFIER_DOWN:
383 return false; 392 return true;
384 case TARGET_MODIFIER_UP: 393 case TARGET_MODIFIER_UP:
385 current_state_ = STICKY_KEY_STATE_LOCKED; 394 current_state_ = STICKY_KEY_STATE_LOCKED;
386 modifier_up_event_.reset(); 395 modifier_up_event_.reset();
387 return true; 396 return true;
388 case NORMAL_KEY_DOWN: { 397 case NORMAL_KEY_DOWN: {
389 current_state_ = STICKY_KEY_STATE_DISABLED; 398 current_state_ = STICKY_KEY_STATE_DISABLED;
390 *mod_down_flags |= modifier_flag_; 399 AppendModifier(event);
391 *released = true; 400 DispatchEventAndReleaseModifier(event);
392 return false; 401 return true;
393 } 402 }
394 case OTHER_MODIFIER_DOWN: 403 case OTHER_MODIFIER_DOWN:
395 case OTHER_MODIFIER_UP: 404 case OTHER_MODIFIER_UP:
396 return false; 405 return false;
397 } 406 }
398 NOTREACHED(); 407 NOTREACHED();
399 return false; 408 return false;
400 } 409 }
401 410
402 bool StickyKeysHandler::HandleLockedState(const ui::KeyEvent& event, 411 bool StickyKeysHandler::HandleLockedState(ui::KeyEvent* event) {
403 ui::KeyboardCode key_code, 412 switch (TranslateKeyEvent(event)) {
404 int* mod_down_flags,
405 bool* released) {
406 switch (TranslateKeyEvent(event.type(), key_code)) {
407 case TARGET_MODIFIER_DOWN: 413 case TARGET_MODIFIER_DOWN:
408 return true; 414 return true;
409 case TARGET_MODIFIER_UP: 415 case TARGET_MODIFIER_UP:
410 current_state_ = STICKY_KEY_STATE_DISABLED; 416 current_state_ = STICKY_KEY_STATE_DISABLED;
411 return false; 417 return false;
412 case NORMAL_KEY_DOWN: 418 case NORMAL_KEY_DOWN:
413 case NORMAL_KEY_UP: 419 case NORMAL_KEY_UP:
414 *mod_down_flags |= modifier_flag_; 420 AppendModifier(event);
415 return false; 421 return false;
416 case OTHER_MODIFIER_DOWN: 422 case OTHER_MODIFIER_DOWN:
417 case OTHER_MODIFIER_UP: 423 case OTHER_MODIFIER_UP:
418 return false; 424 return false;
419 } 425 }
420 NOTREACHED(); 426 NOTREACHED();
421 return false; 427 return false;
422 } 428 }
423 429
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
424 } // namespace ash 551 } // namespace ash
OLDNEW
« no previous file with comments | « trunk/src/ash/sticky_keys/sticky_keys_controller.h ('k') | trunk/src/ash/sticky_keys/sticky_keys_overlay_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698