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/display/display_manager.h"
10 #include "ash/ime_control_delegate.h"
11 #include "ash/screen_util.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/test/test_window_delegate.h"
26 #include "ui/aura/test/test_windows.h"
27 #include "ui/aura/window.h"
28 #include "ui/events/event.h"
29 #include "ui/events/event_processor.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 scoped_ptr
<aura::Window
> window(
473 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
474 const ui::Accelerator dummy
;
476 wm::WindowState
* window_state
= wm::GetWindowState(window
.get());
478 window_state
->Activate();
481 GetController()->PerformAction(WINDOW_SNAP_LEFT
, dummy
);
482 gfx::Rect expected_bounds
= wm::GetDefaultLeftSnappedWindowBoundsInParent(
484 EXPECT_EQ(expected_bounds
.ToString(), window
->bounds().ToString());
487 GetController()->PerformAction(WINDOW_SNAP_RIGHT
, dummy
);
488 gfx::Rect expected_bounds
= wm::GetDefaultRightSnappedWindowBoundsInParent(
490 EXPECT_EQ(expected_bounds
.ToString(), window
->bounds().ToString());
493 gfx::Rect normal_bounds
= window_state
->GetRestoreBoundsInParent();
495 GetController()->PerformAction(TOGGLE_MAXIMIZED
, dummy
);
496 EXPECT_TRUE(window_state
->IsMaximized());
497 EXPECT_NE(normal_bounds
.ToString(), window
->bounds().ToString());
499 GetController()->PerformAction(TOGGLE_MAXIMIZED
, dummy
);
500 EXPECT_FALSE(window_state
->IsMaximized());
501 // Window gets restored to its restore bounds since side-maximized state
502 // is treated as a "maximized" state.
503 EXPECT_EQ(normal_bounds
.ToString(), window
->bounds().ToString());
505 GetController()->PerformAction(TOGGLE_MAXIMIZED
, dummy
);
506 GetController()->PerformAction(WINDOW_SNAP_LEFT
, dummy
);
507 EXPECT_FALSE(window_state
->IsMaximized());
509 GetController()->PerformAction(TOGGLE_MAXIMIZED
, dummy
);
510 GetController()->PerformAction(WINDOW_SNAP_RIGHT
, dummy
);
511 EXPECT_FALSE(window_state
->IsMaximized());
513 GetController()->PerformAction(TOGGLE_MAXIMIZED
, dummy
);
514 EXPECT_TRUE(window_state
->IsMaximized());
515 GetController()->PerformAction(WINDOW_MINIMIZE
, dummy
);
516 EXPECT_FALSE(window_state
->IsMaximized());
517 EXPECT_TRUE(window_state
->IsMinimized());
518 window_state
->Restore();
519 window_state
->Activate();
522 GetController()->PerformAction(WINDOW_MINIMIZE
, dummy
);
523 EXPECT_TRUE(window_state
->IsMinimized());
527 TEST_F(AcceleratorControllerTest
, CenterWindowAccelerator
) {
528 scoped_ptr
<aura::Window
> window(
529 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
530 const ui::Accelerator dummy
;
531 wm::WindowState
* window_state
= wm::GetWindowState(window
.get());
532 window_state
->Activate();
534 // Center the window using accelerator.
535 GetController()->PerformAction(WINDOW_POSITION_CENTER
, dummy
);
536 gfx::Rect work_area
=
537 Shell::GetScreen()->GetDisplayNearestWindow(window
.get()).work_area();
538 gfx::Rect bounds
= window
->GetBoundsInScreen();
539 EXPECT_NEAR(bounds
.x() - work_area
.x(),
540 work_area
.right() - bounds
.right(),
542 EXPECT_NEAR(bounds
.y() - work_area
.y(),
543 work_area
.bottom() - bounds
.bottom(),
546 // Add the window to docked container and try to center it.
547 window
->SetBounds(gfx::Rect(0, 0, 20, 20));
548 aura::Window
* docked_container
= Shell::GetContainer(
549 window
->GetRootWindow(), kShellWindowId_DockedContainer
);
550 docked_container
->AddChild(window
.get());
551 gfx::Rect docked_bounds
= window
->GetBoundsInScreen();
552 GetController()->PerformAction(WINDOW_POSITION_CENTER
, dummy
);
553 // It should not get centered and should remain docked.
554 EXPECT_EQ(kShellWindowId_DockedContainer
, window
->parent()->id());
555 EXPECT_EQ(docked_bounds
.ToString(), window
->GetBoundsInScreen().ToString());
558 TEST_F(AcceleratorControllerTest
, ControllerContext
) {
559 ui::Accelerator
accelerator_a(ui::VKEY_A
, ui::EF_NONE
);
560 ui::Accelerator
accelerator_a2(ui::VKEY_A
, ui::EF_NONE
);
561 ui::Accelerator
accelerator_b(ui::VKEY_B
, ui::EF_NONE
);
563 accelerator_a
.set_type(ui::ET_KEY_PRESSED
);
564 accelerator_a2
.set_type(ui::ET_KEY_RELEASED
);
565 accelerator_b
.set_type(ui::ET_KEY_PRESSED
);
567 EXPECT_FALSE(GetController()->context()->repeated());
568 EXPECT_EQ(ui::ET_UNKNOWN
,
569 GetController()->context()->previous_accelerator().type());
571 GetController()->context()->UpdateContext(accelerator_a
);
572 EXPECT_FALSE(GetController()->context()->repeated());
573 EXPECT_EQ(ui::ET_UNKNOWN
,
574 GetController()->context()->previous_accelerator().type());
576 GetController()->context()->UpdateContext(accelerator_a2
);
577 EXPECT_FALSE(GetController()->context()->repeated());
578 EXPECT_EQ(ui::ET_KEY_PRESSED
,
579 GetController()->context()->previous_accelerator().type());
581 GetController()->context()->UpdateContext(accelerator_a2
);
582 EXPECT_TRUE(GetController()->context()->repeated());
583 EXPECT_EQ(ui::ET_KEY_RELEASED
,
584 GetController()->context()->previous_accelerator().type());
586 GetController()->context()->UpdateContext(accelerator_b
);
587 EXPECT_FALSE(GetController()->context()->repeated());
588 EXPECT_EQ(ui::ET_KEY_RELEASED
,
589 GetController()->context()->previous_accelerator().type());
592 #if defined(OS_WIN) && defined(USE_AURA)
594 #define MAYBE_SuppressToggleMaximized DISABLED_SuppressToggleMaximized
596 #define MAYBE_SuppressToggleMaximized SuppressToggleMaximized
599 TEST_F(AcceleratorControllerTest
, MAYBE_SuppressToggleMaximized
) {
600 scoped_ptr
<aura::Window
> window(
601 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
602 wm::ActivateWindow(window
.get());
603 const ui::Accelerator
accelerator(ui::VKEY_A
, ui::EF_NONE
);
604 const ui::Accelerator empty_accelerator
;
606 wm::WindowState
* window_state
= wm::GetWindowState(window
.get());
608 // Toggling not suppressed.
609 GetController()->context()->UpdateContext(accelerator
);
610 GetController()->PerformAction(TOGGLE_MAXIMIZED
, accelerator
);
611 EXPECT_TRUE(window_state
->IsMaximized());
613 // The same accelerator - toggling suppressed.
614 GetController()->context()->UpdateContext(accelerator
);
615 GetController()->PerformAction(TOGGLE_MAXIMIZED
, accelerator
);
616 EXPECT_TRUE(window_state
->IsMaximized());
618 // Suppressed but not for gesture events.
619 GetController()->PerformAction(TOGGLE_MAXIMIZED
, empty_accelerator
);
620 EXPECT_FALSE(window_state
->IsMaximized());
623 #if defined(OS_WIN) && defined(USE_AURA)
625 #define MAYBE_ProcessOnce DISABLED_ProcessOnce
627 #define MAYBE_ProcessOnce ProcessOnce
630 #if defined(OS_WIN) || defined(USE_X11)
631 TEST_F(AcceleratorControllerTest
, MAYBE_ProcessOnce
) {
632 ui::Accelerator
accelerator_a(ui::VKEY_A
, ui::EF_NONE
);
634 GetController()->Register(accelerator_a
, &target
);
636 // The accelerator is processed only once.
637 ui::EventProcessor
* dispatcher
=
638 Shell::GetPrimaryRootWindow()->GetHost()->event_processor();
640 MSG msg1
= { NULL
, WM_KEYDOWN
, ui::VKEY_A
, 0 };
641 ui::TranslatedKeyEvent
key_event1(msg1
, false);
642 ui::EventDispatchDetails details
= dispatcher
->OnEventFromSource(&key_event1
);
643 EXPECT_TRUE(key_event1
.handled() || details
.dispatcher_destroyed
);
645 MSG msg2
= { NULL
, WM_CHAR
, L
'A', 0 };
646 ui::TranslatedKeyEvent
key_event2(msg2
, true);
647 details
= dispatcher
->OnEventFromSource(&key_event2
);
648 EXPECT_FALSE(key_event2
.handled() || details
.dispatcher_destroyed
);
650 MSG msg3
= { NULL
, WM_KEYUP
, ui::VKEY_A
, 0 };
651 ui::TranslatedKeyEvent
key_event3(msg3
, false);
652 details
= dispatcher
->OnEventFromSource(&key_event3
);
653 EXPECT_FALSE(key_event3
.handled() || details
.dispatcher_destroyed
);
654 #elif defined(USE_X11)
655 ui::ScopedXI2Event key_event
;
656 key_event
.InitKeyEvent(ui::ET_KEY_PRESSED
, ui::VKEY_A
, 0);
657 ui::TranslatedKeyEvent
key_event1(key_event
, false);
658 ui::EventDispatchDetails details
= dispatcher
->OnEventFromSource(&key_event1
);
659 EXPECT_TRUE(key_event1
.handled() || details
.dispatcher_destroyed
);
661 ui::TranslatedKeyEvent
key_event2(key_event
, true);
662 details
= dispatcher
->OnEventFromSource(&key_event2
);
663 EXPECT_FALSE(key_event2
.handled() || details
.dispatcher_destroyed
);
665 key_event
.InitKeyEvent(ui::ET_KEY_RELEASED
, ui::VKEY_A
, 0);
666 ui::TranslatedKeyEvent
key_event3(key_event
, false);
667 details
= dispatcher
->OnEventFromSource(&key_event3
);
668 EXPECT_FALSE(key_event3
.handled() || details
.dispatcher_destroyed
);
670 EXPECT_EQ(1, target
.accelerator_pressed_count());
674 TEST_F(AcceleratorControllerTest
, GlobalAccelerators
) {
676 EXPECT_TRUE(ProcessWithContext(
677 ui::Accelerator(ui::VKEY_TAB
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
)));
679 EXPECT_TRUE(ProcessWithContext(
680 ui::Accelerator(ui::VKEY_TAB
, ui::EF_ALT_DOWN
)));
682 EXPECT_TRUE(ProcessWithContext(
683 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_NONE
)));
685 #if defined(OS_CHROMEOS)
686 // Take screenshot / partial screenshot
687 // True should always be returned regardless of the existence of the delegate.
689 test::TestScreenshotDelegate
* delegate
= GetScreenshotDelegate();
690 delegate
->set_can_take_screenshot(false);
691 EXPECT_TRUE(ProcessWithContext(
692 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_CONTROL_DOWN
)));
693 EXPECT_TRUE(ProcessWithContext(
694 ui::Accelerator(ui::VKEY_PRINT
, ui::EF_NONE
)));
695 EXPECT_TRUE(ProcessWithContext(
696 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1
,
697 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
)));
699 delegate
->set_can_take_screenshot(true);
700 EXPECT_EQ(0, delegate
->handle_take_screenshot_count());
701 EXPECT_TRUE(ProcessWithContext(
702 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_CONTROL_DOWN
)));
703 EXPECT_EQ(1, delegate
->handle_take_screenshot_count());
704 EXPECT_TRUE(ProcessWithContext(
705 ui::Accelerator(ui::VKEY_PRINT
, ui::EF_NONE
)));
706 EXPECT_EQ(2, delegate
->handle_take_screenshot_count());
707 EXPECT_TRUE(ProcessWithContext(
708 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1
,
709 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
)));
710 EXPECT_EQ(2, delegate
->handle_take_screenshot_count());
713 const ui::Accelerator
volume_mute(ui::VKEY_VOLUME_MUTE
, ui::EF_NONE
);
714 const ui::Accelerator
volume_down(ui::VKEY_VOLUME_DOWN
, ui::EF_NONE
);
715 const ui::Accelerator
volume_up(ui::VKEY_VOLUME_UP
, ui::EF_NONE
);
717 DummyVolumeControlDelegate
* delegate
=
718 new DummyVolumeControlDelegate(false);
719 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
720 scoped_ptr
<VolumeControlDelegate
>(delegate
).Pass());
721 EXPECT_EQ(0, delegate
->handle_volume_mute_count());
722 EXPECT_FALSE(ProcessWithContext(volume_mute
));
723 EXPECT_EQ(1, delegate
->handle_volume_mute_count());
724 EXPECT_EQ(volume_mute
, delegate
->last_accelerator());
725 EXPECT_EQ(0, delegate
->handle_volume_down_count());
726 EXPECT_FALSE(ProcessWithContext(volume_down
));
727 EXPECT_EQ(1, delegate
->handle_volume_down_count());
728 EXPECT_EQ(volume_down
, delegate
->last_accelerator());
729 EXPECT_EQ(0, delegate
->handle_volume_up_count());
730 EXPECT_FALSE(ProcessWithContext(volume_up
));
731 EXPECT_EQ(1, delegate
->handle_volume_up_count());
732 EXPECT_EQ(volume_up
, delegate
->last_accelerator());
735 DummyVolumeControlDelegate
* delegate
= new DummyVolumeControlDelegate(true);
736 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
737 scoped_ptr
<VolumeControlDelegate
>(delegate
).Pass());
738 EXPECT_EQ(0, delegate
->handle_volume_mute_count());
739 EXPECT_TRUE(ProcessWithContext(volume_mute
));
740 EXPECT_EQ(1, delegate
->handle_volume_mute_count());
741 EXPECT_EQ(volume_mute
, delegate
->last_accelerator());
742 EXPECT_EQ(0, delegate
->handle_volume_down_count());
743 EXPECT_TRUE(ProcessWithContext(volume_down
));
744 EXPECT_EQ(1, delegate
->handle_volume_down_count());
745 EXPECT_EQ(volume_down
, delegate
->last_accelerator());
746 EXPECT_EQ(0, delegate
->handle_volume_up_count());
747 EXPECT_TRUE(ProcessWithContext(volume_up
));
748 EXPECT_EQ(1, delegate
->handle_volume_up_count());
749 EXPECT_EQ(volume_up
, delegate
->last_accelerator());
751 #if defined(OS_CHROMEOS)
753 // ui::VKEY_BRIGHTNESS_DOWN/UP are not defined on Windows.
754 const ui::Accelerator
brightness_down(ui::VKEY_BRIGHTNESS_DOWN
, ui::EF_NONE
);
755 const ui::Accelerator
brightness_up(ui::VKEY_BRIGHTNESS_UP
, ui::EF_NONE
);
757 DummyBrightnessControlDelegate
* delegate
=
758 new DummyBrightnessControlDelegate(false);
759 GetController()->SetBrightnessControlDelegate(
760 scoped_ptr
<BrightnessControlDelegate
>(delegate
).Pass());
761 EXPECT_EQ(0, delegate
->handle_brightness_down_count());
762 EXPECT_FALSE(ProcessWithContext(brightness_down
));
763 EXPECT_EQ(1, delegate
->handle_brightness_down_count());
764 EXPECT_EQ(brightness_down
, delegate
->last_accelerator());
765 EXPECT_EQ(0, delegate
->handle_brightness_up_count());
766 EXPECT_FALSE(ProcessWithContext(brightness_up
));
767 EXPECT_EQ(1, delegate
->handle_brightness_up_count());
768 EXPECT_EQ(brightness_up
, delegate
->last_accelerator());
771 DummyBrightnessControlDelegate
* delegate
=
772 new DummyBrightnessControlDelegate(true);
773 GetController()->SetBrightnessControlDelegate(
774 scoped_ptr
<BrightnessControlDelegate
>(delegate
).Pass());
775 EXPECT_EQ(0, delegate
->handle_brightness_down_count());
776 EXPECT_TRUE(ProcessWithContext(brightness_down
));
777 EXPECT_EQ(1, delegate
->handle_brightness_down_count());
778 EXPECT_EQ(brightness_down
, delegate
->last_accelerator());
779 EXPECT_EQ(0, delegate
->handle_brightness_up_count());
780 EXPECT_TRUE(ProcessWithContext(brightness_up
));
781 EXPECT_EQ(1, delegate
->handle_brightness_up_count());
782 EXPECT_EQ(brightness_up
, delegate
->last_accelerator());
785 // Keyboard brightness
786 const ui::Accelerator
alt_brightness_down(ui::VKEY_BRIGHTNESS_DOWN
,
788 const ui::Accelerator
alt_brightness_up(ui::VKEY_BRIGHTNESS_UP
,
791 EXPECT_TRUE(ProcessWithContext(alt_brightness_down
));
792 EXPECT_TRUE(ProcessWithContext(alt_brightness_up
));
793 DummyKeyboardBrightnessControlDelegate
* delegate
=
794 new DummyKeyboardBrightnessControlDelegate(false);
795 GetController()->SetKeyboardBrightnessControlDelegate(
796 scoped_ptr
<KeyboardBrightnessControlDelegate
>(delegate
).Pass());
797 EXPECT_EQ(0, delegate
->handle_keyboard_brightness_down_count());
798 EXPECT_FALSE(ProcessWithContext(alt_brightness_down
));
799 EXPECT_EQ(1, delegate
->handle_keyboard_brightness_down_count());
800 EXPECT_EQ(alt_brightness_down
, delegate
->last_accelerator());
801 EXPECT_EQ(0, delegate
->handle_keyboard_brightness_up_count());
802 EXPECT_FALSE(ProcessWithContext(alt_brightness_up
));
803 EXPECT_EQ(1, delegate
->handle_keyboard_brightness_up_count());
804 EXPECT_EQ(alt_brightness_up
, delegate
->last_accelerator());
807 DummyKeyboardBrightnessControlDelegate
* delegate
=
808 new DummyKeyboardBrightnessControlDelegate(true);
809 GetController()->SetKeyboardBrightnessControlDelegate(
810 scoped_ptr
<KeyboardBrightnessControlDelegate
>(delegate
).Pass());
811 EXPECT_EQ(0, delegate
->handle_keyboard_brightness_down_count());
812 EXPECT_TRUE(ProcessWithContext(alt_brightness_down
));
813 EXPECT_EQ(1, delegate
->handle_keyboard_brightness_down_count());
814 EXPECT_EQ(alt_brightness_down
, delegate
->last_accelerator());
815 EXPECT_EQ(0, delegate
->handle_keyboard_brightness_up_count());
816 EXPECT_TRUE(ProcessWithContext(alt_brightness_up
));
817 EXPECT_EQ(1, delegate
->handle_keyboard_brightness_up_count());
818 EXPECT_EQ(alt_brightness_up
, delegate
->last_accelerator());
823 // ToggleDesktopBackgroundMode
824 EXPECT_TRUE(ProcessWithContext(
825 ui::Accelerator(ui::VKEY_B
, ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
)));
826 #if !defined(OS_LINUX)
827 // ToggleDesktopFullScreen (not implemented yet on Linux)
828 EXPECT_TRUE(ProcessWithContext(
829 ui::Accelerator(ui::VKEY_F11
, ui::EF_CONTROL_DOWN
)));
835 ExitWarningHandler
* ewh
= GetController()->GetExitWarningHandlerForTest();
838 EXPECT_TRUE(is_idle(ewh
));
839 EXPECT_FALSE(is_ui_shown(ewh
));
840 EXPECT_TRUE(ProcessWithContext(
841 ui::Accelerator(ui::VKEY_Q
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
)));
842 EXPECT_FALSE(is_idle(ewh
));
843 EXPECT_TRUE(is_ui_shown(ewh
));
844 SimulateTimerExpired(ewh
);
845 EXPECT_TRUE(is_idle(ewh
));
846 EXPECT_FALSE(is_ui_shown(ewh
));
851 EXPECT_TRUE(ProcessWithContext(
852 ui::Accelerator(ui::VKEY_T
, ui::EF_CONTROL_DOWN
)));
854 // New incognito window
855 EXPECT_TRUE(ProcessWithContext(
856 ui::Accelerator(ui::VKEY_N
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
)));
859 EXPECT_TRUE(ProcessWithContext(
860 ui::Accelerator(ui::VKEY_N
, ui::EF_CONTROL_DOWN
)));
863 EXPECT_TRUE(ProcessWithContext(
864 ui::Accelerator(ui::VKEY_T
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
)));
867 EXPECT_TRUE(ProcessWithContext(
868 ui::Accelerator(ui::VKEY_ESCAPE
, ui::EF_SHIFT_DOWN
)));
870 #if defined(OS_CHROMEOS)
872 EXPECT_TRUE(ProcessWithContext(
873 ui::Accelerator(ui::VKEY_M
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
)));
876 // NOTE: Accelerators that do not work on the lock screen need to be
877 // tested before the sequence below is invoked because it causes a side
878 // effect of locking the screen.
879 EXPECT_TRUE(ProcessWithContext(
880 ui::Accelerator(ui::VKEY_L
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
)));
884 TEST_F(AcceleratorControllerTest
, GlobalAcceleratorsToggleAppList
) {
885 AccessibilityDelegate
* delegate
=
886 ash::Shell::GetInstance()->accessibility_delegate();
887 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
889 // The press event should not open the AppList, the release should instead.
890 EXPECT_FALSE(ProcessWithContext(
891 ui::Accelerator(ui::VKEY_LWIN
, ui::EF_NONE
)));
892 EXPECT_TRUE(ProcessWithContext(
893 ReleaseAccelerator(ui::VKEY_LWIN
, ui::EF_NONE
)));
894 EXPECT_TRUE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
896 // When spoken feedback is on, the AppList should not toggle.
897 delegate
->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE
);
898 EXPECT_FALSE(ProcessWithContext(
899 ui::Accelerator(ui::VKEY_LWIN
, ui::EF_NONE
)));
900 EXPECT_FALSE(ProcessWithContext(
901 ReleaseAccelerator(ui::VKEY_LWIN
, ui::EF_NONE
)));
902 delegate
->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE
);
903 EXPECT_TRUE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
905 EXPECT_FALSE(ProcessWithContext(
906 ui::Accelerator(ui::VKEY_LWIN
, ui::EF_NONE
)));
907 EXPECT_TRUE(ProcessWithContext(
908 ReleaseAccelerator(ui::VKEY_LWIN
, ui::EF_NONE
)));
909 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
911 // When spoken feedback is on, the AppList should not toggle.
912 delegate
->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE
);
913 EXPECT_FALSE(ProcessWithContext(
914 ui::Accelerator(ui::VKEY_LWIN
, ui::EF_NONE
)));
915 EXPECT_FALSE(ProcessWithContext(
916 ReleaseAccelerator(ui::VKEY_LWIN
, ui::EF_NONE
)));
917 delegate
->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE
);
918 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
921 TEST_F(AcceleratorControllerTest
, ImeGlobalAccelerators
) {
922 // Test IME shortcuts.
924 const ui::Accelerator
control_space(ui::VKEY_SPACE
, ui::EF_CONTROL_DOWN
);
925 const ui::Accelerator
convert(ui::VKEY_CONVERT
, ui::EF_NONE
);
926 const ui::Accelerator
non_convert(ui::VKEY_NONCONVERT
, ui::EF_NONE
);
927 const ui::Accelerator
wide_half_1(ui::VKEY_DBE_SBCSCHAR
, ui::EF_NONE
);
928 const ui::Accelerator
wide_half_2(ui::VKEY_DBE_DBCSCHAR
, ui::EF_NONE
);
929 const ui::Accelerator
hangul(ui::VKEY_HANGUL
, ui::EF_NONE
);
930 EXPECT_FALSE(ProcessWithContext(control_space
));
931 EXPECT_FALSE(ProcessWithContext(convert
));
932 EXPECT_FALSE(ProcessWithContext(non_convert
));
933 EXPECT_FALSE(ProcessWithContext(wide_half_1
));
934 EXPECT_FALSE(ProcessWithContext(wide_half_2
));
935 EXPECT_FALSE(ProcessWithContext(hangul
));
936 DummyImeControlDelegate
* delegate
= new DummyImeControlDelegate(true);
937 GetController()->SetImeControlDelegate(
938 scoped_ptr
<ImeControlDelegate
>(delegate
).Pass());
939 EXPECT_EQ(0, delegate
->handle_previous_ime_count());
940 EXPECT_TRUE(ProcessWithContext(control_space
));
941 EXPECT_EQ(1, delegate
->handle_previous_ime_count());
942 EXPECT_EQ(0, delegate
->handle_switch_ime_count());
943 EXPECT_TRUE(ProcessWithContext(convert
));
944 EXPECT_EQ(1, delegate
->handle_switch_ime_count());
945 EXPECT_TRUE(ProcessWithContext(non_convert
));
946 EXPECT_EQ(2, delegate
->handle_switch_ime_count());
947 EXPECT_TRUE(ProcessWithContext(wide_half_1
));
948 EXPECT_EQ(3, delegate
->handle_switch_ime_count());
949 EXPECT_TRUE(ProcessWithContext(wide_half_2
));
950 EXPECT_EQ(4, delegate
->handle_switch_ime_count());
951 EXPECT_TRUE(ProcessWithContext(hangul
));
952 EXPECT_EQ(5, delegate
->handle_switch_ime_count());
955 // Test IME shortcuts that are triggered on key release.
957 const ui::Accelerator
shift_alt_press(ui::VKEY_MENU
,
958 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
959 const ReleaseAccelerator
shift_alt(ui::VKEY_MENU
, ui::EF_SHIFT_DOWN
);
960 const ui::Accelerator
alt_shift_press(ui::VKEY_SHIFT
,
961 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
962 const ReleaseAccelerator
alt_shift(ui::VKEY_SHIFT
, ui::EF_ALT_DOWN
);
964 DummyImeControlDelegate
* delegate
= new DummyImeControlDelegate(true);
965 GetController()->SetImeControlDelegate(
966 scoped_ptr
<ImeControlDelegate
>(delegate
).Pass());
967 EXPECT_EQ(0, delegate
->handle_next_ime_count());
968 EXPECT_FALSE(ProcessWithContext(shift_alt_press
));
969 EXPECT_TRUE(ProcessWithContext(shift_alt
));
970 EXPECT_EQ(1, delegate
->handle_next_ime_count());
971 EXPECT_FALSE(ProcessWithContext(alt_shift_press
));
972 EXPECT_TRUE(ProcessWithContext(alt_shift
));
973 EXPECT_EQ(2, delegate
->handle_next_ime_count());
975 // We should NOT switch IME when e.g. Shift+Alt+X is pressed and X is
977 const ui::Accelerator
shift_alt_x_press(
979 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
980 const ReleaseAccelerator
shift_alt_x(ui::VKEY_X
,
981 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
983 EXPECT_FALSE(ProcessWithContext(shift_alt_press
));
984 EXPECT_FALSE(ProcessWithContext(shift_alt_x_press
));
985 EXPECT_FALSE(ProcessWithContext(shift_alt_x
));
986 EXPECT_FALSE(ProcessWithContext(shift_alt
));
987 EXPECT_EQ(2, delegate
->handle_next_ime_count());
989 // But we _should_ if X is either VKEY_RETURN or VKEY_SPACE.
990 // TODO(nona|mazda): Remove this when crbug.com/139556 in a better way.
991 const ui::Accelerator
shift_alt_return_press(
993 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
994 const ReleaseAccelerator
shift_alt_return(
996 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
998 EXPECT_FALSE(ProcessWithContext(shift_alt_press
));
999 EXPECT_FALSE(ProcessWithContext(shift_alt_return_press
));
1000 EXPECT_FALSE(ProcessWithContext(shift_alt_return
));
1001 EXPECT_TRUE(ProcessWithContext(shift_alt
));
1002 EXPECT_EQ(3, delegate
->handle_next_ime_count());
1004 const ui::Accelerator
shift_alt_space_press(
1006 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
1007 const ReleaseAccelerator
shift_alt_space(
1009 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
1011 EXPECT_FALSE(ProcessWithContext(shift_alt_press
));
1012 EXPECT_FALSE(ProcessWithContext(shift_alt_space_press
));
1013 EXPECT_FALSE(ProcessWithContext(shift_alt_space
));
1014 EXPECT_TRUE(ProcessWithContext(shift_alt
));
1015 EXPECT_EQ(4, delegate
->handle_next_ime_count());
1018 #if defined(OS_CHROMEOS)
1019 // Test IME shortcuts again with unnormalized accelerators (Chrome OS only).
1021 const ui::Accelerator
shift_alt_press(ui::VKEY_MENU
, ui::EF_SHIFT_DOWN
);
1022 const ReleaseAccelerator
shift_alt(ui::VKEY_MENU
, ui::EF_SHIFT_DOWN
);
1023 const ui::Accelerator
alt_shift_press(ui::VKEY_SHIFT
, ui::EF_ALT_DOWN
);
1024 const ReleaseAccelerator
alt_shift(ui::VKEY_SHIFT
, ui::EF_ALT_DOWN
);
1026 DummyImeControlDelegate
* delegate
= new DummyImeControlDelegate(true);
1027 GetController()->SetImeControlDelegate(
1028 scoped_ptr
<ImeControlDelegate
>(delegate
).Pass());
1029 EXPECT_EQ(0, delegate
->handle_next_ime_count());
1030 EXPECT_FALSE(ProcessWithContext(shift_alt_press
));
1031 EXPECT_TRUE(ProcessWithContext(shift_alt
));
1032 EXPECT_EQ(1, delegate
->handle_next_ime_count());
1033 EXPECT_FALSE(ProcessWithContext(alt_shift_press
));
1034 EXPECT_TRUE(ProcessWithContext(alt_shift
));
1035 EXPECT_EQ(2, delegate
->handle_next_ime_count());
1037 // We should NOT switch IME when e.g. Shift+Alt+X is pressed and X is
1039 const ui::Accelerator
shift_alt_x_press(
1041 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
1042 const ReleaseAccelerator
shift_alt_x(ui::VKEY_X
,
1043 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
1045 EXPECT_FALSE(ProcessWithContext(shift_alt_press
));
1046 EXPECT_FALSE(ProcessWithContext(shift_alt_x_press
));
1047 EXPECT_FALSE(ProcessWithContext(shift_alt_x
));
1048 EXPECT_FALSE(ProcessWithContext(shift_alt
));
1049 EXPECT_EQ(2, delegate
->handle_next_ime_count());
1054 // TODO(nona|mazda): Remove this when crbug.com/139556 in a better way.
1055 TEST_F(AcceleratorControllerTest
, ImeGlobalAcceleratorsWorkaround139556
) {
1056 // The workaround for crbug.com/139556 depends on the fact that we don't
1057 // use Shift+Alt+Enter/Space with ET_KEY_PRESSED as an accelerator. Test it.
1058 const ui::Accelerator
shift_alt_return_press(
1060 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
1061 EXPECT_FALSE(ProcessWithContext(shift_alt_return_press
));
1062 const ui::Accelerator
shift_alt_space_press(
1064 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
1065 EXPECT_FALSE(ProcessWithContext(shift_alt_space_press
));
1068 TEST_F(AcceleratorControllerTest
, ReservedAccelerators
) {
1069 // (Shift+)Alt+Tab and Chrome OS top-row keys are reserved.
1070 EXPECT_TRUE(GetController()->IsReservedAccelerator(
1071 ui::Accelerator(ui::VKEY_TAB
, ui::EF_ALT_DOWN
)));
1072 EXPECT_TRUE(GetController()->IsReservedAccelerator(
1073 ui::Accelerator(ui::VKEY_TAB
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
)));
1074 #if defined(OS_CHROMEOS)
1075 EXPECT_TRUE(GetController()->IsReservedAccelerator(
1076 ui::Accelerator(ui::VKEY_POWER
, ui::EF_NONE
)));
1078 // Others are not reserved.
1079 EXPECT_FALSE(GetController()->IsReservedAccelerator(
1080 ui::Accelerator(ui::VKEY_PRINT
, ui::EF_NONE
)));
1081 EXPECT_FALSE(GetController()->IsReservedAccelerator(
1082 ui::Accelerator(ui::VKEY_TAB
, ui::EF_NONE
)));
1083 EXPECT_FALSE(GetController()->IsReservedAccelerator(
1084 ui::Accelerator(ui::VKEY_A
, ui::EF_NONE
)));
1087 #if defined(OS_CHROMEOS)
1088 TEST_F(AcceleratorControllerTest
, DisallowedAtModalWindow
) {
1089 std::set
<AcceleratorAction
> all_actions
;
1090 for (size_t i
= 0 ; i
< kAcceleratorDataLength
; ++i
)
1091 all_actions
.insert(kAcceleratorData
[i
].action
);
1092 #if !defined(NDEBUG)
1093 std::set
<AcceleratorAction
> all_desktop_actions
;
1094 for (size_t i
= 0 ; i
< kDesktopAcceleratorDataLength
; ++i
)
1095 all_desktop_actions
.insert(kDesktopAcceleratorData
[i
].action
);
1098 std::set
<AcceleratorAction
> actionsAllowedAtModalWindow
;
1099 for (size_t k
= 0 ; k
< kActionsAllowedAtModalWindowLength
; ++k
)
1100 actionsAllowedAtModalWindow
.insert(kActionsAllowedAtModalWindow
[k
]);
1101 for (std::set
<AcceleratorAction
>::const_iterator it
=
1102 actionsAllowedAtModalWindow
.begin();
1103 it
!= actionsAllowedAtModalWindow
.end(); ++it
) {
1104 EXPECT_TRUE(all_actions
.find(*it
) != all_actions
.end()
1106 #if !defined(NDEBUG)
1107 || all_desktop_actions
.find(*it
) != all_desktop_actions
.end()
1110 << " action from kActionsAllowedAtModalWindow"
1111 << " not found in kAcceleratorData or kDesktopAcceleratorData. "
1112 << "action: " << *it
;
1114 scoped_ptr
<aura::Window
> window(
1115 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
1116 const ui::Accelerator dummy
;
1117 wm::ActivateWindow(window
.get());
1118 Shell::GetInstance()->SimulateModalWindowOpenForTesting(true);
1119 for (std::set
<AcceleratorAction
>::const_iterator it
= all_actions
.begin();
1120 it
!= all_actions
.end(); ++it
) {
1121 if (actionsAllowedAtModalWindow
.find(*it
) ==
1122 actionsAllowedAtModalWindow
.end()) {
1123 EXPECT_TRUE(GetController()->PerformAction(*it
, dummy
))
1124 << " for action (disallowed at modal window): " << *it
;
1127 // Testing of top row (F5-F10) accelerators that should still work
1128 // when a modal window is open
1132 test::TestScreenshotDelegate
* delegate
= GetScreenshotDelegate();
1133 delegate
->set_can_take_screenshot(false);
1134 EXPECT_TRUE(ProcessWithContext(
1135 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_CONTROL_DOWN
)));
1136 EXPECT_TRUE(ProcessWithContext(
1137 ui::Accelerator(ui::VKEY_PRINT
, ui::EF_NONE
)));
1138 EXPECT_TRUE(ProcessWithContext(
1139 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1
,
1140 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
)));
1141 delegate
->set_can_take_screenshot(true);
1142 EXPECT_EQ(0, delegate
->handle_take_screenshot_count());
1143 EXPECT_TRUE(ProcessWithContext(
1144 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_CONTROL_DOWN
)));
1145 EXPECT_EQ(1, delegate
->handle_take_screenshot_count());
1146 EXPECT_TRUE(ProcessWithContext(
1147 ui::Accelerator(ui::VKEY_PRINT
, ui::EF_NONE
)));
1148 EXPECT_EQ(2, delegate
->handle_take_screenshot_count());
1149 EXPECT_TRUE(ProcessWithContext(
1150 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1
,
1151 ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
)));
1152 EXPECT_EQ(2, delegate
->handle_take_screenshot_count());
1155 const ui::Accelerator
brightness_down(ui::VKEY_BRIGHTNESS_DOWN
, ui::EF_NONE
);
1156 const ui::Accelerator
brightness_up(ui::VKEY_BRIGHTNESS_UP
, ui::EF_NONE
);
1158 DummyBrightnessControlDelegate
* delegate
=
1159 new DummyBrightnessControlDelegate(false);
1160 GetController()->SetBrightnessControlDelegate(
1161 scoped_ptr
<BrightnessControlDelegate
>(delegate
).Pass());
1162 EXPECT_EQ(0, delegate
->handle_brightness_down_count());
1163 EXPECT_FALSE(ProcessWithContext(brightness_down
));
1164 EXPECT_EQ(1, delegate
->handle_brightness_down_count());
1165 EXPECT_EQ(brightness_down
, delegate
->last_accelerator());
1166 EXPECT_EQ(0, delegate
->handle_brightness_up_count());
1167 EXPECT_FALSE(ProcessWithContext(brightness_up
));
1168 EXPECT_EQ(1, delegate
->handle_brightness_up_count());
1169 EXPECT_EQ(brightness_up
, delegate
->last_accelerator());
1172 DummyBrightnessControlDelegate
* delegate
=
1173 new DummyBrightnessControlDelegate(true);
1174 GetController()->SetBrightnessControlDelegate(
1175 scoped_ptr
<BrightnessControlDelegate
>(delegate
).Pass());
1176 EXPECT_EQ(0, delegate
->handle_brightness_down_count());
1177 EXPECT_TRUE(ProcessWithContext(brightness_down
));
1178 EXPECT_EQ(1, delegate
->handle_brightness_down_count());
1179 EXPECT_EQ(brightness_down
, delegate
->last_accelerator());
1180 EXPECT_EQ(0, delegate
->handle_brightness_up_count());
1181 EXPECT_TRUE(ProcessWithContext(brightness_up
));
1182 EXPECT_EQ(1, delegate
->handle_brightness_up_count());
1183 EXPECT_EQ(brightness_up
, delegate
->last_accelerator());
1186 const ui::Accelerator
volume_mute(ui::VKEY_VOLUME_MUTE
, ui::EF_NONE
);
1187 const ui::Accelerator
volume_down(ui::VKEY_VOLUME_DOWN
, ui::EF_NONE
);
1188 const ui::Accelerator
volume_up(ui::VKEY_VOLUME_UP
, ui::EF_NONE
);
1190 EXPECT_TRUE(ProcessWithContext(volume_mute
));
1191 EXPECT_TRUE(ProcessWithContext(volume_down
));
1192 EXPECT_TRUE(ProcessWithContext(volume_up
));
1193 DummyVolumeControlDelegate
* delegate
=
1194 new DummyVolumeControlDelegate(false);
1195 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
1196 scoped_ptr
<VolumeControlDelegate
>(delegate
).Pass());
1197 EXPECT_EQ(0, delegate
->handle_volume_mute_count());
1198 EXPECT_FALSE(ProcessWithContext(volume_mute
));
1199 EXPECT_EQ(1, delegate
->handle_volume_mute_count());
1200 EXPECT_EQ(volume_mute
, delegate
->last_accelerator());
1201 EXPECT_EQ(0, delegate
->handle_volume_down_count());
1202 EXPECT_FALSE(ProcessWithContext(volume_down
));
1203 EXPECT_EQ(1, delegate
->handle_volume_down_count());
1204 EXPECT_EQ(volume_down
, delegate
->last_accelerator());
1205 EXPECT_EQ(0, delegate
->handle_volume_up_count());
1206 EXPECT_FALSE(ProcessWithContext(volume_up
));
1207 EXPECT_EQ(1, delegate
->handle_volume_up_count());
1208 EXPECT_EQ(volume_up
, delegate
->last_accelerator());
1211 DummyVolumeControlDelegate
* delegate
= new DummyVolumeControlDelegate(true);
1212 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
1213 scoped_ptr
<VolumeControlDelegate
>(delegate
).Pass());
1214 EXPECT_EQ(0, delegate
->handle_volume_mute_count());
1215 EXPECT_TRUE(ProcessWithContext(volume_mute
));
1216 EXPECT_EQ(1, delegate
->handle_volume_mute_count());
1217 EXPECT_EQ(volume_mute
, delegate
->last_accelerator());
1218 EXPECT_EQ(0, delegate
->handle_volume_down_count());
1219 EXPECT_TRUE(ProcessWithContext(volume_down
));
1220 EXPECT_EQ(1, delegate
->handle_volume_down_count());
1221 EXPECT_EQ(volume_down
, delegate
->last_accelerator());
1222 EXPECT_EQ(0, delegate
->handle_volume_up_count());
1223 EXPECT_TRUE(ProcessWithContext(volume_up
));
1224 EXPECT_EQ(1, delegate
->handle_volume_up_count());
1225 EXPECT_EQ(volume_up
, delegate
->last_accelerator());
1230 TEST_F(AcceleratorControllerTest
, DisallowedWithNoWindow
) {
1231 const ui::Accelerator dummy
;
1232 AccessibilityDelegate
* delegate
=
1233 ash::Shell::GetInstance()->accessibility_delegate();
1235 for (size_t i
= 0; i
< kActionsNeedingWindowLength
; ++i
) {
1236 delegate
->TriggerAccessibilityAlert(A11Y_ALERT_NONE
);
1238 GetController()->PerformAction(kActionsNeedingWindow
[i
], dummy
));
1239 EXPECT_EQ(delegate
->GetLastAccessibilityAlert(), A11Y_ALERT_WINDOW_NEEDED
);
1242 // Make sure we don't alert if we do have a window.
1243 scoped_ptr
<aura::Window
> window(
1244 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
1245 wm::ActivateWindow(window
.get());
1246 for (size_t i
= 0; i
< kActionsNeedingWindowLength
; ++i
) {
1247 delegate
->TriggerAccessibilityAlert(A11Y_ALERT_NONE
);
1248 GetController()->PerformAction(kActionsNeedingWindow
[i
], dummy
);
1249 EXPECT_EQ(delegate
->GetLastAccessibilityAlert(), A11Y_ALERT_NONE
);
1252 // Don't alert if we have a minimized window either.
1253 GetController()->PerformAction(WINDOW_MINIMIZE
, dummy
);
1254 for (size_t i
= 0; i
< kActionsNeedingWindowLength
; ++i
) {
1255 delegate
->TriggerAccessibilityAlert(A11Y_ALERT_NONE
);
1256 GetController()->PerformAction(kActionsNeedingWindow
[i
], dummy
);
1257 EXPECT_EQ(delegate
->GetLastAccessibilityAlert(), A11Y_ALERT_NONE
);