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

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

Issue 255033003: Convert sticky keys to a chromeos::EventRewriter phase. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@x354034-er
Patch Set: Convert sticky keys to a chromeos::EventRewriter phase. 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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698