| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/mus/ws/event_dispatcher.h" | 5 #include "components/mus/ws/event_dispatcher.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <queue> | 10 #include <queue> |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 DispatchedEventDetails() : window(nullptr), in_nonclient_area(false) {} | 28 DispatchedEventDetails() : window(nullptr), in_nonclient_area(false) {} |
| 29 | 29 |
| 30 ServerWindow* window; | 30 ServerWindow* window; |
| 31 bool in_nonclient_area; | 31 bool in_nonclient_area; |
| 32 mojom::EventPtr event; | 32 mojom::EventPtr event; |
| 33 }; | 33 }; |
| 34 | 34 |
| 35 class TestEventDispatcherDelegate : public EventDispatcherDelegate { | 35 class TestEventDispatcherDelegate : public EventDispatcherDelegate { |
| 36 public: | 36 public: |
| 37 explicit TestEventDispatcherDelegate(ServerWindow* root) | 37 explicit TestEventDispatcherDelegate(ServerWindow* root) |
| 38 : root_(root), focused_window_(nullptr), last_accelerator_(0) {} | 38 : root_(root), |
| 39 focused_window_(nullptr), |
| 40 lost_capture_window_(nullptr), |
| 41 last_accelerator_(0) {} |
| 39 ~TestEventDispatcherDelegate() override {} | 42 ~TestEventDispatcherDelegate() override {} |
| 40 | 43 |
| 41 uint32_t GetAndClearLastAccelerator() { | 44 uint32_t GetAndClearLastAccelerator() { |
| 42 uint32_t return_value = last_accelerator_; | 45 uint32_t return_value = last_accelerator_; |
| 43 last_accelerator_ = 0; | 46 last_accelerator_ = 0; |
| 44 return return_value; | 47 return return_value; |
| 45 } | 48 } |
| 46 | 49 |
| 47 // Returns the last dispatched event, or null if there are no more. | 50 // Returns the last dispatched event, or null if there are no more. |
| 48 scoped_ptr<DispatchedEventDetails> GetAndAdvanceDispatchedEventDetails() { | 51 scoped_ptr<DispatchedEventDetails> GetAndAdvanceDispatchedEventDetails() { |
| 49 if (dispatched_event_queue_.empty()) | 52 if (dispatched_event_queue_.empty()) |
| 50 return nullptr; | 53 return nullptr; |
| 51 | 54 |
| 52 scoped_ptr<DispatchedEventDetails> details = | 55 scoped_ptr<DispatchedEventDetails> details = |
| 53 std::move(dispatched_event_queue_.front()); | 56 std::move(dispatched_event_queue_.front()); |
| 54 dispatched_event_queue_.pop(); | 57 dispatched_event_queue_.pop(); |
| 55 return details; | 58 return details; |
| 56 } | 59 } |
| 57 | 60 |
| 58 ServerWindow* GetAndClearLastFocusedWindow() { | 61 ServerWindow* GetAndClearLastFocusedWindow() { |
| 59 ServerWindow* result = focused_window_; | 62 ServerWindow* result = focused_window_; |
| 60 focused_window_ = nullptr; | 63 focused_window_ = nullptr; |
| 61 return result; | 64 return result; |
| 62 } | 65 } |
| 63 | 66 |
| 64 bool has_queued_events() const { return !dispatched_event_queue_.empty(); } | 67 bool has_queued_events() const { return !dispatched_event_queue_.empty(); } |
| 68 ServerWindow* lost_capture_window() { return lost_capture_window_; } |
| 65 | 69 |
| 66 private: | 70 private: |
| 67 // EventDispatcherDelegate: | 71 // EventDispatcherDelegate: |
| 68 void OnAccelerator(uint32_t accelerator, mojom::EventPtr event) override { | 72 void OnAccelerator(uint32_t accelerator, mojom::EventPtr event) override { |
| 69 EXPECT_EQ(0u, last_accelerator_); | 73 EXPECT_EQ(0u, last_accelerator_); |
| 70 last_accelerator_ = accelerator; | 74 last_accelerator_ = accelerator; |
| 71 } | 75 } |
| 72 void SetFocusedWindowFromEventDispatcher(ServerWindow* window) override { | 76 void SetFocusedWindowFromEventDispatcher(ServerWindow* window) override { |
| 73 focused_window_ = window; | 77 focused_window_ = window; |
| 74 } | 78 } |
| 75 ServerWindow* GetFocusedWindowForEventDispatcher() override { | 79 ServerWindow* GetFocusedWindowForEventDispatcher() override { |
| 76 return focused_window_; | 80 return focused_window_; |
| 77 } | 81 } |
| 82 void OnLostCapture(ServerWindow* window) override { |
| 83 lost_capture_window_ = window; |
| 84 } |
| 78 void DispatchInputEventToWindow(ServerWindow* target, | 85 void DispatchInputEventToWindow(ServerWindow* target, |
| 79 bool in_nonclient_area, | 86 bool in_nonclient_area, |
| 80 mojom::EventPtr event) override { | 87 mojom::EventPtr event) override { |
| 81 scoped_ptr<DispatchedEventDetails> details(new DispatchedEventDetails); | 88 scoped_ptr<DispatchedEventDetails> details(new DispatchedEventDetails); |
| 82 details->window = target; | 89 details->window = target; |
| 83 details->in_nonclient_area = in_nonclient_area; | 90 details->in_nonclient_area = in_nonclient_area; |
| 84 details->event = std::move(event); | 91 details->event = std::move(event); |
| 85 dispatched_event_queue_.push(std::move(details)); | 92 dispatched_event_queue_.push(std::move(details)); |
| 86 } | 93 } |
| 87 | 94 |
| 88 ServerWindow* root_; | 95 ServerWindow* root_; |
| 89 ServerWindow* focused_window_; | 96 ServerWindow* focused_window_; |
| 97 ServerWindow* lost_capture_window_; |
| 90 uint32_t last_accelerator_; | 98 uint32_t last_accelerator_; |
| 91 std::queue<scoped_ptr<DispatchedEventDetails>> dispatched_event_queue_; | 99 std::queue<scoped_ptr<DispatchedEventDetails>> dispatched_event_queue_; |
| 92 | 100 |
| 93 DISALLOW_COPY_AND_ASSIGN(TestEventDispatcherDelegate); | 101 DISALLOW_COPY_AND_ASSIGN(TestEventDispatcherDelegate); |
| 94 }; | 102 }; |
| 95 | 103 |
| 96 // Used by RunMouseEventTests(). Can identify up to two generated events. The | 104 // Used by RunMouseEventTests(). Can identify up to two generated events. The |
| 97 // first ServerWindow and two points identify the first event, the second | 105 // first ServerWindow and two points identify the first event, the second |
| 98 // ServerWindow and points identify the second event. If only one event is | 106 // ServerWindow and points identify the second event. If only one event is |
| 99 // generated set the second window to null. | 107 // generated set the second window to null. |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 details.get(), test.expected_target_window2, | 159 details.get(), test.expected_target_window2, |
| 152 test.expected_root_location2, test.expected_location2)) | 160 test.expected_root_location2, test.expected_location2)) |
| 153 << " details2 don't match " << i; | 161 << " details2 don't match " << i; |
| 154 ASSERT_FALSE(dispatcher_delegate->has_queued_events()) | 162 ASSERT_FALSE(dispatcher_delegate->has_queued_events()) |
| 155 << " unexpected queued events after running " << i; | 163 << " unexpected queued events after running " << i; |
| 156 } | 164 } |
| 157 } | 165 } |
| 158 | 166 |
| 159 } // namespace | 167 } // namespace |
| 160 | 168 |
| 161 TEST(EventDispatcherTest, ProcessEvent) { | 169 // Test fixture for EventDispatcher with friend access to verify the internal |
| 162 TestServerWindowDelegate window_delegate; | 170 // state. Setup creates a TestServerWindowDelegate, a visible root ServerWindow, |
| 163 ServerWindow root(&window_delegate, WindowId(1, 2)); | 171 // a TestEventDispatcher and the EventDispatcher for testing. |
| 164 window_delegate.set_root_window(&root); | 172 class EventDispatcherTest : public testing::Test { |
| 165 root.SetVisible(true); | 173 public: |
| 174 EventDispatcherTest() {} |
| 175 ~EventDispatcherTest() override {} |
| 166 | 176 |
| 167 ServerWindow child(&window_delegate, WindowId(1, 3)); | 177 ServerWindow* root_window() { return root_window_.get(); } |
| 168 root.Add(&child); | 178 TestEventDispatcherDelegate* test_event_dispatcher_delegate() { |
| 169 child.SetVisible(true); | 179 return test_event_dispatcher_delegate_.get(); |
| 170 EnableHitTest(&child); | 180 } |
| 181 EventDispatcher* event_dispatcher() { return event_dispatcher_.get(); } |
| 171 | 182 |
| 172 root.SetBounds(gfx::Rect(0, 0, 100, 100)); | 183 bool AreAnyPointersDown() const; |
| 173 child.SetBounds(gfx::Rect(10, 10, 20, 20)); | 184 // Deletes everything created during SetUp() |
| 185 void ClearSetup(); |
| 186 // Creates a window which is a child of |root_window_|. It is not owned by |
| 187 // EventDispatcherTest. |
| 188 ServerWindow* CreateChildWindow(const WindowId& id); |
| 189 bool IsMouseButtonDown() const; |
| 190 bool IsWindowPointerTarget(ServerWindow* window) const; |
| 191 int NumberPointerTargetsForWindow(ServerWindow* window) const; |
| 174 | 192 |
| 175 TestEventDispatcherDelegate event_dispatcher_delegate(&root); | 193 protected: |
| 176 EventDispatcher dispatcher(&event_dispatcher_delegate); | 194 // testing::Test: |
| 177 dispatcher.set_root(&root); | 195 void SetUp() override; |
| 196 |
| 197 private: |
| 198 scoped_ptr<TestServerWindowDelegate> window_delegate_; |
| 199 scoped_ptr<ServerWindow> root_window_; |
| 200 scoped_ptr<TestEventDispatcherDelegate> test_event_dispatcher_delegate_; |
| 201 scoped_ptr<EventDispatcher> event_dispatcher_; |
| 202 |
| 203 DISALLOW_COPY_AND_ASSIGN(EventDispatcherTest); |
| 204 }; |
| 205 |
| 206 bool EventDispatcherTest::AreAnyPointersDown() const { |
| 207 return event_dispatcher_->AreAnyPointersDown(); |
| 208 } |
| 209 |
| 210 void EventDispatcherTest::ClearSetup() { |
| 211 window_delegate_.reset(); |
| 212 root_window_.reset(); |
| 213 test_event_dispatcher_delegate_.reset(); |
| 214 event_dispatcher_.reset(); |
| 215 } |
| 216 |
| 217 ServerWindow* EventDispatcherTest::CreateChildWindow(const WindowId& id) { |
| 218 ServerWindow* child = new ServerWindow(window_delegate_.get(), id); |
| 219 root_window_->Add(child); |
| 220 child->SetVisible(true); |
| 221 EnableHitTest(child); |
| 222 return child; |
| 223 } |
| 224 |
| 225 bool EventDispatcherTest::IsMouseButtonDown() const { |
| 226 return event_dispatcher_->mouse_button_down_; |
| 227 } |
| 228 |
| 229 bool EventDispatcherTest::IsWindowPointerTarget(ServerWindow* window) const { |
| 230 return event_dispatcher_->IsObservingWindow(window); |
| 231 } |
| 232 |
| 233 int EventDispatcherTest::NumberPointerTargetsForWindow( |
| 234 ServerWindow* window) const { |
| 235 int count = 0; |
| 236 for (const auto& pair : event_dispatcher_->pointer_targets_) |
| 237 if (pair.second.window == window) |
| 238 count++; |
| 239 return count; |
| 240 } |
| 241 |
| 242 void EventDispatcherTest::SetUp() { |
| 243 testing::Test::SetUp(); |
| 244 |
| 245 window_delegate_.reset(new TestServerWindowDelegate()); |
| 246 root_window_.reset(new ServerWindow(window_delegate_.get(), WindowId(1, 2))); |
| 247 window_delegate_->set_root_window(root_window_.get()); |
| 248 root_window_->SetVisible(true); |
| 249 |
| 250 test_event_dispatcher_delegate_.reset( |
| 251 new TestEventDispatcherDelegate(root_window_.get())); |
| 252 event_dispatcher_.reset( |
| 253 new EventDispatcher(test_event_dispatcher_delegate_.get())); |
| 254 event_dispatcher_->set_root(root_window_.get()); |
| 255 } |
| 256 |
| 257 TEST_F(EventDispatcherTest, ProcessEvent) { |
| 258 scoped_ptr<ServerWindow> child(CreateChildWindow(WindowId(1, 3))); |
| 259 |
| 260 root_window()->SetBounds(gfx::Rect(0, 0, 100, 100)); |
| 261 child->SetBounds(gfx::Rect(10, 10, 20, 20)); |
| 178 | 262 |
| 179 // Send event that is over child. | 263 // Send event that is over child. |
| 180 const ui::MouseEvent ui_event( | 264 const ui::MouseEvent ui_event( |
| 181 ui::ET_MOUSE_PRESSED, gfx::Point(20, 25), gfx::Point(20, 25), | 265 ui::ET_MOUSE_PRESSED, gfx::Point(20, 25), gfx::Point(20, 25), |
| 182 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); | 266 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); |
| 183 dispatcher.ProcessEvent( | 267 event_dispatcher()->ProcessEvent( |
| 184 mojom::Event::From(static_cast<const ui::Event&>(ui_event))); | 268 mojom::Event::From(static_cast<const ui::Event&>(ui_event))); |
| 185 | 269 |
| 186 scoped_ptr<DispatchedEventDetails> details = | 270 scoped_ptr<DispatchedEventDetails> details = |
| 187 event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails(); | 271 test_event_dispatcher_delegate()->GetAndAdvanceDispatchedEventDetails(); |
| 188 | |
| 189 ASSERT_TRUE(details); | 272 ASSERT_TRUE(details); |
| 190 ASSERT_EQ(&child, details->window); | 273 ASSERT_EQ(child.get(), details->window); |
| 191 | 274 |
| 192 scoped_ptr<ui::Event> dispatched_event( | 275 scoped_ptr<ui::Event> dispatched_event( |
| 193 details->event.To<scoped_ptr<ui::Event>>()); | 276 details->event.To<scoped_ptr<ui::Event>>()); |
| 194 ASSERT_TRUE(dispatched_event); | 277 ASSERT_TRUE(dispatched_event); |
| 195 ASSERT_TRUE(dispatched_event->IsMouseEvent()); | 278 ASSERT_TRUE(dispatched_event->IsMouseEvent()); |
| 279 |
| 196 ui::MouseEvent* dispatched_mouse_event = | 280 ui::MouseEvent* dispatched_mouse_event = |
| 197 static_cast<ui::MouseEvent*>(dispatched_event.get()); | 281 static_cast<ui::MouseEvent*>(dispatched_event.get()); |
| 198 EXPECT_EQ(gfx::Point(20, 25), dispatched_mouse_event->root_location()); | 282 EXPECT_EQ(gfx::Point(20, 25), dispatched_mouse_event->root_location()); |
| 199 EXPECT_EQ(gfx::Point(10, 15), dispatched_mouse_event->location()); | 283 EXPECT_EQ(gfx::Point(10, 15), dispatched_mouse_event->location()); |
| 200 } | 284 } |
| 201 | 285 |
| 202 TEST(EventDispatcherTest, AcceleratorBasic) { | 286 TEST_F(EventDispatcherTest, AcceleratorBasic) { |
| 287 ClearSetup(); |
| 203 TestEventDispatcherDelegate event_dispatcher_delegate(nullptr); | 288 TestEventDispatcherDelegate event_dispatcher_delegate(nullptr); |
| 204 EventDispatcher dispatcher(&event_dispatcher_delegate); | 289 EventDispatcher dispatcher(&event_dispatcher_delegate); |
| 290 |
| 205 uint32_t accelerator_1 = 1; | 291 uint32_t accelerator_1 = 1; |
| 206 mojom::EventMatcherPtr matcher = mus::CreateKeyMatcher( | 292 mojom::EventMatcherPtr matcher = mus::CreateKeyMatcher( |
| 207 mus::mojom::KeyboardCode::W, mus::mojom::kEventFlagControlDown); | 293 mus::mojom::KeyboardCode::W, mus::mojom::kEventFlagControlDown); |
| 208 EXPECT_TRUE(dispatcher.AddAccelerator(accelerator_1, std::move(matcher))); | 294 EXPECT_TRUE(dispatcher.AddAccelerator(accelerator_1, std::move(matcher))); |
| 209 | 295 |
| 210 uint32_t accelerator_2 = 2; | 296 uint32_t accelerator_2 = 2; |
| 211 matcher = mus::CreateKeyMatcher(mus::mojom::KeyboardCode::N, | 297 matcher = mus::CreateKeyMatcher(mus::mojom::KeyboardCode::N, |
| 212 mus::mojom::kEventFlagNone); | 298 mus::mojom::kEventFlagNone); |
| 213 EXPECT_TRUE(dispatcher.AddAccelerator(accelerator_2, std::move(matcher))); | 299 EXPECT_TRUE(dispatcher.AddAccelerator(accelerator_2, std::move(matcher))); |
| 214 | 300 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 228 uint32_t accelerator_3 = 3; | 314 uint32_t accelerator_3 = 3; |
| 229 matcher = mus::CreateKeyMatcher(mus::mojom::KeyboardCode::T, | 315 matcher = mus::CreateKeyMatcher(mus::mojom::KeyboardCode::T, |
| 230 mus::mojom::kEventFlagNone); | 316 mus::mojom::kEventFlagNone); |
| 231 EXPECT_FALSE(dispatcher.AddAccelerator(accelerator_3, std::move(matcher))); | 317 EXPECT_FALSE(dispatcher.AddAccelerator(accelerator_3, std::move(matcher))); |
| 232 | 318 |
| 233 matcher = mus::CreateKeyMatcher(mus::mojom::KeyboardCode::T, | 319 matcher = mus::CreateKeyMatcher(mus::mojom::KeyboardCode::T, |
| 234 mus::mojom::kEventFlagControlDown); | 320 mus::mojom::kEventFlagControlDown); |
| 235 EXPECT_TRUE(dispatcher.AddAccelerator(accelerator_3, std::move(matcher))); | 321 EXPECT_TRUE(dispatcher.AddAccelerator(accelerator_3, std::move(matcher))); |
| 236 } | 322 } |
| 237 | 323 |
| 238 TEST(EventDispatcherTest, EventMatching) { | 324 TEST_F(EventDispatcherTest, EventMatching) { |
| 239 TestServerWindowDelegate window_delegate; | 325 TestEventDispatcherDelegate* event_dispatcher_delegate = |
| 240 ServerWindow root(&window_delegate, WindowId(1, 2)); | 326 test_event_dispatcher_delegate(); |
| 241 TestEventDispatcherDelegate event_dispatcher_delegate(&root); | 327 EventDispatcher* dispatcher = event_dispatcher(); |
| 242 EventDispatcher dispatcher(&event_dispatcher_delegate); | |
| 243 dispatcher.set_root(&root); | |
| 244 | 328 |
| 245 mojom::EventMatcherPtr matcher = mus::CreateKeyMatcher( | 329 mojom::EventMatcherPtr matcher = mus::CreateKeyMatcher( |
| 246 mus::mojom::KeyboardCode::W, mus::mojom::kEventFlagControlDown); | 330 mus::mojom::KeyboardCode::W, mus::mojom::kEventFlagControlDown); |
| 247 uint32_t accelerator_1 = 1; | 331 uint32_t accelerator_1 = 1; |
| 248 dispatcher.AddAccelerator(accelerator_1, std::move(matcher)); | 332 dispatcher->AddAccelerator(accelerator_1, std::move(matcher)); |
| 249 | 333 |
| 250 ui::KeyEvent key(ui::ET_KEY_PRESSED, ui::VKEY_W, ui::EF_CONTROL_DOWN); | 334 ui::KeyEvent key(ui::ET_KEY_PRESSED, ui::VKEY_W, ui::EF_CONTROL_DOWN); |
| 251 dispatcher.ProcessEvent(mojom::Event::From(key)); | 335 dispatcher->ProcessEvent(mojom::Event::From(key)); |
| 252 EXPECT_EQ(accelerator_1, | 336 EXPECT_EQ(accelerator_1, |
| 253 event_dispatcher_delegate.GetAndClearLastAccelerator()); | 337 event_dispatcher_delegate->GetAndClearLastAccelerator()); |
| 254 | 338 |
| 255 // EF_NUM_LOCK_ON should be ignored since CreateKeyMatcher defaults to | 339 // EF_NUM_LOCK_ON should be ignored since CreateKeyMatcher defaults to |
| 256 // ignoring. | 340 // ignoring. |
| 257 key = ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_W, | 341 key = ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_W, |
| 258 ui::EF_CONTROL_DOWN | ui::EF_NUM_LOCK_ON); | 342 ui::EF_CONTROL_DOWN | ui::EF_NUM_LOCK_ON); |
| 259 dispatcher.ProcessEvent(mojom::Event::From(key)); | 343 dispatcher->ProcessEvent(mojom::Event::From(key)); |
| 260 EXPECT_EQ(accelerator_1, | 344 EXPECT_EQ(accelerator_1, |
| 261 event_dispatcher_delegate.GetAndClearLastAccelerator()); | 345 event_dispatcher_delegate->GetAndClearLastAccelerator()); |
| 262 | 346 |
| 263 key = ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_W, ui::EF_NONE); | 347 key = ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_W, ui::EF_NONE); |
| 264 dispatcher.ProcessEvent(mojom::Event::From(key)); | 348 dispatcher->ProcessEvent(mojom::Event::From(key)); |
| 265 EXPECT_EQ(0u, event_dispatcher_delegate.GetAndClearLastAccelerator()); | 349 EXPECT_EQ(0u, event_dispatcher_delegate->GetAndClearLastAccelerator()); |
| 266 | 350 |
| 267 uint32_t accelerator_2 = 2; | 351 uint32_t accelerator_2 = 2; |
| 268 matcher = mus::CreateKeyMatcher(mus::mojom::KeyboardCode::W, | 352 matcher = mus::CreateKeyMatcher(mus::mojom::KeyboardCode::W, |
| 269 mus::mojom::kEventFlagNone); | 353 mus::mojom::kEventFlagNone); |
| 270 dispatcher.AddAccelerator(accelerator_2, std::move(matcher)); | 354 dispatcher->AddAccelerator(accelerator_2, std::move(matcher)); |
| 271 dispatcher.ProcessEvent(mojom::Event::From(key)); | 355 dispatcher->ProcessEvent(mojom::Event::From(key)); |
| 272 EXPECT_EQ(accelerator_2, | 356 EXPECT_EQ(accelerator_2, |
| 273 event_dispatcher_delegate.GetAndClearLastAccelerator()); | 357 event_dispatcher_delegate->GetAndClearLastAccelerator()); |
| 274 | 358 |
| 275 dispatcher.RemoveAccelerator(accelerator_2); | 359 dispatcher->RemoveAccelerator(accelerator_2); |
| 276 dispatcher.ProcessEvent(mojom::Event::From(key)); | 360 dispatcher->ProcessEvent(mojom::Event::From(key)); |
| 277 EXPECT_EQ(0u, event_dispatcher_delegate.GetAndClearLastAccelerator()); | 361 EXPECT_EQ(0u, event_dispatcher_delegate->GetAndClearLastAccelerator()); |
| 278 } | 362 } |
| 279 | 363 |
| 280 TEST(EventDispatcherTest, Capture) { | 364 TEST_F(EventDispatcherTest, Capture) { |
| 281 TestServerWindowDelegate window_delegate; | 365 ServerWindow* root = root_window(); |
| 282 ServerWindow root(&window_delegate, WindowId(1, 2)); | 366 scoped_ptr<ServerWindow> child(CreateChildWindow(WindowId(1, 3))); |
| 283 window_delegate.set_root_window(&root); | |
| 284 root.SetVisible(true); | |
| 285 | 367 |
| 286 ServerWindow child(&window_delegate, WindowId(1, 3)); | 368 root->SetBounds(gfx::Rect(0, 0, 100, 100)); |
| 287 root.Add(&child); | 369 child->SetBounds(gfx::Rect(10, 10, 20, 20)); |
| 288 child.SetVisible(true); | |
| 289 | |
| 290 root.SetBounds(gfx::Rect(0, 0, 100, 100)); | |
| 291 child.SetBounds(gfx::Rect(10, 10, 20, 20)); | |
| 292 EnableHitTest(&child); | |
| 293 | |
| 294 TestEventDispatcherDelegate event_dispatcher_delegate(&root); | |
| 295 EventDispatcher dispatcher(&event_dispatcher_delegate); | |
| 296 dispatcher.set_root(&root); | |
| 297 | 370 |
| 298 MouseEventTest tests[] = { | 371 MouseEventTest tests[] = { |
| 299 // Send a mouse down event over child. | 372 // Send a mouse down event over child. |
| 300 {ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(20, 25), | 373 {ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(20, 25), |
| 301 gfx::Point(20, 25), base::TimeDelta(), | 374 gfx::Point(20, 25), base::TimeDelta(), |
| 302 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON), | 375 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON), |
| 303 &child, gfx::Point(20, 25), gfx::Point(10, 15), nullptr, gfx::Point(), | 376 child.get(), gfx::Point(20, 25), gfx::Point(10, 15), nullptr, |
| 304 gfx::Point()}, | 377 gfx::Point(), gfx::Point()}, |
| 305 | 378 |
| 306 // Capture should be activated. Let's send a mouse move outside the bounds | 379 // Capture should be activated. Let's send a mouse move outside the bounds |
| 307 // of the child. | 380 // of the child. |
| 308 {ui::MouseEvent(ui::ET_MOUSE_MOVED, gfx::Point(50, 50), | 381 {ui::MouseEvent(ui::ET_MOUSE_MOVED, gfx::Point(50, 50), |
| 309 gfx::Point(50, 50), base::TimeDelta(), | 382 gfx::Point(50, 50), base::TimeDelta(), |
| 310 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON), | 383 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON), |
| 311 &child, gfx::Point(50, 50), gfx::Point(40, 40), nullptr, gfx::Point(), | 384 child.get(), gfx::Point(50, 50), gfx::Point(40, 40), nullptr, |
| 312 gfx::Point()}, | 385 gfx::Point(), gfx::Point()}, |
| 313 // Release the mouse and verify that the mouse up event goes to the child. | 386 // Release the mouse and verify that the mouse up event goes to the child. |
| 314 {ui::MouseEvent(ui::ET_MOUSE_RELEASED, gfx::Point(50, 50), | 387 {ui::MouseEvent(ui::ET_MOUSE_RELEASED, gfx::Point(50, 50), |
| 315 gfx::Point(50, 50), base::TimeDelta(), | 388 gfx::Point(50, 50), base::TimeDelta(), |
| 316 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON), | 389 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON), |
| 317 &child, gfx::Point(50, 50), gfx::Point(40, 40), nullptr, gfx::Point(), | 390 child.get(), gfx::Point(50, 50), gfx::Point(40, 40), nullptr, |
| 318 gfx::Point()}, | 391 gfx::Point(), gfx::Point()}, |
| 319 | 392 |
| 320 // A mouse move at (50, 50) should now go to the root window. As the | 393 // A mouse move at (50, 50) should now go to the root window. As the |
| 321 // move crosses between |child| and |root| |child| gets an exit, and | 394 // move crosses between |child| and |root| |child| gets an exit, and |
| 322 // |root| the move. | 395 // |root| the move. |
| 323 {ui::MouseEvent(ui::ET_MOUSE_MOVED, gfx::Point(50, 50), | 396 {ui::MouseEvent(ui::ET_MOUSE_MOVED, gfx::Point(50, 50), |
| 324 gfx::Point(50, 50), base::TimeDelta(), | 397 gfx::Point(50, 50), base::TimeDelta(), |
| 325 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON), | 398 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON), |
| 326 &child, gfx::Point(50, 50), gfx::Point(40, 40), &root, | 399 child.get(), gfx::Point(50, 50), gfx::Point(40, 40), root, |
| 327 gfx::Point(50, 50), gfx::Point(50, 50)}, | 400 gfx::Point(50, 50), gfx::Point(50, 50)}, |
| 328 | 401 |
| 329 }; | 402 }; |
| 330 RunMouseEventTests(&dispatcher, &event_dispatcher_delegate, tests, | 403 RunMouseEventTests(event_dispatcher(), test_event_dispatcher_delegate(), |
| 331 arraysize(tests)); | 404 tests, arraysize(tests)); |
| 332 } | 405 } |
| 333 | 406 |
| 334 TEST(EventDispatcherTest, CaptureMultipleMouseButtons) { | 407 TEST_F(EventDispatcherTest, CaptureMultipleMouseButtons) { |
| 335 TestServerWindowDelegate window_delegate; | 408 scoped_ptr<ServerWindow> child(CreateChildWindow(WindowId(1, 3))); |
| 336 ServerWindow root(&window_delegate, WindowId(1, 2)); | |
| 337 window_delegate.set_root_window(&root); | |
| 338 root.SetVisible(true); | |
| 339 | 409 |
| 340 ServerWindow child(&window_delegate, WindowId(1, 3)); | 410 root_window()->SetBounds(gfx::Rect(0, 0, 100, 100)); |
| 341 root.Add(&child); | 411 child->SetBounds(gfx::Rect(10, 10, 20, 20)); |
| 342 child.SetVisible(true); | |
| 343 EnableHitTest(&child); | |
| 344 | |
| 345 root.SetBounds(gfx::Rect(0, 0, 100, 100)); | |
| 346 child.SetBounds(gfx::Rect(10, 10, 20, 20)); | |
| 347 | |
| 348 TestEventDispatcherDelegate event_dispatcher_delegate(&root); | |
| 349 EventDispatcher dispatcher(&event_dispatcher_delegate); | |
| 350 dispatcher.set_root(&root); | |
| 351 | 412 |
| 352 MouseEventTest tests[] = { | 413 MouseEventTest tests[] = { |
| 353 // Send a mouse down event over child with a left mouse button | 414 // Send a mouse down event over child with a left mouse button |
| 354 {ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(20, 25), | 415 {ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(20, 25), |
| 355 gfx::Point(20, 25), base::TimeDelta(), | 416 gfx::Point(20, 25), base::TimeDelta(), |
| 356 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON), | 417 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON), |
| 357 &child, gfx::Point(20, 25), gfx::Point(10, 15), nullptr, gfx::Point(), | 418 child.get(), gfx::Point(20, 25), gfx::Point(10, 15), nullptr, |
| 358 gfx::Point()}, | 419 gfx::Point(), gfx::Point()}, |
| 359 | 420 |
| 360 // Capture should be activated. Let's send a mouse move outside the bounds | 421 // Capture should be activated. Let's send a mouse move outside the bounds |
| 361 // of the child and press the right mouse button too. | 422 // of the child and press the right mouse button too. |
| 362 {ui::MouseEvent(ui::ET_MOUSE_MOVED, gfx::Point(50, 50), | 423 {ui::MouseEvent(ui::ET_MOUSE_MOVED, gfx::Point(50, 50), |
| 363 gfx::Point(50, 50), base::TimeDelta(), | 424 gfx::Point(50, 50), base::TimeDelta(), |
| 364 ui::EF_LEFT_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON, 0), | 425 ui::EF_LEFT_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON, 0), |
| 365 &child, gfx::Point(50, 50), gfx::Point(40, 40), nullptr, gfx::Point(), | 426 child.get(), gfx::Point(50, 50), gfx::Point(40, 40), nullptr, |
| 366 gfx::Point()}, | 427 gfx::Point(), gfx::Point()}, |
| 367 | 428 |
| 368 // Release the left mouse button and verify that the mouse up event goes | 429 // Release the left mouse button and verify that the mouse up event goes |
| 369 // to the child. | 430 // to the child. |
| 370 {ui::MouseEvent(ui::ET_MOUSE_RELEASED, gfx::Point(50, 50), | 431 {ui::MouseEvent(ui::ET_MOUSE_RELEASED, gfx::Point(50, 50), |
| 371 gfx::Point(50, 50), base::TimeDelta(), | 432 gfx::Point(50, 50), base::TimeDelta(), |
| 372 ui::EF_LEFT_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON, | 433 ui::EF_LEFT_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON, |
| 373 ui::EF_RIGHT_MOUSE_BUTTON), | 434 ui::EF_RIGHT_MOUSE_BUTTON), |
| 374 &child, gfx::Point(50, 50), gfx::Point(40, 40), nullptr, gfx::Point(), | 435 child.get(), gfx::Point(50, 50), gfx::Point(40, 40), nullptr, |
| 375 gfx::Point()}, | 436 gfx::Point(), gfx::Point()}, |
| 376 | 437 |
| 377 // A mouse move at (50, 50) should still go to the child. | 438 // A mouse move at (50, 50) should still go to the child. |
| 378 {ui::MouseEvent(ui::ET_MOUSE_MOVED, gfx::Point(50, 50), | 439 {ui::MouseEvent(ui::ET_MOUSE_MOVED, gfx::Point(50, 50), |
| 379 gfx::Point(50, 50), base::TimeDelta(), | 440 gfx::Point(50, 50), base::TimeDelta(), |
| 380 ui::EF_LEFT_MOUSE_BUTTON, 0), | 441 ui::EF_LEFT_MOUSE_BUTTON, 0), |
| 381 &child, gfx::Point(50, 50), gfx::Point(40, 40), nullptr, gfx::Point(), | 442 child.get(), gfx::Point(50, 50), gfx::Point(40, 40), nullptr, |
| 382 gfx::Point()}, | 443 gfx::Point(), gfx::Point()}, |
| 383 | 444 |
| 384 }; | 445 }; |
| 385 RunMouseEventTests(&dispatcher, &event_dispatcher_delegate, tests, | 446 RunMouseEventTests(event_dispatcher(), test_event_dispatcher_delegate(), |
| 386 arraysize(tests)); | 447 tests, arraysize(tests)); |
| 387 } | 448 } |
| 388 | 449 |
| 389 TEST(EventDispatcherTest, ClientAreaGoesToOwner) { | 450 TEST_F(EventDispatcherTest, ClientAreaGoesToOwner) { |
| 390 TestServerWindowDelegate window_delegate; | 451 scoped_ptr<ServerWindow> child(CreateChildWindow(WindowId(1, 3))); |
| 391 ServerWindow root(&window_delegate, WindowId(1, 2)); | |
| 392 window_delegate.set_root_window(&root); | |
| 393 root.SetVisible(true); | |
| 394 | 452 |
| 395 ServerWindow child(&window_delegate, WindowId(1, 3)); | 453 root_window()->SetBounds(gfx::Rect(0, 0, 100, 100)); |
| 396 root.Add(&child); | 454 child->SetBounds(gfx::Rect(10, 10, 20, 20)); |
| 397 child.SetVisible(true); | |
| 398 EnableHitTest(&child); | |
| 399 | 455 |
| 400 root.SetBounds(gfx::Rect(0, 0, 100, 100)); | 456 child->SetClientArea(gfx::Insets(5, 5, 5, 5), std::vector<gfx::Rect>()); |
| 401 child.SetBounds(gfx::Rect(10, 10, 20, 20)); | |
| 402 | 457 |
| 403 child.SetClientArea(gfx::Insets(5, 5, 5, 5), std::vector<gfx::Rect>()); | 458 TestEventDispatcherDelegate* event_dispatcher_delegate = |
| 404 | 459 test_event_dispatcher_delegate(); |
| 405 TestEventDispatcherDelegate event_dispatcher_delegate(&root); | 460 EventDispatcher* dispatcher = event_dispatcher(); |
| 406 EventDispatcher dispatcher(&event_dispatcher_delegate); | |
| 407 dispatcher.set_root(&root); | |
| 408 | 461 |
| 409 // Start move loop by sending mouse event over non-client area. | 462 // Start move loop by sending mouse event over non-client area. |
| 410 const ui::MouseEvent press_event( | 463 const ui::MouseEvent press_event( |
| 411 ui::ET_MOUSE_PRESSED, gfx::Point(12, 12), gfx::Point(12, 12), | 464 ui::ET_MOUSE_PRESSED, gfx::Point(12, 12), gfx::Point(12, 12), |
| 412 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); | 465 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); |
| 413 dispatcher.ProcessEvent( | 466 dispatcher->ProcessEvent( |
| 414 mojom::Event::From(static_cast<const ui::Event&>(press_event))); | 467 mojom::Event::From(static_cast<const ui::Event&>(press_event))); |
| 415 | 468 |
| 416 // Events should target child and be in the non-client area. | 469 // Events should target child and be in the non-client area. |
| 417 scoped_ptr<DispatchedEventDetails> details = | 470 scoped_ptr<DispatchedEventDetails> details = |
| 418 event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails(); | 471 event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 419 EXPECT_FALSE(event_dispatcher_delegate.has_queued_events()); | 472 EXPECT_FALSE(event_dispatcher_delegate->has_queued_events()); |
| 420 ASSERT_TRUE(details); | 473 ASSERT_TRUE(details); |
| 421 ASSERT_EQ(&child, details->window); | 474 ASSERT_EQ(child.get(), details->window); |
| 422 EXPECT_TRUE(details->in_nonclient_area); | 475 EXPECT_TRUE(details->in_nonclient_area); |
| 423 | 476 |
| 424 // Move the mouse 5,6 pixels and target is the same. | 477 // Move the mouse 5,6 pixels and target is the same. |
| 425 const ui::MouseEvent move_event(ui::ET_MOUSE_MOVED, gfx::Point(17, 18), | 478 const ui::MouseEvent move_event(ui::ET_MOUSE_MOVED, gfx::Point(17, 18), |
| 426 gfx::Point(17, 18), base::TimeDelta(), | 479 gfx::Point(17, 18), base::TimeDelta(), |
| 427 ui::EF_LEFT_MOUSE_BUTTON, 0); | 480 ui::EF_LEFT_MOUSE_BUTTON, 0); |
| 428 dispatcher.ProcessEvent( | 481 dispatcher->ProcessEvent( |
| 429 mojom::Event::From(static_cast<const ui::Event&>(move_event))); | 482 mojom::Event::From(static_cast<const ui::Event&>(move_event))); |
| 430 | 483 |
| 431 // Still same target. | 484 // Still same target. |
| 432 details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails(); | 485 details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 433 EXPECT_FALSE(event_dispatcher_delegate.has_queued_events()); | 486 EXPECT_FALSE(event_dispatcher_delegate->has_queued_events()); |
| 434 ASSERT_EQ(&child, details->window); | 487 ASSERT_EQ(child.get(), details->window); |
| 435 EXPECT_TRUE(details->in_nonclient_area); | 488 EXPECT_TRUE(details->in_nonclient_area); |
| 436 | 489 |
| 437 // Release the mouse. | 490 // Release the mouse. |
| 438 const ui::MouseEvent release_event( | 491 const ui::MouseEvent release_event( |
| 439 ui::ET_MOUSE_RELEASED, gfx::Point(17, 18), gfx::Point(17, 18), | 492 ui::ET_MOUSE_RELEASED, gfx::Point(17, 18), gfx::Point(17, 18), |
| 440 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); | 493 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); |
| 441 dispatcher.ProcessEvent( | 494 dispatcher->ProcessEvent( |
| 442 mojom::Event::From(static_cast<const ui::Event&>(release_event))); | 495 mojom::Event::From(static_cast<const ui::Event&>(release_event))); |
| 443 | 496 |
| 444 // The event should not have been dispatched to the delegate. | 497 // The event should not have been dispatched to the delegate. |
| 445 details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails(); | 498 details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 446 EXPECT_FALSE(event_dispatcher_delegate.has_queued_events()); | 499 EXPECT_FALSE(event_dispatcher_delegate->has_queued_events()); |
| 447 ASSERT_EQ(&child, details->window); | 500 ASSERT_EQ(child.get(), details->window); |
| 448 EXPECT_TRUE(details->in_nonclient_area); | 501 EXPECT_TRUE(details->in_nonclient_area); |
| 449 | 502 |
| 450 // Press in the client area and verify target/client area. The non-client area | 503 // Press in the client area and verify target/client area. The non-client area |
| 451 // should get an exit first. | 504 // should get an exit first. |
| 452 const ui::MouseEvent press_event2( | 505 const ui::MouseEvent press_event2( |
| 453 ui::ET_MOUSE_PRESSED, gfx::Point(21, 22), gfx::Point(21, 22), | 506 ui::ET_MOUSE_PRESSED, gfx::Point(21, 22), gfx::Point(21, 22), |
| 454 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); | 507 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); |
| 455 dispatcher.ProcessEvent( | 508 dispatcher->ProcessEvent( |
| 456 mojom::Event::From(static_cast<const ui::Event&>(press_event2))); | 509 mojom::Event::From(static_cast<const ui::Event&>(press_event2))); |
| 457 details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails(); | 510 details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 458 EXPECT_TRUE(event_dispatcher_delegate.has_queued_events()); | 511 EXPECT_TRUE(event_dispatcher_delegate->has_queued_events()); |
| 459 ASSERT_EQ(&child, details->window); | 512 ASSERT_EQ(child.get(), details->window); |
| 460 EXPECT_TRUE(details->in_nonclient_area); | 513 EXPECT_TRUE(details->in_nonclient_area); |
| 461 EXPECT_EQ(mojom::EventType::MOUSE_EXIT, details->event->action); | 514 EXPECT_EQ(mojom::EventType::MOUSE_EXIT, details->event->action); |
| 462 | 515 |
| 463 details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails(); | 516 details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 464 EXPECT_FALSE(event_dispatcher_delegate.has_queued_events()); | 517 EXPECT_FALSE(event_dispatcher_delegate->has_queued_events()); |
| 465 ASSERT_EQ(&child, details->window); | 518 ASSERT_EQ(child.get(), details->window); |
| 466 EXPECT_FALSE(details->in_nonclient_area); | 519 EXPECT_FALSE(details->in_nonclient_area); |
| 467 EXPECT_EQ(mojom::EventType::POINTER_DOWN, details->event->action); | 520 EXPECT_EQ(mojom::EventType::POINTER_DOWN, details->event->action); |
| 468 } | 521 } |
| 469 | 522 |
| 470 TEST(EventDispatcherTest, AdditionalClientArea) { | 523 TEST_F(EventDispatcherTest, AdditionalClientArea) { |
| 471 TestServerWindowDelegate window_delegate; | 524 scoped_ptr<ServerWindow> child(CreateChildWindow(WindowId(1, 3))); |
| 472 ServerWindow root(&window_delegate, WindowId(1, 2)); | |
| 473 window_delegate.set_root_window(&root); | |
| 474 root.SetVisible(true); | |
| 475 | 525 |
| 476 ServerWindow child(&window_delegate, WindowId(1, 3)); | 526 root_window()->SetBounds(gfx::Rect(0, 0, 100, 100)); |
| 477 root.Add(&child); | 527 child->SetBounds(gfx::Rect(10, 10, 20, 20)); |
| 478 child.SetVisible(true); | |
| 479 EnableHitTest(&child); | |
| 480 | |
| 481 root.SetBounds(gfx::Rect(0, 0, 100, 100)); | |
| 482 child.SetBounds(gfx::Rect(10, 10, 20, 20)); | |
| 483 | 528 |
| 484 std::vector<gfx::Rect> additional_client_areas; | 529 std::vector<gfx::Rect> additional_client_areas; |
| 485 additional_client_areas.push_back(gfx::Rect(18, 0, 2, 2)); | 530 additional_client_areas.push_back(gfx::Rect(18, 0, 2, 2)); |
| 486 child.SetClientArea(gfx::Insets(5, 5, 5, 5), additional_client_areas); | 531 child->SetClientArea(gfx::Insets(5, 5, 5, 5), additional_client_areas); |
| 487 | 532 |
| 488 TestEventDispatcherDelegate event_dispatcher_delegate(&root); | 533 TestEventDispatcherDelegate* event_dispatcher_delegate = |
| 489 EventDispatcher dispatcher(&event_dispatcher_delegate); | 534 test_event_dispatcher_delegate(); |
| 490 dispatcher.set_root(&root); | |
| 491 | |
| 492 // Press in the additional client area, it should go to the child. | 535 // Press in the additional client area, it should go to the child. |
| 493 const ui::MouseEvent press_event( | 536 const ui::MouseEvent press_event( |
| 494 ui::ET_MOUSE_PRESSED, gfx::Point(28, 11), gfx::Point(28, 11), | 537 ui::ET_MOUSE_PRESSED, gfx::Point(28, 11), gfx::Point(28, 11), |
| 495 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); | 538 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); |
| 496 dispatcher.ProcessEvent( | 539 event_dispatcher()->ProcessEvent( |
| 497 mojom::Event::From(static_cast<const ui::Event&>(press_event))); | 540 mojom::Event::From(static_cast<const ui::Event&>(press_event))); |
| 498 | 541 |
| 499 // Events should target child and be in the client area. | 542 // Events should target child and be in the client area. |
| 500 scoped_ptr<DispatchedEventDetails> details = | 543 scoped_ptr<DispatchedEventDetails> details = |
| 501 event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails(); | 544 event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 502 EXPECT_FALSE(event_dispatcher_delegate.has_queued_events()); | 545 EXPECT_FALSE(event_dispatcher_delegate->has_queued_events()); |
| 503 ASSERT_EQ(&child, details->window); | 546 ASSERT_EQ(child.get(), details->window); |
| 504 EXPECT_FALSE(details->in_nonclient_area); | 547 EXPECT_FALSE(details->in_nonclient_area); |
| 505 } | 548 } |
| 506 | 549 |
| 507 TEST(EventDispatcherTest, DontFocusOnSecondDown) { | 550 TEST_F(EventDispatcherTest, DontFocusOnSecondDown) { |
| 508 TestServerWindowDelegate window_delegate; | 551 scoped_ptr<ServerWindow> child1(CreateChildWindow(WindowId(1, 3))); |
| 509 ServerWindow root(&window_delegate, WindowId(1, 2)); | 552 scoped_ptr<ServerWindow> child2(CreateChildWindow(WindowId(1, 4))); |
| 510 window_delegate.set_root_window(&root); | |
| 511 root.SetVisible(true); | |
| 512 | 553 |
| 513 ServerWindow child1(&window_delegate, WindowId(1, 3)); | 554 root_window()->SetBounds(gfx::Rect(0, 0, 100, 100)); |
| 514 root.Add(&child1); | 555 child1->SetBounds(gfx::Rect(10, 10, 20, 20)); |
| 515 child1.SetVisible(true); | 556 child2->SetBounds(gfx::Rect(50, 51, 11, 12)); |
| 516 EnableHitTest(&child1); | |
| 517 | 557 |
| 518 ServerWindow child2(&window_delegate, WindowId(1, 4)); | 558 TestEventDispatcherDelegate* event_dispatcher_delegate = |
| 519 root.Add(&child2); | 559 test_event_dispatcher_delegate(); |
| 520 child2.SetVisible(true); | 560 EventDispatcher* dispatcher = event_dispatcher(); |
| 521 EnableHitTest(&child2); | |
| 522 | |
| 523 root.SetBounds(gfx::Rect(0, 0, 100, 100)); | |
| 524 child1.SetBounds(gfx::Rect(10, 10, 20, 20)); | |
| 525 child2.SetBounds(gfx::Rect(50, 51, 11, 12)); | |
| 526 | |
| 527 TestEventDispatcherDelegate event_dispatcher_delegate(&root); | |
| 528 EventDispatcher dispatcher(&event_dispatcher_delegate); | |
| 529 dispatcher.set_root(&root); | |
| 530 | 561 |
| 531 // Press on child1. First press event should change focus. | 562 // Press on child1. First press event should change focus. |
| 532 const ui::MouseEvent press_event( | 563 const ui::MouseEvent press_event( |
| 533 ui::ET_MOUSE_PRESSED, gfx::Point(12, 12), gfx::Point(12, 12), | 564 ui::ET_MOUSE_PRESSED, gfx::Point(12, 12), gfx::Point(12, 12), |
| 534 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); | 565 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); |
| 535 dispatcher.ProcessEvent( | 566 dispatcher->ProcessEvent( |
| 536 mojom::Event::From(static_cast<const ui::Event&>(press_event))); | 567 mojom::Event::From(static_cast<const ui::Event&>(press_event))); |
| 537 scoped_ptr<DispatchedEventDetails> details = | 568 scoped_ptr<DispatchedEventDetails> details = |
| 538 event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails(); | 569 event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 539 EXPECT_FALSE(event_dispatcher_delegate.has_queued_events()); | 570 EXPECT_FALSE(event_dispatcher_delegate->has_queued_events()); |
| 540 EXPECT_EQ(&child1, details->window); | 571 EXPECT_EQ(child1.get(), details->window); |
| 541 EXPECT_EQ(&child1, event_dispatcher_delegate.GetAndClearLastFocusedWindow()); | 572 EXPECT_EQ(child1.get(), |
| 573 event_dispatcher_delegate->GetAndClearLastFocusedWindow()); |
| 542 | 574 |
| 543 // Press (with a different pointer id) on child2. Event should go to child2, | 575 // Press (with a different pointer id) on child2. Event should go to child2, |
| 544 // but focus should not change. | 576 // but focus should not change. |
| 545 const ui::TouchEvent touch_event(ui::ET_TOUCH_PRESSED, gfx::Point(53, 54), 2, | 577 const ui::TouchEvent touch_event(ui::ET_TOUCH_PRESSED, gfx::Point(53, 54), 2, |
| 546 base::TimeDelta()); | 578 base::TimeDelta()); |
| 547 dispatcher.ProcessEvent( | 579 dispatcher->ProcessEvent( |
| 548 mojom::Event::From(static_cast<const ui::Event&>(touch_event))); | 580 mojom::Event::From(static_cast<const ui::Event&>(touch_event))); |
| 549 details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails(); | 581 details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 550 EXPECT_FALSE(event_dispatcher_delegate.has_queued_events()); | 582 EXPECT_FALSE(event_dispatcher_delegate->has_queued_events()); |
| 551 EXPECT_EQ(&child2, details->window); | 583 EXPECT_EQ(child2.get(), details->window); |
| 552 EXPECT_EQ(nullptr, event_dispatcher_delegate.GetAndClearLastFocusedWindow()); | 584 EXPECT_EQ(nullptr, event_dispatcher_delegate->GetAndClearLastFocusedWindow()); |
| 553 } | 585 } |
| 554 | 586 |
| 555 TEST(EventDispatcherTest, TwoPointersActive) { | 587 TEST_F(EventDispatcherTest, TwoPointersActive) { |
| 556 TestServerWindowDelegate window_delegate; | 588 scoped_ptr<ServerWindow> child1(CreateChildWindow(WindowId(1, 3))); |
| 557 ServerWindow root(&window_delegate, WindowId(1, 2)); | 589 scoped_ptr<ServerWindow> child2(CreateChildWindow(WindowId(1, 4))); |
| 558 window_delegate.set_root_window(&root); | |
| 559 root.SetVisible(true); | |
| 560 | 590 |
| 561 ServerWindow child1(&window_delegate, WindowId(1, 3)); | 591 root_window()->SetBounds(gfx::Rect(0, 0, 100, 100)); |
| 562 root.Add(&child1); | 592 child1->SetBounds(gfx::Rect(10, 10, 20, 20)); |
| 563 child1.SetVisible(true); | 593 child2->SetBounds(gfx::Rect(50, 51, 11, 12)); |
| 564 EnableHitTest(&child1); | |
| 565 | 594 |
| 566 ServerWindow child2(&window_delegate, WindowId(1, 4)); | 595 TestEventDispatcherDelegate* event_dispatcher_delegate = |
| 567 root.Add(&child2); | 596 test_event_dispatcher_delegate(); |
| 568 child2.SetVisible(true); | 597 EventDispatcher* dispatcher = event_dispatcher(); |
| 569 EnableHitTest(&child2); | |
| 570 | |
| 571 root.SetBounds(gfx::Rect(0, 0, 100, 100)); | |
| 572 child1.SetBounds(gfx::Rect(10, 10, 20, 20)); | |
| 573 child2.SetBounds(gfx::Rect(50, 51, 11, 12)); | |
| 574 | |
| 575 TestEventDispatcherDelegate event_dispatcher_delegate(&root); | |
| 576 EventDispatcher dispatcher(&event_dispatcher_delegate); | |
| 577 dispatcher.set_root(&root); | |
| 578 | 598 |
| 579 // Press on child1. | 599 // Press on child1. |
| 580 const ui::TouchEvent touch_event1(ui::ET_TOUCH_PRESSED, gfx::Point(12, 13), 1, | 600 const ui::TouchEvent touch_event1(ui::ET_TOUCH_PRESSED, gfx::Point(12, 13), 1, |
| 581 base::TimeDelta()); | 601 base::TimeDelta()); |
| 582 dispatcher.ProcessEvent( | 602 dispatcher->ProcessEvent( |
| 583 mojom::Event::From(static_cast<const ui::Event&>(touch_event1))); | 603 mojom::Event::From(static_cast<const ui::Event&>(touch_event1))); |
| 584 scoped_ptr<DispatchedEventDetails> details = | 604 scoped_ptr<DispatchedEventDetails> details = |
| 585 event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails(); | 605 event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 586 EXPECT_EQ(&child1, details->window); | 606 EXPECT_EQ(child1.get(), details->window); |
| 587 | 607 |
| 588 // Drag over child2, child1 should get the drag. | 608 // Drag over child2, child1 should get the drag. |
| 589 const ui::TouchEvent drag_event1(ui::ET_TOUCH_MOVED, gfx::Point(53, 54), 1, | 609 const ui::TouchEvent drag_event1(ui::ET_TOUCH_MOVED, gfx::Point(53, 54), 1, |
| 590 base::TimeDelta()); | 610 base::TimeDelta()); |
| 591 dispatcher.ProcessEvent( | 611 dispatcher->ProcessEvent( |
| 592 mojom::Event::From(static_cast<const ui::Event&>(drag_event1))); | 612 mojom::Event::From(static_cast<const ui::Event&>(drag_event1))); |
| 593 details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails(); | 613 details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 594 EXPECT_EQ(&child1, details->window); | 614 EXPECT_EQ(child1.get(), details->window); |
| 595 | 615 |
| 596 // Press on child2 with a different touch id. | 616 // Press on child2 with a different touch id. |
| 597 const ui::TouchEvent touch_event2(ui::ET_TOUCH_PRESSED, gfx::Point(54, 55), 2, | 617 const ui::TouchEvent touch_event2(ui::ET_TOUCH_PRESSED, gfx::Point(54, 55), 2, |
| 598 base::TimeDelta()); | 618 base::TimeDelta()); |
| 599 dispatcher.ProcessEvent( | 619 dispatcher->ProcessEvent( |
| 600 mojom::Event::From(static_cast<const ui::Event&>(touch_event2))); | 620 mojom::Event::From(static_cast<const ui::Event&>(touch_event2))); |
| 601 details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails(); | 621 details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 602 EXPECT_EQ(&child2, details->window); | 622 EXPECT_EQ(child2.get(), details->window); |
| 603 | 623 |
| 604 // Drag over child1 with id 2, child2 should continue to get the drag. | 624 // Drag over child1 with id 2, child2 should continue to get the drag. |
| 605 const ui::TouchEvent drag_event2(ui::ET_TOUCH_MOVED, gfx::Point(13, 14), 2, | 625 const ui::TouchEvent drag_event2(ui::ET_TOUCH_MOVED, gfx::Point(13, 14), 2, |
| 606 base::TimeDelta()); | 626 base::TimeDelta()); |
| 607 dispatcher.ProcessEvent( | 627 dispatcher->ProcessEvent( |
| 608 mojom::Event::From(static_cast<const ui::Event&>(drag_event2))); | 628 mojom::Event::From(static_cast<const ui::Event&>(drag_event2))); |
| 609 details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails(); | 629 details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 610 EXPECT_EQ(&child2, details->window); | 630 EXPECT_EQ(child2.get(), details->window); |
| 611 | 631 |
| 612 // Drag again with id 1, child1 should continue to get it. | 632 // Drag again with id 1, child1 should continue to get it. |
| 613 dispatcher.ProcessEvent( | 633 dispatcher->ProcessEvent( |
| 614 mojom::Event::From(static_cast<const ui::Event&>(drag_event1))); | 634 mojom::Event::From(static_cast<const ui::Event&>(drag_event1))); |
| 615 details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails(); | 635 details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 616 EXPECT_EQ(&child1, details->window); | 636 EXPECT_EQ(child1.get(), details->window); |
| 617 | 637 |
| 618 // Release touch id 1, and click on 2. 2 should get it. | 638 // Release touch id 1, and click on 2. 2 should get it. |
| 619 const ui::TouchEvent touch_release(ui::ET_TOUCH_RELEASED, gfx::Point(54, 55), | 639 const ui::TouchEvent touch_release(ui::ET_TOUCH_RELEASED, gfx::Point(54, 55), |
| 620 1, base::TimeDelta()); | 640 1, base::TimeDelta()); |
| 621 dispatcher.ProcessEvent( | 641 dispatcher->ProcessEvent( |
| 622 mojom::Event::From(static_cast<const ui::Event&>(touch_release))); | 642 mojom::Event::From(static_cast<const ui::Event&>(touch_release))); |
| 623 details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails(); | 643 details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 624 EXPECT_EQ(&child1, details->window); | 644 EXPECT_EQ(child1.get(), details->window); |
| 625 const ui::TouchEvent touch_event3(ui::ET_TOUCH_PRESSED, gfx::Point(54, 55), 2, | 645 const ui::TouchEvent touch_event3(ui::ET_TOUCH_PRESSED, gfx::Point(54, 55), 2, |
| 626 base::TimeDelta()); | 646 base::TimeDelta()); |
| 627 dispatcher.ProcessEvent( | 647 dispatcher->ProcessEvent( |
| 628 mojom::Event::From(static_cast<const ui::Event&>(touch_event3))); | 648 mojom::Event::From(static_cast<const ui::Event&>(touch_event3))); |
| 629 details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails(); | 649 details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 630 EXPECT_EQ(&child2, details->window); | 650 EXPECT_EQ(child2.get(), details->window); |
| 631 } | 651 } |
| 632 | 652 |
| 633 TEST(EventDispatcherTest, DestroyWindowWhileGettingEvents) { | 653 TEST_F(EventDispatcherTest, DestroyWindowWhileGettingEvents) { |
| 634 TestServerWindowDelegate window_delegate; | 654 scoped_ptr<ServerWindow> child(CreateChildWindow(WindowId(1, 3))); |
| 635 ServerWindow root(&window_delegate, WindowId(1, 2)); | |
| 636 window_delegate.set_root_window(&root); | |
| 637 root.SetVisible(true); | |
| 638 | 655 |
| 639 scoped_ptr<ServerWindow> child( | 656 root_window()->SetBounds(gfx::Rect(0, 0, 100, 100)); |
| 640 new ServerWindow(&window_delegate, WindowId(1, 3))); | |
| 641 root.Add(child.get()); | |
| 642 child->SetVisible(true); | |
| 643 EnableHitTest(child.get()); | |
| 644 | |
| 645 root.SetBounds(gfx::Rect(0, 0, 100, 100)); | |
| 646 child->SetBounds(gfx::Rect(10, 10, 20, 20)); | 657 child->SetBounds(gfx::Rect(10, 10, 20, 20)); |
| 647 | 658 |
| 648 TestEventDispatcherDelegate event_dispatcher_delegate(&root); | 659 TestEventDispatcherDelegate* event_dispatcher_delegate = |
| 649 EventDispatcher dispatcher(&event_dispatcher_delegate); | 660 test_event_dispatcher_delegate(); |
| 650 dispatcher.set_root(&root); | 661 EventDispatcher* dispatcher = event_dispatcher(); |
| 651 | 662 |
| 652 // Press on child. | 663 // Press on child. |
| 653 const ui::TouchEvent touch_event1(ui::ET_TOUCH_PRESSED, gfx::Point(12, 13), 1, | 664 const ui::TouchEvent touch_event1(ui::ET_TOUCH_PRESSED, gfx::Point(12, 13), 1, |
| 654 base::TimeDelta()); | 665 base::TimeDelta()); |
| 655 dispatcher.ProcessEvent( | 666 dispatcher->ProcessEvent( |
| 656 mojom::Event::From(static_cast<const ui::Event&>(touch_event1))); | 667 mojom::Event::From(static_cast<const ui::Event&>(touch_event1))); |
| 657 scoped_ptr<DispatchedEventDetails> details = | 668 scoped_ptr<DispatchedEventDetails> details = |
| 658 event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails(); | 669 event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 659 EXPECT_FALSE(event_dispatcher_delegate.has_queued_events()); | 670 EXPECT_FALSE(event_dispatcher_delegate->has_queued_events()); |
| 660 EXPECT_EQ(child.get(), details->window); | 671 EXPECT_EQ(child.get(), details->window); |
| 661 | 672 |
| 662 // Delete child, and continue the drag. Event should not be dispatched. | 673 // Delete child, and continue the drag. Event should not be dispatched. |
| 663 child.reset(); | 674 child.reset(); |
| 664 | 675 |
| 665 const ui::TouchEvent drag_event1(ui::ET_TOUCH_MOVED, gfx::Point(53, 54), 1, | 676 const ui::TouchEvent drag_event1(ui::ET_TOUCH_MOVED, gfx::Point(53, 54), 1, |
| 666 base::TimeDelta()); | 677 base::TimeDelta()); |
| 667 dispatcher.ProcessEvent( | 678 dispatcher->ProcessEvent( |
| 668 mojom::Event::From(static_cast<const ui::Event&>(drag_event1))); | 679 mojom::Event::From(static_cast<const ui::Event&>(drag_event1))); |
| 669 details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails(); | 680 details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 670 EXPECT_EQ(nullptr, details.get()); | 681 EXPECT_EQ(nullptr, details.get()); |
| 671 } | 682 } |
| 672 | 683 |
| 673 TEST(EventDispatcherTest, MouseInExtendedHitTestRegion) { | 684 TEST_F(EventDispatcherTest, MouseInExtendedHitTestRegion) { |
| 674 TestServerWindowDelegate window_delegate; | 685 ServerWindow* root = root_window(); |
| 675 ServerWindow root(&window_delegate, WindowId(1, 2)); | 686 scoped_ptr<ServerWindow> child(CreateChildWindow(WindowId(1, 3))); |
| 676 window_delegate.set_root_window(&root); | |
| 677 root.SetVisible(true); | |
| 678 | 687 |
| 679 ServerWindow child(&window_delegate, WindowId(1, 3)); | 688 root->SetBounds(gfx::Rect(0, 0, 100, 100)); |
| 680 root.Add(&child); | 689 child->SetBounds(gfx::Rect(10, 10, 20, 20)); |
| 681 child.SetVisible(true); | |
| 682 EnableHitTest(&child); | |
| 683 | 690 |
| 684 root.SetBounds(gfx::Rect(0, 0, 100, 100)); | 691 TestEventDispatcherDelegate* event_dispatcher_delegate = |
| 685 child.SetBounds(gfx::Rect(10, 10, 20, 20)); | 692 test_event_dispatcher_delegate(); |
| 686 | 693 EventDispatcher* dispatcher = event_dispatcher(); |
| 687 TestEventDispatcherDelegate event_dispatcher_delegate(&root); | |
| 688 EventDispatcher dispatcher(&event_dispatcher_delegate); | |
| 689 dispatcher.set_root(&root); | |
| 690 | 694 |
| 691 // Send event that is not over child. | 695 // Send event that is not over child. |
| 692 const ui::MouseEvent ui_event( | 696 const ui::MouseEvent ui_event( |
| 693 ui::ET_MOUSE_PRESSED, gfx::Point(8, 9), gfx::Point(8, 9), | 697 ui::ET_MOUSE_PRESSED, gfx::Point(8, 9), gfx::Point(8, 9), |
| 694 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); | 698 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); |
| 695 dispatcher.ProcessEvent( | 699 dispatcher->ProcessEvent( |
| 696 mojom::Event::From(static_cast<const ui::Event&>(ui_event))); | 700 mojom::Event::From(static_cast<const ui::Event&>(ui_event))); |
| 697 scoped_ptr<DispatchedEventDetails> details = | 701 scoped_ptr<DispatchedEventDetails> details = |
| 698 event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails(); | 702 event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 699 ASSERT_EQ(&root, details->window); | 703 ASSERT_EQ(root, details->window); |
| 700 | 704 |
| 701 // Release the mouse. | 705 // Release the mouse. |
| 702 const ui::MouseEvent release_event( | 706 const ui::MouseEvent release_event( |
| 703 ui::ET_MOUSE_RELEASED, gfx::Point(8, 9), gfx::Point(8, 9), | 707 ui::ET_MOUSE_RELEASED, gfx::Point(8, 9), gfx::Point(8, 9), |
| 704 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); | 708 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); |
| 705 dispatcher.ProcessEvent( | 709 dispatcher->ProcessEvent( |
| 706 mojom::Event::From(static_cast<const ui::Event&>(release_event))); | 710 mojom::Event::From(static_cast<const ui::Event&>(release_event))); |
| 707 details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails(); | 711 details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 708 EXPECT_FALSE(event_dispatcher_delegate.has_queued_events()); | 712 EXPECT_FALSE(event_dispatcher_delegate->has_queued_events()); |
| 709 ASSERT_EQ(&root, details->window); | 713 ASSERT_EQ(root, details->window); |
| 710 EXPECT_FALSE(details->in_nonclient_area); | 714 EXPECT_FALSE(details->in_nonclient_area); |
| 711 | 715 |
| 712 // Change the extended hit test region and send event in extended hit test | 716 // Change the extended hit test region and send event in extended hit test |
| 713 // region. Should result in exit for root, followed by press for child. | 717 // region. Should result in exit for root, followed by press for child. |
| 714 child.set_extended_hit_test_region(gfx::Insets(5, 5, 5, 5)); | 718 child->set_extended_hit_test_region(gfx::Insets(5, 5, 5, 5)); |
| 715 dispatcher.ProcessEvent( | 719 dispatcher->ProcessEvent( |
| 716 mojom::Event::From(static_cast<const ui::Event&>(ui_event))); | 720 mojom::Event::From(static_cast<const ui::Event&>(ui_event))); |
| 717 details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails(); | 721 details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 718 EXPECT_EQ(&root, details->window); | 722 EXPECT_EQ(root, details->window); |
| 719 EXPECT_EQ(mojom::EventType::MOUSE_EXIT, details->event->action); | 723 EXPECT_EQ(mojom::EventType::MOUSE_EXIT, details->event->action); |
| 720 details = event_dispatcher_delegate.GetAndAdvanceDispatchedEventDetails(); | 724 details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 721 ASSERT_TRUE(details); | 725 ASSERT_TRUE(details); |
| 722 | 726 |
| 723 EXPECT_FALSE(event_dispatcher_delegate.has_queued_events()); | 727 EXPECT_FALSE(event_dispatcher_delegate->has_queued_events()); |
| 724 EXPECT_TRUE(details->in_nonclient_area); | 728 EXPECT_TRUE(details->in_nonclient_area); |
| 725 ASSERT_EQ(&child, details->window); | 729 ASSERT_EQ(child.get(), details->window); |
| 726 EXPECT_EQ(mojom::EventType::POINTER_DOWN, details->event->action); | 730 EXPECT_EQ(mojom::EventType::POINTER_DOWN, details->event->action); |
| 727 scoped_ptr<ui::Event> dispatched_event( | 731 scoped_ptr<ui::Event> dispatched_event( |
| 728 details->event.To<scoped_ptr<ui::Event>>()); | 732 details->event.To<scoped_ptr<ui::Event>>()); |
| 729 ASSERT_TRUE(dispatched_event.get()); | 733 ASSERT_TRUE(dispatched_event.get()); |
| 730 ASSERT_TRUE(dispatched_event->IsMouseEvent()); | 734 ASSERT_TRUE(dispatched_event->IsMouseEvent()); |
| 731 ui::MouseEvent* dispatched_mouse_event = | 735 ui::MouseEvent* dispatched_mouse_event = |
| 732 static_cast<ui::MouseEvent*>(dispatched_event.get()); | 736 static_cast<ui::MouseEvent*>(dispatched_event.get()); |
| 733 EXPECT_EQ(gfx::Point(-2, -1), dispatched_mouse_event->location()); | 737 EXPECT_EQ(gfx::Point(-2, -1), dispatched_mouse_event->location()); |
| 734 } | 738 } |
| 735 | 739 |
| 736 TEST(EventDispatcherTest, WheelWhileDown) { | 740 TEST_F(EventDispatcherTest, WheelWhileDown) { |
| 737 TestServerWindowDelegate window_delegate; | 741 scoped_ptr<ServerWindow> child1(CreateChildWindow(WindowId(1, 3))); |
| 738 ServerWindow root(&window_delegate, WindowId(1, 2)); | 742 scoped_ptr<ServerWindow> child2(CreateChildWindow(WindowId(1, 4))); |
| 739 window_delegate.set_root_window(&root); | 743 |
| 740 root.SetVisible(true); | 744 root_window()->SetBounds(gfx::Rect(0, 0, 100, 100)); |
| 741 | 745 child1->SetBounds(gfx::Rect(10, 10, 20, 20)); |
| 742 ServerWindow child1(&window_delegate, WindowId(1, 3)); | 746 child2->SetBounds(gfx::Rect(50, 51, 11, 12)); |
| 743 root.Add(&child1); | |
| 744 child1.SetVisible(true); | |
| 745 EnableHitTest(&child1); | |
| 746 | |
| 747 ServerWindow child2(&window_delegate, WindowId(1, 4)); | |
| 748 root.Add(&child2); | |
| 749 child2.SetVisible(true); | |
| 750 EnableHitTest(&child2); | |
| 751 | |
| 752 root.SetBounds(gfx::Rect(0, 0, 100, 100)); | |
| 753 child1.SetBounds(gfx::Rect(10, 10, 20, 20)); | |
| 754 child2.SetBounds(gfx::Rect(50, 51, 11, 12)); | |
| 755 | |
| 756 TestEventDispatcherDelegate event_dispatcher_delegate(&root); | |
| 757 EventDispatcher dispatcher(&event_dispatcher_delegate); | |
| 758 dispatcher.set_root(&root); | |
| 759 | 747 |
| 760 MouseEventTest tests[] = { | 748 MouseEventTest tests[] = { |
| 761 // Send a mouse down event over child1. | 749 // Send a mouse down event over child1. |
| 762 {ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(15, 15), | 750 {ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(15, 15), |
| 763 gfx::Point(15, 15), base::TimeDelta(), | 751 gfx::Point(15, 15), base::TimeDelta(), |
| 764 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON), | 752 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON), |
| 765 &child1, gfx::Point(15, 15), gfx::Point(5, 5), nullptr, gfx::Point(), | 753 child1.get(), gfx::Point(15, 15), gfx::Point(5, 5), nullptr, |
| 766 gfx::Point()}, | 754 gfx::Point(), gfx::Point()}, |
| 767 // Send mouse wheel over child2, should go to child1 as it has capture. | 755 // Send mouse wheel over child2, should go to child1 as it has capture. |
| 768 {ui::MouseWheelEvent(gfx::Vector2d(1, 0), gfx::Point(53, 54), | 756 {ui::MouseWheelEvent(gfx::Vector2d(1, 0), gfx::Point(53, 54), |
| 769 gfx::Point(53, 54), base::TimeDelta(), ui::EF_NONE, | 757 gfx::Point(53, 54), base::TimeDelta(), ui::EF_NONE, |
| 770 ui::EF_NONE), | 758 ui::EF_NONE), |
| 771 &child1, gfx::Point(53, 54), gfx::Point(43, 44), nullptr, gfx::Point(), | 759 child1.get(), gfx::Point(53, 54), gfx::Point(43, 44), nullptr, |
| 772 gfx::Point()}, | 760 gfx::Point(), gfx::Point()}, |
| 773 }; | 761 }; |
| 774 RunMouseEventTests(&dispatcher, &event_dispatcher_delegate, tests, | 762 RunMouseEventTests(event_dispatcher(), test_event_dispatcher_delegate(), |
| 763 tests, arraysize(tests)); |
| 764 } |
| 765 |
| 766 // Tests that when explicit capture has been set that all events go to the |
| 767 // designated window, and that when capture is cleared, events find the |
| 768 // appropriate target window. |
| 769 TEST_F(EventDispatcherTest, SetExplicitCapture) { |
| 770 ServerWindow* root = root_window(); |
| 771 scoped_ptr<ServerWindow> child(CreateChildWindow(WindowId(1, 3))); |
| 772 |
| 773 root->SetBounds(gfx::Rect(0, 0, 100, 100)); |
| 774 child->SetBounds(gfx::Rect(10, 10, 20, 20)); |
| 775 |
| 776 TestEventDispatcherDelegate* event_dispatcher_delegate = |
| 777 test_event_dispatcher_delegate(); |
| 778 EventDispatcher* dispatcher = event_dispatcher(); |
| 779 |
| 780 { |
| 781 // Send all pointer events to the child. |
| 782 dispatcher->SetCaptureWindow(child.get(), false); |
| 783 |
| 784 // The mouse press should go to the child even though its outside its |
| 785 // bounds. |
| 786 const ui::MouseEvent left_press_event( |
| 787 ui::ET_MOUSE_PRESSED, gfx::Point(5, 5), gfx::Point(5, 5), |
| 788 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); |
| 789 dispatcher->ProcessEvent( |
| 790 mojom::Event::From(static_cast<const ui::Event&>(left_press_event))); |
| 791 |
| 792 // Events should target child. |
| 793 scoped_ptr<DispatchedEventDetails> details = |
| 794 event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 795 |
| 796 ASSERT_TRUE(details); |
| 797 ASSERT_EQ(child.get(), details->window); |
| 798 EXPECT_FALSE(details->in_nonclient_area); |
| 799 EXPECT_TRUE(IsMouseButtonDown()); |
| 800 |
| 801 // The mouse down state should update while capture is set. |
| 802 const ui::MouseEvent right_press_event( |
| 803 ui::ET_MOUSE_PRESSED, gfx::Point(5, 5), gfx::Point(5, 5), |
| 804 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON, |
| 805 ui::EF_RIGHT_MOUSE_BUTTON); |
| 806 dispatcher->ProcessEvent( |
| 807 mojom::Event::From(static_cast<const ui::Event&>(right_press_event))); |
| 808 details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 809 EXPECT_TRUE(IsMouseButtonDown()); |
| 810 |
| 811 // One button released should not clear mouse down |
| 812 const ui::MouseEvent left_release_event( |
| 813 ui::ET_MOUSE_RELEASED, gfx::Point(5, 5), gfx::Point(5, 5), |
| 814 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON, |
| 815 ui::EF_LEFT_MOUSE_BUTTON); |
| 816 dispatcher->ProcessEvent( |
| 817 mojom::Event::From(static_cast<const ui::Event&>(left_release_event))); |
| 818 details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 819 EXPECT_TRUE(IsMouseButtonDown()); |
| 820 |
| 821 // Touch Event while mouse is down should not affect state. |
| 822 const ui::TouchEvent touch_event(ui::ET_TOUCH_PRESSED, gfx::Point(15, 15), |
| 823 2, base::TimeDelta()); |
| 824 dispatcher->ProcessEvent( |
| 825 mojom::Event::From(static_cast<const ui::Event&>(touch_event))); |
| 826 details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 827 EXPECT_TRUE(IsMouseButtonDown()); |
| 828 |
| 829 // Move event should not affect down |
| 830 const ui::MouseEvent move_event(ui::ET_MOUSE_MOVED, gfx::Point(15, 5), |
| 831 gfx::Point(15, 5), base::TimeDelta(), |
| 832 ui::EF_RIGHT_MOUSE_BUTTON, |
| 833 ui::EF_RIGHT_MOUSE_BUTTON); |
| 834 dispatcher->ProcessEvent( |
| 835 mojom::Event::From(static_cast<const ui::Event&>(move_event))); |
| 836 details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 837 EXPECT_TRUE(IsMouseButtonDown()); |
| 838 |
| 839 // All mouse buttons up should clear mouse down. |
| 840 const ui::MouseEvent right_release_event( |
| 841 ui::ET_MOUSE_RELEASED, gfx::Point(5, 5), gfx::Point(5, 5), |
| 842 base::TimeDelta(), ui::EF_RIGHT_MOUSE_BUTTON, |
| 843 ui::EF_RIGHT_MOUSE_BUTTON); |
| 844 dispatcher->ProcessEvent( |
| 845 mojom::Event::From(static_cast<const ui::Event&>(right_release_event))); |
| 846 details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 847 EXPECT_FALSE(IsMouseButtonDown()); |
| 848 } |
| 849 |
| 850 { |
| 851 // Releasing capture and sending the same event will go to the root. |
| 852 dispatcher->SetCaptureWindow(nullptr, false); |
| 853 const ui::MouseEvent press_event( |
| 854 ui::ET_MOUSE_PRESSED, gfx::Point(5, 5), gfx::Point(5, 5), |
| 855 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); |
| 856 dispatcher->ProcessEvent( |
| 857 mojom::Event::From(static_cast<const ui::Event&>(press_event))); |
| 858 |
| 859 // Events should target the root. |
| 860 scoped_ptr<DispatchedEventDetails> details = |
| 861 event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 862 |
| 863 ASSERT_TRUE(details); |
| 864 ASSERT_EQ(root, details->window); |
| 865 } |
| 866 } |
| 867 |
| 868 // This test verifies that explicit capture overrides and resets implicit |
| 869 // capture. |
| 870 TEST_F(EventDispatcherTest, ExplicitCaptureOverridesImplicitCapture) { |
| 871 ServerWindow* root = root_window(); |
| 872 scoped_ptr<ServerWindow> child(CreateChildWindow(WindowId(1, 3))); |
| 873 |
| 874 root->SetBounds(gfx::Rect(0, 0, 100, 100)); |
| 875 child->SetBounds(gfx::Rect(10, 10, 20, 20)); |
| 876 |
| 877 TestEventDispatcherDelegate* event_dispatcher_delegate = |
| 878 test_event_dispatcher_delegate(); |
| 879 EventDispatcher* dispatcher = event_dispatcher(); |
| 880 |
| 881 // Run some implicit capture tests. |
| 882 MouseEventTest tests[] = { |
| 883 // Send a mouse down event over child with a left mouse button |
| 884 {ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(20, 25), |
| 885 gfx::Point(20, 25), base::TimeDelta(), |
| 886 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON), |
| 887 child.get(), gfx::Point(20, 25), gfx::Point(10, 15)}, |
| 888 // Capture should be activated. Let's send a mouse move outside the bounds |
| 889 // of the child and press the right mouse button too. |
| 890 {ui::MouseEvent(ui::ET_MOUSE_MOVED, gfx::Point(50, 50), |
| 891 gfx::Point(50, 50), base::TimeDelta(), |
| 892 ui::EF_LEFT_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON, 0), |
| 893 child.get(), gfx::Point(50, 50), gfx::Point(40, 40)}, |
| 894 // Release the left mouse button and verify that the mouse up event goes |
| 895 // to the child. |
| 896 {ui::MouseEvent(ui::ET_MOUSE_RELEASED, gfx::Point(50, 50), |
| 897 gfx::Point(50, 50), base::TimeDelta(), |
| 898 ui::EF_LEFT_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON, |
| 899 ui::EF_RIGHT_MOUSE_BUTTON), |
| 900 child.get(), gfx::Point(50, 50), gfx::Point(40, 40)}, |
| 901 // A mouse move at (50, 50) should still go to the child. |
| 902 {ui::MouseEvent(ui::ET_MOUSE_MOVED, gfx::Point(50, 50), |
| 903 gfx::Point(50, 50), base::TimeDelta(), |
| 904 ui::EF_LEFT_MOUSE_BUTTON, 0), |
| 905 child.get(), gfx::Point(50, 50), gfx::Point(40, 40)}, |
| 906 |
| 907 }; |
| 908 RunMouseEventTests(dispatcher, event_dispatcher_delegate, tests, |
| 775 arraysize(tests)); | 909 arraysize(tests)); |
| 910 |
| 911 // Add a second pointer target to the child. |
| 912 { |
| 913 const ui::TouchEvent touch_event(ui::ET_TOUCH_PRESSED, gfx::Point(12, 13), |
| 914 1, base::TimeDelta()); |
| 915 dispatcher->ProcessEvent( |
| 916 mojom::Event::From(static_cast<const ui::Event&>(touch_event))); |
| 917 } |
| 918 |
| 919 scoped_ptr<DispatchedEventDetails> details = |
| 920 event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 921 EXPECT_FALSE(event_dispatcher_delegate->has_queued_events()); |
| 922 EXPECT_EQ(child.get(), details->window); |
| 923 |
| 924 // Verify that no window has explicit capture and hence we did indeed do |
| 925 // implicit capture. |
| 926 ASSERT_EQ(nullptr, dispatcher->capture_window()); |
| 927 |
| 928 // Give the root window explicit capture and verify input events over the |
| 929 // child go to the root instead. |
| 930 dispatcher->SetCaptureWindow(root, true); |
| 931 |
| 932 // The implicit target should receive a cancel event for each pointer target. |
| 933 details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 934 ASSERT_TRUE(details); |
| 935 EXPECT_TRUE(event_dispatcher_delegate->has_queued_events()); |
| 936 EXPECT_EQ(child.get(), details->window); |
| 937 EXPECT_EQ(mojom::EventType::POINTER_CANCEL, details->event->action); |
| 938 |
| 939 details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 940 ASSERT_TRUE(details); |
| 941 EXPECT_FALSE(event_dispatcher_delegate->has_queued_events()); |
| 942 EXPECT_EQ(child.get(), details->window); |
| 943 EXPECT_EQ(mojom::EventType::POINTER_CANCEL, details->event->action); |
| 944 |
| 945 const ui::MouseEvent press_event( |
| 946 ui::ET_MOUSE_PRESSED, gfx::Point(15, 15), gfx::Point(15, 15), |
| 947 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); |
| 948 dispatcher->ProcessEvent( |
| 949 mojom::Event::From(static_cast<const ui::Event&>(press_event))); |
| 950 |
| 951 // Events should target the root. |
| 952 details = event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 953 ASSERT_TRUE(details); |
| 954 ASSERT_EQ(root, details->window); |
| 955 ASSERT_TRUE(details->in_nonclient_area); |
| 956 } |
| 957 |
| 958 // Tests that setting capture does delete active pointer targets for the capture |
| 959 // window. |
| 960 TEST_F(EventDispatcherTest, CaptureUpdatesActivePointerTargets) { |
| 961 ServerWindow* root = root_window(); |
| 962 root->SetBounds(gfx::Rect(0, 0, 100, 100)); |
| 963 |
| 964 EventDispatcher* dispatcher = event_dispatcher(); |
| 965 { |
| 966 const ui::MouseEvent press_event( |
| 967 ui::ET_MOUSE_PRESSED, gfx::Point(5, 5), gfx::Point(5, 5), |
| 968 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); |
| 969 dispatcher->ProcessEvent( |
| 970 mojom::Event::From(static_cast<const ui::Event&>(press_event))); |
| 971 |
| 972 scoped_ptr<DispatchedEventDetails> details = |
| 973 test_event_dispatcher_delegate()->GetAndAdvanceDispatchedEventDetails(); |
| 974 ASSERT_TRUE(details); |
| 975 ASSERT_EQ(root, details->window); |
| 976 } |
| 977 { |
| 978 const ui::TouchEvent touch_event(ui::ET_TOUCH_PRESSED, gfx::Point(12, 13), |
| 979 1, base::TimeDelta()); |
| 980 dispatcher->ProcessEvent( |
| 981 mojom::Event::From(static_cast<const ui::Event&>(touch_event))); |
| 982 } |
| 983 |
| 984 ASSERT_TRUE(AreAnyPointersDown()); |
| 985 ASSERT_TRUE(IsWindowPointerTarget(root)); |
| 986 EXPECT_EQ(2, NumberPointerTargetsForWindow(root)); |
| 987 |
| 988 // Setting the capture should clear the implicit pointers for the specified |
| 989 // window. |
| 990 dispatcher->SetCaptureWindow(root, true); |
| 991 EXPECT_FALSE(AreAnyPointersDown()); |
| 992 EXPECT_FALSE(IsWindowPointerTarget(root)); |
| 993 } |
| 994 |
| 995 // Tests that when explicit capture is changed, that the previous window with |
| 996 // capture is no longer being observed. |
| 997 TEST_F(EventDispatcherTest, UpdatingCaptureStopsObservingPreviousCapture) { |
| 998 scoped_ptr<ServerWindow> child1(CreateChildWindow(WindowId(1, 3))); |
| 999 scoped_ptr<ServerWindow> child2(CreateChildWindow(WindowId(1, 4))); |
| 1000 |
| 1001 root_window()->SetBounds(gfx::Rect(0, 0, 100, 100)); |
| 1002 child1->SetBounds(gfx::Rect(10, 10, 20, 20)); |
| 1003 child2->SetBounds(gfx::Rect(50, 51, 11, 12)); |
| 1004 |
| 1005 EventDispatcher* dispatcher = event_dispatcher(); |
| 1006 ASSERT_FALSE(AreAnyPointersDown()); |
| 1007 ASSERT_FALSE(IsWindowPointerTarget(child1.get())); |
| 1008 ASSERT_FALSE(IsWindowPointerTarget(child2.get())); |
| 1009 dispatcher->SetCaptureWindow(child1.get(), false); |
| 1010 dispatcher->SetCaptureWindow(child2.get(), false); |
| 1011 EXPECT_EQ(child1.get(), |
| 1012 test_event_dispatcher_delegate()->lost_capture_window()); |
| 1013 |
| 1014 // If observing does not stop during the capture update this crashes. |
| 1015 child1->AddObserver(dispatcher); |
| 1016 } |
| 1017 |
| 1018 // Tests that destroying a window with explicit capture clears the capture |
| 1019 // state. |
| 1020 TEST_F(EventDispatcherTest, DestroyingCaptureWindowRemovesExplicitCapture) { |
| 1021 scoped_ptr<ServerWindow> child(CreateChildWindow(WindowId(1, 3))); |
| 1022 child->SetBounds(gfx::Rect(10, 10, 20, 20)); |
| 1023 |
| 1024 EventDispatcher* dispatcher = event_dispatcher(); |
| 1025 dispatcher->SetCaptureWindow(child.get(), false); |
| 1026 EXPECT_EQ(child.get(), dispatcher->capture_window()); |
| 1027 |
| 1028 ServerWindow* lost_capture_window = child.get(); |
| 1029 child.reset(); |
| 1030 EXPECT_EQ(nullptr, dispatcher->capture_window()); |
| 1031 EXPECT_EQ(lost_capture_window, |
| 1032 test_event_dispatcher_delegate()->lost_capture_window()); |
| 1033 } |
| 1034 |
| 1035 // Tests that when |in_nonclient_area| is set for a window performing capture, |
| 1036 // that this preference is used regardless of whether an event targets the |
| 1037 // client region. |
| 1038 TEST_F(EventDispatcherTest, CaptureInNonClientAreaOverridesActualPoint) { |
| 1039 ServerWindow* root = root_window(); |
| 1040 root->SetBounds(gfx::Rect(0, 0, 100, 100)); |
| 1041 |
| 1042 root->SetClientArea(gfx::Insets(5, 5, 5, 5), std::vector<gfx::Rect>()); |
| 1043 EventDispatcher* dispatcher = event_dispatcher(); |
| 1044 dispatcher->SetCaptureWindow(root, true); |
| 1045 |
| 1046 TestEventDispatcherDelegate* event_dispatcher_delegate = |
| 1047 test_event_dispatcher_delegate(); |
| 1048 // Press in the client area, it should be marked as non client. |
| 1049 const ui::MouseEvent press_event( |
| 1050 ui::ET_MOUSE_PRESSED, gfx::Point(6, 6), gfx::Point(6, 6), |
| 1051 base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); |
| 1052 event_dispatcher()->ProcessEvent( |
| 1053 mojom::Event::From(static_cast<const ui::Event&>(press_event))); |
| 1054 |
| 1055 // Events should target child and be in the client area. |
| 1056 scoped_ptr<DispatchedEventDetails> details = |
| 1057 event_dispatcher_delegate->GetAndAdvanceDispatchedEventDetails(); |
| 1058 EXPECT_FALSE(event_dispatcher_delegate->has_queued_events()); |
| 1059 ASSERT_EQ(root, details->window); |
| 1060 EXPECT_TRUE(details->in_nonclient_area); |
| 776 } | 1061 } |
| 777 | 1062 |
| 778 } // namespace ws | 1063 } // namespace ws |
| 779 } // namespace mus | 1064 } // namespace mus |
| OLD | NEW |