1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ash/accelerators/accelerator_controller.h"
6 #include "ash/accelerators/accelerator_table.h"
7 #include "ash/accessibility_delegate.h"
8 #include "ash/caps_lock_delegate.h"
9 #include "ash/display/display_manager.h"
10 #include "ash/ime_control_delegate.h"
11 #include "ash/shell.h"
12 #include "ash/shell_window_ids.h"
13 #include "ash/system/brightness_control_delegate.h"
14 #include "ash/system/keyboard_brightness/keyboard_brightness_control_delegate.h"
15 #include "ash/system/tray/system_tray_delegate.h"
16 #include "ash/test/ash_test_base.h"
17 #include "ash/test/display_manager_test_api.h"
18 #include "ash/test/test_screenshot_delegate.h"
19 #include "ash/test/test_shell_delegate.h"
20 #include "ash/volume_control_delegate.h"
21 #include "ash/wm/window_state.h"
22 #include "ash/wm/window_util.h"
23 #include "ui/aura/root_window.h"
24 #include "ui/aura/test/test_window_delegate.h"
25 #include "ui/aura/test/test_windows.h"
26 #include "ui/aura/window.h"
27 #include "ui/events/event.h"
31 #include "ui/events/x/events_x_utils.h"
38 class TestTarget : public ui::AcceleratorTarget {
40 TestTarget() : accelerator_pressed_count_(0) {}
41 virtual ~TestTarget() {}
43 int accelerator_pressed_count() const {
44 return accelerator_pressed_count_;
47 void set_accelerator_pressed_count(int accelerator_pressed_count) {
48 accelerator_pressed_count_ = accelerator_pressed_count;
51 // Overridden from ui::AcceleratorTarget:
52 virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
53 virtual bool CanHandleAccelerators() const OVERRIDE;
56 int accelerator_pressed_count_;
58 DISALLOW_COPY_AND_ASSIGN(TestTarget);
61 class ReleaseAccelerator : public ui::Accelerator {
63 ReleaseAccelerator(ui::KeyboardCode keycode, int modifiers)
64 : ui::Accelerator(keycode, modifiers) {
65 set_type(ui::ET_KEY_RELEASED);
69 class DummyVolumeControlDelegate : public VolumeControlDelegate {
71 explicit DummyVolumeControlDelegate(bool consume)
73 handle_volume_mute_count_(0),
74 handle_volume_down_count_(0),
75 handle_volume_up_count_(0) {
77 virtual ~DummyVolumeControlDelegate() {}
79 virtual bool HandleVolumeMute(const ui::Accelerator& accelerator) OVERRIDE {
80 ++handle_volume_mute_count_;
81 last_accelerator_ = accelerator;
84 virtual bool HandleVolumeDown(const ui::Accelerator& accelerator) OVERRIDE {
85 ++handle_volume_down_count_;
86 last_accelerator_ = accelerator;
89 virtual bool HandleVolumeUp(const ui::Accelerator& accelerator) OVERRIDE {
90 ++handle_volume_up_count_;
91 last_accelerator_ = accelerator;
95 int handle_volume_mute_count() const {
96 return handle_volume_mute_count_;
98 int handle_volume_down_count() const {
99 return handle_volume_down_count_;
101 int handle_volume_up_count() const {
102 return handle_volume_up_count_;
104 const ui::Accelerator& last_accelerator() const {
105 return last_accelerator_;
110 int handle_volume_mute_count_;
111 int handle_volume_down_count_;
112 int handle_volume_up_count_;
113 ui::Accelerator last_accelerator_;
115 DISALLOW_COPY_AND_ASSIGN(DummyVolumeControlDelegate);
118 class DummyBrightnessControlDelegate : public BrightnessControlDelegate {
120 explicit DummyBrightnessControlDelegate(bool consume)
122 handle_brightness_down_count_(0),
123 handle_brightness_up_count_(0) {
125 virtual ~DummyBrightnessControlDelegate() {}
127 virtual bool HandleBrightnessDown(
128 const ui::Accelerator& accelerator) OVERRIDE {
129 ++handle_brightness_down_count_;
130 last_accelerator_ = accelerator;
133 virtual bool HandleBrightnessUp(const ui::Accelerator& accelerator) OVERRIDE {
134 ++handle_brightness_up_count_;
135 last_accelerator_ = accelerator;
138 virtual void SetBrightnessPercent(double percent, bool gradual) OVERRIDE {}
139 virtual void GetBrightnessPercent(
140 const base::Callback<void(double)>& callback) OVERRIDE {
144 int handle_brightness_down_count() const {
145 return handle_brightness_down_count_;
147 int handle_brightness_up_count() const {
148 return handle_brightness_up_count_;
150 const ui::Accelerator& last_accelerator() const {
151 return last_accelerator_;
156 int handle_brightness_down_count_;
157 int handle_brightness_up_count_;
158 ui::Accelerator last_accelerator_;
160 DISALLOW_COPY_AND_ASSIGN(DummyBrightnessControlDelegate);
163 class DummyImeControlDelegate : public ImeControlDelegate {
165 explicit DummyImeControlDelegate(bool consume)
167 handle_next_ime_count_(0),
168 handle_previous_ime_count_(0),
169 handle_switch_ime_count_(0) {
171 virtual ~DummyImeControlDelegate() {}
173 virtual bool HandleNextIme() OVERRIDE {
174 ++handle_next_ime_count_;
177 virtual bool HandlePreviousIme(const ui::Accelerator& accelerator) OVERRIDE {
178 ++handle_previous_ime_count_;
179 last_accelerator_ = accelerator;
182 virtual bool HandleSwitchIme(const ui::Accelerator& accelerator) OVERRIDE {
183 ++handle_switch_ime_count_;
184 last_accelerator_ = accelerator;
188 int handle_next_ime_count() const {
189 return handle_next_ime_count_;
191 int handle_previous_ime_count() const {
192 return handle_previous_ime_count_;
194 int handle_switch_ime_count() const {
195 return handle_switch_ime_count_;
197 const ui::Accelerator& last_accelerator() const {
198 return last_accelerator_;
200 virtual ui::Accelerator RemapAccelerator(
201 const ui::Accelerator& accelerator) OVERRIDE {
202 return ui::Accelerator(accelerator);
207 int handle_next_ime_count_;
208 int handle_previous_ime_count_;
209 int handle_switch_ime_count_;
210 ui::Accelerator last_accelerator_;
212 DISALLOW_COPY_AND_ASSIGN(DummyImeControlDelegate);
215 class DummyKeyboardBrightnessControlDelegate
216 : public KeyboardBrightnessControlDelegate {
218 explicit DummyKeyboardBrightnessControlDelegate(bool consume)
220 handle_keyboard_brightness_down_count_(0),
221 handle_keyboard_brightness_up_count_(0) {
223 virtual ~DummyKeyboardBrightnessControlDelegate() {}
225 virtual bool HandleKeyboardBrightnessDown(
226 const ui::Accelerator& accelerator) OVERRIDE {
227 ++handle_keyboard_brightness_down_count_;
228 last_accelerator_ = accelerator;
232 virtual bool HandleKeyboardBrightnessUp(
233 const ui::Accelerator& accelerator) OVERRIDE {
234 ++handle_keyboard_brightness_up_count_;
235 last_accelerator_ = accelerator;
239 int handle_keyboard_brightness_down_count() const {
240 return handle_keyboard_brightness_down_count_;
243 int handle_keyboard_brightness_up_count() const {
244 return handle_keyboard_brightness_up_count_;
247 const ui::Accelerator& last_accelerator() const {
248 return last_accelerator_;
253 int handle_keyboard_brightness_down_count_;
254 int handle_keyboard_brightness_up_count_;
255 ui::Accelerator last_accelerator_;
257 DISALLOW_COPY_AND_ASSIGN(DummyKeyboardBrightnessControlDelegate);
260 bool TestTarget::AcceleratorPressed(const ui::Accelerator& accelerator) {
261 ++accelerator_pressed_count_;
265 bool TestTarget::CanHandleAccelerators() const {
271 class AcceleratorControllerTest : public test::AshTestBase {
273 AcceleratorControllerTest() {}
274 virtual ~AcceleratorControllerTest() {}
277 void EnableInternalDisplay() {
278 test::DisplayManagerTestApi(Shell::GetInstance()->display_manager()).
279 SetFirstDisplayAsInternalDisplay();
282 static AcceleratorController* GetController();
283 static bool ProcessWithContext(const ui::Accelerator& accelerator);
285 // Several functions to access ExitWarningHandler (as friend).
286 static void StubForTest(ExitWarningHandler* ewh) {
287 ewh->stub_timer_for_test_ = true;
289 static void Reset(ExitWarningHandler* ewh) {
290 ewh->state_ = ExitWarningHandler::IDLE;
292 static void SimulateTimerExpired(ExitWarningHandler* ewh) {
295 static bool is_ui_shown(ExitWarningHandler* ewh) {
296 return !!ewh->widget_;
298 static bool is_idle(ExitWarningHandler* ewh) {
299 return ewh->state_ == ExitWarningHandler::IDLE;
301 static bool is_exiting(ExitWarningHandler* ewh) {
302 return ewh->state_ == ExitWarningHandler::EXITING;
306 DISALLOW_COPY_AND_ASSIGN(AcceleratorControllerTest);
309 AcceleratorController* AcceleratorControllerTest::GetController() {
310 return Shell::GetInstance()->accelerator_controller();
313 bool AcceleratorControllerTest::ProcessWithContext(
314 const ui::Accelerator& accelerator) {
315 AcceleratorController* controller = GetController();
316 controller->context()->UpdateContext(accelerator);
317 return controller->Process(accelerator);
321 // Double press of exit shortcut => exiting
322 TEST_F(AcceleratorControllerTest, ExitWarningHandlerTestDoublePress) {
323 ui::Accelerator press(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN);
324 ui::Accelerator release(press);
325 release.set_type(ui::ET_KEY_RELEASED);
326 ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest();
329 EXPECT_TRUE(is_idle(ewh));
330 EXPECT_FALSE(is_ui_shown(ewh));
331 EXPECT_TRUE(ProcessWithContext(press));
332 EXPECT_FALSE(ProcessWithContext(release));
333 EXPECT_FALSE(is_idle(ewh));
334 EXPECT_TRUE(is_ui_shown(ewh));
335 EXPECT_TRUE(ProcessWithContext(press)); // second press before timer.
336 EXPECT_FALSE(ProcessWithContext(release));
337 SimulateTimerExpired(ewh);
338 EXPECT_TRUE(is_exiting(ewh));
339 EXPECT_FALSE(is_ui_shown(ewh));
343 // Single press of exit shortcut before timer => idle
344 TEST_F(AcceleratorControllerTest, ExitWarningHandlerTestSinglePress) {
345 ui::Accelerator press(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN);
346 ui::Accelerator release(press);
347 release.set_type(ui::ET_KEY_RELEASED);
348 ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest();
351 EXPECT_TRUE(is_idle(ewh));
352 EXPECT_FALSE(is_ui_shown(ewh));
353 EXPECT_TRUE(ProcessWithContext(press));
354 EXPECT_FALSE(ProcessWithContext(release));
355 EXPECT_FALSE(is_idle(ewh));
356 EXPECT_TRUE(is_ui_shown(ewh));
357 SimulateTimerExpired(ewh);
358 EXPECT_TRUE(is_idle(ewh));
359 EXPECT_FALSE(is_ui_shown(ewh));
363 // Shutdown ash with exit warning bubble open should not crash.
364 TEST_F(AcceleratorControllerTest, LingeringExitWarningBubble) {
365 ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest();
369 // Trigger once to show the bubble.
370 ewh->HandleAccelerator();
371 EXPECT_FALSE(is_idle(ewh));
372 EXPECT_TRUE(is_ui_shown(ewh));
374 // Exit ash and there should be no crash
376 #endif // !defined(OS_WIN)
378 TEST_F(AcceleratorControllerTest, Register) {
379 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
381 GetController()->Register(accelerator_a, &target);
383 // The registered accelerator is processed.
384 EXPECT_TRUE(ProcessWithContext(accelerator_a));
385 EXPECT_EQ(1, target.accelerator_pressed_count());
388 TEST_F(AcceleratorControllerTest, RegisterMultipleTarget) {
389 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
391 GetController()->Register(accelerator_a, &target1);
393 GetController()->Register(accelerator_a, &target2);
395 // If multiple targets are registered with the same accelerator, the target
396 // registered later processes the accelerator.
397 EXPECT_TRUE(ProcessWithContext(accelerator_a));
398 EXPECT_EQ(0, target1.accelerator_pressed_count());
399 EXPECT_EQ(1, target2.accelerator_pressed_count());
402 TEST_F(AcceleratorControllerTest, Unregister) {
403 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
405 GetController()->Register(accelerator_a, &target);
406 const ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_NONE);
407 GetController()->Register(accelerator_b, &target);
409 // Unregistering a different accelerator does not affect the other
411 GetController()->Unregister(accelerator_b, &target);
412 EXPECT_TRUE(ProcessWithContext(accelerator_a));
413 EXPECT_EQ(1, target.accelerator_pressed_count());
415 // The unregistered accelerator is no longer processed.
416 target.set_accelerator_pressed_count(0);
417 GetController()->Unregister(accelerator_a, &target);
418 EXPECT_FALSE(ProcessWithContext(accelerator_a));
419 EXPECT_EQ(0, target.accelerator_pressed_count());
422 TEST_F(AcceleratorControllerTest, UnregisterAll) {
423 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
425 GetController()->Register(accelerator_a, &target1);
426 const ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_NONE);
427 GetController()->Register(accelerator_b, &target1);
428 const ui::Accelerator accelerator_c(ui::VKEY_C, ui::EF_NONE);
430 GetController()->Register(accelerator_c, &target2);
431 GetController()->UnregisterAll(&target1);
433 // All the accelerators registered for |target1| are no longer processed.
434 EXPECT_FALSE(ProcessWithContext(accelerator_a));
435 EXPECT_FALSE(ProcessWithContext(accelerator_b));
436 EXPECT_EQ(0, target1.accelerator_pressed_count());
438 // UnregisterAll with a different target does not affect the other target.
439 EXPECT_TRUE(ProcessWithContext(accelerator_c));
440 EXPECT_EQ(1, target2.accelerator_pressed_count());
443 TEST_F(AcceleratorControllerTest, Process) {
444 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
446 GetController()->Register(accelerator_a, &target1);
448 // The registered accelerator is processed.
449 EXPECT_TRUE(ProcessWithContext(accelerator_a));
450 EXPECT_EQ(1, target1.accelerator_pressed_count());
452 // The non-registered accelerator is not processed.
453 const ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_NONE);
454 EXPECT_FALSE(ProcessWithContext(accelerator_b));
457 TEST_F(AcceleratorControllerTest, IsRegistered) {
458 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
459 const ui::Accelerator accelerator_shift_a(ui::VKEY_A, ui::EF_SHIFT_DOWN);
461 GetController()->Register(accelerator_a, &target);
462 EXPECT_TRUE(GetController()->IsRegistered(accelerator_a));
463 EXPECT_FALSE(GetController()->IsRegistered(accelerator_shift_a));
464 GetController()->UnregisterAll(&target);
465 EXPECT_FALSE(GetController()->IsRegistered(accelerator_a));
468 TEST_F(AcceleratorControllerTest, WindowSnap) {
469 scoped_ptr<aura::Window> window(
470 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
471 const ui::Accelerator dummy;
473 wm::WindowState* window_state = wm::GetWindowState(window.get());
475 window_state->Activate();
478 GetController()->PerformAction(WINDOW_SNAP_LEFT, dummy);
479 gfx::Rect snap_left = window->bounds();
480 GetController()->PerformAction(WINDOW_SNAP_LEFT, dummy);
481 EXPECT_NE(window->bounds().ToString(), snap_left.ToString());
482 GetController()->PerformAction(WINDOW_SNAP_LEFT, dummy);
483 EXPECT_NE(window->bounds().ToString(), snap_left.ToString());
485 // It should cycle back to the first snapped position.
486 GetController()->PerformAction(WINDOW_SNAP_LEFT, dummy);
487 EXPECT_EQ(window->bounds().ToString(), snap_left.ToString());
490 GetController()->PerformAction(WINDOW_SNAP_RIGHT, dummy);
491 gfx::Rect snap_right = window->bounds();
492 GetController()->PerformAction(WINDOW_SNAP_RIGHT, dummy);
493 EXPECT_NE(window->bounds().ToString(), snap_right.ToString());
494 GetController()->PerformAction(WINDOW_SNAP_RIGHT, dummy);
495 EXPECT_NE(window->bounds().ToString(), snap_right.ToString());
497 // It should cycle back to the first snapped position.
498 GetController()->PerformAction(WINDOW_SNAP_RIGHT, dummy);
499 EXPECT_EQ(window->bounds().ToString(), snap_right.ToString());
502 gfx::Rect normal_bounds = window->bounds();
504 GetController()->PerformAction(TOGGLE_MAXIMIZED, dummy);
505 EXPECT_TRUE(window_state->IsMaximized());
506 EXPECT_NE(normal_bounds.ToString(), window->bounds().ToString());
508 GetController()->PerformAction(TOGGLE_MAXIMIZED, dummy);
509 EXPECT_FALSE(window_state->IsMaximized());
510 EXPECT_EQ(normal_bounds.ToString(), window->bounds().ToString());
512 GetController()->PerformAction(TOGGLE_MAXIMIZED, dummy);
513 GetController()->PerformAction(WINDOW_SNAP_LEFT, dummy);
514 EXPECT_FALSE(window_state->IsMaximized());
516 GetController()->PerformAction(TOGGLE_MAXIMIZED, dummy);
517 GetController()->PerformAction(WINDOW_SNAP_RIGHT, dummy);
518 EXPECT_FALSE(window_state->IsMaximized());
520 GetController()->PerformAction(TOGGLE_MAXIMIZED, dummy);
521 EXPECT_TRUE(window_state->IsMaximized());
522 GetController()->PerformAction(WINDOW_MINIMIZE, dummy);
523 EXPECT_FALSE(window_state->IsMaximized());
524 EXPECT_TRUE(window_state->IsMinimized());
525 window_state->Restore();
526 window_state->Activate();
529 GetController()->PerformAction(WINDOW_MINIMIZE, dummy);
530 EXPECT_TRUE(window_state->IsMinimized());
534 #if defined(OS_WIN) && defined(USE_AURA)
536 #define MAYBE_ControllerContext DISABLED_ControllerContext
538 #define MAYBE_ControllerContext ControllerContext
541 TEST_F(AcceleratorControllerTest, MAYBE_ControllerContext) {
542 ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
543 ui::Accelerator accelerator_a2(ui::VKEY_A, ui::EF_NONE);
544 ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_NONE);
546 accelerator_a.set_type(ui::ET_KEY_PRESSED);
547 accelerator_a2.set_type(ui::ET_KEY_RELEASED);
548 accelerator_b.set_type(ui::ET_KEY_PRESSED);
550 EXPECT_FALSE(GetController()->context()->repeated());
551 EXPECT_EQ(ui::ET_UNKNOWN,
552 GetController()->context()->previous_accelerator().type());
554 GetController()->context()->UpdateContext(accelerator_a);
555 EXPECT_FALSE(GetController()->context()->repeated());
556 EXPECT_EQ(ui::ET_UNKNOWN,
557 GetController()->context()->previous_accelerator().type());
559 GetController()->context()->UpdateContext(accelerator_a2);
560 EXPECT_FALSE(GetController()->context()->repeated());
561 EXPECT_EQ(ui::ET_KEY_PRESSED,
562 GetController()->context()->previous_accelerator().type());
564 GetController()->context()->UpdateContext(accelerator_a2);
565 EXPECT_TRUE(GetController()->context()->repeated());
566 EXPECT_EQ(ui::ET_KEY_RELEASED,
567 GetController()->context()->previous_accelerator().type());
569 GetController()->context()->UpdateContext(accelerator_b);
570 EXPECT_FALSE(GetController()->context()->repeated());
571 EXPECT_EQ(ui::ET_KEY_RELEASED,
572 GetController()->context()->previous_accelerator().type());
575 #if defined(OS_WIN) && defined(USE_AURA)
577 #define MAYBE_SuppressToggleMaximized DISABLED_SuppressToggleMaximized
579 #define MAYBE_SuppressToggleMaximized SuppressToggleMaximized
582 TEST_F(AcceleratorControllerTest, MAYBE_SuppressToggleMaximized) {
583 scoped_ptr<aura::Window> window(
584 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
585 wm::ActivateWindow(window.get());
586 const ui::Accelerator accelerator(ui::VKEY_A, ui::EF_NONE);
587 const ui::Accelerator empty_accelerator;
589 wm::WindowState* window_state = wm::GetWindowState(window.get());
591 // Toggling not suppressed.
592 GetController()->context()->UpdateContext(accelerator);
593 GetController()->PerformAction(TOGGLE_MAXIMIZED, accelerator);
594 EXPECT_TRUE(window_state->IsMaximized());
596 // The same accelerator - toggling suppressed.
597 GetController()->context()->UpdateContext(accelerator);
598 GetController()->PerformAction(TOGGLE_MAXIMIZED, accelerator);
599 EXPECT_TRUE(window_state->IsMaximized());
601 // Suppressed but not for gesture events.
602 GetController()->PerformAction(TOGGLE_MAXIMIZED, empty_accelerator);
603 EXPECT_FALSE(window_state->IsMaximized());
606 #if defined(OS_WIN) || defined(USE_X11)
607 TEST_F(AcceleratorControllerTest, ProcessOnce) {
608 ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
610 GetController()->Register(accelerator_a, &target);
612 // The accelerator is processed only once.
613 aura::WindowEventDispatcher* dispatcher =
614 Shell::GetPrimaryRootWindow()->GetDispatcher();
616 MSG msg1 = { NULL, WM_KEYDOWN, ui::VKEY_A, 0 };
617 ui::TranslatedKeyEvent key_event1(msg1, false);
618 EXPECT_TRUE(dispatcher->AsRootWindowHostDelegate()->OnHostKeyEvent(
621 MSG msg2 = { NULL, WM_CHAR, L'A', 0 };
622 ui::TranslatedKeyEvent key_event2(msg2, true);
623 EXPECT_FALSE(dispatcher->AsRootWindowHostDelegate()->OnHostKeyEvent(
626 MSG msg3 = { NULL, WM_KEYUP, ui::VKEY_A, 0 };
627 ui::TranslatedKeyEvent key_event3(msg3, false);
628 EXPECT_FALSE(dispatcher->AsRootWindowHostDelegate()->OnHostKeyEvent(
630 #elif defined(USE_X11)
632 ui::InitXKeyEventForTesting(ui::ET_KEY_PRESSED,
636 ui::TranslatedKeyEvent key_event1(&key_event, false);
637 EXPECT_TRUE(dispatcher->AsRootWindowHostDelegate()->OnHostKeyEvent(
640 ui::TranslatedKeyEvent key_event2(&key_event, true);
641 EXPECT_FALSE(dispatcher->AsRootWindowHostDelegate()->OnHostKeyEvent(
644 ui::InitXKeyEventForTesting(ui::ET_KEY_RELEASED,
648 ui::TranslatedKeyEvent key_event3(&key_event, false);
649 EXPECT_FALSE(dispatcher->AsRootWindowHostDelegate()->OnHostKeyEvent(
652 EXPECT_EQ(1, target.accelerator_pressed_count());
656 TEST_F(AcceleratorControllerTest, GlobalAccelerators) {
658 EXPECT_TRUE(ProcessWithContext(
659 ui::Accelerator(ui::VKEY_TAB, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN)));
661 EXPECT_TRUE(ProcessWithContext(
662 ui::Accelerator(ui::VKEY_TAB, ui::EF_ALT_DOWN)));
664 EXPECT_TRUE(ProcessWithContext(
665 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_NONE)));
667 #if defined(OS_CHROMEOS)
668 // Take screenshot / partial screenshot
669 // True should always be returned regardless of the existence of the delegate.
671 test::TestScreenshotDelegate* delegate = GetScreenshotDelegate();
672 delegate->set_can_take_screenshot(false);
673 EXPECT_TRUE(ProcessWithContext(
674 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN)));
675 EXPECT_TRUE(ProcessWithContext(
676 ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE)));
677 EXPECT_TRUE(ProcessWithContext(
678 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1,
679 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
681 delegate->set_can_take_screenshot(true);
682 EXPECT_EQ(0, delegate->handle_take_screenshot_count());
683 EXPECT_TRUE(ProcessWithContext(
684 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN)));
685 EXPECT_EQ(1, delegate->handle_take_screenshot_count());
686 EXPECT_TRUE(ProcessWithContext(
687 ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE)));
688 EXPECT_EQ(2, delegate->handle_take_screenshot_count());
689 EXPECT_TRUE(ProcessWithContext(
690 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1,
691 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
692 EXPECT_EQ(2, delegate->handle_take_screenshot_count());
697 CapsLockDelegate* delegate = Shell::GetInstance()->caps_lock_delegate();
698 delegate->SetCapsLockEnabled(true);
699 EXPECT_TRUE(delegate->IsCapsLockEnabled());
700 // Handled only on key release.
701 EXPECT_FALSE(ProcessWithContext(
702 ui::Accelerator(ui::VKEY_LSHIFT, ui::EF_NONE)));
703 EXPECT_TRUE(delegate->IsCapsLockEnabled());
704 EXPECT_TRUE(ProcessWithContext(
705 ReleaseAccelerator(ui::VKEY_SHIFT, ui::EF_NONE)));
706 EXPECT_FALSE(delegate->IsCapsLockEnabled());
707 delegate->SetCapsLockEnabled(true);
708 EXPECT_FALSE(ProcessWithContext(
709 ui::Accelerator(ui::VKEY_RSHIFT, ui::EF_NONE)));
710 EXPECT_TRUE(delegate->IsCapsLockEnabled());
711 EXPECT_TRUE(ProcessWithContext(
712 ReleaseAccelerator(ui::VKEY_LSHIFT, ui::EF_NONE)));
713 EXPECT_FALSE(delegate->IsCapsLockEnabled());
714 delegate->SetCapsLockEnabled(true);
715 EXPECT_FALSE(ProcessWithContext(
716 ui::Accelerator(ui::VKEY_SHIFT, ui::EF_NONE)));
717 EXPECT_TRUE(delegate->IsCapsLockEnabled());
718 EXPECT_TRUE(ProcessWithContext(
719 ReleaseAccelerator(ui::VKEY_RSHIFT, ui::EF_NONE)));
720 EXPECT_FALSE(delegate->IsCapsLockEnabled());
722 // Do not handle when a shift pressed with other keys.
723 delegate->SetCapsLockEnabled(true);
724 EXPECT_FALSE(ProcessWithContext(
725 ui::Accelerator(ui::VKEY_A, ui::EF_SHIFT_DOWN)));
726 EXPECT_TRUE(delegate->IsCapsLockEnabled());
727 EXPECT_FALSE(ProcessWithContext(
728 ReleaseAccelerator(ui::VKEY_A, ui::EF_SHIFT_DOWN)));
729 EXPECT_TRUE(delegate->IsCapsLockEnabled());
731 // Do not handle when a shift pressed with other keys, and shift is
733 delegate->SetCapsLockEnabled(true);
734 EXPECT_FALSE(ProcessWithContext(
735 ui::Accelerator(ui::VKEY_A, ui::EF_SHIFT_DOWN)));
736 EXPECT_TRUE(delegate->IsCapsLockEnabled());
737 EXPECT_FALSE(ProcessWithContext(
738 ReleaseAccelerator(ui::VKEY_LSHIFT, ui::EF_NONE)));
739 EXPECT_TRUE(delegate->IsCapsLockEnabled());
741 EXPECT_FALSE(ProcessWithContext(
742 ui::Accelerator(ui::VKEY_A, ui::EF_SHIFT_DOWN)));
743 EXPECT_TRUE(delegate->IsCapsLockEnabled());
744 EXPECT_FALSE(ProcessWithContext(
745 ReleaseAccelerator(ui::VKEY_SHIFT, ui::EF_NONE)));
746 EXPECT_TRUE(delegate->IsCapsLockEnabled());
748 EXPECT_FALSE(ProcessWithContext(
749 ui::Accelerator(ui::VKEY_A, ui::EF_SHIFT_DOWN)));
750 EXPECT_TRUE(delegate->IsCapsLockEnabled());
751 EXPECT_FALSE(ProcessWithContext(
752 ReleaseAccelerator(ui::VKEY_RSHIFT, ui::EF_NONE)));
753 EXPECT_TRUE(delegate->IsCapsLockEnabled());
755 // Do not consume shift keyup when caps lock is off.
756 delegate->SetCapsLockEnabled(false);
757 EXPECT_FALSE(ProcessWithContext(
758 ui::Accelerator(ui::VKEY_LSHIFT, ui::EF_NONE)));
759 EXPECT_FALSE(ProcessWithContext(
760 ReleaseAccelerator(ui::VKEY_LSHIFT, ui::EF_NONE)));
761 EXPECT_FALSE(ProcessWithContext(
762 ui::Accelerator(ui::VKEY_RSHIFT, ui::EF_NONE)));
763 EXPECT_FALSE(ProcessWithContext(
764 ReleaseAccelerator(ui::VKEY_RSHIFT, ui::EF_NONE)));
765 EXPECT_FALSE(ProcessWithContext(
766 ui::Accelerator(ui::VKEY_SHIFT, ui::EF_NONE)));
767 EXPECT_FALSE(ProcessWithContext(
768 ReleaseAccelerator(ui::VKEY_SHIFT, ui::EF_NONE)));
772 CapsLockDelegate* delegate = Shell::GetInstance()->caps_lock_delegate();
773 delegate->SetCapsLockEnabled(true);
774 EXPECT_TRUE(delegate->IsCapsLockEnabled());
775 EXPECT_FALSE(ProcessWithContext(
776 ui::Accelerator(ui::VKEY_LWIN, ui::EF_ALT_DOWN)));
777 EXPECT_TRUE(ProcessWithContext(
778 ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_ALT_DOWN)));
779 EXPECT_FALSE(delegate->IsCapsLockEnabled());
780 EXPECT_FALSE(ProcessWithContext(
781 ui::Accelerator(ui::VKEY_LWIN, ui::EF_ALT_DOWN)));
782 EXPECT_TRUE(ProcessWithContext(
783 ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_ALT_DOWN)));
784 EXPECT_TRUE(delegate->IsCapsLockEnabled());
786 const ui::Accelerator volume_mute(ui::VKEY_VOLUME_MUTE, ui::EF_NONE);
787 const ui::Accelerator volume_down(ui::VKEY_VOLUME_DOWN, ui::EF_NONE);
788 const ui::Accelerator volume_up(ui::VKEY_VOLUME_UP, ui::EF_NONE);
790 DummyVolumeControlDelegate* delegate =
791 new DummyVolumeControlDelegate(false);
792 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
793 scoped_ptr<VolumeControlDelegate>(delegate).Pass());
794 EXPECT_EQ(0, delegate->handle_volume_mute_count());
795 EXPECT_FALSE(ProcessWithContext(volume_mute));
796 EXPECT_EQ(1, delegate->handle_volume_mute_count());
797 EXPECT_EQ(volume_mute, delegate->last_accelerator());
798 EXPECT_EQ(0, delegate->handle_volume_down_count());
799 EXPECT_FALSE(ProcessWithContext(volume_down));
800 EXPECT_EQ(1, delegate->handle_volume_down_count());
801 EXPECT_EQ(volume_down, delegate->last_accelerator());
802 EXPECT_EQ(0, delegate->handle_volume_up_count());
803 EXPECT_FALSE(ProcessWithContext(volume_up));
804 EXPECT_EQ(1, delegate->handle_volume_up_count());
805 EXPECT_EQ(volume_up, delegate->last_accelerator());
808 DummyVolumeControlDelegate* delegate = new DummyVolumeControlDelegate(true);
809 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
810 scoped_ptr<VolumeControlDelegate>(delegate).Pass());
811 EXPECT_EQ(0, delegate->handle_volume_mute_count());
812 EXPECT_TRUE(ProcessWithContext(volume_mute));
813 EXPECT_EQ(1, delegate->handle_volume_mute_count());
814 EXPECT_EQ(volume_mute, delegate->last_accelerator());
815 EXPECT_EQ(0, delegate->handle_volume_down_count());
816 EXPECT_TRUE(ProcessWithContext(volume_down));
817 EXPECT_EQ(1, delegate->handle_volume_down_count());
818 EXPECT_EQ(volume_down, delegate->last_accelerator());
819 EXPECT_EQ(0, delegate->handle_volume_up_count());
820 EXPECT_TRUE(ProcessWithContext(volume_up));
821 EXPECT_EQ(1, delegate->handle_volume_up_count());
822 EXPECT_EQ(volume_up, delegate->last_accelerator());
824 #if defined(OS_CHROMEOS)
826 // ui::VKEY_BRIGHTNESS_DOWN/UP are not defined on Windows.
827 const ui::Accelerator brightness_down(ui::VKEY_BRIGHTNESS_DOWN, ui::EF_NONE);
828 const ui::Accelerator brightness_up(ui::VKEY_BRIGHTNESS_UP, ui::EF_NONE);
830 EXPECT_FALSE(ProcessWithContext(brightness_down));
831 EXPECT_FALSE(ProcessWithContext(brightness_up));
832 DummyBrightnessControlDelegate* delegate =
833 new DummyBrightnessControlDelegate(true);
834 GetController()->SetBrightnessControlDelegate(
835 scoped_ptr<BrightnessControlDelegate>(delegate).Pass());
836 EXPECT_FALSE(ProcessWithContext(brightness_down));
837 EXPECT_FALSE(ProcessWithContext(brightness_up));
839 // Enable internal display.
840 EnableInternalDisplay();
842 DummyBrightnessControlDelegate* delegate =
843 new DummyBrightnessControlDelegate(false);
844 GetController()->SetBrightnessControlDelegate(
845 scoped_ptr<BrightnessControlDelegate>(delegate).Pass());
846 EXPECT_EQ(0, delegate->handle_brightness_down_count());
847 EXPECT_FALSE(ProcessWithContext(brightness_down));
848 EXPECT_EQ(1, delegate->handle_brightness_down_count());
849 EXPECT_EQ(brightness_down, delegate->last_accelerator());
850 EXPECT_EQ(0, delegate->handle_brightness_up_count());
851 EXPECT_FALSE(ProcessWithContext(brightness_up));
852 EXPECT_EQ(1, delegate->handle_brightness_up_count());
853 EXPECT_EQ(brightness_up, delegate->last_accelerator());
856 DummyBrightnessControlDelegate* delegate =
857 new DummyBrightnessControlDelegate(true);
858 GetController()->SetBrightnessControlDelegate(
859 scoped_ptr<BrightnessControlDelegate>(delegate).Pass());
860 EXPECT_EQ(0, delegate->handle_brightness_down_count());
861 EXPECT_TRUE(ProcessWithContext(brightness_down));
862 EXPECT_EQ(1, delegate->handle_brightness_down_count());
863 EXPECT_EQ(brightness_down, delegate->last_accelerator());
864 EXPECT_EQ(0, delegate->handle_brightness_up_count());
865 EXPECT_TRUE(ProcessWithContext(brightness_up));
866 EXPECT_EQ(1, delegate->handle_brightness_up_count());
867 EXPECT_EQ(brightness_up, delegate->last_accelerator());
870 // Keyboard brightness
871 const ui::Accelerator alt_brightness_down(ui::VKEY_BRIGHTNESS_DOWN,
873 const ui::Accelerator alt_brightness_up(ui::VKEY_BRIGHTNESS_UP,
876 EXPECT_TRUE(ProcessWithContext(alt_brightness_down));
877 EXPECT_TRUE(ProcessWithContext(alt_brightness_up));
878 DummyKeyboardBrightnessControlDelegate* delegate =
879 new DummyKeyboardBrightnessControlDelegate(false);
880 GetController()->SetKeyboardBrightnessControlDelegate(
881 scoped_ptr<KeyboardBrightnessControlDelegate>(delegate).Pass());
882 EXPECT_EQ(0, delegate->handle_keyboard_brightness_down_count());
883 EXPECT_FALSE(ProcessWithContext(alt_brightness_down));
884 EXPECT_EQ(1, delegate->handle_keyboard_brightness_down_count());
885 EXPECT_EQ(alt_brightness_down, delegate->last_accelerator());
886 EXPECT_EQ(0, delegate->handle_keyboard_brightness_up_count());
887 EXPECT_FALSE(ProcessWithContext(alt_brightness_up));
888 EXPECT_EQ(1, delegate->handle_keyboard_brightness_up_count());
889 EXPECT_EQ(alt_brightness_up, delegate->last_accelerator());
892 DummyKeyboardBrightnessControlDelegate* delegate =
893 new DummyKeyboardBrightnessControlDelegate(true);
894 GetController()->SetKeyboardBrightnessControlDelegate(
895 scoped_ptr<KeyboardBrightnessControlDelegate>(delegate).Pass());
896 EXPECT_EQ(0, delegate->handle_keyboard_brightness_down_count());
897 EXPECT_TRUE(ProcessWithContext(alt_brightness_down));
898 EXPECT_EQ(1, delegate->handle_keyboard_brightness_down_count());
899 EXPECT_EQ(alt_brightness_down, delegate->last_accelerator());
900 EXPECT_EQ(0, delegate->handle_keyboard_brightness_up_count());
901 EXPECT_TRUE(ProcessWithContext(alt_brightness_up));
902 EXPECT_EQ(1, delegate->handle_keyboard_brightness_up_count());
903 EXPECT_EQ(alt_brightness_up, delegate->last_accelerator());
908 // ToggleDesktopBackgroundMode
909 EXPECT_TRUE(ProcessWithContext(
910 ui::Accelerator(ui::VKEY_B, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN)));
911 #if !defined(OS_LINUX)
912 // ToggleDesktopFullScreen (not implemented yet on Linux)
913 EXPECT_TRUE(ProcessWithContext(
914 ui::Accelerator(ui::VKEY_F11, ui::EF_CONTROL_DOWN)));
920 ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest();
923 EXPECT_TRUE(is_idle(ewh));
924 EXPECT_FALSE(is_ui_shown(ewh));
925 EXPECT_TRUE(ProcessWithContext(
926 ui::Accelerator(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
927 EXPECT_FALSE(is_idle(ewh));
928 EXPECT_TRUE(is_ui_shown(ewh));
929 SimulateTimerExpired(ewh);
930 EXPECT_TRUE(is_idle(ewh));
931 EXPECT_FALSE(is_ui_shown(ewh));
936 EXPECT_TRUE(ProcessWithContext(
937 ui::Accelerator(ui::VKEY_T, ui::EF_CONTROL_DOWN)));
939 // New incognito window
940 EXPECT_TRUE(ProcessWithContext(
941 ui::Accelerator(ui::VKEY_N, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
944 EXPECT_TRUE(ProcessWithContext(
945 ui::Accelerator(ui::VKEY_N, ui::EF_CONTROL_DOWN)));
948 EXPECT_TRUE(ProcessWithContext(
949 ui::Accelerator(ui::VKEY_T, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
952 EXPECT_TRUE(ProcessWithContext(
953 ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_SHIFT_DOWN)));
955 #if defined(OS_CHROMEOS)
957 EXPECT_TRUE(ProcessWithContext(
958 ui::Accelerator(ui::VKEY_M, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN)));
961 // NOTE: Accelerators that do not work on the lock screen need to be
962 // tested before the sequence below is invoked because it causes a side
963 // effect of locking the screen.
964 EXPECT_TRUE(ProcessWithContext(
965 ui::Accelerator(ui::VKEY_L, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
969 TEST_F(AcceleratorControllerTest, GlobalAcceleratorsToggleAppList) {
970 AccessibilityDelegate* delegate =
971 ash::Shell::GetInstance()->accessibility_delegate();
972 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
974 // The press event should not open the AppList, the release should instead.
975 EXPECT_FALSE(ProcessWithContext(
976 ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE)));
977 EXPECT_TRUE(ProcessWithContext(
978 ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE)));
979 EXPECT_TRUE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
981 // When spoken feedback is on, the AppList should not toggle.
982 delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE);
983 EXPECT_FALSE(ProcessWithContext(
984 ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE)));
985 EXPECT_FALSE(ProcessWithContext(
986 ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE)));
987 delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE);
988 EXPECT_TRUE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
990 EXPECT_FALSE(ProcessWithContext(
991 ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE)));
992 EXPECT_TRUE(ProcessWithContext(
993 ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE)));
994 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
996 // When spoken feedback is on, the AppList should not toggle.
997 delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE);
998 EXPECT_FALSE(ProcessWithContext(
999 ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE)));
1000 EXPECT_FALSE(ProcessWithContext(
1001 ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE)));
1002 delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE);
1003 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
1006 TEST_F(AcceleratorControllerTest, ImeGlobalAccelerators) {
1007 // Test IME shortcuts.
1009 const ui::Accelerator control_space(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN);
1010 const ui::Accelerator convert(ui::VKEY_CONVERT, ui::EF_NONE);
1011 const ui::Accelerator non_convert(ui::VKEY_NONCONVERT, ui::EF_NONE);
1012 const ui::Accelerator wide_half_1(ui::VKEY_DBE_SBCSCHAR, ui::EF_NONE);
1013 const ui::Accelerator wide_half_2(ui::VKEY_DBE_DBCSCHAR, ui::EF_NONE);
1014 const ui::Accelerator hangul(ui::VKEY_HANGUL, ui::EF_NONE);
1015 EXPECT_FALSE(ProcessWithContext(control_space));
1016 EXPECT_FALSE(ProcessWithContext(convert));
1017 EXPECT_FALSE(ProcessWithContext(non_convert));
1018 EXPECT_FALSE(ProcessWithContext(wide_half_1));
1019 EXPECT_FALSE(ProcessWithContext(wide_half_2));
1020 EXPECT_FALSE(ProcessWithContext(hangul));
1021 DummyImeControlDelegate* delegate = new DummyImeControlDelegate(true);
1022 GetController()->SetImeControlDelegate(
1023 scoped_ptr<ImeControlDelegate>(delegate).Pass());
1024 EXPECT_EQ(0, delegate->handle_previous_ime_count());
1025 EXPECT_TRUE(ProcessWithContext(control_space));
1026 EXPECT_EQ(1, delegate->handle_previous_ime_count());
1027 EXPECT_EQ(0, delegate->handle_switch_ime_count());
1028 EXPECT_TRUE(ProcessWithContext(convert));
1029 EXPECT_EQ(1, delegate->handle_switch_ime_count());
1030 EXPECT_TRUE(ProcessWithContext(non_convert));
1031 EXPECT_EQ(2, delegate->handle_switch_ime_count());
1032 EXPECT_TRUE(ProcessWithContext(wide_half_1));
1033 EXPECT_EQ(3, delegate->handle_switch_ime_count());
1034 EXPECT_TRUE(ProcessWithContext(wide_half_2));
1035 EXPECT_EQ(4, delegate->handle_switch_ime_count());
1036 EXPECT_TRUE(ProcessWithContext(hangul));
1037 EXPECT_EQ(5, delegate->handle_switch_ime_count());
1040 // Test IME shortcuts that are triggered on key release.
1042 const ui::Accelerator shift_alt_press(ui::VKEY_MENU,
1043 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1044 const ReleaseAccelerator shift_alt(ui::VKEY_MENU, ui::EF_SHIFT_DOWN);
1045 const ui::Accelerator alt_shift_press(ui::VKEY_SHIFT,
1046 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1047 const ReleaseAccelerator alt_shift(ui::VKEY_SHIFT, ui::EF_ALT_DOWN);
1049 DummyImeControlDelegate* delegate = new DummyImeControlDelegate(true);
1050 GetController()->SetImeControlDelegate(
1051 scoped_ptr<ImeControlDelegate>(delegate).Pass());
1052 EXPECT_EQ(0, delegate->handle_next_ime_count());
1053 EXPECT_FALSE(ProcessWithContext(shift_alt_press));
1054 EXPECT_TRUE(ProcessWithContext(shift_alt));
1055 EXPECT_EQ(1, delegate->handle_next_ime_count());
1056 EXPECT_FALSE(ProcessWithContext(alt_shift_press));
1057 EXPECT_TRUE(ProcessWithContext(alt_shift));
1058 EXPECT_EQ(2, delegate->handle_next_ime_count());
1060 // We should NOT switch IME when e.g. Shift+Alt+X is pressed and X is
1062 const ui::Accelerator shift_alt_x_press(
1064 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1065 const ReleaseAccelerator shift_alt_x(ui::VKEY_X,
1066 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1068 EXPECT_FALSE(ProcessWithContext(shift_alt_press));
1069 EXPECT_FALSE(ProcessWithContext(shift_alt_x_press));
1070 EXPECT_FALSE(ProcessWithContext(shift_alt_x));
1071 EXPECT_FALSE(ProcessWithContext(shift_alt));
1072 EXPECT_EQ(2, delegate->handle_next_ime_count());
1074 // But we _should_ if X is either VKEY_RETURN or VKEY_SPACE.
1075 // TODO(nona|mazda): Remove this when crbug.com/139556 in a better way.
1076 const ui::Accelerator shift_alt_return_press(
1078 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1079 const ReleaseAccelerator shift_alt_return(
1081 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1083 EXPECT_FALSE(ProcessWithContext(shift_alt_press));
1084 EXPECT_FALSE(ProcessWithContext(shift_alt_return_press));
1085 EXPECT_FALSE(ProcessWithContext(shift_alt_return));
1086 EXPECT_TRUE(ProcessWithContext(shift_alt));
1087 EXPECT_EQ(3, delegate->handle_next_ime_count());
1089 const ui::Accelerator shift_alt_space_press(
1091 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1092 const ReleaseAccelerator shift_alt_space(
1094 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1096 EXPECT_FALSE(ProcessWithContext(shift_alt_press));
1097 EXPECT_FALSE(ProcessWithContext(shift_alt_space_press));
1098 EXPECT_FALSE(ProcessWithContext(shift_alt_space));
1099 EXPECT_TRUE(ProcessWithContext(shift_alt));
1100 EXPECT_EQ(4, delegate->handle_next_ime_count());
1103 #if defined(OS_CHROMEOS)
1104 // Test IME shortcuts again with unnormalized accelerators (Chrome OS only).
1106 const ui::Accelerator shift_alt_press(ui::VKEY_MENU, ui::EF_SHIFT_DOWN);
1107 const ReleaseAccelerator shift_alt(ui::VKEY_MENU, ui::EF_SHIFT_DOWN);
1108 const ui::Accelerator alt_shift_press(ui::VKEY_SHIFT, ui::EF_ALT_DOWN);
1109 const ReleaseAccelerator alt_shift(ui::VKEY_SHIFT, ui::EF_ALT_DOWN);
1111 DummyImeControlDelegate* delegate = new DummyImeControlDelegate(true);
1112 GetController()->SetImeControlDelegate(
1113 scoped_ptr<ImeControlDelegate>(delegate).Pass());
1114 EXPECT_EQ(0, delegate->handle_next_ime_count());
1115 EXPECT_FALSE(ProcessWithContext(shift_alt_press));
1116 EXPECT_TRUE(ProcessWithContext(shift_alt));
1117 EXPECT_EQ(1, delegate->handle_next_ime_count());
1118 EXPECT_FALSE(ProcessWithContext(alt_shift_press));
1119 EXPECT_TRUE(ProcessWithContext(alt_shift));
1120 EXPECT_EQ(2, delegate->handle_next_ime_count());
1122 // We should NOT switch IME when e.g. Shift+Alt+X is pressed and X is
1124 const ui::Accelerator shift_alt_x_press(
1126 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1127 const ReleaseAccelerator shift_alt_x(ui::VKEY_X,
1128 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1130 EXPECT_FALSE(ProcessWithContext(shift_alt_press));
1131 EXPECT_FALSE(ProcessWithContext(shift_alt_x_press));
1132 EXPECT_FALSE(ProcessWithContext(shift_alt_x));
1133 EXPECT_FALSE(ProcessWithContext(shift_alt));
1134 EXPECT_EQ(2, delegate->handle_next_ime_count());
1139 // TODO(nona|mazda): Remove this when crbug.com/139556 in a better way.
1140 TEST_F(AcceleratorControllerTest, ImeGlobalAcceleratorsWorkaround139556) {
1141 // The workaround for crbug.com/139556 depends on the fact that we don't
1142 // use Shift+Alt+Enter/Space with ET_KEY_PRESSED as an accelerator. Test it.
1143 const ui::Accelerator shift_alt_return_press(
1145 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1146 EXPECT_FALSE(ProcessWithContext(shift_alt_return_press));
1147 const ui::Accelerator shift_alt_space_press(
1149 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1150 EXPECT_FALSE(ProcessWithContext(shift_alt_space_press));
1153 TEST_F(AcceleratorControllerTest, ReservedAccelerators) {
1154 // (Shift+)Alt+Tab and Chrome OS top-row keys are reserved.
1155 EXPECT_TRUE(GetController()->IsReservedAccelerator(
1156 ui::Accelerator(ui::VKEY_TAB, ui::EF_ALT_DOWN)));
1157 EXPECT_TRUE(GetController()->IsReservedAccelerator(
1158 ui::Accelerator(ui::VKEY_TAB, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN)));
1159 #if defined(OS_CHROMEOS)
1160 EXPECT_TRUE(GetController()->IsReservedAccelerator(
1161 ui::Accelerator(ui::VKEY_POWER, ui::EF_NONE)));
1163 // Others are not reserved.
1164 EXPECT_FALSE(GetController()->IsReservedAccelerator(
1165 ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE)));
1166 EXPECT_FALSE(GetController()->IsReservedAccelerator(
1167 ui::Accelerator(ui::VKEY_TAB, ui::EF_NONE)));
1168 EXPECT_FALSE(GetController()->IsReservedAccelerator(
1169 ui::Accelerator(ui::VKEY_A, ui::EF_NONE)));
1172 #if defined(OS_CHROMEOS)
1173 TEST_F(AcceleratorControllerTest, DisallowedAtModalWindow) {
1174 std::set<AcceleratorAction> all_actions;
1175 for (size_t i = 0 ; i < kAcceleratorDataLength; ++i)
1176 all_actions.insert(kAcceleratorData[i].action);
1177 #if !defined(NDEBUG)
1178 std::set<AcceleratorAction> all_desktop_actions;
1179 for (size_t i = 0 ; i < kDesktopAcceleratorDataLength; ++i)
1180 all_desktop_actions.insert(kDesktopAcceleratorData[i].action);
1183 std::set<AcceleratorAction> actionsAllowedAtModalWindow;
1184 for (size_t k = 0 ; k < kActionsAllowedAtModalWindowLength; ++k)
1185 actionsAllowedAtModalWindow.insert(kActionsAllowedAtModalWindow[k]);
1186 for (std::set<AcceleratorAction>::const_iterator it =
1187 actionsAllowedAtModalWindow.begin();
1188 it != actionsAllowedAtModalWindow.end(); ++it) {
1189 EXPECT_TRUE(all_actions.find(*it) != all_actions.end()
1191 #if !defined(NDEBUG)
1192 || all_desktop_actions.find(*it) != all_desktop_actions.end()
1195 << " action from kActionsAllowedAtModalWindow"
1196 << " not found in kAcceleratorData or kDesktopAcceleratorData. "
1197 << "action: " << *it;
1199 scoped_ptr<aura::Window> window(
1200 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
1201 const ui::Accelerator dummy;
1202 wm::ActivateWindow(window.get());
1203 Shell::GetInstance()->SimulateModalWindowOpenForTesting(true);
1204 for (std::set<AcceleratorAction>::const_iterator it = all_actions.begin();
1205 it != all_actions.end(); ++it) {
1206 if (actionsAllowedAtModalWindow.find(*it) ==
1207 actionsAllowedAtModalWindow.end()) {
1208 EXPECT_TRUE(GetController()->PerformAction(*it, dummy))
1209 << " for action (disallowed at modal window): " << *it;
1212 // Testing of top row (F5-F10) accelerators that should still work
1213 // when a modal window is open
1217 test::TestScreenshotDelegate* delegate = GetScreenshotDelegate();
1218 delegate->set_can_take_screenshot(false);
1219 EXPECT_TRUE(ProcessWithContext(
1220 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN)));
1221 EXPECT_TRUE(ProcessWithContext(
1222 ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE)));
1223 EXPECT_TRUE(ProcessWithContext(
1224 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1,
1225 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
1226 delegate->set_can_take_screenshot(true);
1227 EXPECT_EQ(0, delegate->handle_take_screenshot_count());
1228 EXPECT_TRUE(ProcessWithContext(
1229 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN)));
1230 EXPECT_EQ(1, delegate->handle_take_screenshot_count());
1231 EXPECT_TRUE(ProcessWithContext(
1232 ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE)));
1233 EXPECT_EQ(2, delegate->handle_take_screenshot_count());
1234 EXPECT_TRUE(ProcessWithContext(
1235 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1,
1236 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
1237 EXPECT_EQ(2, delegate->handle_take_screenshot_count());
1240 const ui::Accelerator brightness_down(ui::VKEY_BRIGHTNESS_DOWN, ui::EF_NONE);
1241 const ui::Accelerator brightness_up(ui::VKEY_BRIGHTNESS_UP, ui::EF_NONE);
1243 EXPECT_FALSE(ProcessWithContext(brightness_down));
1244 EXPECT_FALSE(ProcessWithContext(brightness_up));
1245 DummyBrightnessControlDelegate* delegate =
1246 new DummyBrightnessControlDelegate(true);
1247 GetController()->SetBrightnessControlDelegate(
1248 scoped_ptr<BrightnessControlDelegate>(delegate).Pass());
1249 EXPECT_FALSE(ProcessWithContext(brightness_down));
1250 EXPECT_FALSE(ProcessWithContext(brightness_up));
1252 EnableInternalDisplay();
1254 EXPECT_FALSE(ProcessWithContext(brightness_down));
1255 EXPECT_FALSE(ProcessWithContext(brightness_up));
1256 DummyBrightnessControlDelegate* delegate =
1257 new DummyBrightnessControlDelegate(false);
1258 GetController()->SetBrightnessControlDelegate(
1259 scoped_ptr<BrightnessControlDelegate>(delegate).Pass());
1260 EXPECT_EQ(0, delegate->handle_brightness_down_count());
1261 EXPECT_FALSE(ProcessWithContext(brightness_down));
1262 EXPECT_EQ(1, delegate->handle_brightness_down_count());
1263 EXPECT_EQ(brightness_down, delegate->last_accelerator());
1264 EXPECT_EQ(0, delegate->handle_brightness_up_count());
1265 EXPECT_FALSE(ProcessWithContext(brightness_up));
1266 EXPECT_EQ(1, delegate->handle_brightness_up_count());
1267 EXPECT_EQ(brightness_up, delegate->last_accelerator());
1270 DummyBrightnessControlDelegate* delegate =
1271 new DummyBrightnessControlDelegate(true);
1272 GetController()->SetBrightnessControlDelegate(
1273 scoped_ptr<BrightnessControlDelegate>(delegate).Pass());
1274 EXPECT_EQ(0, delegate->handle_brightness_down_count());
1275 EXPECT_TRUE(ProcessWithContext(brightness_down));
1276 EXPECT_EQ(1, delegate->handle_brightness_down_count());
1277 EXPECT_EQ(brightness_down, delegate->last_accelerator());
1278 EXPECT_EQ(0, delegate->handle_brightness_up_count());
1279 EXPECT_TRUE(ProcessWithContext(brightness_up));
1280 EXPECT_EQ(1, delegate->handle_brightness_up_count());
1281 EXPECT_EQ(brightness_up, delegate->last_accelerator());
1284 const ui::Accelerator volume_mute(ui::VKEY_VOLUME_MUTE, ui::EF_NONE);
1285 const ui::Accelerator volume_down(ui::VKEY_VOLUME_DOWN, ui::EF_NONE);
1286 const ui::Accelerator volume_up(ui::VKEY_VOLUME_UP, ui::EF_NONE);
1288 EXPECT_TRUE(ProcessWithContext(volume_mute));
1289 EXPECT_TRUE(ProcessWithContext(volume_down));
1290 EXPECT_TRUE(ProcessWithContext(volume_up));
1291 DummyVolumeControlDelegate* delegate =
1292 new DummyVolumeControlDelegate(false);
1293 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
1294 scoped_ptr<VolumeControlDelegate>(delegate).Pass());
1295 EXPECT_EQ(0, delegate->handle_volume_mute_count());
1296 EXPECT_FALSE(ProcessWithContext(volume_mute));
1297 EXPECT_EQ(1, delegate->handle_volume_mute_count());
1298 EXPECT_EQ(volume_mute, delegate->last_accelerator());
1299 EXPECT_EQ(0, delegate->handle_volume_down_count());
1300 EXPECT_FALSE(ProcessWithContext(volume_down));
1301 EXPECT_EQ(1, delegate->handle_volume_down_count());
1302 EXPECT_EQ(volume_down, delegate->last_accelerator());
1303 EXPECT_EQ(0, delegate->handle_volume_up_count());
1304 EXPECT_FALSE(ProcessWithContext(volume_up));
1305 EXPECT_EQ(1, delegate->handle_volume_up_count());
1306 EXPECT_EQ(volume_up, delegate->last_accelerator());
1309 DummyVolumeControlDelegate* delegate = new DummyVolumeControlDelegate(true);
1310 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
1311 scoped_ptr<VolumeControlDelegate>(delegate).Pass());
1312 EXPECT_EQ(0, delegate->handle_volume_mute_count());
1313 EXPECT_TRUE(ProcessWithContext(volume_mute));
1314 EXPECT_EQ(1, delegate->handle_volume_mute_count());
1315 EXPECT_EQ(volume_mute, delegate->last_accelerator());
1316 EXPECT_EQ(0, delegate->handle_volume_down_count());
1317 EXPECT_TRUE(ProcessWithContext(volume_down));
1318 EXPECT_EQ(1, delegate->handle_volume_down_count());
1319 EXPECT_EQ(volume_down, delegate->last_accelerator());
1320 EXPECT_EQ(0, delegate->handle_volume_up_count());
1321 EXPECT_TRUE(ProcessWithContext(volume_up));
1322 EXPECT_EQ(1, delegate->handle_volume_up_count());
1323 EXPECT_EQ(volume_up, delegate->last_accelerator());