| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 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. | |
| 4 | |
| 5 #include "ui/wm/core/nested_accelerator_controller.h" | |
| 6 | |
| 7 #include <stdint.h> | |
| 8 | |
| 9 #include "base/bind.h" | |
| 10 #include "base/event_types.h" | |
| 11 #include "base/macros.h" | |
| 12 #include "base/message_loop/message_loop.h" | |
| 13 #include "build/build_config.h" | |
| 14 #include "ui/aura/test/aura_test_base.h" | |
| 15 #include "ui/aura/test/test_windows.h" | |
| 16 #include "ui/aura/window.h" | |
| 17 #include "ui/aura/window_event_dispatcher.h" | |
| 18 #include "ui/base/accelerators/accelerator.h" | |
| 19 #include "ui/base/accelerators/accelerator.h" | |
| 20 #include "ui/base/accelerators/accelerator_manager.h" | |
| 21 #include "ui/events/event_constants.h" | |
| 22 #include "ui/events/event_utils.h" | |
| 23 #include "ui/events/platform/platform_event_dispatcher.h" | |
| 24 #include "ui/events/platform/platform_event_source.h" | |
| 25 #include "ui/events/platform/scoped_event_dispatcher.h" | |
| 26 #include "ui/wm/core/nested_accelerator_delegate.h" | |
| 27 #include "ui/wm/public/dispatcher_client.h" | |
| 28 | |
| 29 #if defined(USE_X11) | |
| 30 #include <X11/Xlib.h> | |
| 31 #include "ui/aura/test/x11_event_sender.h" | |
| 32 #include "ui/events/test/events_test_utils_x11.h" | |
| 33 #endif // USE_X11 | |
| 34 | |
| 35 namespace wm { | |
| 36 namespace test { | |
| 37 | |
| 38 namespace { | |
| 39 | |
| 40 class MockDispatcher : public ui::PlatformEventDispatcher { | |
| 41 public: | |
| 42 MockDispatcher() : num_key_events_dispatched_(0) {} | |
| 43 | |
| 44 int num_key_events_dispatched() { return num_key_events_dispatched_; } | |
| 45 | |
| 46 private: | |
| 47 // ui::PlatformEventDispatcher: | |
| 48 bool CanDispatchEvent(const ui::PlatformEvent& event) override { | |
| 49 return true; | |
| 50 } | |
| 51 uint32_t DispatchEvent(const ui::PlatformEvent& event) override { | |
| 52 if (ui::EventTypeFromNative(event) == ui::ET_KEY_RELEASED) | |
| 53 num_key_events_dispatched_++; | |
| 54 return ui::POST_DISPATCH_NONE; | |
| 55 } | |
| 56 | |
| 57 int num_key_events_dispatched_; | |
| 58 | |
| 59 DISALLOW_COPY_AND_ASSIGN(MockDispatcher); | |
| 60 }; | |
| 61 | |
| 62 class TestTarget : public ui::AcceleratorTarget { | |
| 63 public: | |
| 64 TestTarget() : accelerator_pressed_count_(0) {} | |
| 65 ~TestTarget() override {} | |
| 66 | |
| 67 int accelerator_pressed_count() const { return accelerator_pressed_count_; } | |
| 68 | |
| 69 // Overridden from ui::AcceleratorTarget: | |
| 70 bool AcceleratorPressed(const ui::Accelerator& accelerator) override { | |
| 71 accelerator_pressed_count_++; | |
| 72 return true; | |
| 73 } | |
| 74 bool CanHandleAccelerators() const override { return true; } | |
| 75 | |
| 76 private: | |
| 77 int accelerator_pressed_count_; | |
| 78 | |
| 79 DISALLOW_COPY_AND_ASSIGN(TestTarget); | |
| 80 }; | |
| 81 | |
| 82 void DispatchKeyReleaseA(aura::Window* root_window) { | |
| 83 // Sending both keydown and keyup is necessary here because the accelerator | |
| 84 // manager only checks a keyup event following a keydown event. See | |
| 85 // ShouldHandle() in ui/base/accelerators/accelerator_manager.cc for details. | |
| 86 #if defined(OS_WIN) | |
| 87 aura::WindowTreeHost* host = root_window->GetHost(); | |
| 88 HWND hwnd = host->GetAcceleratedWidget(); | |
| 89 ::PostMessage(hwnd, WM_KEYDOWN, ui::VKEY_A, 0); | |
| 90 ::PostMessage(hwnd, WM_KEYUP, ui::VKEY_A, 0); | |
| 91 #elif defined(USE_X11) | |
| 92 ui::ScopedXI2Event native_event; | |
| 93 native_event.InitKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_A, 0); | |
| 94 aura::WindowTreeHost* host = root_window->GetHost(); | |
| 95 aura::test::PostEventToWindowTreeHost(*native_event, host); | |
| 96 native_event.InitKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_A, 0); | |
| 97 aura::test::PostEventToWindowTreeHost(*native_event, host); | |
| 98 #endif | |
| 99 // Make sure the inner message-loop terminates after dispatching the events. | |
| 100 base::MessageLoop::current()->PostTask( | |
| 101 FROM_HERE, base::MessageLoop::current()->QuitWhenIdleClosure()); | |
| 102 } | |
| 103 | |
| 104 class MockNestedAcceleratorDelegate : public NestedAcceleratorDelegate { | |
| 105 public: | |
| 106 MockNestedAcceleratorDelegate() | |
| 107 : accelerator_manager_(new ui::AcceleratorManager) {} | |
| 108 ~MockNestedAcceleratorDelegate() override {} | |
| 109 | |
| 110 // NestedAcceleratorDelegate: | |
| 111 Result ProcessAccelerator(const ui::Accelerator& accelerator) override { | |
| 112 return accelerator_manager_->Process(accelerator) ? | |
| 113 RESULT_PROCESSED : RESULT_NOT_PROCESSED; | |
| 114 } | |
| 115 | |
| 116 void Register(const ui::Accelerator& accelerator, | |
| 117 ui::AcceleratorTarget* target) { | |
| 118 accelerator_manager_->Register( | |
| 119 accelerator, ui::AcceleratorManager::kNormalPriority, target); | |
| 120 } | |
| 121 | |
| 122 private: | |
| 123 scoped_ptr<ui::AcceleratorManager> accelerator_manager_; | |
| 124 | |
| 125 DISALLOW_COPY_AND_ASSIGN(MockNestedAcceleratorDelegate); | |
| 126 }; | |
| 127 | |
| 128 class NestedAcceleratorTest : public aura::test::AuraTestBase { | |
| 129 public: | |
| 130 NestedAcceleratorTest() {} | |
| 131 ~NestedAcceleratorTest() override {} | |
| 132 | |
| 133 void SetUp() override { | |
| 134 AuraTestBase::SetUp(); | |
| 135 delegate_ = new MockNestedAcceleratorDelegate(); | |
| 136 nested_accelerator_controller_.reset( | |
| 137 new NestedAcceleratorController(delegate_)); | |
| 138 aura::client::SetDispatcherClient(root_window(), | |
| 139 nested_accelerator_controller_.get()); | |
| 140 } | |
| 141 | |
| 142 void TearDown() override { | |
| 143 aura::client::SetDispatcherClient(root_window(), NULL); | |
| 144 AuraTestBase::TearDown(); | |
| 145 delegate_ = NULL; | |
| 146 nested_accelerator_controller_.reset(); | |
| 147 } | |
| 148 | |
| 149 MockNestedAcceleratorDelegate* delegate() { return delegate_; } | |
| 150 | |
| 151 private: | |
| 152 scoped_ptr<NestedAcceleratorController> nested_accelerator_controller_; | |
| 153 MockNestedAcceleratorDelegate* delegate_; | |
| 154 | |
| 155 DISALLOW_COPY_AND_ASSIGN(NestedAcceleratorTest); | |
| 156 }; | |
| 157 | |
| 158 } // namespace | |
| 159 | |
| 160 // Aura window above lock screen in z order. | |
| 161 // http://crbug.com/396494 | |
| 162 TEST_F(NestedAcceleratorTest, DISABLED_AssociatedWindowAboveLockScreen) { | |
| 163 // TODO(oshima|sadrul): remove when Win implements PES. | |
| 164 if (!ui::PlatformEventSource::GetInstance()) | |
| 165 return; | |
| 166 MockDispatcher inner_dispatcher; | |
| 167 scoped_ptr<aura::Window> mock_lock_container( | |
| 168 CreateNormalWindow(0, root_window(), NULL)); | |
| 169 aura::test::CreateTestWindowWithId(1, mock_lock_container.get()); | |
| 170 | |
| 171 scoped_ptr<aura::Window> associated_window( | |
| 172 CreateNormalWindow(2, root_window(), NULL)); | |
| 173 EXPECT_TRUE(aura::test::WindowIsAbove(associated_window.get(), | |
| 174 mock_lock_container.get())); | |
| 175 | |
| 176 DispatchKeyReleaseA(root_window()); | |
| 177 scoped_ptr<ui::ScopedEventDispatcher> override_dispatcher = | |
| 178 ui::PlatformEventSource::GetInstance()->OverrideDispatcher( | |
| 179 &inner_dispatcher); | |
| 180 aura::client::DispatcherRunLoop run_loop( | |
| 181 aura::client::GetDispatcherClient(root_window()), NULL); | |
| 182 run_loop.Run(); | |
| 183 EXPECT_EQ(1, inner_dispatcher.num_key_events_dispatched()); | |
| 184 } | |
| 185 | |
| 186 // Test that the nested dispatcher handles accelerators. | |
| 187 // http://crbug.com/396494 | |
| 188 TEST_F(NestedAcceleratorTest, DISABLED_AcceleratorsHandled) { | |
| 189 // TODO(oshima|sadrul): remove when Win implements PES. | |
| 190 if (!ui::PlatformEventSource::GetInstance()) | |
| 191 return; | |
| 192 MockDispatcher inner_dispatcher; | |
| 193 ui::Accelerator accelerator(ui::VKEY_A, ui::EF_NONE); | |
| 194 accelerator.set_type(ui::ET_KEY_RELEASED); | |
| 195 TestTarget target; | |
| 196 delegate()->Register(accelerator, &target); | |
| 197 | |
| 198 DispatchKeyReleaseA(root_window()); | |
| 199 scoped_ptr<ui::ScopedEventDispatcher> override_dispatcher = | |
| 200 ui::PlatformEventSource::GetInstance()->OverrideDispatcher( | |
| 201 &inner_dispatcher); | |
| 202 aura::client::DispatcherRunLoop run_loop( | |
| 203 aura::client::GetDispatcherClient(root_window()), NULL); | |
| 204 run_loop.Run(); | |
| 205 EXPECT_EQ(0, inner_dispatcher.num_key_events_dispatched()); | |
| 206 EXPECT_EQ(1, target.accelerator_pressed_count()); | |
| 207 } | |
| 208 | |
| 209 } // namespace test | |
| 210 } // namespace wm | |
| OLD | NEW |