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/ash_switches.h"
9 #include "ash/caps_lock_delegate.h"
10 #include "ash/display/display_manager.h"
11 #include "ash/ime_control_delegate.h"
12 #include "ash/shell.h"
13 #include "ash/shell_window_ids.h"
14 #include "ash/system/brightness_control_delegate.h"
15 #include "ash/system/keyboard_brightness/keyboard_brightness_control_delegate.h"
16 #include "ash/system/tray/system_tray_delegate.h"
17 #include "ash/test/ash_test_base.h"
18 #include "ash/test/display_manager_test_api.h"
19 #include "ash/test/test_screenshot_delegate.h"
20 #include "ash/test/test_shell_delegate.h"
21 #include "ash/volume_control_delegate.h"
22 #include "ash/wm/window_state.h"
23 #include "ash/wm/window_util.h"
24 #include "base/command_line.h"
25 #include "ui/aura/root_window.h"
26 #include "ui/aura/test/test_window_delegate.h"
27 #include "ui/aura/test/test_windows.h"
28 #include "ui/aura/window.h"
29 #include "ui/events/event.h"
30 #include "ui/gfx/screen.h"
34 #include "ui/events/test/events_test_utils_x11.h"
41 class TestTarget
: public ui::AcceleratorTarget
{
43 TestTarget() : accelerator_pressed_count_(0) {}
44 virtual ~TestTarget() {}
46 int accelerator_pressed_count() const {
47 return accelerator_pressed_count_
;
50 void set_accelerator_pressed_count(int accelerator_pressed_count
) {
51 accelerator_pressed_count_
= accelerator_pressed_count
;
54 // Overridden from ui::AcceleratorTarget:
55 virtual bool AcceleratorPressed(const ui::Accelerator
& accelerator
) OVERRIDE
;
56 virtual bool CanHandleAccelerators() const OVERRIDE
;
59 int accelerator_pressed_count_
;
61 DISALLOW_COPY_AND_ASSIGN(TestTarget
);
64 class ReleaseAccelerator
: public ui::Accelerator
{
66 ReleaseAccelerator(ui::KeyboardCode keycode
, int modifiers
)
67 : ui::Accelerator(keycode
, modifiers
) {
68 set_type(ui::ET_KEY_RELEASED
);
72 class DummyVolumeControlDelegate
: public VolumeControlDelegate
{
74 explicit DummyVolumeControlDelegate(bool consume
)
76 handle_volume_mute_count_(0),
77 handle_volume_down_count_(0),
78 handle_volume_up_count_(0) {
80 virtual ~DummyVolumeControlDelegate() {}
82 virtual bool HandleVolumeMute(const ui::Accelerator
& accelerator
) OVERRIDE
{
83 ++handle_volume_mute_count_
;
84 last_accelerator_
= accelerator
;
87 virtual bool HandleVolumeDown(const ui::Accelerator
& accelerator
) OVERRIDE
{
88 ++handle_volume_down_count_
;
89 last_accelerator_
= accelerator
;
92 virtual bool HandleVolumeUp(const ui::Accelerator
& accelerator
) OVERRIDE
{
93 ++handle_volume_up_count_
;
94 last_accelerator_
= accelerator
;
98 int handle_volume_mute_count() const {
99 return handle_volume_mute_count_
;
101 int handle_volume_down_count() const {
102 return handle_volume_down_count_
;
104 int handle_volume_up_count() const {
105 return handle_volume_up_count_
;
107 const ui::Accelerator
& last_accelerator() const {
108 return last_accelerator_
;
113 int handle_volume_mute_count_
;
114 int handle_volume_down_count_
;
115 int handle_volume_up_count_
;
116 ui::Accelerator last_accelerator_
;
118 DISALLOW_COPY_AND_ASSIGN(DummyVolumeControlDelegate
);
121 class DummyBrightnessControlDelegate
: public BrightnessControlDelegate
{
123 explicit DummyBrightnessControlDelegate(bool consume
)
125 handle_brightness_down_count_(0),
126 handle_brightness_up_count_(0) {
128 virtual ~DummyBrightnessControlDelegate() {}
130 virtual bool HandleBrightnessDown(
131 const ui::Accelerator
& accelerator
) OVERRIDE
{
132 ++handle_brightness_down_count_
;
133 last_accelerator_
= accelerator
;
136 virtual bool HandleBrightnessUp(const ui::Accelerator
& accelerator
) OVERRIDE
{
137 ++handle_brightness_up_count_
;
138 last_accelerator_
= accelerator
;
141 virtual void SetBrightnessPercent(double percent
, bool gradual
) OVERRIDE
{}
142 virtual void GetBrightnessPercent(
143 const base::Callback
<void(double)>& callback
) OVERRIDE
{
147 int handle_brightness_down_count() const {
148 return handle_brightness_down_count_
;
150 int handle_brightness_up_count() const {
151 return handle_brightness_up_count_
;
153 const ui::Accelerator
& last_accelerator() const {
154 return last_accelerator_
;
159 int handle_brightness_down_count_
;
160 int handle_brightness_up_count_
;
161 ui::Accelerator last_accelerator_
;
163 DISALLOW_COPY_AND_ASSIGN(DummyBrightnessControlDelegate
);
166 class DummyImeControlDelegate
: public ImeControlDelegate
{
168 explicit DummyImeControlDelegate(bool consume
)
170 handle_next_ime_count_(0),
171 handle_previous_ime_count_(0),
172 handle_switch_ime_count_(0) {
174 virtual ~DummyImeControlDelegate() {}
176 virtual bool HandleNextIme() OVERRIDE
{
177 ++handle_next_ime_count_
;
180 virtual bool HandlePreviousIme(const ui::Accelerator
& accelerator
) OVERRIDE
{
181 ++handle_previous_ime_count_
;
182 last_accelerator_
= accelerator
;
185 virtual bool HandleSwitchIme(const ui::Accelerator
& accelerator
) OVERRIDE
{
186 ++handle_switch_ime_count_
;
187 last_accelerator_
= accelerator
;
191 int handle_next_ime_count() const {
192 return handle_next_ime_count_
;
194 int handle_previous_ime_count() const {
195 return handle_previous_ime_count_
;
197 int handle_switch_ime_count() const {
198 return handle_switch_ime_count_
;
200 const ui::Accelerator
& last_accelerator() const {
201 return last_accelerator_
;
203 virtual ui::Accelerator
RemapAccelerator(
204 const ui::Accelerator
& accelerator
) OVERRIDE
{
205 return ui::Accelerator(accelerator
);
210 int handle_next_ime_count_
;
211 int handle_previous_ime_count_
;
212 int handle_switch_ime_count_
;
213 ui::Accelerator last_accelerator_
;
215 DISALLOW_COPY_AND_ASSIGN(DummyImeControlDelegate
);
218 class DummyKeyboardBrightnessControlDelegate
219 : public KeyboardBrightnessControlDelegate
{
221 explicit DummyKeyboardBrightnessControlDelegate(bool consume
)
223 handle_keyboard_brightness_down_count_(0),
224 handle_keyboard_brightness_up_count_(0) {
226 virtual ~DummyKeyboardBrightnessControlDelegate() {}
228 virtual bool HandleKeyboardBrightnessDown(
229 const ui::Accelerator
& accelerator
) OVERRIDE
{
230 ++handle_keyboard_brightness_down_count_
;
231 last_accelerator_
= accelerator
;
235 virtual bool HandleKeyboardBrightnessUp(
236 const ui::Accelerator
& accelerator
) OVERRIDE
{
237 ++handle_keyboard_brightness_up_count_
;
238 last_accelerator_
= accelerator
;
242 int handle_keyboard_brightness_down_count() const {
243 return handle_keyboard_brightness_down_count_
;
246 int handle_keyboard_brightness_up_count() const {
247 return handle_keyboard_brightness_up_count_
;
250 const ui::Accelerator
& last_accelerator() const {
251 return last_accelerator_
;
256 int handle_keyboard_brightness_down_count_
;
257 int handle_keyboard_brightness_up_count_
;
258 ui::Accelerator last_accelerator_
;
260 DISALLOW_COPY_AND_ASSIGN(DummyKeyboardBrightnessControlDelegate
);
263 bool TestTarget::AcceleratorPressed(const ui::Accelerator
& accelerator
) {
264 ++accelerator_pressed_count_
;
268 bool TestTarget::CanHandleAccelerators() const {
274 class AcceleratorControllerTest
: public test::AshTestBase
{
276 AcceleratorControllerTest() {}
277 virtual ~AcceleratorControllerTest() {}
280 void EnableInternalDisplay() {
281 test::DisplayManagerTestApi(Shell::GetInstance()->display_manager()).
282 SetFirstDisplayAsInternalDisplay();
285 static AcceleratorController
* GetController();
286 static bool ProcessWithContext(const ui::Accelerator
& accelerator
);
288 // Several functions to access ExitWarningHandler (as friend).
289 static void StubForTest(ExitWarningHandler
* ewh
) {
290 ewh
->stub_timer_for_test_
= true;
292 static void Reset(ExitWarningHandler
* ewh
) {
293 ewh
->state_
= ExitWarningHandler::IDLE
;
295 static void SimulateTimerExpired(ExitWarningHandler
* ewh
) {
298 static bool is_ui_shown(ExitWarningHandler
* ewh
) {
299 return !!ewh
->widget_
;
301 static bool is_idle(ExitWarningHandler
* ewh
) {
302 return ewh
->state_
== ExitWarningHandler::IDLE
;
304 static bool is_exiting(ExitWarningHandler
* ewh
) {
305 return ewh
->state_
== ExitWarningHandler::EXITING
;
309 DISALLOW_COPY_AND_ASSIGN(AcceleratorControllerTest
);
312 AcceleratorController
* AcceleratorControllerTest::GetController() {
313 return Shell::GetInstance()->accelerator_controller();
316 bool AcceleratorControllerTest::ProcessWithContext(
317 const ui::Accelerator
& accelerator
) {
318 AcceleratorController
* controller
= GetController();
319 controller
->context()->UpdateContext(accelerator
);
320 return controller
->Process(accelerator
);
324 // Double press of exit shortcut => exiting
325 TEST_F(AcceleratorControllerTest
, ExitWarningHandlerTestDoublePress
) {
326 ui::Accelerator
press(ui::VKEY_Q
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
);
327 ui::Accelerator
release(press
);
328 release
.set_type(ui::ET_KEY_RELEASED
);
329 ExitWarningHandler
* ewh
= GetController()->GetExitWarningHandlerForTest();
332 EXPECT_TRUE(is_idle(ewh
));
333 EXPECT_FALSE(is_ui_shown(ewh
));
334 EXPECT_TRUE(ProcessWithContext(press
));
335 EXPECT_FALSE(ProcessWithContext(release
));
336 EXPECT_FALSE(is_idle(ewh
));
337 EXPECT_TRUE(is_ui_shown(ewh
));
338 EXPECT_TRUE(ProcessWithContext(press
)); // second press before timer.
339 EXPECT_FALSE(ProcessWithContext(release
));
340 SimulateTimerExpired(ewh
);
341 EXPECT_TRUE(is_exiting(ewh
));
342 EXPECT_FALSE(is_ui_shown(ewh
));
346 // Single press of exit shortcut before timer => idle
347 TEST_F(AcceleratorControllerTest
, ExitWarningHandlerTestSinglePress
) {
348 ui::Accelerator
press(ui::VKEY_Q
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
);
349 ui::Accelerator
release(press
);
350 release
.set_type(ui::ET_KEY_RELEASED
);
351 ExitWarningHandler
* ewh
= GetController()->GetExitWarningHandlerForTest();
354 EXPECT_TRUE(is_idle(ewh
));
355 EXPECT_FALSE(is_ui_shown(ewh
));
356 EXPECT_TRUE(ProcessWithContext(press
));
357 EXPECT_FALSE(ProcessWithContext(release
));
358 EXPECT_FALSE(is_idle(ewh
));
359 EXPECT_TRUE(is_ui_shown(ewh
));
360 SimulateTimerExpired(ewh
);
361 EXPECT_TRUE(is_idle(ewh
));
362 EXPECT_FALSE(is_ui_shown(ewh
));
366 // Shutdown ash with exit warning bubble open should not crash.
367 TEST_F(AcceleratorControllerTest
, LingeringExitWarningBubble
) {
368 ExitWarningHandler
* ewh
= GetController()->GetExitWarningHandlerForTest();
372 // Trigger once to show the bubble.
373 ewh
->HandleAccelerator();
374 EXPECT_FALSE(is_idle(ewh
));
375 EXPECT_TRUE(is_ui_shown(ewh
));
377 // Exit ash and there should be no crash
379 #endif // !defined(OS_WIN)
381 TEST_F(AcceleratorControllerTest
, Register
) {
382 const ui::Accelerator
accelerator_a(ui::VKEY_A
, ui::EF_NONE
);
384 GetController()->Register(accelerator_a
, &target
);
386 // The registered accelerator is processed.
387 EXPECT_TRUE(ProcessWithContext(accelerator_a
));
388 EXPECT_EQ(1, target
.accelerator_pressed_count());
391 TEST_F(AcceleratorControllerTest
, RegisterMultipleTarget
) {
392 const ui::Accelerator
accelerator_a(ui::VKEY_A
, ui::EF_NONE
);
394 GetController()->Register(accelerator_a
, &target1
);
396 GetController()->Register(accelerator_a
, &target2
);
398 // If multiple targets are registered with the same accelerator, the target
399 // registered later processes the accelerator.
400 EXPECT_TRUE(ProcessWithContext(accelerator_a
));
401 EXPECT_EQ(0, target1
.accelerator_pressed_count());
402 EXPECT_EQ(1, target2
.accelerator_pressed_count());
405 TEST_F(AcceleratorControllerTest
, Unregister
) {
406 const ui::Accelerator
accelerator_a(ui::VKEY_A
, ui::EF_NONE
);
408 GetController()->Register(accelerator_a
, &target
);
409 const ui::Accelerator
accelerator_b(ui::VKEY_B
, ui::EF_NONE
);
410 GetController()->Register(accelerator_b
, &target
);
412 // Unregistering a different accelerator does not affect the other
414 GetController()->Unregister(accelerator_b
, &target
);
415 EXPECT_TRUE(ProcessWithContext(accelerator_a
));
416 EXPECT_EQ(1, target
.accelerator_pressed_count());
418 // The unregistered accelerator is no longer processed.
419 target
.set_accelerator_pressed_count(0);
420 GetController()->Unregister(accelerator_a
, &target
);
421 EXPECT_FALSE(ProcessWithContext(accelerator_a
));
422 EXPECT_EQ(0, target
.accelerator_pressed_count());
425 TEST_F(AcceleratorControllerTest
, UnregisterAll
) {
426 const ui::Accelerator
accelerator_a(ui::VKEY_A
, ui::EF_NONE
);
428 GetController()->Register(accelerator_a
, &target1
);
429 const ui::Accelerator
accelerator_b(ui::VKEY_B
, ui::EF_NONE
);
430 GetController()->Register(accelerator_b
, &target1
);
431 const ui::Accelerator
accelerator_c(ui::VKEY_C
, ui::EF_NONE
);
433 GetController()->Register(accelerator_c
, &target2
);
434 GetController()->UnregisterAll(&target1
);
436 // All the accelerators registered for |target1| are no longer processed.
437 EXPECT_FALSE(ProcessWithContext(accelerator_a
));
438 EXPECT_FALSE(ProcessWithContext(accelerator_b
));
439 EXPECT_EQ(0, target1
.accelerator_pressed_count());
441 // UnregisterAll with a different target does not affect the other target.
442 EXPECT_TRUE(ProcessWithContext(accelerator_c
));
443 EXPECT_EQ(1, target2
.accelerator_pressed_count());
446 TEST_F(AcceleratorControllerTest
, Process
) {
447 const ui::Accelerator
accelerator_a(ui::VKEY_A
, ui::EF_NONE
);
449 GetController()->Register(accelerator_a
, &target1
);
451 // The registered accelerator is processed.
452 EXPECT_TRUE(ProcessWithContext(accelerator_a
));
453 EXPECT_EQ(1, target1
.accelerator_pressed_count());
455 // The non-registered accelerator is not processed.
456 const ui::Accelerator
accelerator_b(ui::VKEY_B
, ui::EF_NONE
);
457 EXPECT_FALSE(ProcessWithContext(accelerator_b
));
460 TEST_F(AcceleratorControllerTest
, IsRegistered
) {
461 const ui::Accelerator
accelerator_a(ui::VKEY_A
, ui::EF_NONE
);
462 const ui::Accelerator
accelerator_shift_a(ui::VKEY_A
, ui::EF_SHIFT_DOWN
);
464 GetController()->Register(accelerator_a
, &target
);
465 EXPECT_TRUE(GetController()->IsRegistered(accelerator_a
));
466 EXPECT_FALSE(GetController()->IsRegistered(accelerator_shift_a
));
467 GetController()->UnregisterAll(&target
);
468 EXPECT_FALSE(GetController()->IsRegistered(accelerator_a
));
471 TEST_F(AcceleratorControllerTest
, WindowSnap
) {
472 CommandLine::ForCurrentProcess()->AppendSwitch(
473 switches::kAshMultipleSnapWindowWidths
);
475 scoped_ptr
<aura::Window
> window(
476 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
477 const ui::Accelerator dummy
;
479 wm::WindowState
* window_state
= wm::GetWindowState(window
.get());
481 window_state
->Activate();
484 GetController()->PerformAction(WINDOW_SNAP_LEFT
, dummy
);
485 gfx::Rect snap_left
= window
->bounds();
486 GetController()->PerformAction(WINDOW_SNAP_LEFT
, dummy
);
487 EXPECT_NE(window
->bounds().ToString(), snap_left
.ToString());
488 GetController()->PerformAction(WINDOW_SNAP_LEFT
, dummy
);
489 EXPECT_NE(window
->bounds().ToString(), snap_left
.ToString());
491 // It should cycle back to the first snapped position.
492 GetController()->PerformAction(WINDOW_SNAP_LEFT
, dummy
);
493 EXPECT_EQ(window
->bounds().ToString(), snap_left
.ToString());
496 GetController()->PerformAction(WINDOW_SNAP_RIGHT
, dummy
);
497 gfx::Rect snap_right
= window
->bounds();
498 GetController()->PerformAction(WINDOW_SNAP_RIGHT
, dummy
);
499 EXPECT_NE(window
->bounds().ToString(), snap_right
.ToString());
500 GetController()->PerformAction(WINDOW_SNAP_RIGHT
, dummy
);
501 EXPECT_NE(window
->bounds().ToString(), snap_right
.ToString());
503 // It should cycle back to the first snapped position.
504 GetController()->PerformAction(WINDOW_SNAP_RIGHT
, dummy
);
505 EXPECT_EQ(window
->bounds().ToString(), snap_right
.ToString());
508 gfx::Rect normal_bounds
= window_state
->GetRestoreBoundsInParent();
510 GetController()->PerformAction(TOGGLE_MAXIMIZED
, dummy
);
511 EXPECT_TRUE(window_state
->IsMaximized());
512 EXPECT_NE(normal_bounds
.ToString(), window
->bounds().ToString());
514 GetController()->PerformAction(TOGGLE_MAXIMIZED
, dummy
);
515 EXPECT_FALSE(window_state
->IsMaximized());
516 // Window gets restored to its restore bounds since side-maximized state
517 // is treated as a "maximized" state.
518 EXPECT_EQ(normal_bounds
.ToString(), window
->bounds().ToString());
520 GetController()->PerformAction(TOGGLE_MAXIMIZED
, dummy
);
521 GetController()->PerformAction(WINDOW_SNAP_LEFT
, dummy
);
522 EXPECT_FALSE(window_state
->IsMaximized());
524 GetController()->PerformAction(TOGGLE_MAXIMIZED
, dummy
);
525 GetController()->PerformAction(WINDOW_SNAP_RIGHT
, dummy
);
526 EXPECT_FALSE(window_state
->IsMaximized());
528 GetController()->PerformAction(TOGGLE_MAXIMIZED
, dummy
);
529 EXPECT_TRUE(window_state
->IsMaximized());
530 GetController()->PerformAction(WINDOW_MINIMIZE
, dummy
);
531 EXPECT_FALSE(window_state
->IsMaximized());
532 EXPECT_TRUE(window_state
->IsMinimized());
533 window_state
->Restore();
534 window_state
->Activate();
537 GetController()->PerformAction(WINDOW_MINIMIZE
, dummy
);
538 EXPECT_TRUE(window_state
->IsMinimized());
542 TEST_F(AcceleratorControllerTest
, CenterWindowAccelerator
) {
543 scoped_ptr
<aura::Window
> window(
544 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
545 const ui::Accelerator dummy
;
546 wm::WindowState
* window_state
= wm::GetWindowState(window
.get());
547 window_state
->Activate();
549 // Center the window using accelerator.
550 GetController()->PerformAction(WINDOW_POSITION_CENTER
, dummy
);
551 gfx::Rect work_area
=
552 Shell::GetScreen()->GetDisplayNearestWindow(window
.get()).work_area();
553 gfx::Rect bounds
= window
->GetBoundsInScreen();
554 EXPECT_NEAR(bounds
.x() - work_area
.x(),
555 work_area
.right() - bounds
.right(),
557 EXPECT_NEAR(bounds
.y() - work_area
.y(),
558 work_area
.bottom() - bounds
.bottom(),
561 // Add the window to docked container and try to center it.
562 window
->SetBounds(gfx::Rect(0, 0, 20, 20));
563 aura::Window
* docked_container
= Shell::GetContainer(
564 window
->GetRootWindow(), internal::kShellWindowId_DockedContainer
);
565 docked_container
->AddChild(window
.get());
566 gfx::Rect docked_bounds
= window
->GetBoundsInScreen();
567 GetController()->PerformAction(WINDOW_POSITION_CENTER
, dummy
);
568 // It should not get centered and should remain docked.
569 EXPECT_EQ(internal::kShellWindowId_DockedContainer
, window
->parent()->id());
570 EXPECT_EQ(docked_bounds
.ToString(), window
->GetBoundsInScreen().ToString());
573 TEST_F(AcceleratorControllerTest
, ControllerContext
) {
574 ui::Accelerator
accelerator_a(ui::VKEY_A
, ui::EF_NONE
);
575 ui::Accelerator
accelerator_a2(ui::VKEY_A
, ui::EF_NONE
);
576 ui::Accelerator
accelerator_b(ui::VKEY_B
, ui::EF_NONE
);
578 accelerator_a
.set_type(ui::ET_KEY_PRESSED
);
579 accelerator_a2
.set_type(ui::ET_KEY_RELEASED
);
580 accelerator_b
.set_type(ui::ET_KEY_PRESSED
);
582 EXPECT_FALSE(GetController()->context()->repeated());
583 EXPECT_EQ(ui::ET_UNKNOWN
,
584 GetController()->context()->previous_accelerator().type());
586 GetController()->context()->UpdateContext(accelerator_a
);
587 EXPECT_FALSE(GetController()->context()->repeated());
588 EXPECT_EQ(ui::ET_UNKNOWN
,
589 GetController()->context()->previous_accelerator().type());
591 GetController()->context()->UpdateContext(accelerator_a2
);
592 EXPECT_FALSE(GetController()->context()->repeated());
593 EXPECT_EQ(ui::ET_KEY_PRESSED
,
594 GetController()->context()->previous_accelerator().type());
596 GetController()->context()->UpdateContext(accelerator_a2
);
597 EXPECT_TRUE(GetController()->context()->repeated());
598 EXPECT_EQ(ui::ET_KEY_RELEASED
,
599 GetController()->context()->previous_accelerator().type());
601 GetController()->context()->UpdateContext(accelerator_b
);
602 EXPECT_FALSE(GetController()->context()->repeated());
603 EXPECT_EQ(ui::ET_KEY_RELEASED
,
604 GetController()->context()->previous_accelerator().type());
607 #if defined(OS_WIN) && defined(USE_AURA)
609 #define MAYBE_SuppressToggleMaximized DISABLED_SuppressToggleMaximized
611 #define MAYBE_SuppressToggleMaximized SuppressToggleMaximized
614 TEST_F(AcceleratorControllerTest
, MAYBE_SuppressToggleMaximized
) {
615 scoped_ptr
<aura::Window
> window(
616 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
617 wm::ActivateWindow(window
.get());
618 const ui::Accelerator
accelerator(ui::VKEY_A
, ui::EF_NONE
);
619 const ui::Accelerator empty_accelerator
;
621 wm::WindowState
* window_state
= wm::GetWindowState(window
.get());
623 // Toggling not suppressed.
624 GetController()->context()->UpdateContext(accelerator
);
625 GetController()->PerformAction(TOGGLE_MAXIMIZED
, accelerator
);
626 EXPECT_TRUE(window_state
->IsMaximized());
628 // The same accelerator - toggling suppressed.
629 GetController()->context()->UpdateContext(accelerator
);
630 GetController()->PerformAction(TOGGLE_MAXIMIZED
, accelerator
);
631 EXPECT_TRUE(window_state
->IsMaximized());
633 // Suppressed but not for gesture events.
634 GetController()->PerformAction(TOGGLE_MAXIMIZED
, empty_accelerator
);
635 EXPECT_FALSE(window_state
->IsMaximized());
638 #if defined(OS_WIN) && defined(USE_AURA)
640 #define MAYBE_ProcessOnce DISABLED_ProcessOnce
642 #define MAYBE_ProcessOnce ProcessOnce
645 #if defined(OS_WIN) || defined(USE_X11)
646 TEST_F(AcceleratorControllerTest
, MAYBE_ProcessOnce
) {
647 ui::Accelerator
accelerator_a(ui::VKEY_A
, ui::EF_NONE
);
649 GetController()->Register(accelerator_a
, &target
);
651 // The accelerator is processed only once.
652 aura::WindowEventDispatcher
* dispatcher
=
653 Shell::GetPrimaryRootWindow()->GetDispatcher();
655 MSG msg1
= { NULL
, WM_KEYDOWN
, ui::VKEY_A
, 0 };
656 ui::TranslatedKeyEvent
key_event1(msg1
, false);
657 EXPECT_TRUE(dispatcher
->AsWindowTreeHostDelegate()->OnHostKeyEvent(
660 MSG msg2
= { NULL
, WM_CHAR
, L
'A', 0 };
661 ui::TranslatedKeyEvent
key_event2(msg2
, true);
662 EXPECT_FALSE(dispatcher
->AsWindowTreeHostDelegate()->OnHostKeyEvent(
665 MSG msg3
= { NULL
, WM_KEYUP
, ui::VKEY_A
, 0 };
666 ui::TranslatedKeyEvent
key_event3(msg3
, false);
667 EXPECT_FALSE(dispatcher
->AsWindowTreeHostDelegate()->OnHostKeyEvent(
669 #elif defined(USE_X11)
670 ui::ScopedXI2Event key_event
;
671 key_event
.InitKeyEvent(ui::ET_KEY_PRESSED
, ui::VKEY_A
, 0);
672 ui::TranslatedKeyEvent
key_event1(key_event
, false);
673 EXPECT_TRUE(dispatcher
->AsWindowTreeHostDelegate()->OnHostKeyEvent(
676 ui::TranslatedKeyEvent
key_event2(key_event
, true);
677 EXPECT_FALSE(dispatcher
->AsWindowTreeHostDelegate()->OnHostKeyEvent(
680 key_event
.InitKeyEvent(ui::ET_KEY_RELEASED
, ui::VKEY_A
, 0);
681 ui::TranslatedKeyEvent
key_event3(key_event
, false);
682 EXPECT_FALSE(dispatcher
->AsWindowTreeHostDelegate()->OnHostKeyEvent(
685 EXPECT_EQ(1, target
.accelerator_pressed_count());
689 TEST_F(AcceleratorControllerTest
, GlobalAccelerators
) {
691 EXPECT_TRUE(ProcessWithContext(
692 ui::Accelerator(ui::VKEY_TAB
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
)));
694 EXPECT_TRUE(ProcessWithContext(
695 ui::Accelerator(ui::VKEY_TAB
, ui::EF_ALT_DOWN
)));
697 EXPECT_TRUE(ProcessWithContext(
698 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_NONE
)));
700 #if defined(OS_CHROMEOS)
701 // Take screenshot / partial screenshot
702 // True should always be returned regardless of the existence of the delegate.
704 test::TestScreenshotDelegate
* delegate
= GetScreenshotDelegate();
705 delegate
->set_can_take_screenshot(false);
706 EXPECT_TRUE(ProcessWithContext(
707 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_CONTROL_DOWN
)));
708 EXPECT_TRUE(ProcessWithContext(
709 ui::Accelerator(ui::VKEY_PRINT
, ui::EF_NONE
)));
710 EXPECT_TRUE(ProcessWithContext(
711 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1
,
712 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
)));
714 delegate
->set_can_take_screenshot(true);
715 EXPECT_EQ(0, delegate
->handle_take_screenshot_count());
716 EXPECT_TRUE(ProcessWithContext(
717 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_CONTROL_DOWN
)));
718 EXPECT_EQ(1, delegate
->handle_take_screenshot_count());
719 EXPECT_TRUE(ProcessWithContext(
720 ui::Accelerator(ui::VKEY_PRINT
, ui::EF_NONE
)));
721 EXPECT_EQ(2, delegate
->handle_take_screenshot_count());
722 EXPECT_TRUE(ProcessWithContext(
723 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1
,
724 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
)));
725 EXPECT_EQ(2, delegate
->handle_take_screenshot_count());
730 CapsLockDelegate
* delegate
= Shell::GetInstance()->caps_lock_delegate();
731 delegate
->SetCapsLockEnabled(true);
732 EXPECT_TRUE(delegate
->IsCapsLockEnabled());
733 // Handled only on key release.
734 EXPECT_FALSE(ProcessWithContext(
735 ui::Accelerator(ui::VKEY_LSHIFT
, ui::EF_NONE
)));
736 EXPECT_TRUE(delegate
->IsCapsLockEnabled());
737 EXPECT_TRUE(ProcessWithContext(
738 ReleaseAccelerator(ui::VKEY_SHIFT
, ui::EF_NONE
)));
739 EXPECT_FALSE(delegate
->IsCapsLockEnabled());
740 delegate
->SetCapsLockEnabled(true);
741 EXPECT_FALSE(ProcessWithContext(
742 ui::Accelerator(ui::VKEY_RSHIFT
, ui::EF_NONE
)));
743 EXPECT_TRUE(delegate
->IsCapsLockEnabled());
744 EXPECT_TRUE(ProcessWithContext(
745 ReleaseAccelerator(ui::VKEY_LSHIFT
, ui::EF_NONE
)));
746 EXPECT_FALSE(delegate
->IsCapsLockEnabled());
747 delegate
->SetCapsLockEnabled(true);
748 EXPECT_FALSE(ProcessWithContext(
749 ui::Accelerator(ui::VKEY_SHIFT
, ui::EF_NONE
)));
750 EXPECT_TRUE(delegate
->IsCapsLockEnabled());
751 EXPECT_TRUE(ProcessWithContext(
752 ReleaseAccelerator(ui::VKEY_RSHIFT
, ui::EF_NONE
)));
753 EXPECT_FALSE(delegate
->IsCapsLockEnabled());
755 // Do not handle when a shift pressed with other keys.
756 delegate
->SetCapsLockEnabled(true);
757 EXPECT_FALSE(ProcessWithContext(
758 ui::Accelerator(ui::VKEY_A
, ui::EF_SHIFT_DOWN
)));
759 EXPECT_TRUE(delegate
->IsCapsLockEnabled());
760 EXPECT_FALSE(ProcessWithContext(
761 ReleaseAccelerator(ui::VKEY_A
, ui::EF_SHIFT_DOWN
)));
762 EXPECT_TRUE(delegate
->IsCapsLockEnabled());
764 // Do not handle when a shift pressed with other keys, and shift is
766 delegate
->SetCapsLockEnabled(true);
767 EXPECT_FALSE(ProcessWithContext(
768 ui::Accelerator(ui::VKEY_A
, ui::EF_SHIFT_DOWN
)));
769 EXPECT_TRUE(delegate
->IsCapsLockEnabled());
770 EXPECT_FALSE(ProcessWithContext(
771 ReleaseAccelerator(ui::VKEY_LSHIFT
, ui::EF_NONE
)));
772 EXPECT_TRUE(delegate
->IsCapsLockEnabled());
774 EXPECT_FALSE(ProcessWithContext(
775 ui::Accelerator(ui::VKEY_A
, ui::EF_SHIFT_DOWN
)));
776 EXPECT_TRUE(delegate
->IsCapsLockEnabled());
777 EXPECT_FALSE(ProcessWithContext(
778 ReleaseAccelerator(ui::VKEY_SHIFT
, ui::EF_NONE
)));
779 EXPECT_TRUE(delegate
->IsCapsLockEnabled());
781 EXPECT_FALSE(ProcessWithContext(
782 ui::Accelerator(ui::VKEY_A
, ui::EF_SHIFT_DOWN
)));
783 EXPECT_TRUE(delegate
->IsCapsLockEnabled());
784 EXPECT_FALSE(ProcessWithContext(
785 ReleaseAccelerator(ui::VKEY_RSHIFT
, ui::EF_NONE
)));
786 EXPECT_TRUE(delegate
->IsCapsLockEnabled());
788 // Do not consume shift keyup when caps lock is off.
789 delegate
->SetCapsLockEnabled(false);
790 EXPECT_FALSE(ProcessWithContext(
791 ui::Accelerator(ui::VKEY_LSHIFT
, ui::EF_NONE
)));
792 EXPECT_FALSE(ProcessWithContext(
793 ReleaseAccelerator(ui::VKEY_LSHIFT
, ui::EF_NONE
)));
794 EXPECT_FALSE(ProcessWithContext(
795 ui::Accelerator(ui::VKEY_RSHIFT
, ui::EF_NONE
)));
796 EXPECT_FALSE(ProcessWithContext(
797 ReleaseAccelerator(ui::VKEY_RSHIFT
, ui::EF_NONE
)));
798 EXPECT_FALSE(ProcessWithContext(
799 ui::Accelerator(ui::VKEY_SHIFT
, ui::EF_NONE
)));
800 EXPECT_FALSE(ProcessWithContext(
801 ReleaseAccelerator(ui::VKEY_SHIFT
, ui::EF_NONE
)));
805 CapsLockDelegate
* delegate
= Shell::GetInstance()->caps_lock_delegate();
806 delegate
->SetCapsLockEnabled(true);
807 EXPECT_TRUE(delegate
->IsCapsLockEnabled());
808 EXPECT_FALSE(ProcessWithContext(
809 ui::Accelerator(ui::VKEY_LWIN
, ui::EF_ALT_DOWN
)));
810 EXPECT_TRUE(ProcessWithContext(
811 ReleaseAccelerator(ui::VKEY_LWIN
, ui::EF_ALT_DOWN
)));
812 EXPECT_FALSE(delegate
->IsCapsLockEnabled());
813 EXPECT_FALSE(ProcessWithContext(
814 ui::Accelerator(ui::VKEY_LWIN
, ui::EF_ALT_DOWN
)));
815 EXPECT_TRUE(ProcessWithContext(
816 ReleaseAccelerator(ui::VKEY_LWIN
, ui::EF_ALT_DOWN
)));
817 EXPECT_TRUE(delegate
->IsCapsLockEnabled());
819 const ui::Accelerator
volume_mute(ui::VKEY_VOLUME_MUTE
, ui::EF_NONE
);
820 const ui::Accelerator
volume_down(ui::VKEY_VOLUME_DOWN
, ui::EF_NONE
);
821 const ui::Accelerator
volume_up(ui::VKEY_VOLUME_UP
, ui::EF_NONE
);
823 DummyVolumeControlDelegate
* delegate
=
824 new DummyVolumeControlDelegate(false);
825 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
826 scoped_ptr
<VolumeControlDelegate
>(delegate
).Pass());
827 EXPECT_EQ(0, delegate
->handle_volume_mute_count());
828 EXPECT_FALSE(ProcessWithContext(volume_mute
));
829 EXPECT_EQ(1, delegate
->handle_volume_mute_count());
830 EXPECT_EQ(volume_mute
, delegate
->last_accelerator());
831 EXPECT_EQ(0, delegate
->handle_volume_down_count());
832 EXPECT_FALSE(ProcessWithContext(volume_down
));
833 EXPECT_EQ(1, delegate
->handle_volume_down_count());
834 EXPECT_EQ(volume_down
, delegate
->last_accelerator());
835 EXPECT_EQ(0, delegate
->handle_volume_up_count());
836 EXPECT_FALSE(ProcessWithContext(volume_up
));
837 EXPECT_EQ(1, delegate
->handle_volume_up_count());
838 EXPECT_EQ(volume_up
, delegate
->last_accelerator());
841 DummyVolumeControlDelegate
* delegate
= new DummyVolumeControlDelegate(true);
842 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
843 scoped_ptr
<VolumeControlDelegate
>(delegate
).Pass());
844 EXPECT_EQ(0, delegate
->handle_volume_mute_count());
845 EXPECT_TRUE(ProcessWithContext(volume_mute
));
846 EXPECT_EQ(1, delegate
->handle_volume_mute_count());
847 EXPECT_EQ(volume_mute
, delegate
->last_accelerator());
848 EXPECT_EQ(0, delegate
->handle_volume_down_count());
849 EXPECT_TRUE(ProcessWithContext(volume_down
));
850 EXPECT_EQ(1, delegate
->handle_volume_down_count());
851 EXPECT_EQ(volume_down
, delegate
->last_accelerator());
852 EXPECT_EQ(0, delegate
->handle_volume_up_count());
853 EXPECT_TRUE(ProcessWithContext(volume_up
));
854 EXPECT_EQ(1, delegate
->handle_volume_up_count());
855 EXPECT_EQ(volume_up
, delegate
->last_accelerator());
857 #if defined(OS_CHROMEOS)
859 // ui::VKEY_BRIGHTNESS_DOWN/UP are not defined on Windows.
860 const ui::Accelerator
brightness_down(ui::VKEY_BRIGHTNESS_DOWN
, ui::EF_NONE
);
861 const ui::Accelerator
brightness_up(ui::VKEY_BRIGHTNESS_UP
, ui::EF_NONE
);
863 EXPECT_FALSE(ProcessWithContext(brightness_down
));
864 EXPECT_FALSE(ProcessWithContext(brightness_up
));
865 DummyBrightnessControlDelegate
* delegate
=
866 new DummyBrightnessControlDelegate(true);
867 GetController()->SetBrightnessControlDelegate(
868 scoped_ptr
<BrightnessControlDelegate
>(delegate
).Pass());
869 EXPECT_FALSE(ProcessWithContext(brightness_down
));
870 EXPECT_FALSE(ProcessWithContext(brightness_up
));
872 // Enable internal display.
873 EnableInternalDisplay();
875 DummyBrightnessControlDelegate
* delegate
=
876 new DummyBrightnessControlDelegate(false);
877 GetController()->SetBrightnessControlDelegate(
878 scoped_ptr
<BrightnessControlDelegate
>(delegate
).Pass());
879 EXPECT_EQ(0, delegate
->handle_brightness_down_count());
880 EXPECT_FALSE(ProcessWithContext(brightness_down
));
881 EXPECT_EQ(1, delegate
->handle_brightness_down_count());
882 EXPECT_EQ(brightness_down
, delegate
->last_accelerator());
883 EXPECT_EQ(0, delegate
->handle_brightness_up_count());
884 EXPECT_FALSE(ProcessWithContext(brightness_up
));
885 EXPECT_EQ(1, delegate
->handle_brightness_up_count());
886 EXPECT_EQ(brightness_up
, delegate
->last_accelerator());
889 DummyBrightnessControlDelegate
* delegate
=
890 new DummyBrightnessControlDelegate(true);
891 GetController()->SetBrightnessControlDelegate(
892 scoped_ptr
<BrightnessControlDelegate
>(delegate
).Pass());
893 EXPECT_EQ(0, delegate
->handle_brightness_down_count());
894 EXPECT_TRUE(ProcessWithContext(brightness_down
));
895 EXPECT_EQ(1, delegate
->handle_brightness_down_count());
896 EXPECT_EQ(brightness_down
, delegate
->last_accelerator());
897 EXPECT_EQ(0, delegate
->handle_brightness_up_count());
898 EXPECT_TRUE(ProcessWithContext(brightness_up
));
899 EXPECT_EQ(1, delegate
->handle_brightness_up_count());
900 EXPECT_EQ(brightness_up
, delegate
->last_accelerator());
903 // Keyboard brightness
904 const ui::Accelerator
alt_brightness_down(ui::VKEY_BRIGHTNESS_DOWN
,
906 const ui::Accelerator
alt_brightness_up(ui::VKEY_BRIGHTNESS_UP
,
909 EXPECT_TRUE(ProcessWithContext(alt_brightness_down
));
910 EXPECT_TRUE(ProcessWithContext(alt_brightness_up
));
911 DummyKeyboardBrightnessControlDelegate
* delegate
=
912 new DummyKeyboardBrightnessControlDelegate(false);
913 GetController()->SetKeyboardBrightnessControlDelegate(
914 scoped_ptr
<KeyboardBrightnessControlDelegate
>(delegate
).Pass());
915 EXPECT_EQ(0, delegate
->handle_keyboard_brightness_down_count());
916 EXPECT_FALSE(ProcessWithContext(alt_brightness_down
));
917 EXPECT_EQ(1, delegate
->handle_keyboard_brightness_down_count());
918 EXPECT_EQ(alt_brightness_down
, delegate
->last_accelerator());
919 EXPECT_EQ(0, delegate
->handle_keyboard_brightness_up_count());
920 EXPECT_FALSE(ProcessWithContext(alt_brightness_up
));
921 EXPECT_EQ(1, delegate
->handle_keyboard_brightness_up_count());
922 EXPECT_EQ(alt_brightness_up
, delegate
->last_accelerator());
925 DummyKeyboardBrightnessControlDelegate
* delegate
=
926 new DummyKeyboardBrightnessControlDelegate(true);
927 GetController()->SetKeyboardBrightnessControlDelegate(
928 scoped_ptr
<KeyboardBrightnessControlDelegate
>(delegate
).Pass());
929 EXPECT_EQ(0, delegate
->handle_keyboard_brightness_down_count());
930 EXPECT_TRUE(ProcessWithContext(alt_brightness_down
));
931 EXPECT_EQ(1, delegate
->handle_keyboard_brightness_down_count());
932 EXPECT_EQ(alt_brightness_down
, delegate
->last_accelerator());
933 EXPECT_EQ(0, delegate
->handle_keyboard_brightness_up_count());
934 EXPECT_TRUE(ProcessWithContext(alt_brightness_up
));
935 EXPECT_EQ(1, delegate
->handle_keyboard_brightness_up_count());
936 EXPECT_EQ(alt_brightness_up
, delegate
->last_accelerator());
941 // ToggleDesktopBackgroundMode
942 EXPECT_TRUE(ProcessWithContext(
943 ui::Accelerator(ui::VKEY_B
, ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
)));
944 #if !defined(OS_LINUX)
945 // ToggleDesktopFullScreen (not implemented yet on Linux)
946 EXPECT_TRUE(ProcessWithContext(
947 ui::Accelerator(ui::VKEY_F11
, ui::EF_CONTROL_DOWN
)));
953 ExitWarningHandler
* ewh
= GetController()->GetExitWarningHandlerForTest();
956 EXPECT_TRUE(is_idle(ewh
));
957 EXPECT_FALSE(is_ui_shown(ewh
));
958 EXPECT_TRUE(ProcessWithContext(
959 ui::Accelerator(ui::VKEY_Q
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
)));
960 EXPECT_FALSE(is_idle(ewh
));
961 EXPECT_TRUE(is_ui_shown(ewh
));
962 SimulateTimerExpired(ewh
);
963 EXPECT_TRUE(is_idle(ewh
));
964 EXPECT_FALSE(is_ui_shown(ewh
));
969 EXPECT_TRUE(ProcessWithContext(
970 ui::Accelerator(ui::VKEY_T
, ui::EF_CONTROL_DOWN
)));
972 // New incognito window
973 EXPECT_TRUE(ProcessWithContext(
974 ui::Accelerator(ui::VKEY_N
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
)));
977 EXPECT_TRUE(ProcessWithContext(
978 ui::Accelerator(ui::VKEY_N
, ui::EF_CONTROL_DOWN
)));
981 EXPECT_TRUE(ProcessWithContext(
982 ui::Accelerator(ui::VKEY_T
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
)));
985 EXPECT_TRUE(ProcessWithContext(
986 ui::Accelerator(ui::VKEY_ESCAPE
, ui::EF_SHIFT_DOWN
)));
988 #if defined(OS_CHROMEOS)
990 EXPECT_TRUE(ProcessWithContext(
991 ui::Accelerator(ui::VKEY_M
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
)));
994 // NOTE: Accelerators that do not work on the lock screen need to be
995 // tested before the sequence below is invoked because it causes a side
996 // effect of locking the screen.
997 EXPECT_TRUE(ProcessWithContext(
998 ui::Accelerator(ui::VKEY_L
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
)));
1002 TEST_F(AcceleratorControllerTest
, GlobalAcceleratorsToggleAppList
) {
1003 AccessibilityDelegate
* delegate
=
1004 ash::Shell::GetInstance()->accessibility_delegate();
1005 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
1007 // The press event should not open the AppList, the release should instead.
1008 EXPECT_FALSE(ProcessWithContext(
1009 ui::Accelerator(ui::VKEY_LWIN
, ui::EF_NONE
)));
1010 EXPECT_TRUE(ProcessWithContext(
1011 ReleaseAccelerator(ui::VKEY_LWIN
, ui::EF_NONE
)));
1012 EXPECT_TRUE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
1014 // When spoken feedback is on, the AppList should not toggle.
1015 delegate
->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE
);
1016 EXPECT_FALSE(ProcessWithContext(
1017 ui::Accelerator(ui::VKEY_LWIN
, ui::EF_NONE
)));
1018 EXPECT_FALSE(ProcessWithContext(
1019 ReleaseAccelerator(ui::VKEY_LWIN
, ui::EF_NONE
)));
1020 delegate
->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE
);
1021 EXPECT_TRUE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
1023 EXPECT_FALSE(ProcessWithContext(
1024 ui::Accelerator(ui::VKEY_LWIN
, ui::EF_NONE
)));
1025 EXPECT_TRUE(ProcessWithContext(
1026 ReleaseAccelerator(ui::VKEY_LWIN
, ui::EF_NONE
)));
1027 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
1029 // When spoken feedback is on, the AppList should not toggle.
1030 delegate
->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE
);
1031 EXPECT_FALSE(ProcessWithContext(
1032 ui::Accelerator(ui::VKEY_LWIN
, ui::EF_NONE
)));
1033 EXPECT_FALSE(ProcessWithContext(
1034 ReleaseAccelerator(ui::VKEY_LWIN
, ui::EF_NONE
)));
1035 delegate
->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE
);
1036 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
1039 TEST_F(AcceleratorControllerTest
, ImeGlobalAccelerators
) {
1040 // Test IME shortcuts.
1042 const ui::Accelerator
control_space(ui::VKEY_SPACE
, ui::EF_CONTROL_DOWN
);
1043 const ui::Accelerator
convert(ui::VKEY_CONVERT
, ui::EF_NONE
);
1044 const ui::Accelerator
non_convert(ui::VKEY_NONCONVERT
, ui::EF_NONE
);
1045 const ui::Accelerator
wide_half_1(ui::VKEY_DBE_SBCSCHAR
, ui::EF_NONE
);
1046 const ui::Accelerator
wide_half_2(ui::VKEY_DBE_DBCSCHAR
, ui::EF_NONE
);
1047 const ui::Accelerator
hangul(ui::VKEY_HANGUL
, ui::EF_NONE
);
1048 EXPECT_FALSE(ProcessWithContext(control_space
));
1049 EXPECT_FALSE(ProcessWithContext(convert
));
1050 EXPECT_FALSE(ProcessWithContext(non_convert
));
1051 EXPECT_FALSE(ProcessWithContext(wide_half_1
));
1052 EXPECT_FALSE(ProcessWithContext(wide_half_2
));
1053 EXPECT_FALSE(ProcessWithContext(hangul
));
1054 DummyImeControlDelegate
* delegate
= new DummyImeControlDelegate(true);
1055 GetController()->SetImeControlDelegate(
1056 scoped_ptr
<ImeControlDelegate
>(delegate
).Pass());
1057 EXPECT_EQ(0, delegate
->handle_previous_ime_count());
1058 EXPECT_TRUE(ProcessWithContext(control_space
));
1059 EXPECT_EQ(1, delegate
->handle_previous_ime_count());
1060 EXPECT_EQ(0, delegate
->handle_switch_ime_count());
1061 EXPECT_TRUE(ProcessWithContext(convert
));
1062 EXPECT_EQ(1, delegate
->handle_switch_ime_count());
1063 EXPECT_TRUE(ProcessWithContext(non_convert
));
1064 EXPECT_EQ(2, delegate
->handle_switch_ime_count());
1065 EXPECT_TRUE(ProcessWithContext(wide_half_1
));
1066 EXPECT_EQ(3, delegate
->handle_switch_ime_count());
1067 EXPECT_TRUE(ProcessWithContext(wide_half_2
));
1068 EXPECT_EQ(4, delegate
->handle_switch_ime_count());
1069 EXPECT_TRUE(ProcessWithContext(hangul
));
1070 EXPECT_EQ(5, delegate
->handle_switch_ime_count());
1073 // Test IME shortcuts that are triggered on key release.
1075 const ui::Accelerator
shift_alt_press(ui::VKEY_MENU
,
1076 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
1077 const ReleaseAccelerator
shift_alt(ui::VKEY_MENU
, ui::EF_SHIFT_DOWN
);
1078 const ui::Accelerator
alt_shift_press(ui::VKEY_SHIFT
,
1079 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
1080 const ReleaseAccelerator
alt_shift(ui::VKEY_SHIFT
, ui::EF_ALT_DOWN
);
1082 DummyImeControlDelegate
* delegate
= new DummyImeControlDelegate(true);
1083 GetController()->SetImeControlDelegate(
1084 scoped_ptr
<ImeControlDelegate
>(delegate
).Pass());
1085 EXPECT_EQ(0, delegate
->handle_next_ime_count());
1086 EXPECT_FALSE(ProcessWithContext(shift_alt_press
));
1087 EXPECT_TRUE(ProcessWithContext(shift_alt
));
1088 EXPECT_EQ(1, delegate
->handle_next_ime_count());
1089 EXPECT_FALSE(ProcessWithContext(alt_shift_press
));
1090 EXPECT_TRUE(ProcessWithContext(alt_shift
));
1091 EXPECT_EQ(2, delegate
->handle_next_ime_count());
1093 // We should NOT switch IME when e.g. Shift+Alt+X is pressed and X is
1095 const ui::Accelerator
shift_alt_x_press(
1097 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
1098 const ReleaseAccelerator
shift_alt_x(ui::VKEY_X
,
1099 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
1101 EXPECT_FALSE(ProcessWithContext(shift_alt_press
));
1102 EXPECT_FALSE(ProcessWithContext(shift_alt_x_press
));
1103 EXPECT_FALSE(ProcessWithContext(shift_alt_x
));
1104 EXPECT_FALSE(ProcessWithContext(shift_alt
));
1105 EXPECT_EQ(2, delegate
->handle_next_ime_count());
1107 // But we _should_ if X is either VKEY_RETURN or VKEY_SPACE.
1108 // TODO(nona|mazda): Remove this when crbug.com/139556 in a better way.
1109 const ui::Accelerator
shift_alt_return_press(
1111 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
1112 const ReleaseAccelerator
shift_alt_return(
1114 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
1116 EXPECT_FALSE(ProcessWithContext(shift_alt_press
));
1117 EXPECT_FALSE(ProcessWithContext(shift_alt_return_press
));
1118 EXPECT_FALSE(ProcessWithContext(shift_alt_return
));
1119 EXPECT_TRUE(ProcessWithContext(shift_alt
));
1120 EXPECT_EQ(3, delegate
->handle_next_ime_count());
1122 const ui::Accelerator
shift_alt_space_press(
1124 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
1125 const ReleaseAccelerator
shift_alt_space(
1127 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
1129 EXPECT_FALSE(ProcessWithContext(shift_alt_press
));
1130 EXPECT_FALSE(ProcessWithContext(shift_alt_space_press
));
1131 EXPECT_FALSE(ProcessWithContext(shift_alt_space
));
1132 EXPECT_TRUE(ProcessWithContext(shift_alt
));
1133 EXPECT_EQ(4, delegate
->handle_next_ime_count());
1136 #if defined(OS_CHROMEOS)
1137 // Test IME shortcuts again with unnormalized accelerators (Chrome OS only).
1139 const ui::Accelerator
shift_alt_press(ui::VKEY_MENU
, ui::EF_SHIFT_DOWN
);
1140 const ReleaseAccelerator
shift_alt(ui::VKEY_MENU
, ui::EF_SHIFT_DOWN
);
1141 const ui::Accelerator
alt_shift_press(ui::VKEY_SHIFT
, ui::EF_ALT_DOWN
);
1142 const ReleaseAccelerator
alt_shift(ui::VKEY_SHIFT
, ui::EF_ALT_DOWN
);
1144 DummyImeControlDelegate
* delegate
= new DummyImeControlDelegate(true);
1145 GetController()->SetImeControlDelegate(
1146 scoped_ptr
<ImeControlDelegate
>(delegate
).Pass());
1147 EXPECT_EQ(0, delegate
->handle_next_ime_count());
1148 EXPECT_FALSE(ProcessWithContext(shift_alt_press
));
1149 EXPECT_TRUE(ProcessWithContext(shift_alt
));
1150 EXPECT_EQ(1, delegate
->handle_next_ime_count());
1151 EXPECT_FALSE(ProcessWithContext(alt_shift_press
));
1152 EXPECT_TRUE(ProcessWithContext(alt_shift
));
1153 EXPECT_EQ(2, delegate
->handle_next_ime_count());
1155 // We should NOT switch IME when e.g. Shift+Alt+X is pressed and X is
1157 const ui::Accelerator
shift_alt_x_press(
1159 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
1160 const ReleaseAccelerator
shift_alt_x(ui::VKEY_X
,
1161 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
1163 EXPECT_FALSE(ProcessWithContext(shift_alt_press
));
1164 EXPECT_FALSE(ProcessWithContext(shift_alt_x_press
));
1165 EXPECT_FALSE(ProcessWithContext(shift_alt_x
));
1166 EXPECT_FALSE(ProcessWithContext(shift_alt
));
1167 EXPECT_EQ(2, delegate
->handle_next_ime_count());
1172 // TODO(nona|mazda): Remove this when crbug.com/139556 in a better way.
1173 TEST_F(AcceleratorControllerTest
, ImeGlobalAcceleratorsWorkaround139556
) {
1174 // The workaround for crbug.com/139556 depends on the fact that we don't
1175 // use Shift+Alt+Enter/Space with ET_KEY_PRESSED as an accelerator. Test it.
1176 const ui::Accelerator
shift_alt_return_press(
1178 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
1179 EXPECT_FALSE(ProcessWithContext(shift_alt_return_press
));
1180 const ui::Accelerator
shift_alt_space_press(
1182 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
1183 EXPECT_FALSE(ProcessWithContext(shift_alt_space_press
));
1186 TEST_F(AcceleratorControllerTest
, ReservedAccelerators
) {
1187 // (Shift+)Alt+Tab and Chrome OS top-row keys are reserved.
1188 EXPECT_TRUE(GetController()->IsReservedAccelerator(
1189 ui::Accelerator(ui::VKEY_TAB
, ui::EF_ALT_DOWN
)));
1190 EXPECT_TRUE(GetController()->IsReservedAccelerator(
1191 ui::Accelerator(ui::VKEY_TAB
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
)));
1192 #if defined(OS_CHROMEOS)
1193 EXPECT_TRUE(GetController()->IsReservedAccelerator(
1194 ui::Accelerator(ui::VKEY_POWER
, ui::EF_NONE
)));
1196 // Others are not reserved.
1197 EXPECT_FALSE(GetController()->IsReservedAccelerator(
1198 ui::Accelerator(ui::VKEY_PRINT
, ui::EF_NONE
)));
1199 EXPECT_FALSE(GetController()->IsReservedAccelerator(
1200 ui::Accelerator(ui::VKEY_TAB
, ui::EF_NONE
)));
1201 EXPECT_FALSE(GetController()->IsReservedAccelerator(
1202 ui::Accelerator(ui::VKEY_A
, ui::EF_NONE
)));
1205 #if defined(OS_CHROMEOS)
1206 TEST_F(AcceleratorControllerTest
, DisallowedAtModalWindow
) {
1207 std::set
<AcceleratorAction
> all_actions
;
1208 for (size_t i
= 0 ; i
< kAcceleratorDataLength
; ++i
)
1209 all_actions
.insert(kAcceleratorData
[i
].action
);
1210 #if !defined(NDEBUG)
1211 std::set
<AcceleratorAction
> all_desktop_actions
;
1212 for (size_t i
= 0 ; i
< kDesktopAcceleratorDataLength
; ++i
)
1213 all_desktop_actions
.insert(kDesktopAcceleratorData
[i
].action
);
1216 std::set
<AcceleratorAction
> actionsAllowedAtModalWindow
;
1217 for (size_t k
= 0 ; k
< kActionsAllowedAtModalWindowLength
; ++k
)
1218 actionsAllowedAtModalWindow
.insert(kActionsAllowedAtModalWindow
[k
]);
1219 for (std::set
<AcceleratorAction
>::const_iterator it
=
1220 actionsAllowedAtModalWindow
.begin();
1221 it
!= actionsAllowedAtModalWindow
.end(); ++it
) {
1222 EXPECT_TRUE(all_actions
.find(*it
) != all_actions
.end()
1224 #if !defined(NDEBUG)
1225 || all_desktop_actions
.find(*it
) != all_desktop_actions
.end()
1228 << " action from kActionsAllowedAtModalWindow"
1229 << " not found in kAcceleratorData or kDesktopAcceleratorData. "
1230 << "action: " << *it
;
1232 scoped_ptr
<aura::Window
> window(
1233 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
1234 const ui::Accelerator dummy
;
1235 wm::ActivateWindow(window
.get());
1236 Shell::GetInstance()->SimulateModalWindowOpenForTesting(true);
1237 for (std::set
<AcceleratorAction
>::const_iterator it
= all_actions
.begin();
1238 it
!= all_actions
.end(); ++it
) {
1239 if (actionsAllowedAtModalWindow
.find(*it
) ==
1240 actionsAllowedAtModalWindow
.end()) {
1241 EXPECT_TRUE(GetController()->PerformAction(*it
, dummy
))
1242 << " for action (disallowed at modal window): " << *it
;
1245 // Testing of top row (F5-F10) accelerators that should still work
1246 // when a modal window is open
1250 test::TestScreenshotDelegate
* delegate
= GetScreenshotDelegate();
1251 delegate
->set_can_take_screenshot(false);
1252 EXPECT_TRUE(ProcessWithContext(
1253 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_CONTROL_DOWN
)));
1254 EXPECT_TRUE(ProcessWithContext(
1255 ui::Accelerator(ui::VKEY_PRINT
, ui::EF_NONE
)));
1256 EXPECT_TRUE(ProcessWithContext(
1257 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1
,
1258 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
)));
1259 delegate
->set_can_take_screenshot(true);
1260 EXPECT_EQ(0, delegate
->handle_take_screenshot_count());
1261 EXPECT_TRUE(ProcessWithContext(
1262 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_CONTROL_DOWN
)));
1263 EXPECT_EQ(1, delegate
->handle_take_screenshot_count());
1264 EXPECT_TRUE(ProcessWithContext(
1265 ui::Accelerator(ui::VKEY_PRINT
, ui::EF_NONE
)));
1266 EXPECT_EQ(2, delegate
->handle_take_screenshot_count());
1267 EXPECT_TRUE(ProcessWithContext(
1268 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1
,
1269 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
)));
1270 EXPECT_EQ(2, delegate
->handle_take_screenshot_count());
1273 const ui::Accelerator
brightness_down(ui::VKEY_BRIGHTNESS_DOWN
, ui::EF_NONE
);
1274 const ui::Accelerator
brightness_up(ui::VKEY_BRIGHTNESS_UP
, ui::EF_NONE
);
1276 EXPECT_FALSE(ProcessWithContext(brightness_down
));
1277 EXPECT_FALSE(ProcessWithContext(brightness_up
));
1278 DummyBrightnessControlDelegate
* delegate
=
1279 new DummyBrightnessControlDelegate(true);
1280 GetController()->SetBrightnessControlDelegate(
1281 scoped_ptr
<BrightnessControlDelegate
>(delegate
).Pass());
1282 EXPECT_FALSE(ProcessWithContext(brightness_down
));
1283 EXPECT_FALSE(ProcessWithContext(brightness_up
));
1285 EnableInternalDisplay();
1287 EXPECT_FALSE(ProcessWithContext(brightness_down
));
1288 EXPECT_FALSE(ProcessWithContext(brightness_up
));
1289 DummyBrightnessControlDelegate
* delegate
=
1290 new DummyBrightnessControlDelegate(false);
1291 GetController()->SetBrightnessControlDelegate(
1292 scoped_ptr
<BrightnessControlDelegate
>(delegate
).Pass());
1293 EXPECT_EQ(0, delegate
->handle_brightness_down_count());
1294 EXPECT_FALSE(ProcessWithContext(brightness_down
));
1295 EXPECT_EQ(1, delegate
->handle_brightness_down_count());
1296 EXPECT_EQ(brightness_down
, delegate
->last_accelerator());
1297 EXPECT_EQ(0, delegate
->handle_brightness_up_count());
1298 EXPECT_FALSE(ProcessWithContext(brightness_up
));
1299 EXPECT_EQ(1, delegate
->handle_brightness_up_count());
1300 EXPECT_EQ(brightness_up
, delegate
->last_accelerator());
1303 DummyBrightnessControlDelegate
* delegate
=
1304 new DummyBrightnessControlDelegate(true);
1305 GetController()->SetBrightnessControlDelegate(
1306 scoped_ptr
<BrightnessControlDelegate
>(delegate
).Pass());
1307 EXPECT_EQ(0, delegate
->handle_brightness_down_count());
1308 EXPECT_TRUE(ProcessWithContext(brightness_down
));
1309 EXPECT_EQ(1, delegate
->handle_brightness_down_count());
1310 EXPECT_EQ(brightness_down
, delegate
->last_accelerator());
1311 EXPECT_EQ(0, delegate
->handle_brightness_up_count());
1312 EXPECT_TRUE(ProcessWithContext(brightness_up
));
1313 EXPECT_EQ(1, delegate
->handle_brightness_up_count());
1314 EXPECT_EQ(brightness_up
, delegate
->last_accelerator());
1317 const ui::Accelerator
volume_mute(ui::VKEY_VOLUME_MUTE
, ui::EF_NONE
);
1318 const ui::Accelerator
volume_down(ui::VKEY_VOLUME_DOWN
, ui::EF_NONE
);
1319 const ui::Accelerator
volume_up(ui::VKEY_VOLUME_UP
, ui::EF_NONE
);
1321 EXPECT_TRUE(ProcessWithContext(volume_mute
));
1322 EXPECT_TRUE(ProcessWithContext(volume_down
));
1323 EXPECT_TRUE(ProcessWithContext(volume_up
));
1324 DummyVolumeControlDelegate
* delegate
=
1325 new DummyVolumeControlDelegate(false);
1326 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
1327 scoped_ptr
<VolumeControlDelegate
>(delegate
).Pass());
1328 EXPECT_EQ(0, delegate
->handle_volume_mute_count());
1329 EXPECT_FALSE(ProcessWithContext(volume_mute
));
1330 EXPECT_EQ(1, delegate
->handle_volume_mute_count());
1331 EXPECT_EQ(volume_mute
, delegate
->last_accelerator());
1332 EXPECT_EQ(0, delegate
->handle_volume_down_count());
1333 EXPECT_FALSE(ProcessWithContext(volume_down
));
1334 EXPECT_EQ(1, delegate
->handle_volume_down_count());
1335 EXPECT_EQ(volume_down
, delegate
->last_accelerator());
1336 EXPECT_EQ(0, delegate
->handle_volume_up_count());
1337 EXPECT_FALSE(ProcessWithContext(volume_up
));
1338 EXPECT_EQ(1, delegate
->handle_volume_up_count());
1339 EXPECT_EQ(volume_up
, delegate
->last_accelerator());
1342 DummyVolumeControlDelegate
* delegate
= new DummyVolumeControlDelegate(true);
1343 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
1344 scoped_ptr
<VolumeControlDelegate
>(delegate
).Pass());
1345 EXPECT_EQ(0, delegate
->handle_volume_mute_count());
1346 EXPECT_TRUE(ProcessWithContext(volume_mute
));
1347 EXPECT_EQ(1, delegate
->handle_volume_mute_count());
1348 EXPECT_EQ(volume_mute
, delegate
->last_accelerator());
1349 EXPECT_EQ(0, delegate
->handle_volume_down_count());
1350 EXPECT_TRUE(ProcessWithContext(volume_down
));
1351 EXPECT_EQ(1, delegate
->handle_volume_down_count());
1352 EXPECT_EQ(volume_down
, delegate
->last_accelerator());
1353 EXPECT_EQ(0, delegate
->handle_volume_up_count());
1354 EXPECT_TRUE(ProcessWithContext(volume_up
));
1355 EXPECT_EQ(1, delegate
->handle_volume_up_count());
1356 EXPECT_EQ(volume_up
, delegate
->last_accelerator());
1361 TEST_F(AcceleratorControllerTest
, DisallowedWithNoWindow
) {
1362 const ui::Accelerator dummy
;
1363 AccessibilityDelegate
* delegate
=
1364 ash::Shell::GetInstance()->accessibility_delegate();
1366 for (size_t i
= 0; i
< kActionsNeedingWindowLength
; ++i
) {
1367 delegate
->TriggerAccessibilityAlert(A11Y_ALERT_NONE
);
1369 GetController()->PerformAction(kActionsNeedingWindow
[i
], dummy
));
1370 EXPECT_EQ(delegate
->GetLastAccessibilityAlert(), A11Y_ALERT_WINDOW_NEEDED
);
1373 // Make sure we don't alert if we do have a window.
1374 scoped_ptr
<aura::Window
> window(
1375 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
1376 wm::ActivateWindow(window
.get());
1377 for (size_t i
= 0; i
< kActionsNeedingWindowLength
; ++i
) {
1378 delegate
->TriggerAccessibilityAlert(A11Y_ALERT_NONE
);
1379 GetController()->PerformAction(kActionsNeedingWindow
[i
], dummy
);
1380 EXPECT_EQ(delegate
->GetLastAccessibilityAlert(), A11Y_ALERT_NONE
);
1383 // Don't alert if we have a minimized window either.
1384 GetController()->PerformAction(WINDOW_MINIMIZE
, dummy
);
1385 for (size_t i
= 0; i
< kActionsNeedingWindowLength
; ++i
) {
1386 delegate
->TriggerAccessibilityAlert(A11Y_ALERT_NONE
);
1387 GetController()->PerformAction(kActionsNeedingWindow
[i
], dummy
);
1388 EXPECT_EQ(delegate
->GetLastAccessibilityAlert(), A11Y_ALERT_NONE
);