Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(117)

Side by Side Diff: components/mus/ws/event_dispatcher_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698