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"
7 #include "ash/accelerators/accelerator_table.h"
8 #include "ash/accessibility_delegate.h"
9 #include "ash/ash_switches.h"
10 #include "ash/display/display_manager.h"
11 #include "ash/ime_control_delegate.h"
12 #include "ash/screen_util.h"
13 #include "ash/shell.h"
14 #include "ash/shell_window_ids.h"
15 #include "ash/system/brightness_control_delegate.h"
16 #include "ash/system/keyboard_brightness/keyboard_brightness_control_delegate.h"
17 #include "ash/system/tray/system_tray_delegate.h"
18 #include "ash/test/ash_test_base.h"
19 #include "ash/test/display_manager_test_api.h"
20 #include "ash/test/test_screenshot_delegate.h"
21 #include "ash/test/test_shell_delegate.h"
22 #include "ash/test/test_volume_control_delegate.h"
23 #include "ash/volume_control_delegate.h"
24 #include "ash/wm/window_state.h"
25 #include "ash/wm/window_util.h"
26 #include "base/command_line.h"
27 #include "ui/aura/client/aura_constants.h"
28 #include "ui/aura/test/test_window_delegate.h"
29 #include "ui/aura/test/test_windows.h"
30 #include "ui/aura/window.h"
31 #include "ui/events/event.h"
32 #include "ui/events/event_processor.h"
33 #include "ui/events/test/event_generator.h"
34 #include "ui/gfx/screen.h"
35 #include "ui/views/widget/widget.h"
39 #include "ui/events/test/events_test_utils_x11.h"
46 class TestTarget
: public ui::AcceleratorTarget
{
48 TestTarget() : accelerator_pressed_count_(0), accelerator_repeat_count_(0) {}
49 virtual ~TestTarget() {}
51 int accelerator_pressed_count() const {
52 return accelerator_pressed_count_
;
55 int accelerator_repeat_count() const { return accelerator_repeat_count_
; }
58 accelerator_pressed_count_
= 0;
59 accelerator_repeat_count_
= 0;
62 // Overridden from ui::AcceleratorTarget:
63 virtual bool AcceleratorPressed(const ui::Accelerator
& accelerator
) OVERRIDE
;
64 virtual bool CanHandleAccelerators() const OVERRIDE
;
67 int accelerator_pressed_count_
;
68 int accelerator_repeat_count_
;
70 DISALLOW_COPY_AND_ASSIGN(TestTarget
);
73 class ReleaseAccelerator
: public ui::Accelerator
{
75 ReleaseAccelerator(ui::KeyboardCode keycode
, int modifiers
)
76 : ui::Accelerator(keycode
, modifiers
) {
77 set_type(ui::ET_KEY_RELEASED
);
81 class DummyBrightnessControlDelegate
: public BrightnessControlDelegate
{
83 explicit DummyBrightnessControlDelegate(bool consume
)
85 handle_brightness_down_count_(0),
86 handle_brightness_up_count_(0) {
88 virtual ~DummyBrightnessControlDelegate() {}
90 virtual bool HandleBrightnessDown(
91 const ui::Accelerator
& accelerator
) OVERRIDE
{
92 ++handle_brightness_down_count_
;
93 last_accelerator_
= accelerator
;
96 virtual bool HandleBrightnessUp(const ui::Accelerator
& accelerator
) OVERRIDE
{
97 ++handle_brightness_up_count_
;
98 last_accelerator_
= accelerator
;
101 virtual void SetBrightnessPercent(double percent
, bool gradual
) OVERRIDE
{}
102 virtual void GetBrightnessPercent(
103 const base::Callback
<void(double)>& callback
) OVERRIDE
{
107 int handle_brightness_down_count() const {
108 return handle_brightness_down_count_
;
110 int handle_brightness_up_count() const {
111 return handle_brightness_up_count_
;
113 const ui::Accelerator
& last_accelerator() const {
114 return last_accelerator_
;
119 int handle_brightness_down_count_
;
120 int handle_brightness_up_count_
;
121 ui::Accelerator last_accelerator_
;
123 DISALLOW_COPY_AND_ASSIGN(DummyBrightnessControlDelegate
);
126 class DummyImeControlDelegate
: public ImeControlDelegate
{
128 explicit DummyImeControlDelegate(bool consume
)
130 handle_next_ime_count_(0),
131 handle_previous_ime_count_(0),
132 handle_switch_ime_count_(0) {
134 virtual ~DummyImeControlDelegate() {}
136 virtual void HandleNextIme() OVERRIDE
{
137 ++handle_next_ime_count_
;
139 virtual bool HandlePreviousIme(const ui::Accelerator
& accelerator
) OVERRIDE
{
140 ++handle_previous_ime_count_
;
141 last_accelerator_
= accelerator
;
144 virtual bool HandleSwitchIme(const ui::Accelerator
& accelerator
) OVERRIDE
{
145 ++handle_switch_ime_count_
;
146 last_accelerator_
= accelerator
;
150 int handle_next_ime_count() const {
151 return handle_next_ime_count_
;
153 int handle_previous_ime_count() const {
154 return handle_previous_ime_count_
;
156 int handle_switch_ime_count() const {
157 return handle_switch_ime_count_
;
159 const ui::Accelerator
& last_accelerator() const {
160 return last_accelerator_
;
162 virtual ui::Accelerator
RemapAccelerator(
163 const ui::Accelerator
& accelerator
) OVERRIDE
{
164 return ui::Accelerator(accelerator
);
169 int handle_next_ime_count_
;
170 int handle_previous_ime_count_
;
171 int handle_switch_ime_count_
;
172 ui::Accelerator last_accelerator_
;
174 DISALLOW_COPY_AND_ASSIGN(DummyImeControlDelegate
);
177 class DummyKeyboardBrightnessControlDelegate
178 : public KeyboardBrightnessControlDelegate
{
180 explicit DummyKeyboardBrightnessControlDelegate(bool consume
)
182 handle_keyboard_brightness_down_count_(0),
183 handle_keyboard_brightness_up_count_(0) {
185 virtual ~DummyKeyboardBrightnessControlDelegate() {}
187 virtual bool HandleKeyboardBrightnessDown(
188 const ui::Accelerator
& accelerator
) OVERRIDE
{
189 ++handle_keyboard_brightness_down_count_
;
190 last_accelerator_
= accelerator
;
194 virtual bool HandleKeyboardBrightnessUp(
195 const ui::Accelerator
& accelerator
) OVERRIDE
{
196 ++handle_keyboard_brightness_up_count_
;
197 last_accelerator_
= accelerator
;
201 int handle_keyboard_brightness_down_count() const {
202 return handle_keyboard_brightness_down_count_
;
205 int handle_keyboard_brightness_up_count() const {
206 return handle_keyboard_brightness_up_count_
;
209 const ui::Accelerator
& last_accelerator() const {
210 return last_accelerator_
;
215 int handle_keyboard_brightness_down_count_
;
216 int handle_keyboard_brightness_up_count_
;
217 ui::Accelerator last_accelerator_
;
219 DISALLOW_COPY_AND_ASSIGN(DummyKeyboardBrightnessControlDelegate
);
222 bool TestTarget::AcceleratorPressed(const ui::Accelerator
& accelerator
) {
223 if (accelerator
.IsRepeat())
224 ++accelerator_repeat_count_
;
226 ++accelerator_pressed_count_
;
230 bool TestTarget::CanHandleAccelerators() const {
236 class AcceleratorControllerTest
: public test::AshTestBase
{
238 AcceleratorControllerTest() {}
239 virtual ~AcceleratorControllerTest() {}
242 void EnableInternalDisplay() {
243 test::DisplayManagerTestApi(Shell::GetInstance()->display_manager()).
244 SetFirstDisplayAsInternalDisplay();
247 static AcceleratorController
* GetController();
249 // Several functions to access ExitWarningHandler (as friend).
250 static void StubForTest(ExitWarningHandler
* ewh
) {
251 ewh
->stub_timer_for_test_
= true;
253 static void Reset(ExitWarningHandler
* ewh
) {
254 ewh
->state_
= ExitWarningHandler::IDLE
;
256 static void SimulateTimerExpired(ExitWarningHandler
* ewh
) {
259 static bool is_ui_shown(ExitWarningHandler
* ewh
) {
260 return !!ewh
->widget_
;
262 static bool is_idle(ExitWarningHandler
* ewh
) {
263 return ewh
->state_
== ExitWarningHandler::IDLE
;
265 static bool is_exiting(ExitWarningHandler
* ewh
) {
266 return ewh
->state_
== ExitWarningHandler::EXITING
;
270 DISALLOW_COPY_AND_ASSIGN(AcceleratorControllerTest
);
273 AcceleratorController
* AcceleratorControllerTest::GetController() {
274 return Shell::GetInstance()->accelerator_controller();
278 // Double press of exit shortcut => exiting
279 TEST_F(AcceleratorControllerTest
, ExitWarningHandlerTestDoublePress
) {
280 ui::Accelerator
press(ui::VKEY_Q
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
);
281 ui::Accelerator
release(press
);
282 release
.set_type(ui::ET_KEY_RELEASED
);
283 ExitWarningHandler
* ewh
= GetController()->GetExitWarningHandlerForTest();
286 EXPECT_TRUE(is_idle(ewh
));
287 EXPECT_FALSE(is_ui_shown(ewh
));
288 EXPECT_TRUE(GetController()->Process(press
));
289 EXPECT_FALSE(GetController()->Process(release
));
290 EXPECT_FALSE(is_idle(ewh
));
291 EXPECT_TRUE(is_ui_shown(ewh
));
292 EXPECT_TRUE(GetController()->Process(press
)); // second press before timer.
293 EXPECT_FALSE(GetController()->Process(release
));
294 SimulateTimerExpired(ewh
);
295 EXPECT_TRUE(is_exiting(ewh
));
296 EXPECT_FALSE(is_ui_shown(ewh
));
300 // Single press of exit shortcut before timer => idle
301 TEST_F(AcceleratorControllerTest
, ExitWarningHandlerTestSinglePress
) {
302 ui::Accelerator
press(ui::VKEY_Q
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
);
303 ui::Accelerator
release(press
);
304 release
.set_type(ui::ET_KEY_RELEASED
);
305 ExitWarningHandler
* ewh
= GetController()->GetExitWarningHandlerForTest();
308 EXPECT_TRUE(is_idle(ewh
));
309 EXPECT_FALSE(is_ui_shown(ewh
));
310 EXPECT_TRUE(GetController()->Process(press
));
311 EXPECT_FALSE(GetController()->Process(release
));
312 EXPECT_FALSE(is_idle(ewh
));
313 EXPECT_TRUE(is_ui_shown(ewh
));
314 SimulateTimerExpired(ewh
);
315 EXPECT_TRUE(is_idle(ewh
));
316 EXPECT_FALSE(is_ui_shown(ewh
));
320 // Shutdown ash with exit warning bubble open should not crash.
321 TEST_F(AcceleratorControllerTest
, LingeringExitWarningBubble
) {
322 ExitWarningHandler
* ewh
= GetController()->GetExitWarningHandlerForTest();
326 // Trigger once to show the bubble.
327 ewh
->HandleAccelerator();
328 EXPECT_FALSE(is_idle(ewh
));
329 EXPECT_TRUE(is_ui_shown(ewh
));
331 // Exit ash and there should be no crash
333 #endif // !defined(OS_WIN)
335 TEST_F(AcceleratorControllerTest
, Register
) {
336 const ui::Accelerator
accelerator_a(ui::VKEY_A
, ui::EF_NONE
);
338 GetController()->Register(accelerator_a
, &target
);
340 // The registered accelerator is processed.
341 EXPECT_TRUE(GetController()->Process(accelerator_a
));
342 EXPECT_EQ(1, target
.accelerator_pressed_count());
345 TEST_F(AcceleratorControllerTest
, RegisterMultipleTarget
) {
346 const ui::Accelerator
accelerator_a(ui::VKEY_A
, ui::EF_NONE
);
348 GetController()->Register(accelerator_a
, &target1
);
350 GetController()->Register(accelerator_a
, &target2
);
352 // If multiple targets are registered with the same accelerator, the target
353 // registered later processes the accelerator.
354 EXPECT_TRUE(GetController()->Process(accelerator_a
));
355 EXPECT_EQ(0, target1
.accelerator_pressed_count());
356 EXPECT_EQ(1, target2
.accelerator_pressed_count());
359 TEST_F(AcceleratorControllerTest
, Unregister
) {
360 const ui::Accelerator
accelerator_a(ui::VKEY_A
, ui::EF_NONE
);
362 GetController()->Register(accelerator_a
, &target
);
363 const ui::Accelerator
accelerator_b(ui::VKEY_B
, ui::EF_NONE
);
364 GetController()->Register(accelerator_b
, &target
);
366 // Unregistering a different accelerator does not affect the other
368 GetController()->Unregister(accelerator_b
, &target
);
369 EXPECT_TRUE(GetController()->Process(accelerator_a
));
370 EXPECT_EQ(1, target
.accelerator_pressed_count());
372 // The unregistered accelerator is no longer processed.
374 GetController()->Unregister(accelerator_a
, &target
);
375 EXPECT_FALSE(GetController()->Process(accelerator_a
));
376 EXPECT_EQ(0, target
.accelerator_pressed_count());
379 TEST_F(AcceleratorControllerTest
, UnregisterAll
) {
380 const ui::Accelerator
accelerator_a(ui::VKEY_A
, ui::EF_NONE
);
382 GetController()->Register(accelerator_a
, &target1
);
383 const ui::Accelerator
accelerator_b(ui::VKEY_B
, ui::EF_NONE
);
384 GetController()->Register(accelerator_b
, &target1
);
385 const ui::Accelerator
accelerator_c(ui::VKEY_C
, ui::EF_NONE
);
387 GetController()->Register(accelerator_c
, &target2
);
388 GetController()->UnregisterAll(&target1
);
390 // All the accelerators registered for |target1| are no longer processed.
391 EXPECT_FALSE(GetController()->Process(accelerator_a
));
392 EXPECT_FALSE(GetController()->Process(accelerator_b
));
393 EXPECT_EQ(0, target1
.accelerator_pressed_count());
395 // UnregisterAll with a different target does not affect the other target.
396 EXPECT_TRUE(GetController()->Process(accelerator_c
));
397 EXPECT_EQ(1, target2
.accelerator_pressed_count());
400 TEST_F(AcceleratorControllerTest
, Process
) {
401 const ui::Accelerator
accelerator_a(ui::VKEY_A
, ui::EF_NONE
);
403 GetController()->Register(accelerator_a
, &target1
);
405 // The registered accelerator is processed.
406 EXPECT_TRUE(GetController()->Process(accelerator_a
));
407 EXPECT_EQ(1, target1
.accelerator_pressed_count());
409 // The non-registered accelerator is not processed.
410 const ui::Accelerator
accelerator_b(ui::VKEY_B
, ui::EF_NONE
);
411 EXPECT_FALSE(GetController()->Process(accelerator_b
));
414 TEST_F(AcceleratorControllerTest
, IsRegistered
) {
415 const ui::Accelerator
accelerator_a(ui::VKEY_A
, ui::EF_NONE
);
416 const ui::Accelerator
accelerator_shift_a(ui::VKEY_A
, ui::EF_SHIFT_DOWN
);
418 GetController()->Register(accelerator_a
, &target
);
419 EXPECT_TRUE(GetController()->IsRegistered(accelerator_a
));
420 EXPECT_FALSE(GetController()->IsRegistered(accelerator_shift_a
));
421 GetController()->UnregisterAll(&target
);
422 EXPECT_FALSE(GetController()->IsRegistered(accelerator_a
));
425 TEST_F(AcceleratorControllerTest
, WindowSnap
) {
426 scoped_ptr
<aura::Window
> window(
427 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
428 const ui::Accelerator dummy
;
430 wm::WindowState
* window_state
= wm::GetWindowState(window
.get());
432 window_state
->Activate();
435 GetController()->PerformAction(WINDOW_SNAP_LEFT
, dummy
);
436 gfx::Rect expected_bounds
= wm::GetDefaultLeftSnappedWindowBoundsInParent(
438 EXPECT_EQ(expected_bounds
.ToString(), window
->bounds().ToString());
441 GetController()->PerformAction(WINDOW_SNAP_RIGHT
, dummy
);
442 gfx::Rect expected_bounds
= wm::GetDefaultRightSnappedWindowBoundsInParent(
444 EXPECT_EQ(expected_bounds
.ToString(), window
->bounds().ToString());
447 gfx::Rect normal_bounds
= window_state
->GetRestoreBoundsInParent();
449 GetController()->PerformAction(TOGGLE_MAXIMIZED
, dummy
);
450 EXPECT_TRUE(window_state
->IsMaximized());
451 EXPECT_NE(normal_bounds
.ToString(), window
->bounds().ToString());
453 GetController()->PerformAction(TOGGLE_MAXIMIZED
, dummy
);
454 EXPECT_FALSE(window_state
->IsMaximized());
455 // Window gets restored to its restore bounds since side-maximized state
456 // is treated as a "maximized" state.
457 EXPECT_EQ(normal_bounds
.ToString(), window
->bounds().ToString());
459 GetController()->PerformAction(TOGGLE_MAXIMIZED
, dummy
);
460 GetController()->PerformAction(WINDOW_SNAP_LEFT
, dummy
);
461 EXPECT_FALSE(window_state
->IsMaximized());
463 GetController()->PerformAction(TOGGLE_MAXIMIZED
, dummy
);
464 GetController()->PerformAction(WINDOW_SNAP_RIGHT
, dummy
);
465 EXPECT_FALSE(window_state
->IsMaximized());
467 GetController()->PerformAction(TOGGLE_MAXIMIZED
, dummy
);
468 EXPECT_TRUE(window_state
->IsMaximized());
469 GetController()->PerformAction(WINDOW_MINIMIZE
, dummy
);
470 EXPECT_FALSE(window_state
->IsMaximized());
471 EXPECT_TRUE(window_state
->IsMinimized());
472 window_state
->Restore();
473 window_state
->Activate();
476 GetController()->PerformAction(WINDOW_MINIMIZE
, dummy
);
477 EXPECT_TRUE(window_state
->IsMinimized());
481 TEST_F(AcceleratorControllerTest
, CenterWindowAccelerator
) {
482 scoped_ptr
<aura::Window
> window(
483 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
484 const ui::Accelerator dummy
;
485 wm::WindowState
* window_state
= wm::GetWindowState(window
.get());
486 window_state
->Activate();
488 // Center the window using accelerator.
489 GetController()->PerformAction(WINDOW_POSITION_CENTER
, dummy
);
490 gfx::Rect work_area
=
491 Shell::GetScreen()->GetDisplayNearestWindow(window
.get()).work_area();
492 gfx::Rect bounds
= window
->GetBoundsInScreen();
493 EXPECT_NEAR(bounds
.x() - work_area
.x(),
494 work_area
.right() - bounds
.right(),
496 EXPECT_NEAR(bounds
.y() - work_area
.y(),
497 work_area
.bottom() - bounds
.bottom(),
500 // Add the window to docked container and try to center it.
501 window
->SetBounds(gfx::Rect(0, 0, 20, 20));
502 aura::Window
* docked_container
= Shell::GetContainer(
503 window
->GetRootWindow(), kShellWindowId_DockedContainer
);
504 docked_container
->AddChild(window
.get());
505 gfx::Rect docked_bounds
= window
->GetBoundsInScreen();
506 GetController()->PerformAction(WINDOW_POSITION_CENTER
, dummy
);
507 // It should not get centered and should remain docked.
508 EXPECT_EQ(kShellWindowId_DockedContainer
, window
->parent()->id());
509 EXPECT_EQ(docked_bounds
.ToString(), window
->GetBoundsInScreen().ToString());
512 TEST_F(AcceleratorControllerTest
, AutoRepeat
) {
513 ui::Accelerator
accelerator_a(ui::VKEY_A
, ui::EF_CONTROL_DOWN
);
514 accelerator_a
.set_type(ui::ET_KEY_PRESSED
);
516 GetController()->Register(accelerator_a
, &target_a
);
517 ui::Accelerator
accelerator_b(ui::VKEY_B
, ui::EF_CONTROL_DOWN
);
518 accelerator_b
.set_type(ui::ET_KEY_PRESSED
);
520 GetController()->Register(accelerator_b
, &target_b
);
522 ui::test::EventGenerator
& generator
= GetEventGenerator();
523 generator
.PressKey(ui::VKEY_A
, ui::EF_CONTROL_DOWN
);
524 generator
.ReleaseKey(ui::VKEY_A
, ui::EF_CONTROL_DOWN
);
526 EXPECT_EQ(1, target_a
.accelerator_pressed_count());
527 EXPECT_EQ(0, target_a
.accelerator_repeat_count());
529 // Long press should generate one
530 generator
.PressKey(ui::VKEY_A
, ui::EF_CONTROL_DOWN
);
531 generator
.PressKey(ui::VKEY_A
, ui::EF_CONTROL_DOWN
| ui::EF_IS_REPEAT
);
532 EXPECT_EQ(2, target_a
.accelerator_pressed_count());
533 EXPECT_EQ(1, target_a
.accelerator_repeat_count());
534 generator
.PressKey(ui::VKEY_A
, ui::EF_CONTROL_DOWN
| ui::EF_IS_REPEAT
);
535 EXPECT_EQ(2, target_a
.accelerator_pressed_count());
536 EXPECT_EQ(2, target_a
.accelerator_repeat_count());
537 generator
.ReleaseKey(ui::VKEY_A
, ui::EF_CONTROL_DOWN
);
538 EXPECT_EQ(2, target_a
.accelerator_pressed_count());
539 EXPECT_EQ(2, target_a
.accelerator_repeat_count());
541 // Long press was intercepted by another key press.
542 generator
.PressKey(ui::VKEY_A
, ui::EF_CONTROL_DOWN
);
543 generator
.PressKey(ui::VKEY_A
, ui::EF_CONTROL_DOWN
| ui::EF_IS_REPEAT
);
544 generator
.PressKey(ui::VKEY_B
, ui::EF_CONTROL_DOWN
);
545 generator
.ReleaseKey(ui::VKEY_B
, ui::EF_CONTROL_DOWN
);
546 generator
.PressKey(ui::VKEY_A
, ui::EF_CONTROL_DOWN
);
547 generator
.PressKey(ui::VKEY_A
, ui::EF_CONTROL_DOWN
| ui::EF_IS_REPEAT
);
548 generator
.ReleaseKey(ui::VKEY_A
, ui::EF_CONTROL_DOWN
);
550 EXPECT_EQ(1, target_b
.accelerator_pressed_count());
551 EXPECT_EQ(0, target_b
.accelerator_repeat_count());
552 EXPECT_EQ(4, target_a
.accelerator_pressed_count());
553 EXPECT_EQ(4, target_a
.accelerator_repeat_count());
556 TEST_F(AcceleratorControllerTest
, Previous
) {
557 ui::test::EventGenerator
& generator
= GetEventGenerator();
558 generator
.PressKey(ui::VKEY_VOLUME_MUTE
, ui::EF_NONE
);
559 generator
.ReleaseKey(ui::VKEY_VOLUME_MUTE
, ui::EF_NONE
);
561 EXPECT_EQ(ui::VKEY_VOLUME_MUTE
,
562 GetController()->previous_accelerator_for_test().key_code());
563 EXPECT_EQ(ui::EF_NONE
,
564 GetController()->previous_accelerator_for_test().modifiers());
566 generator
.PressKey(ui::VKEY_TAB
, ui::EF_CONTROL_DOWN
);
567 generator
.ReleaseKey(ui::VKEY_TAB
, ui::EF_CONTROL_DOWN
);
569 EXPECT_EQ(ui::VKEY_TAB
,
570 GetController()->previous_accelerator_for_test().key_code());
571 EXPECT_EQ(ui::EF_CONTROL_DOWN
,
572 GetController()->previous_accelerator_for_test().modifiers());
575 TEST_F(AcceleratorControllerTest
, DontRepeatToggleFullscreen
) {
576 const AcceleratorData accelerators
[] = {
577 {true, ui::VKEY_J
, ui::EF_ALT_DOWN
, TOGGLE_FULLSCREEN
},
578 {true, ui::VKEY_K
, ui::EF_ALT_DOWN
, TOGGLE_FULLSCREEN
},
580 GetController()->RegisterAccelerators(accelerators
, arraysize(accelerators
));
582 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
583 params
.context
= CurrentContext();
584 params
.bounds
= gfx::Rect(5, 5, 20, 20);
585 views::Widget
* widget
= new views::Widget
;
586 widget
->Init(params
);
589 widget
->GetNativeView()->SetProperty(aura::client::kCanMaximizeKey
, true);
591 ui::test::EventGenerator
& generator
= GetEventGenerator();
592 wm::WindowState
* window_state
= wm::GetWindowState(widget
->GetNativeView());
594 // Toggling not suppressed.
595 generator
.PressKey(ui::VKEY_J
, ui::EF_ALT_DOWN
);
596 EXPECT_TRUE(window_state
->IsFullscreen());
598 // The same accelerator - toggling suppressed.
599 generator
.PressKey(ui::VKEY_J
, ui::EF_ALT_DOWN
| ui::EF_IS_REPEAT
);
600 EXPECT_TRUE(window_state
->IsFullscreen());
602 // Different accelerator.
603 generator
.PressKey(ui::VKEY_K
, ui::EF_ALT_DOWN
);
604 EXPECT_FALSE(window_state
->IsFullscreen());
607 // TODO(oshima): Fix this test to use EventGenerator.
610 #define MAYBE_ProcessOnce DISABLED_ProcessOnce
612 #define MAYBE_ProcessOnce ProcessOnce
615 #if defined(OS_WIN) || defined(USE_X11)
616 TEST_F(AcceleratorControllerTest
, MAYBE_ProcessOnce
) {
617 ui::Accelerator
accelerator_a(ui::VKEY_A
, ui::EF_NONE
);
619 GetController()->Register(accelerator_a
, &target
);
621 // The accelerator is processed only once.
622 ui::EventProcessor
* dispatcher
=
623 Shell::GetPrimaryRootWindow()->GetHost()->event_processor();
625 MSG msg1
= { NULL
, WM_KEYDOWN
, ui::VKEY_A
, 0 };
626 ui::KeyEvent
key_event1(msg1
);
627 key_event1
.SetTranslated(true);
628 ui::EventDispatchDetails details
= dispatcher
->OnEventFromSource(&key_event1
);
629 EXPECT_TRUE(key_event1
.handled() || details
.dispatcher_destroyed
);
631 MSG msg2
= { NULL
, WM_CHAR
, L
'A', 0 };
632 ui::KeyEvent
key_event2(msg2
);
633 key_event2
.SetTranslated(true);
634 details
= dispatcher
->OnEventFromSource(&key_event2
);
635 EXPECT_FALSE(key_event2
.handled() || details
.dispatcher_destroyed
);
637 MSG msg3
= { NULL
, WM_KEYUP
, ui::VKEY_A
, 0 };
638 ui::KeyEvent
key_event3(msg3
);
639 key_event3
.SetTranslated(true);
640 details
= dispatcher
->OnEventFromSource(&key_event3
);
641 EXPECT_FALSE(key_event3
.handled() || details
.dispatcher_destroyed
);
642 #elif defined(USE_X11)
643 ui::ScopedXI2Event key_event
;
644 key_event
.InitKeyEvent(ui::ET_KEY_PRESSED
, ui::VKEY_A
, 0);
645 ui::KeyEvent
key_event1(key_event
);
646 key_event1
.SetTranslated(true);
647 ui::EventDispatchDetails details
= dispatcher
->OnEventFromSource(&key_event1
);
648 EXPECT_TRUE(key_event1
.handled() || details
.dispatcher_destroyed
);
650 ui::KeyEvent
key_event2('A', ui::VKEY_A
, ui::EF_NONE
);
651 key_event2
.SetTranslated(true);
652 details
= dispatcher
->OnEventFromSource(&key_event2
);
653 EXPECT_FALSE(key_event2
.handled() || details
.dispatcher_destroyed
);
655 key_event
.InitKeyEvent(ui::ET_KEY_RELEASED
, ui::VKEY_A
, 0);
656 ui::KeyEvent
key_event3(key_event
);
657 key_event3
.SetTranslated(true);
658 details
= dispatcher
->OnEventFromSource(&key_event3
);
659 EXPECT_FALSE(key_event3
.handled() || details
.dispatcher_destroyed
);
661 EXPECT_EQ(1, target
.accelerator_pressed_count());
665 TEST_F(AcceleratorControllerTest
, GlobalAccelerators
) {
667 EXPECT_TRUE(GetController()->Process(
668 ui::Accelerator(ui::VKEY_TAB
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
)));
671 GetController()->Process(ui::Accelerator(ui::VKEY_TAB
, ui::EF_ALT_DOWN
)));
673 EXPECT_TRUE(GetController()->Process(
674 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_NONE
)));
676 #if defined(OS_CHROMEOS)
677 // Take screenshot / partial screenshot
678 // True should always be returned regardless of the existence of the delegate.
680 test::TestScreenshotDelegate
* delegate
= GetScreenshotDelegate();
681 delegate
->set_can_take_screenshot(false);
682 EXPECT_TRUE(GetController()->Process(
683 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_CONTROL_DOWN
)));
685 GetController()->Process(ui::Accelerator(ui::VKEY_PRINT
, ui::EF_NONE
)));
686 EXPECT_TRUE(GetController()->Process(ui::Accelerator(
687 ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
)));
689 delegate
->set_can_take_screenshot(true);
690 EXPECT_EQ(0, delegate
->handle_take_screenshot_count());
691 EXPECT_TRUE(GetController()->Process(
692 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_CONTROL_DOWN
)));
693 EXPECT_EQ(1, delegate
->handle_take_screenshot_count());
695 GetController()->Process(ui::Accelerator(ui::VKEY_PRINT
, ui::EF_NONE
)));
696 EXPECT_EQ(2, delegate
->handle_take_screenshot_count());
697 EXPECT_TRUE(GetController()->Process(ui::Accelerator(
698 ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
)));
699 EXPECT_EQ(2, delegate
->handle_take_screenshot_count());
702 const ui::Accelerator
volume_mute(ui::VKEY_VOLUME_MUTE
, ui::EF_NONE
);
703 const ui::Accelerator
volume_down(ui::VKEY_VOLUME_DOWN
, ui::EF_NONE
);
704 const ui::Accelerator
volume_up(ui::VKEY_VOLUME_UP
, ui::EF_NONE
);
706 TestVolumeControlDelegate
* delegate
=
707 new TestVolumeControlDelegate(false);
708 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
709 scoped_ptr
<VolumeControlDelegate
>(delegate
).Pass());
710 EXPECT_EQ(0, delegate
->handle_volume_mute_count());
711 EXPECT_FALSE(GetController()->Process(volume_mute
));
712 EXPECT_EQ(1, delegate
->handle_volume_mute_count());
713 EXPECT_EQ(volume_mute
, delegate
->last_accelerator());
714 EXPECT_EQ(0, delegate
->handle_volume_down_count());
715 EXPECT_FALSE(GetController()->Process(volume_down
));
716 EXPECT_EQ(1, delegate
->handle_volume_down_count());
717 EXPECT_EQ(volume_down
, delegate
->last_accelerator());
718 EXPECT_EQ(0, delegate
->handle_volume_up_count());
719 EXPECT_FALSE(GetController()->Process(volume_up
));
720 EXPECT_EQ(1, delegate
->handle_volume_up_count());
721 EXPECT_EQ(volume_up
, delegate
->last_accelerator());
724 TestVolumeControlDelegate
* delegate
= new TestVolumeControlDelegate(true);
725 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
726 scoped_ptr
<VolumeControlDelegate
>(delegate
).Pass());
727 EXPECT_EQ(0, delegate
->handle_volume_mute_count());
728 EXPECT_TRUE(GetController()->Process(volume_mute
));
729 EXPECT_EQ(1, delegate
->handle_volume_mute_count());
730 EXPECT_EQ(volume_mute
, delegate
->last_accelerator());
731 EXPECT_EQ(0, delegate
->handle_volume_down_count());
732 EXPECT_TRUE(GetController()->Process(volume_down
));
733 EXPECT_EQ(1, delegate
->handle_volume_down_count());
734 EXPECT_EQ(volume_down
, delegate
->last_accelerator());
735 EXPECT_EQ(0, delegate
->handle_volume_up_count());
736 EXPECT_TRUE(GetController()->Process(volume_up
));
737 EXPECT_EQ(1, delegate
->handle_volume_up_count());
738 EXPECT_EQ(volume_up
, delegate
->last_accelerator());
740 #if defined(OS_CHROMEOS)
742 // ui::VKEY_BRIGHTNESS_DOWN/UP are not defined on Windows.
743 const ui::Accelerator
brightness_down(ui::VKEY_BRIGHTNESS_DOWN
, ui::EF_NONE
);
744 const ui::Accelerator
brightness_up(ui::VKEY_BRIGHTNESS_UP
, ui::EF_NONE
);
746 DummyBrightnessControlDelegate
* delegate
=
747 new DummyBrightnessControlDelegate(false);
748 GetController()->SetBrightnessControlDelegate(
749 scoped_ptr
<BrightnessControlDelegate
>(delegate
).Pass());
750 EXPECT_EQ(0, delegate
->handle_brightness_down_count());
751 EXPECT_FALSE(GetController()->Process(brightness_down
));
752 EXPECT_EQ(1, delegate
->handle_brightness_down_count());
753 EXPECT_EQ(brightness_down
, delegate
->last_accelerator());
754 EXPECT_EQ(0, delegate
->handle_brightness_up_count());
755 EXPECT_FALSE(GetController()->Process(brightness_up
));
756 EXPECT_EQ(1, delegate
->handle_brightness_up_count());
757 EXPECT_EQ(brightness_up
, delegate
->last_accelerator());
760 DummyBrightnessControlDelegate
* delegate
=
761 new DummyBrightnessControlDelegate(true);
762 GetController()->SetBrightnessControlDelegate(
763 scoped_ptr
<BrightnessControlDelegate
>(delegate
).Pass());
764 EXPECT_EQ(0, delegate
->handle_brightness_down_count());
765 EXPECT_TRUE(GetController()->Process(brightness_down
));
766 EXPECT_EQ(1, delegate
->handle_brightness_down_count());
767 EXPECT_EQ(brightness_down
, delegate
->last_accelerator());
768 EXPECT_EQ(0, delegate
->handle_brightness_up_count());
769 EXPECT_TRUE(GetController()->Process(brightness_up
));
770 EXPECT_EQ(1, delegate
->handle_brightness_up_count());
771 EXPECT_EQ(brightness_up
, delegate
->last_accelerator());
774 // Keyboard brightness
775 const ui::Accelerator
alt_brightness_down(ui::VKEY_BRIGHTNESS_DOWN
,
777 const ui::Accelerator
alt_brightness_up(ui::VKEY_BRIGHTNESS_UP
,
780 EXPECT_TRUE(GetController()->Process(alt_brightness_down
));
781 EXPECT_TRUE(GetController()->Process(alt_brightness_up
));
782 DummyKeyboardBrightnessControlDelegate
* delegate
=
783 new DummyKeyboardBrightnessControlDelegate(false);
784 GetController()->SetKeyboardBrightnessControlDelegate(
785 scoped_ptr
<KeyboardBrightnessControlDelegate
>(delegate
).Pass());
786 EXPECT_EQ(0, delegate
->handle_keyboard_brightness_down_count());
787 EXPECT_FALSE(GetController()->Process(alt_brightness_down
));
788 EXPECT_EQ(1, delegate
->handle_keyboard_brightness_down_count());
789 EXPECT_EQ(alt_brightness_down
, delegate
->last_accelerator());
790 EXPECT_EQ(0, delegate
->handle_keyboard_brightness_up_count());
791 EXPECT_FALSE(GetController()->Process(alt_brightness_up
));
792 EXPECT_EQ(1, delegate
->handle_keyboard_brightness_up_count());
793 EXPECT_EQ(alt_brightness_up
, delegate
->last_accelerator());
796 DummyKeyboardBrightnessControlDelegate
* delegate
=
797 new DummyKeyboardBrightnessControlDelegate(true);
798 GetController()->SetKeyboardBrightnessControlDelegate(
799 scoped_ptr
<KeyboardBrightnessControlDelegate
>(delegate
).Pass());
800 EXPECT_EQ(0, delegate
->handle_keyboard_brightness_down_count());
801 EXPECT_TRUE(GetController()->Process(alt_brightness_down
));
802 EXPECT_EQ(1, delegate
->handle_keyboard_brightness_down_count());
803 EXPECT_EQ(alt_brightness_down
, delegate
->last_accelerator());
804 EXPECT_EQ(0, delegate
->handle_keyboard_brightness_up_count());
805 EXPECT_TRUE(GetController()->Process(alt_brightness_up
));
806 EXPECT_EQ(1, delegate
->handle_keyboard_brightness_up_count());
807 EXPECT_EQ(alt_brightness_up
, delegate
->last_accelerator());
812 // ToggleDesktopBackgroundMode
813 EXPECT_TRUE(GetController()->Process(
814 ui::Accelerator(ui::VKEY_B
, ui::EF_CONTROL_DOWN
| ui::EF_ALT_DOWN
)));
815 #if !defined(OS_LINUX)
816 // ToggleDesktopFullScreen (not implemented yet on Linux)
817 EXPECT_TRUE(GetController()->Process(
818 ui::Accelerator(ui::VKEY_F11
, ui::EF_CONTROL_DOWN
)));
824 ExitWarningHandler
* ewh
= GetController()->GetExitWarningHandlerForTest();
827 EXPECT_TRUE(is_idle(ewh
));
828 EXPECT_FALSE(is_ui_shown(ewh
));
829 EXPECT_TRUE(GetController()->Process(
830 ui::Accelerator(ui::VKEY_Q
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
)));
831 EXPECT_FALSE(is_idle(ewh
));
832 EXPECT_TRUE(is_ui_shown(ewh
));
833 SimulateTimerExpired(ewh
);
834 EXPECT_TRUE(is_idle(ewh
));
835 EXPECT_FALSE(is_ui_shown(ewh
));
840 EXPECT_TRUE(GetController()->Process(
841 ui::Accelerator(ui::VKEY_T
, ui::EF_CONTROL_DOWN
)));
843 // New incognito window
844 EXPECT_TRUE(GetController()->Process(
845 ui::Accelerator(ui::VKEY_N
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
)));
848 EXPECT_TRUE(GetController()->Process(
849 ui::Accelerator(ui::VKEY_N
, ui::EF_CONTROL_DOWN
)));
852 EXPECT_TRUE(GetController()->Process(
853 ui::Accelerator(ui::VKEY_T
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
)));
856 EXPECT_TRUE(GetController()->Process(
857 ui::Accelerator(ui::VKEY_ESCAPE
, ui::EF_SHIFT_DOWN
)));
859 #if defined(OS_CHROMEOS)
861 EXPECT_TRUE(GetController()->Process(
862 ui::Accelerator(ui::VKEY_M
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
)));
865 // NOTE: Accelerators that do not work on the lock screen need to be
866 // tested before the sequence below is invoked because it causes a side
867 // effect of locking the screen.
868 EXPECT_TRUE(GetController()->Process(
869 ui::Accelerator(ui::VKEY_L
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
)));
873 TEST_F(AcceleratorControllerTest
, GlobalAcceleratorsToggleAppList
) {
874 AccessibilityDelegate
* delegate
=
875 ash::Shell::GetInstance()->accessibility_delegate();
876 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
878 // The press event should not open the AppList, the release should instead.
880 GetController()->Process(ui::Accelerator(ui::VKEY_LWIN
, ui::EF_NONE
)));
881 EXPECT_EQ(ui::VKEY_LWIN
,
882 GetController()->previous_accelerator_for_test().key_code());
885 GetController()->Process(ReleaseAccelerator(ui::VKEY_LWIN
, ui::EF_NONE
)));
886 EXPECT_TRUE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
888 // When spoken feedback is on, the AppList should not toggle.
889 delegate
->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE
);
891 GetController()->Process(ui::Accelerator(ui::VKEY_LWIN
, ui::EF_NONE
)));
893 GetController()->Process(ReleaseAccelerator(ui::VKEY_LWIN
, ui::EF_NONE
)));
894 delegate
->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE
);
895 EXPECT_TRUE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
898 GetController()->Process(ui::Accelerator(ui::VKEY_LWIN
, ui::EF_NONE
)));
900 GetController()->Process(ReleaseAccelerator(ui::VKEY_LWIN
, ui::EF_NONE
)));
901 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
903 // When spoken feedback is on, the AppList should not toggle.
904 delegate
->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE
);
906 GetController()->Process(ui::Accelerator(ui::VKEY_LWIN
, ui::EF_NONE
)));
908 GetController()->Process(ReleaseAccelerator(ui::VKEY_LWIN
, ui::EF_NONE
)));
909 delegate
->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE
);
910 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
913 TEST_F(AcceleratorControllerTest
, ImeGlobalAccelerators
) {
914 // Test IME shortcuts.
916 const ui::Accelerator
control_space(ui::VKEY_SPACE
, ui::EF_CONTROL_DOWN
);
917 const ui::Accelerator
convert(ui::VKEY_CONVERT
, ui::EF_NONE
);
918 const ui::Accelerator
non_convert(ui::VKEY_NONCONVERT
, ui::EF_NONE
);
919 const ui::Accelerator
wide_half_1(ui::VKEY_DBE_SBCSCHAR
, ui::EF_NONE
);
920 const ui::Accelerator
wide_half_2(ui::VKEY_DBE_DBCSCHAR
, ui::EF_NONE
);
921 const ui::Accelerator
hangul(ui::VKEY_HANGUL
, ui::EF_NONE
);
922 EXPECT_FALSE(GetController()->Process(control_space
));
923 EXPECT_FALSE(GetController()->Process(convert
));
924 EXPECT_FALSE(GetController()->Process(non_convert
));
925 EXPECT_FALSE(GetController()->Process(wide_half_1
));
926 EXPECT_FALSE(GetController()->Process(wide_half_2
));
927 EXPECT_FALSE(GetController()->Process(hangul
));
928 DummyImeControlDelegate
* delegate
= new DummyImeControlDelegate(true);
929 GetController()->SetImeControlDelegate(
930 scoped_ptr
<ImeControlDelegate
>(delegate
).Pass());
931 EXPECT_EQ(0, delegate
->handle_previous_ime_count());
932 EXPECT_TRUE(GetController()->Process(control_space
));
933 EXPECT_EQ(1, delegate
->handle_previous_ime_count());
934 EXPECT_EQ(0, delegate
->handle_switch_ime_count());
935 EXPECT_TRUE(GetController()->Process(convert
));
936 EXPECT_EQ(1, delegate
->handle_switch_ime_count());
937 EXPECT_TRUE(GetController()->Process(non_convert
));
938 EXPECT_EQ(2, delegate
->handle_switch_ime_count());
939 EXPECT_TRUE(GetController()->Process(wide_half_1
));
940 EXPECT_EQ(3, delegate
->handle_switch_ime_count());
941 EXPECT_TRUE(GetController()->Process(wide_half_2
));
942 EXPECT_EQ(4, delegate
->handle_switch_ime_count());
943 EXPECT_TRUE(GetController()->Process(hangul
));
944 EXPECT_EQ(5, delegate
->handle_switch_ime_count());
947 // Test IME shortcuts that are triggered on key release.
949 const ui::Accelerator
shift_alt_press(ui::VKEY_MENU
,
950 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
951 const ReleaseAccelerator
shift_alt(ui::VKEY_MENU
, ui::EF_SHIFT_DOWN
);
952 const ui::Accelerator
alt_shift_press(ui::VKEY_SHIFT
,
953 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
954 const ReleaseAccelerator
alt_shift(ui::VKEY_SHIFT
, ui::EF_ALT_DOWN
);
956 DummyImeControlDelegate
* delegate
= new DummyImeControlDelegate(true);
957 GetController()->SetImeControlDelegate(
958 scoped_ptr
<ImeControlDelegate
>(delegate
).Pass());
959 EXPECT_EQ(0, delegate
->handle_next_ime_count());
960 EXPECT_FALSE(GetController()->Process(shift_alt_press
));
961 EXPECT_FALSE(GetController()->Process(shift_alt
));
962 EXPECT_EQ(1, delegate
->handle_next_ime_count());
963 EXPECT_FALSE(GetController()->Process(alt_shift_press
));
964 EXPECT_FALSE(GetController()->Process(alt_shift
));
965 EXPECT_EQ(2, delegate
->handle_next_ime_count());
967 // We should NOT switch IME when e.g. Shift+Alt+X is pressed and X is
969 const ui::Accelerator
shift_alt_x_press(
971 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
972 const ReleaseAccelerator
shift_alt_x(ui::VKEY_X
,
973 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
975 EXPECT_FALSE(GetController()->Process(shift_alt_press
));
976 EXPECT_FALSE(GetController()->Process(shift_alt_x_press
));
977 EXPECT_FALSE(GetController()->Process(shift_alt_x
));
978 EXPECT_FALSE(GetController()->Process(shift_alt
));
979 EXPECT_EQ(2, delegate
->handle_next_ime_count());
981 // But we _should_ if X is either VKEY_RETURN or VKEY_SPACE.
982 // TODO(nona|mazda): Remove this when crbug.com/139556 in a better way.
983 const ui::Accelerator
shift_alt_return_press(
985 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
986 const ReleaseAccelerator
shift_alt_return(
988 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
990 EXPECT_FALSE(GetController()->Process(shift_alt_press
));
991 EXPECT_FALSE(GetController()->Process(shift_alt_return_press
));
992 EXPECT_FALSE(GetController()->Process(shift_alt_return
));
993 EXPECT_FALSE(GetController()->Process(shift_alt
));
994 EXPECT_EQ(3, delegate
->handle_next_ime_count());
996 const ui::Accelerator
shift_alt_space_press(
998 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
999 const ReleaseAccelerator
shift_alt_space(
1001 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
1003 EXPECT_FALSE(GetController()->Process(shift_alt_press
));
1004 EXPECT_FALSE(GetController()->Process(shift_alt_space_press
));
1005 EXPECT_FALSE(GetController()->Process(shift_alt_space
));
1006 EXPECT_FALSE(GetController()->Process(shift_alt
));
1007 EXPECT_EQ(4, delegate
->handle_next_ime_count());
1010 #if defined(OS_CHROMEOS)
1011 // Test IME shortcuts again with unnormalized accelerators (Chrome OS only).
1013 const ui::Accelerator
shift_alt_press(ui::VKEY_MENU
, ui::EF_SHIFT_DOWN
);
1014 const ReleaseAccelerator
shift_alt(ui::VKEY_MENU
, ui::EF_SHIFT_DOWN
);
1015 const ui::Accelerator
alt_shift_press(ui::VKEY_SHIFT
, ui::EF_ALT_DOWN
);
1016 const ReleaseAccelerator
alt_shift(ui::VKEY_SHIFT
, ui::EF_ALT_DOWN
);
1018 DummyImeControlDelegate
* delegate
= new DummyImeControlDelegate(true);
1019 GetController()->SetImeControlDelegate(
1020 scoped_ptr
<ImeControlDelegate
>(delegate
).Pass());
1021 EXPECT_EQ(0, delegate
->handle_next_ime_count());
1022 EXPECT_FALSE(GetController()->Process(shift_alt_press
));
1023 EXPECT_FALSE(GetController()->Process(shift_alt
));
1024 EXPECT_EQ(1, delegate
->handle_next_ime_count());
1025 EXPECT_FALSE(GetController()->Process(alt_shift_press
));
1026 EXPECT_FALSE(GetController()->Process(alt_shift
));
1027 EXPECT_EQ(2, delegate
->handle_next_ime_count());
1029 // We should NOT switch IME when e.g. Shift+Alt+X is pressed and X is
1031 const ui::Accelerator
shift_alt_x_press(
1033 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
1034 const ReleaseAccelerator
shift_alt_x(ui::VKEY_X
,
1035 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
1037 EXPECT_FALSE(GetController()->Process(shift_alt_press
));
1038 EXPECT_FALSE(GetController()->Process(shift_alt_x_press
));
1039 EXPECT_FALSE(GetController()->Process(shift_alt_x
));
1040 EXPECT_FALSE(GetController()->Process(shift_alt
));
1041 EXPECT_EQ(2, delegate
->handle_next_ime_count());
1046 // TODO(nona|mazda): Remove this when crbug.com/139556 in a better way.
1047 TEST_F(AcceleratorControllerTest
, ImeGlobalAcceleratorsWorkaround139556
) {
1048 // The workaround for crbug.com/139556 depends on the fact that we don't
1049 // use Shift+Alt+Enter/Space with ET_KEY_PRESSED as an accelerator. Test it.
1050 const ui::Accelerator
shift_alt_return_press(
1052 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
1053 EXPECT_FALSE(GetController()->Process(shift_alt_return_press
));
1054 const ui::Accelerator
shift_alt_space_press(
1056 ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
);
1057 EXPECT_FALSE(GetController()->Process(shift_alt_space_press
));
1060 TEST_F(AcceleratorControllerTest
, ReservedAccelerators
) {
1061 // (Shift+)Alt+Tab and Chrome OS top-row keys are reserved.
1062 EXPECT_TRUE(GetController()->IsReservedAccelerator(
1063 ui::Accelerator(ui::VKEY_TAB
, ui::EF_ALT_DOWN
)));
1064 EXPECT_TRUE(GetController()->IsReservedAccelerator(
1065 ui::Accelerator(ui::VKEY_TAB
, ui::EF_SHIFT_DOWN
| ui::EF_ALT_DOWN
)));
1066 #if defined(OS_CHROMEOS)
1067 EXPECT_TRUE(GetController()->IsReservedAccelerator(
1068 ui::Accelerator(ui::VKEY_POWER
, ui::EF_NONE
)));
1070 // Others are not reserved.
1071 EXPECT_FALSE(GetController()->IsReservedAccelerator(
1072 ui::Accelerator(ui::VKEY_PRINT
, ui::EF_NONE
)));
1073 EXPECT_FALSE(GetController()->IsReservedAccelerator(
1074 ui::Accelerator(ui::VKEY_TAB
, ui::EF_NONE
)));
1075 EXPECT_FALSE(GetController()->IsReservedAccelerator(
1076 ui::Accelerator(ui::VKEY_A
, ui::EF_NONE
)));
1079 #if defined(OS_CHROMEOS)
1080 TEST_F(AcceleratorControllerTest
, DisallowedAtModalWindow
) {
1081 std::set
<AcceleratorAction
> all_actions
;
1082 for (size_t i
= 0 ; i
< kAcceleratorDataLength
; ++i
)
1083 all_actions
.insert(kAcceleratorData
[i
].action
);
1084 #if !defined(NDEBUG)
1085 std::set
<AcceleratorAction
> all_desktop_actions
;
1086 for (size_t i
= 0 ; i
< kDesktopAcceleratorDataLength
; ++i
)
1087 all_desktop_actions
.insert(kDesktopAcceleratorData
[i
].action
);
1090 std::set
<AcceleratorAction
> actionsAllowedAtModalWindow
;
1091 for (size_t k
= 0 ; k
< kActionsAllowedAtModalWindowLength
; ++k
)
1092 actionsAllowedAtModalWindow
.insert(kActionsAllowedAtModalWindow
[k
]);
1093 for (std::set
<AcceleratorAction
>::const_iterator it
=
1094 actionsAllowedAtModalWindow
.begin();
1095 it
!= actionsAllowedAtModalWindow
.end(); ++it
) {
1096 EXPECT_TRUE(all_actions
.find(*it
) != all_actions
.end()
1098 #if !defined(NDEBUG)
1099 || all_desktop_actions
.find(*it
) != all_desktop_actions
.end()
1102 << " action from kActionsAllowedAtModalWindow"
1103 << " not found in kAcceleratorData or kDesktopAcceleratorData. "
1104 << "action: " << *it
;
1106 scoped_ptr
<aura::Window
> window(
1107 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
1108 const ui::Accelerator dummy
;
1109 wm::ActivateWindow(window
.get());
1110 Shell::GetInstance()->SimulateModalWindowOpenForTesting(true);
1111 for (std::set
<AcceleratorAction
>::const_iterator it
= all_actions
.begin();
1112 it
!= all_actions
.end(); ++it
) {
1113 if (actionsAllowedAtModalWindow
.find(*it
) ==
1114 actionsAllowedAtModalWindow
.end()) {
1115 EXPECT_TRUE(GetController()->PerformAction(*it
, dummy
))
1116 << " for action (disallowed at modal window): " << *it
;
1119 // Testing of top row (F5-F10) accelerators that should still work
1120 // when a modal window is open
1124 test::TestScreenshotDelegate
* delegate
= GetScreenshotDelegate();
1125 delegate
->set_can_take_screenshot(false);
1126 EXPECT_TRUE(GetController()->Process(
1127 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_CONTROL_DOWN
)));
1129 GetController()->Process(ui::Accelerator(ui::VKEY_PRINT
, ui::EF_NONE
)));
1130 EXPECT_TRUE(GetController()->Process(ui::Accelerator(
1131 ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
)));
1132 delegate
->set_can_take_screenshot(true);
1133 EXPECT_EQ(0, delegate
->handle_take_screenshot_count());
1134 EXPECT_TRUE(GetController()->Process(
1135 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_CONTROL_DOWN
)));
1136 EXPECT_EQ(1, delegate
->handle_take_screenshot_count());
1138 GetController()->Process(ui::Accelerator(ui::VKEY_PRINT
, ui::EF_NONE
)));
1139 EXPECT_EQ(2, delegate
->handle_take_screenshot_count());
1140 EXPECT_TRUE(GetController()->Process(ui::Accelerator(
1141 ui::VKEY_MEDIA_LAUNCH_APP1
, ui::EF_SHIFT_DOWN
| ui::EF_CONTROL_DOWN
)));
1142 EXPECT_EQ(2, delegate
->handle_take_screenshot_count());
1145 const ui::Accelerator
brightness_down(ui::VKEY_BRIGHTNESS_DOWN
, ui::EF_NONE
);
1146 const ui::Accelerator
brightness_up(ui::VKEY_BRIGHTNESS_UP
, ui::EF_NONE
);
1148 DummyBrightnessControlDelegate
* delegate
=
1149 new DummyBrightnessControlDelegate(false);
1150 GetController()->SetBrightnessControlDelegate(
1151 scoped_ptr
<BrightnessControlDelegate
>(delegate
).Pass());
1152 EXPECT_EQ(0, delegate
->handle_brightness_down_count());
1153 EXPECT_FALSE(GetController()->Process(brightness_down
));
1154 EXPECT_EQ(1, delegate
->handle_brightness_down_count());
1155 EXPECT_EQ(brightness_down
, delegate
->last_accelerator());
1156 EXPECT_EQ(0, delegate
->handle_brightness_up_count());
1157 EXPECT_FALSE(GetController()->Process(brightness_up
));
1158 EXPECT_EQ(1, delegate
->handle_brightness_up_count());
1159 EXPECT_EQ(brightness_up
, delegate
->last_accelerator());
1162 DummyBrightnessControlDelegate
* delegate
=
1163 new DummyBrightnessControlDelegate(true);
1164 GetController()->SetBrightnessControlDelegate(
1165 scoped_ptr
<BrightnessControlDelegate
>(delegate
).Pass());
1166 EXPECT_EQ(0, delegate
->handle_brightness_down_count());
1167 EXPECT_TRUE(GetController()->Process(brightness_down
));
1168 EXPECT_EQ(1, delegate
->handle_brightness_down_count());
1169 EXPECT_EQ(brightness_down
, delegate
->last_accelerator());
1170 EXPECT_EQ(0, delegate
->handle_brightness_up_count());
1171 EXPECT_TRUE(GetController()->Process(brightness_up
));
1172 EXPECT_EQ(1, delegate
->handle_brightness_up_count());
1173 EXPECT_EQ(brightness_up
, delegate
->last_accelerator());
1176 const ui::Accelerator
volume_mute(ui::VKEY_VOLUME_MUTE
, ui::EF_NONE
);
1177 const ui::Accelerator
volume_down(ui::VKEY_VOLUME_DOWN
, ui::EF_NONE
);
1178 const ui::Accelerator
volume_up(ui::VKEY_VOLUME_UP
, ui::EF_NONE
);
1180 EXPECT_TRUE(GetController()->Process(volume_mute
));
1181 EXPECT_TRUE(GetController()->Process(volume_down
));
1182 EXPECT_TRUE(GetController()->Process(volume_up
));
1183 TestVolumeControlDelegate
* delegate
=
1184 new TestVolumeControlDelegate(false);
1185 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
1186 scoped_ptr
<VolumeControlDelegate
>(delegate
).Pass());
1187 EXPECT_EQ(0, delegate
->handle_volume_mute_count());
1188 EXPECT_FALSE(GetController()->Process(volume_mute
));
1189 EXPECT_EQ(1, delegate
->handle_volume_mute_count());
1190 EXPECT_EQ(volume_mute
, delegate
->last_accelerator());
1191 EXPECT_EQ(0, delegate
->handle_volume_down_count());
1192 EXPECT_FALSE(GetController()->Process(volume_down
));
1193 EXPECT_EQ(1, delegate
->handle_volume_down_count());
1194 EXPECT_EQ(volume_down
, delegate
->last_accelerator());
1195 EXPECT_EQ(0, delegate
->handle_volume_up_count());
1196 EXPECT_FALSE(GetController()->Process(volume_up
));
1197 EXPECT_EQ(1, delegate
->handle_volume_up_count());
1198 EXPECT_EQ(volume_up
, delegate
->last_accelerator());
1201 TestVolumeControlDelegate
* delegate
= new TestVolumeControlDelegate(true);
1202 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
1203 scoped_ptr
<VolumeControlDelegate
>(delegate
).Pass());
1204 EXPECT_EQ(0, delegate
->handle_volume_mute_count());
1205 EXPECT_TRUE(GetController()->Process(volume_mute
));
1206 EXPECT_EQ(1, delegate
->handle_volume_mute_count());
1207 EXPECT_EQ(volume_mute
, delegate
->last_accelerator());
1208 EXPECT_EQ(0, delegate
->handle_volume_down_count());
1209 EXPECT_TRUE(GetController()->Process(volume_down
));
1210 EXPECT_EQ(1, delegate
->handle_volume_down_count());
1211 EXPECT_EQ(volume_down
, delegate
->last_accelerator());
1212 EXPECT_EQ(0, delegate
->handle_volume_up_count());
1213 EXPECT_TRUE(GetController()->Process(volume_up
));
1214 EXPECT_EQ(1, delegate
->handle_volume_up_count());
1215 EXPECT_EQ(volume_up
, delegate
->last_accelerator());
1220 TEST_F(AcceleratorControllerTest
, DisallowedWithNoWindow
) {
1221 const ui::Accelerator dummy
;
1222 AccessibilityDelegate
* delegate
=
1223 ash::Shell::GetInstance()->accessibility_delegate();
1225 for (size_t i
= 0; i
< kActionsNeedingWindowLength
; ++i
) {
1226 delegate
->TriggerAccessibilityAlert(A11Y_ALERT_NONE
);
1228 GetController()->PerformAction(kActionsNeedingWindow
[i
], dummy
));
1229 EXPECT_EQ(delegate
->GetLastAccessibilityAlert(), A11Y_ALERT_WINDOW_NEEDED
);
1232 // Make sure we don't alert if we do have a window.
1233 scoped_ptr
<aura::Window
> window
;
1234 for (size_t i
= 0; i
< kActionsNeedingWindowLength
; ++i
) {
1235 window
.reset(CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
1236 wm::ActivateWindow(window
.get());
1237 delegate
->TriggerAccessibilityAlert(A11Y_ALERT_NONE
);
1238 GetController()->PerformAction(kActionsNeedingWindow
[i
], dummy
);
1239 EXPECT_NE(delegate
->GetLastAccessibilityAlert(), A11Y_ALERT_WINDOW_NEEDED
);
1242 // Don't alert if we have a minimized window either.
1243 for (size_t i
= 0; i
< kActionsNeedingWindowLength
; ++i
) {
1244 window
.reset(CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
1245 wm::ActivateWindow(window
.get());
1246 GetController()->PerformAction(WINDOW_MINIMIZE
, dummy
);
1247 delegate
->TriggerAccessibilityAlert(A11Y_ALERT_NONE
);
1248 GetController()->PerformAction(kActionsNeedingWindow
[i
], dummy
);
1249 EXPECT_NE(delegate
->GetLastAccessibilityAlert(), A11Y_ALERT_WINDOW_NEEDED
);