Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / ash / extended_desktop_unittest.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ash/display/display_controller.h"
6 #include "ash/display/display_manager.h"
7 #include "ash/root_window_controller.h"
8 #include "ash/screen_util.h"
9 #include "ash/shell.h"
10 #include "ash/shell_window_ids.h"
11 #include "ash/system/tray/system_tray.h"
12 #include "ash/test/ash_test_base.h"
13 #include "ash/wm/coordinate_conversion.h"
14 #include "ash/wm/window_properties.h"
15 #include "ash/wm/window_util.h"
16 #include "base/strings/string_util.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "ui/aura/client/capture_client.h"
19 #include "ui/aura/client/focus_client.h"
20 #include "ui/aura/test/test_windows.h"
21 #include "ui/aura/test/window_test_api.h"
22 #include "ui/aura/window.h"
23 #include "ui/aura/window_event_dispatcher.h"
24 #include "ui/base/cursor/cursor.h"
25 #include "ui/events/event_handler.h"
26 #include "ui/events/test/event_generator.h"
27 #include "ui/gfx/display.h"
28 #include "ui/gfx/screen.h"
29 #include "ui/views/controls/textfield/textfield.h"
30 #include "ui/views/widget/widget.h"
31 #include "ui/views/widget/widget_delegate.h"
32 #include "ui/wm/public/activation_client.h"
33
34 namespace ash {
35 namespace {
36
37 void SetSecondaryDisplayLayout(DisplayLayout::Position position) {
38   DisplayLayout layout =
39       Shell::GetInstance()->display_manager()->GetCurrentDisplayLayout();
40   layout.position = position;
41   Shell::GetInstance()->display_manager()->
42       SetLayoutForCurrentDisplays(layout);
43 }
44
45 class ModalWidgetDelegate : public views::WidgetDelegateView {
46  public:
47   ModalWidgetDelegate() {}
48   ~ModalWidgetDelegate() override {}
49
50   // Overridden from views::WidgetDelegate:
51   views::View* GetContentsView() override { return this; }
52   ui::ModalType GetModalType() const override { return ui::MODAL_TYPE_SYSTEM; }
53
54  private:
55   DISALLOW_COPY_AND_ASSIGN(ModalWidgetDelegate);
56 };
57
58 // An event handler which moves the target window to the secondary root window
59 // at pre-handle phase of a mouse release event.
60 class MoveWindowByClickEventHandler : public ui::EventHandler {
61  public:
62   explicit MoveWindowByClickEventHandler(aura::Window* target)
63       : target_(target) {}
64   ~MoveWindowByClickEventHandler() override {}
65
66  private:
67   // ui::EventHandler overrides:
68   void OnMouseEvent(ui::MouseEvent* event) override {
69     if (event->type() == ui::ET_MOUSE_RELEASED) {
70       aura::Window::Windows root_windows = Shell::GetAllRootWindows();
71       DCHECK_LT(1u, root_windows.size());
72       root_windows[1]->AddChild(target_);
73     }
74   }
75
76   aura::Window* target_;
77   DISALLOW_COPY_AND_ASSIGN(MoveWindowByClickEventHandler);
78 };
79
80 // An event handler which records the event's locations.
81 class EventLocationRecordingEventHandler : public ui::EventHandler {
82  public:
83   explicit EventLocationRecordingEventHandler() {
84     reset();
85   }
86   ~EventLocationRecordingEventHandler() override {}
87
88   std::string GetLocationsAndReset() {
89     std::string result =
90         location_.ToString() + " " + root_location_.ToString();
91     reset();
92     return result;
93   }
94
95  private:
96   // ui::EventHandler overrides:
97   void OnMouseEvent(ui::MouseEvent* event) override {
98     if (event->type() == ui::ET_MOUSE_MOVED ||
99         event->type() == ui::ET_MOUSE_DRAGGED) {
100       location_ = event->location();
101       root_location_ = event->root_location();
102     }
103   }
104
105   void reset() {
106     location_.SetPoint(-999, -999);
107     root_location_.SetPoint(-999, -999);
108   }
109
110   gfx::Point root_location_;
111   gfx::Point location_;
112
113   DISALLOW_COPY_AND_ASSIGN(EventLocationRecordingEventHandler);
114 };
115
116 class EventLocationHandler : public ui::EventHandler {
117  public:
118   EventLocationHandler() {}
119   ~EventLocationHandler() override {}
120
121   const gfx::Point& press_location() const { return press_location_; }
122   const gfx::Point& release_location() const { return release_location_; }
123
124  private:
125   // ui::EventHandler:
126   void OnMouseEvent(ui::MouseEvent* event) override {
127     if (event->type() == ui::ET_MOUSE_PRESSED)
128       press_location_ = event->location();
129     else if (event->type() == ui::ET_MOUSE_RELEASED)
130       release_location_ = event->location();
131   }
132
133   gfx::Point press_location_;
134   gfx::Point release_location_;
135
136   DISALLOW_COPY_AND_ASSIGN(EventLocationHandler);
137 };
138
139 }  // namespace
140
141 class ExtendedDesktopTest : public test::AshTestBase {
142  public:
143   views::Widget* CreateTestWidget(const gfx::Rect& bounds) {
144     return CreateTestWidgetWithParentAndContext(
145         NULL, CurrentContext(), bounds, false);
146   }
147
148   views::Widget* CreateTestWidgetWithParent(views::Widget* parent,
149                                             const gfx::Rect& bounds,
150                                             bool child) {
151     CHECK(parent);
152     return CreateTestWidgetWithParentAndContext(parent, NULL, bounds, child);
153   }
154
155   views::Widget* CreateTestWidgetWithParentAndContext(views::Widget* parent,
156                                                       gfx::NativeView context,
157                                                       const gfx::Rect& bounds,
158                                                       bool child) {
159     views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
160     if (parent)
161       params.parent = parent->GetNativeView();
162     params.context = context;
163     params.bounds = bounds;
164     params.child = child;
165     views::Widget* widget = new views::Widget;
166     widget->Init(params);
167     widget->Show();
168     return widget;
169   }
170 };
171
172 // Test conditions that root windows in extended desktop mode
173 // must satisfy.
174 TEST_F(ExtendedDesktopTest, Basic) {
175   if (!SupportsMultipleDisplays())
176     return;
177
178   UpdateDisplay("1000x600,600x400");
179   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
180
181   // All root windows must have the root window controller.
182   ASSERT_EQ(2U, root_windows.size());
183   for (aura::Window::Windows::const_iterator iter = root_windows.begin();
184        iter != root_windows.end(); ++iter) {
185     EXPECT_TRUE(GetRootWindowController(*iter) != NULL);
186   }
187   // Make sure root windows share the same controllers.
188   EXPECT_EQ(aura::client::GetFocusClient(root_windows[0]),
189             aura::client::GetFocusClient(root_windows[1]));
190   EXPECT_EQ(aura::client::GetActivationClient(root_windows[0]),
191             aura::client::GetActivationClient(root_windows[1]));
192   EXPECT_EQ(aura::client::GetCaptureClient(root_windows[0]),
193             aura::client::GetCaptureClient(root_windows[1]));
194 }
195
196 TEST_F(ExtendedDesktopTest, Activation) {
197   if (!SupportsMultipleDisplays())
198     return;
199
200   UpdateDisplay("1000x600,600x400");
201   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
202
203   views::Widget* widget_on_1st = CreateTestWidget(gfx::Rect(10, 10, 100, 100));
204   views::Widget* widget_on_2nd =
205       CreateTestWidget(gfx::Rect(1200, 10, 100, 100));
206   EXPECT_EQ(root_windows[0], widget_on_1st->GetNativeView()->GetRootWindow());
207   EXPECT_EQ(root_windows[1], widget_on_2nd->GetNativeView()->GetRootWindow());
208
209   EXPECT_EQ(widget_on_2nd->GetNativeView(),
210             aura::client::GetFocusClient(root_windows[0])->GetFocusedWindow());
211   EXPECT_TRUE(wm::IsActiveWindow(widget_on_2nd->GetNativeView()));
212
213   ui::test::EventGenerator& event_generator(GetEventGenerator());
214   // Clicking a window changes the active window and active root window.
215   event_generator.MoveMouseToCenterOf(widget_on_1st->GetNativeView());
216   event_generator.ClickLeftButton();
217
218   EXPECT_EQ(widget_on_1st->GetNativeView(),
219             aura::client::GetFocusClient(root_windows[0])->GetFocusedWindow());
220   EXPECT_TRUE(wm::IsActiveWindow(widget_on_1st->GetNativeView()));
221
222   event_generator.MoveMouseToCenterOf(widget_on_2nd->GetNativeView());
223   event_generator.ClickLeftButton();
224
225   EXPECT_EQ(widget_on_2nd->GetNativeView(),
226             aura::client::GetFocusClient(root_windows[0])->GetFocusedWindow());
227   EXPECT_TRUE(wm::IsActiveWindow(widget_on_2nd->GetNativeView()));
228 }
229
230 TEST_F(ExtendedDesktopTest, SystemModal) {
231   if (!SupportsMultipleDisplays())
232     return;
233
234   UpdateDisplay("1000x600,600x400");
235   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
236
237   views::Widget* widget_on_1st = CreateTestWidget(gfx::Rect(10, 10, 100, 100));
238   EXPECT_TRUE(wm::IsActiveWindow(widget_on_1st->GetNativeView()));
239   EXPECT_EQ(root_windows[0], widget_on_1st->GetNativeView()->GetRootWindow());
240   EXPECT_EQ(root_windows[0], Shell::GetTargetRootWindow());
241
242   // Open system modal. Make sure it's on 2nd root window and active.
243   views::Widget* modal_widget = views::Widget::CreateWindowWithContextAndBounds(
244       new ModalWidgetDelegate(),
245       CurrentContext(),
246       gfx::Rect(1200, 100, 100, 100));
247   modal_widget->Show();
248   EXPECT_TRUE(wm::IsActiveWindow(modal_widget->GetNativeView()));
249   EXPECT_EQ(root_windows[1], modal_widget->GetNativeView()->GetRootWindow());
250   EXPECT_EQ(root_windows[1], Shell::GetTargetRootWindow());
251
252   ui::test::EventGenerator& event_generator(GetEventGenerator());
253
254   // Clicking a widget on widget_on_1st display should not change activation.
255   event_generator.MoveMouseToCenterOf(widget_on_1st->GetNativeView());
256   event_generator.ClickLeftButton();
257   EXPECT_TRUE(wm::IsActiveWindow(modal_widget->GetNativeView()));
258   EXPECT_EQ(root_windows[1], Shell::GetTargetRootWindow());
259
260   // Close system modal and so clicking a widget should work now.
261   modal_widget->Close();
262   event_generator.MoveMouseToCenterOf(widget_on_1st->GetNativeView());
263   event_generator.ClickLeftButton();
264   EXPECT_TRUE(wm::IsActiveWindow(widget_on_1st->GetNativeView()));
265   EXPECT_EQ(root_windows[0], Shell::GetTargetRootWindow());
266 }
267
268 TEST_F(ExtendedDesktopTest, TestCursor) {
269   if (!SupportsMultipleDisplays())
270     return;
271
272   UpdateDisplay("1000x600,600x400");
273   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
274   aura::WindowTreeHost* host0 = root_windows[0]->GetHost();
275   aura::WindowTreeHost* host1 = root_windows[1]->GetHost();
276   EXPECT_EQ(ui::kCursorPointer, host0->last_cursor().native_type());
277   EXPECT_EQ(ui::kCursorPointer, host1->last_cursor().native_type());
278   Shell::GetInstance()->cursor_manager()->SetCursor(ui::kCursorCopy);
279   EXPECT_EQ(ui::kCursorCopy, host0->last_cursor().native_type());
280   EXPECT_EQ(ui::kCursorCopy, host1->last_cursor().native_type());
281 }
282
283 TEST_F(ExtendedDesktopTest, TestCursorLocation) {
284   if (!SupportsMultipleDisplays())
285     return;
286
287   UpdateDisplay("1000x600,600x400");
288   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
289   aura::test::WindowTestApi root_window0_test_api(root_windows[0]);
290   aura::test::WindowTestApi root_window1_test_api(root_windows[1]);
291
292   root_windows[0]->MoveCursorTo(gfx::Point(10, 10));
293   EXPECT_EQ("10,10", Shell::GetScreen()->GetCursorScreenPoint().ToString());
294   EXPECT_TRUE(root_window0_test_api.ContainsMouse());
295   EXPECT_FALSE(root_window1_test_api.ContainsMouse());
296   root_windows[1]->MoveCursorTo(gfx::Point(10, 20));
297   EXPECT_EQ("1010,20", Shell::GetScreen()->GetCursorScreenPoint().ToString());
298   EXPECT_FALSE(root_window0_test_api.ContainsMouse());
299   EXPECT_TRUE(root_window1_test_api.ContainsMouse());
300   root_windows[0]->MoveCursorTo(gfx::Point(20, 10));
301   EXPECT_EQ("20,10", Shell::GetScreen()->GetCursorScreenPoint().ToString());
302   EXPECT_TRUE(root_window0_test_api.ContainsMouse());
303   EXPECT_FALSE(root_window1_test_api.ContainsMouse());
304 }
305
306 TEST_F(ExtendedDesktopTest, GetRootWindowAt) {
307   if (!SupportsMultipleDisplays())
308     return;
309
310   UpdateDisplay("700x500,500x500");
311   SetSecondaryDisplayLayout(DisplayLayout::LEFT);
312   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
313
314   EXPECT_EQ(root_windows[1], wm::GetRootWindowAt(gfx::Point(-400, 100)));
315   EXPECT_EQ(root_windows[1], wm::GetRootWindowAt(gfx::Point(-1, 100)));
316   EXPECT_EQ(root_windows[0], wm::GetRootWindowAt(gfx::Point(0, 300)));
317   EXPECT_EQ(root_windows[0], wm::GetRootWindowAt(gfx::Point(700, 300)));
318
319   // Zero origin.
320   EXPECT_EQ(root_windows[0], wm::GetRootWindowAt(gfx::Point(0, 0)));
321
322   // Out of range point should return the nearest root window
323   EXPECT_EQ(root_windows[1], wm::GetRootWindowAt(gfx::Point(-600, 0)));
324   EXPECT_EQ(root_windows[0], wm::GetRootWindowAt(gfx::Point(701, 100)));
325 }
326
327 TEST_F(ExtendedDesktopTest, GetRootWindowMatching) {
328   if (!SupportsMultipleDisplays())
329     return;
330
331   UpdateDisplay("700x500,500x500");
332   SetSecondaryDisplayLayout(DisplayLayout::LEFT);
333
334   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
335
336   // Containing rect.
337   EXPECT_EQ(root_windows[1],
338             wm::GetRootWindowMatching(gfx::Rect(-300, 10, 50, 50)));
339   EXPECT_EQ(root_windows[0],
340             wm::GetRootWindowMatching(gfx::Rect(100, 10, 50, 50)));
341
342   // Intersecting rect.
343   EXPECT_EQ(root_windows[1],
344             wm::GetRootWindowMatching(gfx::Rect(-200, 0, 300, 300)));
345   EXPECT_EQ(root_windows[0],
346             wm::GetRootWindowMatching(gfx::Rect(-100, 0, 300, 300)));
347
348   // Zero origin.
349   EXPECT_EQ(root_windows[0],
350             wm::GetRootWindowMatching(gfx::Rect(0, 0, 0, 0)));
351   EXPECT_EQ(root_windows[0],
352             wm::GetRootWindowMatching(gfx::Rect(0, 0, 1, 1)));
353
354   // Empty rect.
355   EXPECT_EQ(root_windows[1],
356             wm::GetRootWindowMatching(gfx::Rect(-400, 100, 0, 0)));
357   EXPECT_EQ(root_windows[0],
358             wm::GetRootWindowMatching(gfx::Rect(100, 100, 0, 0)));
359
360   // Out of range rect should return the primary root window.
361   EXPECT_EQ(root_windows[0],
362             wm::GetRootWindowMatching(gfx::Rect(-600, -300, 50, 50)));
363   EXPECT_EQ(root_windows[0],
364             wm::GetRootWindowMatching(gfx::Rect(0, 1000, 50, 50)));
365 }
366
367 TEST_F(ExtendedDesktopTest, Capture) {
368   if (!SupportsMultipleDisplays())
369     return;
370
371   UpdateDisplay("1000x600,600x400");
372   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
373
374   aura::test::EventCountDelegate r1_d1;
375   aura::test::EventCountDelegate r1_d2;
376   aura::test::EventCountDelegate r2_d1;
377
378   scoped_ptr<aura::Window> r1_w1(aura::test::CreateTestWindowWithDelegate(
379       &r1_d1, 0, gfx::Rect(10, 10, 100, 100), root_windows[0]));
380   scoped_ptr<aura::Window> r1_w2(aura::test::CreateTestWindowWithDelegate(
381       &r1_d2, 0, gfx::Rect(10, 100, 100, 100), root_windows[0]));
382   scoped_ptr<aura::Window> r2_w1(aura::test::CreateTestWindowWithDelegate(
383       &r2_d1, 0, gfx::Rect(10, 10, 100, 100), root_windows[1]));
384
385   r1_w1->SetCapture();
386
387   EXPECT_EQ(r1_w1.get(),
388             aura::client::GetCaptureWindow(r2_w1->GetRootWindow()));
389
390   ui::test::EventGenerator& generator = GetEventGenerator();
391   generator.MoveMouseToCenterOf(r2_w1.get());
392   // |r1_w1| will receive the events because it has capture.
393   EXPECT_EQ("1 1 0", r1_d1.GetMouseMotionCountsAndReset());
394   EXPECT_EQ("0 0 0", r1_d2.GetMouseMotionCountsAndReset());
395   EXPECT_EQ("0 0 0", r2_d1.GetMouseMotionCountsAndReset());
396
397   generator.ClickLeftButton();
398   EXPECT_EQ("0 0 0", r2_d1.GetMouseMotionCountsAndReset());
399   EXPECT_EQ("0 0", r2_d1.GetMouseButtonCountsAndReset());
400   // The mouse is outside. On chromeos, the mouse is warped to the
401   // dest root window, but it's not implemented on Win yet, so
402   // no mouse move event on Win.
403   EXPECT_EQ("0 0 0", r1_d1.GetMouseMotionCountsAndReset());
404   EXPECT_EQ("1 1", r1_d1.GetMouseButtonCountsAndReset());
405
406   generator.MoveMouseTo(15, 15);
407   EXPECT_EQ("0 1 0", r1_d1.GetMouseMotionCountsAndReset());
408   EXPECT_EQ("0 0 0", r1_d2.GetMouseMotionCountsAndReset());
409
410   r1_w2->SetCapture();
411   EXPECT_EQ(r1_w2.get(),
412             aura::client::GetCaptureWindow(r2_w1->GetRootWindow()));
413   generator.MoveMouseBy(10, 10);
414   // |r1_w2| has the capture. So it will receive the mouse-move event.
415   EXPECT_EQ("0 0 0", r1_d1.GetMouseMotionCountsAndReset());
416   EXPECT_EQ("0 1 0", r1_d2.GetMouseMotionCountsAndReset());
417   EXPECT_EQ("0 0 0", r2_d1.GetMouseMotionCountsAndReset());
418
419   generator.ClickLeftButton();
420   EXPECT_EQ("0 0 0", r2_d1.GetMouseMotionCountsAndReset());
421   EXPECT_EQ("0 0", r2_d1.GetMouseButtonCountsAndReset());
422   EXPECT_EQ("0 0 0", r1_d2.GetMouseMotionCountsAndReset());
423   EXPECT_EQ("1 1", r1_d2.GetMouseButtonCountsAndReset());
424
425   r1_w2->ReleaseCapture();
426   EXPECT_EQ(NULL, aura::client::GetCaptureWindow(r2_w1->GetRootWindow()));
427
428   generator.MoveMouseToCenterOf(r2_w1.get());
429   generator.ClickLeftButton();
430   EXPECT_EQ("1 1 0", r2_d1.GetMouseMotionCountsAndReset());
431   EXPECT_EQ("1 1", r2_d1.GetMouseButtonCountsAndReset());
432   // Make sure the mouse_moved_handler_ is properly reset.
433   EXPECT_EQ("0 0 0", r1_d2.GetMouseMotionCountsAndReset());
434   EXPECT_EQ("0 0", r1_d2.GetMouseButtonCountsAndReset());
435 }
436
437 TEST_F(ExtendedDesktopTest, CaptureEventLocation) {
438   if (!SupportsMultipleDisplays())
439     return;
440
441   UpdateDisplay("1000x600,600x400");
442   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
443
444   aura::test::EventCountDelegate r1_d1;
445   aura::test::EventCountDelegate r1_d2;
446   aura::test::EventCountDelegate r2_d1;
447
448   scoped_ptr<aura::Window> r1_w1(aura::test::CreateTestWindowWithDelegate(
449       &r1_d1, 0, gfx::Rect(10, 10, 100, 100), root_windows[0]));
450   scoped_ptr<aura::Window> r1_w2(aura::test::CreateTestWindowWithDelegate(
451       &r1_d2, 0, gfx::Rect(10, 100, 100, 100), root_windows[0]));
452   scoped_ptr<aura::Window> r2_w1(aura::test::CreateTestWindowWithDelegate(
453       &r2_d1, 0, gfx::Rect(10, 10, 100, 100), root_windows[1]));
454
455   r1_w1->SetCapture();
456
457   ui::test::EventGenerator& generator = GetEventGenerator();
458   generator.MoveMouseToCenterOf(r2_w1.get());
459   EXPECT_EQ(gfx::Point(1060, 60).ToString(),
460             generator.current_location().ToString());
461
462   EventLocationHandler location_handler;
463   r1_w1->AddPreTargetHandler(&location_handler);
464   generator.ClickLeftButton();
465   r1_w1->RemovePreTargetHandler(&location_handler);
466   EXPECT_EQ(gfx::Point(1050, 50).ToString(),
467             location_handler.press_location().ToString());
468   EXPECT_EQ(gfx::Point(1050, 50).ToString(),
469             location_handler.release_location().ToString());
470 }
471
472 TEST_F(ExtendedDesktopTest, CaptureEventLocationHighDPI) {
473   if (!SupportsMultipleDisplays())
474     return;
475
476   UpdateDisplay("1000x600*2,600x400");
477   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
478
479   aura::test::EventCountDelegate r1_d1;
480   aura::test::EventCountDelegate r1_d2;
481   aura::test::EventCountDelegate r2_d1;
482
483   scoped_ptr<aura::Window> r1_w1(aura::test::CreateTestWindowWithDelegate(
484       &r1_d1, 0, gfx::Rect(10, 10, 100, 100), root_windows[0]));
485   scoped_ptr<aura::Window> r1_w2(aura::test::CreateTestWindowWithDelegate(
486       &r1_d2, 0, gfx::Rect(10, 100, 100, 100), root_windows[0]));
487   scoped_ptr<aura::Window> r2_w1(aura::test::CreateTestWindowWithDelegate(
488       &r2_d1, 0, gfx::Rect(10, 10, 100, 100), root_windows[1]));
489
490   r1_w1->SetCapture();
491
492   ui::test::EventGenerator& generator = GetEventGenerator();
493   generator.MoveMouseToCenterOf(r2_w1.get());
494   EXPECT_EQ(gfx::Point(560, 60).ToString(),
495             generator.current_location().ToString());
496
497   EventLocationHandler location_handler;
498   r1_w1->AddPreTargetHandler(&location_handler);
499   generator.ClickLeftButton();
500   r1_w1->RemovePreTargetHandler(&location_handler);
501   EXPECT_EQ(gfx::Point(550, 50).ToString(),
502             location_handler.press_location().ToString());
503   EXPECT_EQ(gfx::Point(550, 50).ToString(),
504             location_handler.release_location().ToString());
505 }
506
507 TEST_F(ExtendedDesktopTest, CaptureEventLocationHighDPI_2) {
508   if (!SupportsMultipleDisplays())
509     return;
510
511   UpdateDisplay("1000x600,600x400*2");
512   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
513
514   aura::test::EventCountDelegate r1_d1;
515   aura::test::EventCountDelegate r1_d2;
516   aura::test::EventCountDelegate r2_d1;
517
518   scoped_ptr<aura::Window> r1_w1(aura::test::CreateTestWindowWithDelegate(
519       &r1_d1, 0, gfx::Rect(10, 10, 100, 100), root_windows[0]));
520   scoped_ptr<aura::Window> r1_w2(aura::test::CreateTestWindowWithDelegate(
521       &r1_d2, 0, gfx::Rect(10, 100, 100, 100), root_windows[0]));
522   scoped_ptr<aura::Window> r2_w1(aura::test::CreateTestWindowWithDelegate(
523       &r2_d1, 0, gfx::Rect(10, 10, 100, 100), root_windows[1]));
524
525   r1_w1->SetCapture();
526
527   ui::test::EventGenerator& generator = GetEventGenerator();
528   generator.MoveMouseToCenterOf(r2_w1.get());
529   EXPECT_EQ(gfx::Point(1060, 60).ToString(),
530             generator.current_location().ToString());
531
532   EventLocationHandler location_handler;
533   r1_w1->AddPreTargetHandler(&location_handler);
534   generator.ClickLeftButton();
535   r1_w1->RemovePreTargetHandler(&location_handler);
536   // Event-generator dispatches the event in the primary root-window's coord
537   // space. Since the location is (1060, 60), it goes to the secondary
538   // root-window as (30, 30) since the secondary root-window has a device scale
539   // factor of 2.
540   EXPECT_EQ(gfx::Point(1020, 20).ToString(),
541             location_handler.press_location().ToString());
542   EXPECT_EQ(gfx::Point(1020, 20).ToString(),
543             location_handler.release_location().ToString());
544 }
545
546 TEST_F(ExtendedDesktopTest, MoveWindow) {
547   if (!SupportsMultipleDisplays())
548     return;
549
550   UpdateDisplay("1000x600,600x400");
551   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
552   views::Widget* d1 = CreateTestWidget(gfx::Rect(10, 10, 100, 100));
553
554   EXPECT_EQ(root_windows[0], d1->GetNativeView()->GetRootWindow());
555
556   d1->SetBounds(gfx::Rect(1010, 10, 100, 100));
557   EXPECT_EQ("1010,10 100x100",
558             d1->GetWindowBoundsInScreen().ToString());
559
560   EXPECT_EQ(root_windows[1], d1->GetNativeView()->GetRootWindow());
561
562   d1->SetBounds(gfx::Rect(10, 10, 100, 100));
563   EXPECT_EQ("10,10 100x100",
564             d1->GetWindowBoundsInScreen().ToString());
565
566   EXPECT_EQ(root_windows[0], d1->GetNativeView()->GetRootWindow());
567
568   // Make sure the bounds which doesn't fit to the root window
569   // works correctly.
570   d1->SetBounds(gfx::Rect(1560, 30, 100, 100));
571   EXPECT_EQ(root_windows[1], d1->GetNativeView()->GetRootWindow());
572   EXPECT_EQ("1560,30 100x100",
573             d1->GetWindowBoundsInScreen().ToString());
574
575   // Setting outside of root windows will be moved to primary root window.
576   // TODO(oshima): This one probably should pick the closest root window.
577   d1->SetBounds(gfx::Rect(200, 10, 100, 100));
578   EXPECT_EQ(root_windows[0], d1->GetNativeView()->GetRootWindow());
579 }
580
581 // Verifies if the mouse event arrives to the window even when the window
582 // moves to another root in a pre-target handler.  See: crbug.com/157583
583 TEST_F(ExtendedDesktopTest, MoveWindowByMouseClick) {
584   if (!SupportsMultipleDisplays())
585     return;
586
587   UpdateDisplay("1000x600,600x400");
588
589   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
590   aura::test::EventCountDelegate delegate;
591   scoped_ptr<aura::Window> window(aura::test::CreateTestWindowWithDelegate(
592       &delegate, 0, gfx::Rect(10, 10, 100, 100), root_windows[0]));
593   MoveWindowByClickEventHandler event_handler(window.get());
594   window->AddPreTargetHandler(&event_handler);
595
596   ui::test::EventGenerator& event_generator(GetEventGenerator());
597
598   event_generator.MoveMouseToCenterOf(window.get());
599   event_generator.ClickLeftButton();
600   // Both mouse pressed and released arrive at the window and its delegate.
601   EXPECT_EQ("1 1", delegate.GetMouseButtonCountsAndReset());
602   // Also event_handler moves the window to another root at mouse release.
603   EXPECT_EQ(root_windows[1], window->GetRootWindow());
604 }
605
606 TEST_F(ExtendedDesktopTest, MoveWindowToDisplay) {
607   if (!SupportsMultipleDisplays())
608     return;
609
610   UpdateDisplay("1000x1000,1000x1000");
611   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
612
613   gfx::Display display0 = Shell::GetScreen()->GetDisplayMatching(
614       root_windows[0]->GetBoundsInScreen());
615   gfx::Display display1 = Shell::GetScreen()->GetDisplayMatching(
616       root_windows[1]->GetBoundsInScreen());
617   EXPECT_NE(display0.id(), display1.id());
618
619   views::Widget* d1 = CreateTestWidget(gfx::Rect(10, 10, 1000, 100));
620   EXPECT_EQ(root_windows[0], d1->GetNativeView()->GetRootWindow());
621
622   // Move the window where the window spans both root windows. Since the second
623   // parameter is |display1|, the window should be shown on the secondary root.
624   d1->GetNativeWindow()->SetBoundsInScreen(gfx::Rect(500, 10, 1000, 100),
625                                            display1);
626   EXPECT_EQ("500,10 1000x100",
627             d1->GetWindowBoundsInScreen().ToString());
628   EXPECT_EQ(root_windows[1], d1->GetNativeView()->GetRootWindow());
629
630   // Move to the primary root.
631   d1->GetNativeWindow()->SetBoundsInScreen(gfx::Rect(500, 10, 1000, 100),
632                                            display0);
633   EXPECT_EQ("500,10 1000x100",
634             d1->GetWindowBoundsInScreen().ToString());
635   EXPECT_EQ(root_windows[0], d1->GetNativeView()->GetRootWindow());
636 }
637
638 TEST_F(ExtendedDesktopTest, MoveWindowWithTransient) {
639   if (!SupportsMultipleDisplays())
640     return;
641
642   UpdateDisplay("1000x600,600x400");
643   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
644   views::Widget* w1 = CreateTestWidget(gfx::Rect(10, 10, 100, 100));
645   views::Widget* w1_t1 = CreateTestWidgetWithParent(
646       w1, gfx::Rect(50, 50, 50, 50), false /* transient */);
647   // Transient child of the transient child.
648   views::Widget* w1_t11 = CreateTestWidgetWithParent(
649       w1_t1, gfx::Rect(1200, 70, 35, 35), false /* transient */);
650
651   views::Widget* w11 = CreateTestWidgetWithParent(
652       w1, gfx::Rect(10, 10, 40, 40), true /* child */);
653   views::Widget* w11_t1 = CreateTestWidgetWithParent(
654       w1, gfx::Rect(1300, 100, 80, 80), false /* transient */);
655
656   EXPECT_EQ(root_windows[0], w1->GetNativeView()->GetRootWindow());
657   EXPECT_EQ(root_windows[0], w11->GetNativeView()->GetRootWindow());
658   EXPECT_EQ(root_windows[0], w1_t1->GetNativeView()->GetRootWindow());
659   EXPECT_EQ(root_windows[0], w1_t11->GetNativeView()->GetRootWindow());
660   EXPECT_EQ(root_windows[0], w11_t1->GetNativeView()->GetRootWindow());
661   EXPECT_EQ("50,50 50x50",
662             w1_t1->GetWindowBoundsInScreen().ToString());
663   EXPECT_EQ("1200,70 35x35",
664             w1_t11->GetWindowBoundsInScreen().ToString());
665   EXPECT_EQ("20,20 40x40",
666             w11->GetWindowBoundsInScreen().ToString());
667   EXPECT_EQ("1300,100 80x80",
668             w11_t1->GetWindowBoundsInScreen().ToString());
669
670   w1->SetBounds(gfx::Rect(1100, 10, 100, 100));
671
672   EXPECT_EQ(root_windows[1], w1_t1->GetNativeView()->GetRootWindow());
673   EXPECT_EQ(root_windows[1], w1_t1->GetNativeView()->GetRootWindow());
674   EXPECT_EQ(root_windows[1], w1_t11->GetNativeView()->GetRootWindow());
675   EXPECT_EQ(root_windows[1], w11->GetNativeView()->GetRootWindow());
676   EXPECT_EQ(root_windows[1], w11_t1->GetNativeView()->GetRootWindow());
677
678   EXPECT_EQ("1110,20 40x40",
679             w11->GetWindowBoundsInScreen().ToString());
680   // Transient window's screen bounds stays the same.
681   EXPECT_EQ("50,50 50x50",
682             w1_t1->GetWindowBoundsInScreen().ToString());
683   EXPECT_EQ("1200,70 35x35",
684             w1_t11->GetWindowBoundsInScreen().ToString());
685   EXPECT_EQ("1300,100 80x80",
686             w11_t1->GetWindowBoundsInScreen().ToString());
687
688   // Transient window doesn't move between root window unless
689   // its transient parent moves.
690   w1_t1->SetBounds(gfx::Rect(10, 50, 50, 50));
691   EXPECT_EQ(root_windows[1], w1_t1->GetNativeView()->GetRootWindow());
692   EXPECT_EQ("10,50 50x50",
693             w1_t1->GetWindowBoundsInScreen().ToString());
694 }
695
696 // Test if the Window::ConvertPointToTarget works across root windows.
697 // TODO(oshima): Move multiple display suport and this test to aura.
698 TEST_F(ExtendedDesktopTest, ConvertPoint) {
699   if (!SupportsMultipleDisplays())
700     return;
701   gfx::Screen* screen = Shell::GetScreen();
702   UpdateDisplay("1000x600,600x400");
703   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
704   gfx::Display display_1 = screen->GetDisplayNearestWindow(root_windows[0]);
705   EXPECT_EQ("0,0", display_1.bounds().origin().ToString());
706   gfx::Display display_2 = screen->GetDisplayNearestWindow(root_windows[1]);
707   EXPECT_EQ("1000,0", display_2.bounds().origin().ToString());
708
709   aura::Window* d1 =
710       CreateTestWidget(gfx::Rect(10, 10, 100, 100))->GetNativeView();
711   aura::Window* d2 =
712       CreateTestWidget(gfx::Rect(1020, 20, 100, 100))->GetNativeView();
713   EXPECT_EQ(root_windows[0], d1->GetRootWindow());
714   EXPECT_EQ(root_windows[1], d2->GetRootWindow());
715
716   // Convert point in the Root2's window to the Root1's window Coord.
717   gfx::Point p(0, 0);
718   aura::Window::ConvertPointToTarget(root_windows[1], root_windows[0], &p);
719   EXPECT_EQ("1000,0", p.ToString());
720   p.SetPoint(0, 0);
721   aura::Window::ConvertPointToTarget(d2, d1, &p);
722   EXPECT_EQ("1010,10", p.ToString());
723
724   // Convert point in the Root1's window to the Root2's window Coord.
725   p.SetPoint(0, 0);
726   aura::Window::ConvertPointToTarget(root_windows[0], root_windows[1], &p);
727   EXPECT_EQ("-1000,0", p.ToString());
728   p.SetPoint(0, 0);
729   aura::Window::ConvertPointToTarget(d1, d2, &p);
730   EXPECT_EQ("-1010,-10", p.ToString());
731
732   // Move the 2nd display to the bottom and test again.
733   SetSecondaryDisplayLayout(DisplayLayout::BOTTOM);
734
735   display_2 = screen->GetDisplayNearestWindow(root_windows[1]);
736   EXPECT_EQ("0,600", display_2.bounds().origin().ToString());
737
738   // Convert point in Root2's window to Root1's window Coord.
739   p.SetPoint(0, 0);
740   aura::Window::ConvertPointToTarget(root_windows[1], root_windows[0], &p);
741   EXPECT_EQ("0,600", p.ToString());
742   p.SetPoint(0, 0);
743   aura::Window::ConvertPointToTarget(d2, d1, &p);
744   EXPECT_EQ("10,610", p.ToString());
745
746   // Convert point in Root1's window to Root2's window Coord.
747   p.SetPoint(0, 0);
748   aura::Window::ConvertPointToTarget(root_windows[0], root_windows[1], &p);
749   EXPECT_EQ("0,-600", p.ToString());
750   p.SetPoint(0, 0);
751   aura::Window::ConvertPointToTarget(d1, d2, &p);
752   EXPECT_EQ("-10,-610", p.ToString());
753 }
754
755 TEST_F(ExtendedDesktopTest, OpenSystemTray) {
756   if (!SupportsMultipleDisplays())
757     return;
758
759   UpdateDisplay("500x600,600x400");
760   SystemTray* tray = ash::Shell::GetInstance()->GetPrimarySystemTray();
761   ASSERT_FALSE(tray->HasSystemBubble());
762
763   ui::test::EventGenerator& event_generator(GetEventGenerator());
764
765   // Opens the tray by a dummy click event and makes sure that adding/removing
766   // displays doesn't break anything.
767   event_generator.MoveMouseToCenterOf(tray->GetWidget()->GetNativeWindow());
768   event_generator.ClickLeftButton();
769   EXPECT_TRUE(tray->HasSystemBubble());
770
771   UpdateDisplay("500x600");
772   EXPECT_TRUE(tray->HasSystemBubble());
773   UpdateDisplay("500x600,600x400");
774   EXPECT_TRUE(tray->HasSystemBubble());
775
776   // Closes the tray and again makes sure that adding/removing displays doesn't
777   // break anything.
778   event_generator.ClickLeftButton();
779   RunAllPendingInMessageLoop();
780
781   EXPECT_FALSE(tray->HasSystemBubble());
782
783   UpdateDisplay("500x600");
784   EXPECT_FALSE(tray->HasSystemBubble());
785   UpdateDisplay("500x600,600x400");
786   EXPECT_FALSE(tray->HasSystemBubble());
787 }
788
789 TEST_F(ExtendedDesktopTest, StayInSameRootWindow) {
790   if (!SupportsMultipleDisplays())
791     return;
792
793   UpdateDisplay("100x100,200x200");
794   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
795   views::Widget* w1 = CreateTestWidget(gfx::Rect(10, 10, 50, 50));
796   EXPECT_EQ(root_windows[0], w1->GetNativeView()->GetRootWindow());
797   w1->SetBounds(gfx::Rect(150, 10, 50, 50));
798   EXPECT_EQ(root_windows[1], w1->GetNativeView()->GetRootWindow());
799
800   // The widget stays in the same root if kStayInSameRootWindowKey is set to
801   // true.
802   w1->GetNativeView()->SetProperty(kStayInSameRootWindowKey, true);
803   w1->SetBounds(gfx::Rect(10, 10, 50, 50));
804   EXPECT_EQ(root_windows[1], w1->GetNativeView()->GetRootWindow());
805
806   // The widget should now move to the 1st root window without the property.
807   w1->GetNativeView()->ClearProperty(kStayInSameRootWindowKey);
808   w1->SetBounds(gfx::Rect(10, 10, 50, 50));
809   EXPECT_EQ(root_windows[0], w1->GetNativeView()->GetRootWindow());
810
811   // a window in SettingsBubbleContainer and StatusContainer should
812   // not move to another root window regardles of the bounds specified.
813   aura::Window* settings_bubble_container =
814       Shell::GetPrimaryRootWindowController()->GetContainer(
815           kShellWindowId_SettingBubbleContainer);
816   aura::Window* window = aura::test::CreateTestWindowWithId(
817       100, settings_bubble_container);
818   window->SetBoundsInScreen(gfx::Rect(150, 10, 50, 50),
819                             ScreenUtil::GetSecondaryDisplay());
820   EXPECT_EQ(root_windows[0], window->GetRootWindow());
821
822   aura::Window* status_container =
823       Shell::GetPrimaryRootWindowController()->GetContainer(
824           kShellWindowId_StatusContainer);
825   window = aura::test::CreateTestWindowWithId(100, status_container);
826   window->SetBoundsInScreen(gfx::Rect(150, 10, 50, 50),
827                             ScreenUtil::GetSecondaryDisplay());
828   EXPECT_EQ(root_windows[0], window->GetRootWindow());
829 }
830
831 TEST_F(ExtendedDesktopTest, KeyEventsOnLockScreen) {
832   if (!SupportsMultipleDisplays())
833     return;
834
835   UpdateDisplay("100x100,200x200");
836   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
837
838   // Create normal windows on both displays.
839   views::Widget* widget1 = CreateTestWidget(
840       Shell::GetScreen()->GetPrimaryDisplay().bounds());
841   widget1->Show();
842   EXPECT_EQ(root_windows[0], widget1->GetNativeView()->GetRootWindow());
843   views::Widget* widget2 = CreateTestWidget(
844       ScreenUtil::GetSecondaryDisplay().bounds());
845   widget2->Show();
846   EXPECT_EQ(root_windows[1], widget2->GetNativeView()->GetRootWindow());
847
848   // Create a LockScreen window.
849   views::Widget* lock_widget = CreateTestWidget(
850       Shell::GetScreen()->GetPrimaryDisplay().bounds());
851   views::Textfield* textfield = new views::Textfield;
852   lock_widget->client_view()->AddChildView(textfield);
853
854   ash::Shell::GetContainer(Shell::GetPrimaryRootWindow(),
855                            ash::kShellWindowId_LockScreenContainer)
856       ->AddChild(lock_widget->GetNativeView());
857   lock_widget->Show();
858   textfield->RequestFocus();
859
860   aura::client::FocusClient* focus_client =
861       aura::client::GetFocusClient(root_windows[0]);
862   EXPECT_EQ(lock_widget->GetNativeView(), focus_client->GetFocusedWindow());
863
864   // The lock window should get events on both root windows.
865   ui::test::EventGenerator& event_generator(GetEventGenerator());
866
867   event_generator.set_current_target(root_windows[0]);
868   event_generator.PressKey(ui::VKEY_A, 0);
869   event_generator.ReleaseKey(ui::VKEY_A, 0);
870   EXPECT_EQ(lock_widget->GetNativeView(), focus_client->GetFocusedWindow());
871   EXPECT_EQ("a", base::UTF16ToASCII(textfield->text()));
872
873   event_generator.set_current_target(root_windows[1]);
874   event_generator.PressKey(ui::VKEY_B, 0);
875   event_generator.ReleaseKey(ui::VKEY_B, 0);
876   EXPECT_EQ(lock_widget->GetNativeView(), focus_client->GetFocusedWindow());
877   EXPECT_EQ("ab", base::UTF16ToASCII(textfield->text()));
878
879   // Deleting 2nd display. The lock window still should get the events.
880   UpdateDisplay("100x100");
881   event_generator.PressKey(ui::VKEY_C, 0);
882   event_generator.ReleaseKey(ui::VKEY_C, 0);
883   EXPECT_EQ(lock_widget->GetNativeView(), focus_client->GetFocusedWindow());
884   EXPECT_EQ("abc", base::UTF16ToASCII(textfield->text()));
885
886   // Creating 2nd display again, and lock window still should get events
887   // on both root windows.
888   UpdateDisplay("100x100,200x200");
889   root_windows = Shell::GetAllRootWindows();
890   event_generator.set_current_target(root_windows[0]);
891   event_generator.PressKey(ui::VKEY_D, 0);
892   event_generator.ReleaseKey(ui::VKEY_D, 0);
893   EXPECT_EQ(lock_widget->GetNativeView(), focus_client->GetFocusedWindow());
894   EXPECT_EQ("abcd", base::UTF16ToASCII(textfield->text()));
895
896   event_generator.set_current_target(root_windows[1]);
897   event_generator.PressKey(ui::VKEY_E, 0);
898   event_generator.ReleaseKey(ui::VKEY_E, 0);
899   EXPECT_EQ(lock_widget->GetNativeView(), focus_client->GetFocusedWindow());
900   EXPECT_EQ("abcde", base::UTF16ToASCII(textfield->text()));
901 }
902
903 TEST_F(ExtendedDesktopTest, PassiveGrab) {
904   if (!SupportsMultipleDisplays())
905     return;
906
907   EventLocationRecordingEventHandler event_handler;
908   ash::Shell::GetInstance()->AddPreTargetHandler(&event_handler);
909
910   UpdateDisplay("300x300,200x200");
911
912   views::Widget* widget = CreateTestWidget(gfx::Rect(50, 50, 200, 200));
913   widget->Show();
914   ASSERT_EQ("50,50 200x200", widget->GetWindowBoundsInScreen().ToString());
915
916   ui::test::EventGenerator& generator(GetEventGenerator());
917   generator.MoveMouseTo(150, 150);
918   EXPECT_EQ("100,100 150,150", event_handler.GetLocationsAndReset());
919
920   generator.PressLeftButton();
921   generator.MoveMouseTo(400, 150);
922
923   EXPECT_EQ("350,100 400,150", event_handler.GetLocationsAndReset());
924
925   generator.ReleaseLeftButton();
926   EXPECT_EQ("-999,-999 -999,-999", event_handler.GetLocationsAndReset());
927
928   generator.MoveMouseTo(400, 150);
929   EXPECT_EQ("100,150 100,150", event_handler.GetLocationsAndReset());
930
931   ash::Shell::GetInstance()->RemovePreTargetHandler(&event_handler);
932 }
933
934 }  // namespace ash