Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / ui / views / widget / widget_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 <algorithm>
6 #include <set>
7
8 #include "base/basictypes.h"
9 #include "base/bind.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/run_loop.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "ui/base/hit_test.h"
16 #include "ui/compositor/layer_animation_observer.h"
17 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
18 #include "ui/compositor/scoped_layer_animation_settings.h"
19 #include "ui/events/event_processor.h"
20 #include "ui/events/event_utils.h"
21 #include "ui/events/test/event_generator.h"
22 #include "ui/gfx/native_widget_types.h"
23 #include "ui/gfx/point.h"
24 #include "ui/views/bubble/bubble_delegate.h"
25 #include "ui/views/controls/textfield/textfield.h"
26 #include "ui/views/test/test_views_delegate.h"
27 #include "ui/views/test/widget_test.h"
28 #include "ui/views/views_delegate.h"
29 #include "ui/views/widget/native_widget_delegate.h"
30 #include "ui/views/widget/root_view.h"
31 #include "ui/views/widget/widget_deletion_observer.h"
32 #include "ui/views/window/dialog_delegate.h"
33 #include "ui/views/window/native_frame_view.h"
34
35 #if defined(OS_WIN)
36 #include "ui/views/win/hwnd_util.h"
37 #endif
38
39 namespace views {
40 namespace test {
41
42 namespace {
43
44 // TODO(tdanderson): This utility function is used in different unittest
45 //                   files. Move to a common location to avoid
46 //                   repeated code.
47 gfx::Point ConvertPointFromWidgetToView(View* view, const gfx::Point& p) {
48   gfx::Point tmp(p);
49   View::ConvertPointToTarget(view->GetWidget()->GetRootView(), view, &tmp);
50   return tmp;
51 }
52
53 }  // namespace
54
55 // A view that keeps track of the events it receives, optionally consuming them.
56 class EventCountView : public View {
57  public:
58   // Whether to call SetHandled() on events as they are received. For some event
59   // types, this will allow EventCountView to receives future events in the
60   // event sequence, such as a drag.
61   enum HandleMode {
62     PROPAGATE_EVENTS,
63     CONSUME_EVENTS
64   };
65
66   EventCountView()
67       : last_flags_(0),
68         handle_mode_(PROPAGATE_EVENTS) {}
69
70   ~EventCountView() override {}
71
72   int GetEventCount(ui::EventType type) {
73     return event_count_[type];
74   }
75
76   void ResetCounts() {
77     event_count_.clear();
78   }
79
80   int last_flags() const {
81     return last_flags_;
82   }
83
84   void set_handle_mode(HandleMode handle_mode) {
85     handle_mode_ = handle_mode;
86   }
87
88  protected:
89   // Overridden from View:
90   void OnMouseMoved(const ui::MouseEvent& event) override {
91     // MouseMove events are not re-dispatched from the RootView.
92     ++event_count_[ui::ET_MOUSE_MOVED];
93     last_flags_ = 0;
94   }
95
96   // Overridden from ui::EventHandler:
97   void OnKeyEvent(ui::KeyEvent* event) override { RecordEvent(event); }
98   void OnMouseEvent(ui::MouseEvent* event) override { RecordEvent(event); }
99   void OnScrollEvent(ui::ScrollEvent* event) override { RecordEvent(event); }
100   void OnGestureEvent(ui::GestureEvent* event) override { RecordEvent(event); }
101
102  private:
103   void RecordEvent(ui::Event* event) {
104     ++event_count_[event->type()];
105     last_flags_ = event->flags();
106     if (handle_mode_ == CONSUME_EVENTS)
107       event->SetHandled();
108   }
109
110   std::map<ui::EventType, int> event_count_;
111   int last_flags_;
112   HandleMode handle_mode_;
113
114   DISALLOW_COPY_AND_ASSIGN(EventCountView);
115 };
116
117 // A view that keeps track of the events it receives, and consumes all scroll
118 // gesture events and ui::ET_SCROLL events.
119 class ScrollableEventCountView : public EventCountView {
120  public:
121   ScrollableEventCountView() {}
122   ~ScrollableEventCountView() override {}
123
124  private:
125   // Overridden from ui::EventHandler:
126   void OnGestureEvent(ui::GestureEvent* event) override {
127     EventCountView::OnGestureEvent(event);
128     switch (event->type()) {
129       case ui::ET_GESTURE_SCROLL_BEGIN:
130       case ui::ET_GESTURE_SCROLL_UPDATE:
131       case ui::ET_GESTURE_SCROLL_END:
132       case ui::ET_SCROLL_FLING_START:
133         event->SetHandled();
134         break;
135       default:
136         break;
137     }
138   }
139
140   void OnScrollEvent(ui::ScrollEvent* event) override {
141     EventCountView::OnScrollEvent(event);
142     if (event->type() == ui::ET_SCROLL)
143       event->SetHandled();
144   }
145
146   DISALLOW_COPY_AND_ASSIGN(ScrollableEventCountView);
147 };
148
149 // A view that implements GetMinimumSize.
150 class MinimumSizeFrameView : public NativeFrameView {
151  public:
152   explicit MinimumSizeFrameView(Widget* frame): NativeFrameView(frame) {}
153   ~MinimumSizeFrameView() override {}
154
155  private:
156   // Overridden from View:
157   gfx::Size GetMinimumSize() const override { return gfx::Size(300, 400); }
158
159   DISALLOW_COPY_AND_ASSIGN(MinimumSizeFrameView);
160 };
161
162 // An event handler that simply keeps a count of the different types of events
163 // it receives.
164 class EventCountHandler : public ui::EventHandler {
165  public:
166   EventCountHandler() {}
167   ~EventCountHandler() override {}
168
169   int GetEventCount(ui::EventType type) {
170     return event_count_[type];
171   }
172
173   void ResetCounts() {
174     event_count_.clear();
175   }
176
177  protected:
178   // Overridden from ui::EventHandler:
179   void OnEvent(ui::Event* event) override {
180     RecordEvent(*event);
181     ui::EventHandler::OnEvent(event);
182   }
183
184  private:
185   void RecordEvent(const ui::Event& event) {
186     ++event_count_[event.type()];
187   }
188
189   std::map<ui::EventType, int> event_count_;
190
191   DISALLOW_COPY_AND_ASSIGN(EventCountHandler);
192 };
193
194 // Class that closes the widget (which ends up deleting it immediately) when the
195 // appropriate event is received.
196 class CloseWidgetView : public View {
197  public:
198   explicit CloseWidgetView(ui::EventType event_type)
199       : event_type_(event_type) {
200   }
201
202   // ui::EventHandler override:
203   void OnEvent(ui::Event* event) override {
204     if (event->type() == event_type_) {
205       // Go through NativeWidgetPrivate to simulate what happens if the OS
206       // deletes the NativeWindow out from under us.
207       GetWidget()->native_widget_private()->CloseNow();
208     } else {
209       View::OnEvent(event);
210       if (!event->IsTouchEvent())
211         event->SetHandled();
212     }
213   }
214
215  private:
216   const ui::EventType event_type_;
217
218   DISALLOW_COPY_AND_ASSIGN(CloseWidgetView);
219 };
220
221 ui::WindowShowState GetWidgetShowState(const Widget* widget) {
222   // Use IsMaximized/IsMinimized/IsFullScreen instead of GetWindowPlacement
223   // because the former is implemented on all platforms but the latter is not.
224   return widget->IsFullscreen() ? ui::SHOW_STATE_FULLSCREEN :
225       widget->IsMaximized() ? ui::SHOW_STATE_MAXIMIZED :
226       widget->IsMinimized() ? ui::SHOW_STATE_MINIMIZED :
227       widget->IsActive() ? ui::SHOW_STATE_NORMAL :
228                            ui::SHOW_STATE_INACTIVE;
229 }
230
231 TEST_F(WidgetTest, WidgetInitParams) {
232   // Widgets are not transparent by default.
233   Widget::InitParams init1;
234   EXPECT_EQ(Widget::InitParams::INFER_OPACITY, init1.opacity);
235 }
236
237 ////////////////////////////////////////////////////////////////////////////////
238 // Widget::GetTopLevelWidget tests.
239
240 TEST_F(WidgetTest, GetTopLevelWidget_Native) {
241   // Create a hierarchy of native widgets.
242   Widget* toplevel = CreateTopLevelPlatformWidget();
243   gfx::NativeView parent = toplevel->GetNativeView();
244   Widget* child = CreateChildPlatformWidget(parent);
245
246   EXPECT_EQ(toplevel, toplevel->GetTopLevelWidget());
247   EXPECT_EQ(toplevel, child->GetTopLevelWidget());
248
249   toplevel->CloseNow();
250   // |child| should be automatically destroyed with |toplevel|.
251 }
252
253 // Test if a focus manager and an inputmethod work without CHECK failure
254 // when window activation changes.
255 TEST_F(WidgetTest, ChangeActivation) {
256   Widget* top1 = CreateTopLevelPlatformWidget();
257   // CreateInputMethod before activated
258   top1->GetInputMethod();
259   top1->Show();
260   RunPendingMessages();
261
262   Widget* top2 = CreateTopLevelPlatformWidget();
263   top2->Show();
264   RunPendingMessages();
265
266   top1->Activate();
267   RunPendingMessages();
268
269   // Create InputMethod after deactivated.
270   top2->GetInputMethod();
271   top2->Activate();
272   RunPendingMessages();
273
274   top1->Activate();
275   RunPendingMessages();
276
277   top1->CloseNow();
278   top2->CloseNow();
279 }
280
281 // Tests visibility of child widgets.
282 TEST_F(WidgetTest, Visibility) {
283   Widget* toplevel = CreateTopLevelPlatformWidget();
284   gfx::NativeView parent = toplevel->GetNativeView();
285   Widget* child = CreateChildPlatformWidget(parent);
286
287   EXPECT_FALSE(toplevel->IsVisible());
288   EXPECT_FALSE(child->IsVisible());
289
290   child->Show();
291
292   EXPECT_FALSE(toplevel->IsVisible());
293   EXPECT_FALSE(child->IsVisible());
294
295   toplevel->Show();
296
297   EXPECT_TRUE(toplevel->IsVisible());
298   EXPECT_TRUE(child->IsVisible());
299
300   toplevel->CloseNow();
301   // |child| should be automatically destroyed with |toplevel|.
302 }
303
304 ////////////////////////////////////////////////////////////////////////////////
305 // Widget ownership tests.
306 //
307 // Tests various permutations of Widget ownership specified in the
308 // InitParams::Ownership param.
309
310 // A WidgetTest that supplies a toplevel widget for NativeWidget to parent to.
311 class WidgetOwnershipTest : public WidgetTest {
312  public:
313   WidgetOwnershipTest() {}
314   ~WidgetOwnershipTest() override {}
315
316   void SetUp() override {
317     WidgetTest::SetUp();
318     desktop_widget_ = CreateTopLevelPlatformWidget();
319   }
320
321   void TearDown() override {
322     desktop_widget_->CloseNow();
323     WidgetTest::TearDown();
324   }
325
326  private:
327   Widget* desktop_widget_;
328
329   DISALLOW_COPY_AND_ASSIGN(WidgetOwnershipTest);
330 };
331
332 // A bag of state to monitor destructions.
333 struct OwnershipTestState {
334   OwnershipTestState() : widget_deleted(false), native_widget_deleted(false) {}
335
336   bool widget_deleted;
337   bool native_widget_deleted;
338 };
339
340 // A platform NativeWidget subclass that updates a bag of state when it is
341 // destroyed.
342 class OwnershipTestNativeWidget : public PlatformNativeWidget {
343  public:
344   OwnershipTestNativeWidget(internal::NativeWidgetDelegate* delegate,
345                             OwnershipTestState* state)
346       : PlatformNativeWidget(delegate),
347         state_(state) {
348   }
349   ~OwnershipTestNativeWidget() override {
350     state_->native_widget_deleted = true;
351   }
352
353  private:
354   OwnershipTestState* state_;
355
356   DISALLOW_COPY_AND_ASSIGN(OwnershipTestNativeWidget);
357 };
358
359 // A views NativeWidget subclass that updates a bag of state when it is
360 // destroyed.
361 class OwnershipTestNativeWidgetAura : public NativeWidgetCapture {
362  public:
363   OwnershipTestNativeWidgetAura(internal::NativeWidgetDelegate* delegate,
364                                 OwnershipTestState* state)
365       : NativeWidgetCapture(delegate),
366         state_(state) {
367   }
368   ~OwnershipTestNativeWidgetAura() override {
369     state_->native_widget_deleted = true;
370   }
371
372  private:
373   OwnershipTestState* state_;
374
375   DISALLOW_COPY_AND_ASSIGN(OwnershipTestNativeWidgetAura);
376 };
377
378 // A Widget subclass that updates a bag of state when it is destroyed.
379 class OwnershipTestWidget : public Widget {
380  public:
381   explicit OwnershipTestWidget(OwnershipTestState* state) : state_(state) {}
382   ~OwnershipTestWidget() override { state_->widget_deleted = true; }
383
384  private:
385   OwnershipTestState* state_;
386
387   DISALLOW_COPY_AND_ASSIGN(OwnershipTestWidget);
388 };
389
390 // Widget owns its NativeWidget, part 1: NativeWidget is a platform-native
391 // widget.
392 TEST_F(WidgetOwnershipTest, Ownership_WidgetOwnsPlatformNativeWidget) {
393   OwnershipTestState state;
394
395   scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
396   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
397   params.native_widget =
398       new OwnershipTestNativeWidgetAura(widget.get(), &state);
399   params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
400   widget->Init(params);
401
402   // Now delete the Widget, which should delete the NativeWidget.
403   widget.reset();
404
405   EXPECT_TRUE(state.widget_deleted);
406   EXPECT_TRUE(state.native_widget_deleted);
407
408   // TODO(beng): write test for this ownership scenario and the NativeWidget
409   //             being deleted out from under the Widget.
410 }
411
412 // Widget owns its NativeWidget, part 2: NativeWidget is a NativeWidget.
413 TEST_F(WidgetOwnershipTest, Ownership_WidgetOwnsViewsNativeWidget) {
414   OwnershipTestState state;
415
416   scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
417   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
418   params.native_widget =
419       new OwnershipTestNativeWidgetAura(widget.get(), &state);
420   params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
421   widget->Init(params);
422
423   // Now delete the Widget, which should delete the NativeWidget.
424   widget.reset();
425
426   EXPECT_TRUE(state.widget_deleted);
427   EXPECT_TRUE(state.native_widget_deleted);
428
429   // TODO(beng): write test for this ownership scenario and the NativeWidget
430   //             being deleted out from under the Widget.
431 }
432
433 // Widget owns its NativeWidget, part 3: NativeWidget is a NativeWidget,
434 // destroy the parent view.
435 TEST_F(WidgetOwnershipTest,
436        Ownership_WidgetOwnsViewsNativeWidget_DestroyParentView) {
437   OwnershipTestState state;
438
439   Widget* toplevel = CreateTopLevelPlatformWidget();
440
441   scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
442   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
443   params.native_widget =
444       new OwnershipTestNativeWidgetAura(widget.get(), &state);
445   params.parent = toplevel->GetNativeView();
446   params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
447   widget->Init(params);
448
449   // Now close the toplevel, which deletes the view hierarchy.
450   toplevel->CloseNow();
451
452   RunPendingMessages();
453
454   // This shouldn't delete the widget because it shouldn't be deleted
455   // from the native side.
456   EXPECT_FALSE(state.widget_deleted);
457   EXPECT_FALSE(state.native_widget_deleted);
458
459   // Now delete it explicitly.
460   widget.reset();
461
462   EXPECT_TRUE(state.widget_deleted);
463   EXPECT_TRUE(state.native_widget_deleted);
464 }
465
466 // NativeWidget owns its Widget, part 1: NativeWidget is a platform-native
467 // widget.
468 TEST_F(WidgetOwnershipTest, Ownership_PlatformNativeWidgetOwnsWidget) {
469   OwnershipTestState state;
470
471   Widget* widget = new OwnershipTestWidget(&state);
472   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
473   params.native_widget =
474       new OwnershipTestNativeWidgetAura(widget, &state);
475   widget->Init(params);
476
477   // Now destroy the native widget.
478   widget->CloseNow();
479
480   EXPECT_TRUE(state.widget_deleted);
481   EXPECT_TRUE(state.native_widget_deleted);
482 }
483
484 // NativeWidget owns its Widget, part 2: NativeWidget is a NativeWidget.
485 TEST_F(WidgetOwnershipTest, Ownership_ViewsNativeWidgetOwnsWidget) {
486   OwnershipTestState state;
487
488   Widget* toplevel = CreateTopLevelPlatformWidget();
489
490   Widget* widget = new OwnershipTestWidget(&state);
491   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
492   params.native_widget =
493       new OwnershipTestNativeWidgetAura(widget, &state);
494   params.parent = toplevel->GetNativeView();
495   widget->Init(params);
496
497   // Now destroy the native widget. This is achieved by closing the toplevel.
498   toplevel->CloseNow();
499
500   // The NativeWidget won't be deleted until after a return to the message loop
501   // so we have to run pending messages before testing the destruction status.
502   RunPendingMessages();
503
504   EXPECT_TRUE(state.widget_deleted);
505   EXPECT_TRUE(state.native_widget_deleted);
506 }
507
508 // NativeWidget owns its Widget, part 3: NativeWidget is a platform-native
509 // widget, destroyed out from under it by the OS.
510 TEST_F(WidgetOwnershipTest,
511        Ownership_PlatformNativeWidgetOwnsWidget_NativeDestroy) {
512   OwnershipTestState state;
513
514   Widget* widget = new OwnershipTestWidget(&state);
515   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
516   params.native_widget =
517       new OwnershipTestNativeWidgetAura(widget, &state);
518   widget->Init(params);
519
520   // Now simulate a destroy of the platform native widget from the OS:
521   SimulateNativeDestroy(widget);
522
523   EXPECT_TRUE(state.widget_deleted);
524   EXPECT_TRUE(state.native_widget_deleted);
525 }
526
527 // NativeWidget owns its Widget, part 4: NativeWidget is a NativeWidget,
528 // destroyed by the view hierarchy that contains it.
529 TEST_F(WidgetOwnershipTest,
530        Ownership_ViewsNativeWidgetOwnsWidget_NativeDestroy) {
531   OwnershipTestState state;
532
533   Widget* toplevel = CreateTopLevelPlatformWidget();
534
535   Widget* widget = new OwnershipTestWidget(&state);
536   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
537   params.native_widget =
538       new OwnershipTestNativeWidgetAura(widget, &state);
539   params.parent = toplevel->GetNativeView();
540   widget->Init(params);
541
542   // Destroy the widget (achieved by closing the toplevel).
543   toplevel->CloseNow();
544
545   // The NativeWidget won't be deleted until after a return to the message loop
546   // so we have to run pending messages before testing the destruction status.
547   RunPendingMessages();
548
549   EXPECT_TRUE(state.widget_deleted);
550   EXPECT_TRUE(state.native_widget_deleted);
551 }
552
553 // NativeWidget owns its Widget, part 5: NativeWidget is a NativeWidget,
554 // we close it directly.
555 TEST_F(WidgetOwnershipTest,
556        Ownership_ViewsNativeWidgetOwnsWidget_Close) {
557   OwnershipTestState state;
558
559   Widget* toplevel = CreateTopLevelPlatformWidget();
560
561   Widget* widget = new OwnershipTestWidget(&state);
562   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
563   params.native_widget =
564       new OwnershipTestNativeWidgetAura(widget, &state);
565   params.parent = toplevel->GetNativeView();
566   widget->Init(params);
567
568   // Destroy the widget.
569   widget->Close();
570   toplevel->CloseNow();
571
572   // The NativeWidget won't be deleted until after a return to the message loop
573   // so we have to run pending messages before testing the destruction status.
574   RunPendingMessages();
575
576   EXPECT_TRUE(state.widget_deleted);
577   EXPECT_TRUE(state.native_widget_deleted);
578 }
579
580 // Widget owns its NativeWidget and has a WidgetDelegateView as its contents.
581 TEST_F(WidgetOwnershipTest,
582        Ownership_WidgetOwnsNativeWidgetWithWithWidgetDelegateView) {
583   OwnershipTestState state;
584
585   WidgetDelegateView* delegate_view = new WidgetDelegateView;
586
587   scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
588   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
589   params.native_widget =
590       new OwnershipTestNativeWidgetAura(widget.get(), &state);
591   params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
592   params.delegate = delegate_view;
593   widget->Init(params);
594   widget->SetContentsView(delegate_view);
595
596   // Now delete the Widget. There should be no crash or use-after-free.
597   widget.reset();
598
599   EXPECT_TRUE(state.widget_deleted);
600   EXPECT_TRUE(state.native_widget_deleted);
601 }
602
603 ////////////////////////////////////////////////////////////////////////////////
604 // Test to verify using various Widget methods doesn't crash when the underlying
605 // NativeView is destroyed.
606 //
607 class WidgetWithDestroyedNativeViewTest : public ViewsTestBase {
608  public:
609   WidgetWithDestroyedNativeViewTest() {}
610   ~WidgetWithDestroyedNativeViewTest() override {}
611
612   void InvokeWidgetMethods(Widget* widget) {
613     widget->GetNativeView();
614     widget->GetNativeWindow();
615     ui::Accelerator accelerator;
616     widget->GetAccelerator(0, &accelerator);
617     widget->GetTopLevelWidget();
618     widget->GetWindowBoundsInScreen();
619     widget->GetClientAreaBoundsInScreen();
620     widget->SetBounds(gfx::Rect(0, 0, 100, 80));
621     widget->SetSize(gfx::Size(10, 11));
622     widget->SetBoundsConstrained(gfx::Rect(0, 0, 120, 140));
623     widget->SetVisibilityChangedAnimationsEnabled(false);
624     widget->StackAtTop();
625     widget->IsClosed();
626     widget->Close();
627     widget->Hide();
628     widget->Activate();
629     widget->Deactivate();
630     widget->IsActive();
631     widget->DisableInactiveRendering();
632     widget->SetAlwaysOnTop(true);
633     widget->IsAlwaysOnTop();
634     widget->Maximize();
635     widget->Minimize();
636     widget->Restore();
637     widget->IsMaximized();
638     widget->IsFullscreen();
639     widget->SetOpacity(0);
640     widget->SetUseDragFrame(true);
641     widget->FlashFrame(true);
642     widget->IsVisible();
643     widget->GetThemeProvider();
644     widget->GetNativeTheme();
645     widget->GetFocusManager();
646     widget->GetInputMethod();
647     widget->SchedulePaintInRect(gfx::Rect(0, 0, 1, 2));
648     widget->IsMouseEventsEnabled();
649     widget->SetNativeWindowProperty("xx", widget);
650     widget->GetNativeWindowProperty("xx");
651     widget->GetFocusTraversable();
652     widget->GetLayer();
653     widget->ReorderNativeViews();
654     widget->SetCapture(widget->GetRootView());
655     widget->ReleaseCapture();
656     widget->HasCapture();
657     widget->GetWorkAreaBoundsInScreen();
658     widget->IsTranslucentWindowOpacitySupported();
659   }
660
661  private:
662   DISALLOW_COPY_AND_ASSIGN(WidgetWithDestroyedNativeViewTest);
663 };
664
665 TEST_F(WidgetWithDestroyedNativeViewTest, Test) {
666   {
667     Widget widget;
668     Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
669     params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
670     widget.Init(params);
671     widget.Show();
672
673     widget.native_widget_private()->CloseNow();
674     InvokeWidgetMethods(&widget);
675   }
676 #if !defined(OS_CHROMEOS)
677   {
678     Widget widget;
679     Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
680     params.native_widget = new PlatformDesktopNativeWidget(&widget);
681     params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
682     widget.Init(params);
683     widget.Show();
684
685     widget.native_widget_private()->CloseNow();
686     InvokeWidgetMethods(&widget);
687   }
688 #endif
689 }
690
691 ////////////////////////////////////////////////////////////////////////////////
692 // Widget observer tests.
693 //
694
695 class WidgetObserverTest : public WidgetTest, public WidgetObserver {
696  public:
697   WidgetObserverTest()
698       : active_(NULL),
699         widget_closed_(NULL),
700         widget_activated_(NULL),
701         widget_shown_(NULL),
702         widget_hidden_(NULL),
703         widget_bounds_changed_(NULL) {
704   }
705
706   ~WidgetObserverTest() override {}
707
708   // Overridden from WidgetObserver:
709   void OnWidgetDestroying(Widget* widget) override {
710     if (active_ == widget)
711       active_ = NULL;
712     widget_closed_ = widget;
713   }
714
715   void OnWidgetActivationChanged(Widget* widget, bool active) override {
716     if (active) {
717       if (widget_activated_)
718         widget_activated_->Deactivate();
719       widget_activated_ = widget;
720       active_ = widget;
721     } else {
722       if (widget_activated_ == widget)
723         widget_activated_ = NULL;
724       widget_deactivated_ = widget;
725     }
726   }
727
728   void OnWidgetVisibilityChanged(Widget* widget, bool visible) override {
729     if (visible)
730       widget_shown_ = widget;
731     else
732       widget_hidden_ = widget;
733   }
734
735   void OnWidgetBoundsChanged(Widget* widget,
736                              const gfx::Rect& new_bounds) override {
737     widget_bounds_changed_ = widget;
738   }
739
740   void reset() {
741     active_ = NULL;
742     widget_closed_ = NULL;
743     widget_activated_ = NULL;
744     widget_deactivated_ = NULL;
745     widget_shown_ = NULL;
746     widget_hidden_ = NULL;
747     widget_bounds_changed_ = NULL;
748   }
749
750   Widget* NewWidget() {
751     Widget* widget = CreateTopLevelNativeWidget();
752     widget->AddObserver(this);
753     return widget;
754   }
755
756   const Widget* active() const { return active_; }
757   const Widget* widget_closed() const { return widget_closed_; }
758   const Widget* widget_activated() const { return widget_activated_; }
759   const Widget* widget_deactivated() const { return widget_deactivated_; }
760   const Widget* widget_shown() const { return widget_shown_; }
761   const Widget* widget_hidden() const { return widget_hidden_; }
762   const Widget* widget_bounds_changed() const { return widget_bounds_changed_; }
763
764  private:
765   Widget* active_;
766
767   Widget* widget_closed_;
768   Widget* widget_activated_;
769   Widget* widget_deactivated_;
770   Widget* widget_shown_;
771   Widget* widget_hidden_;
772   Widget* widget_bounds_changed_;
773 };
774
775 TEST_F(WidgetObserverTest, DISABLED_ActivationChange) {
776   Widget* toplevel = CreateTopLevelPlatformWidget();
777
778   Widget* toplevel1 = NewWidget();
779   Widget* toplevel2 = NewWidget();
780
781   toplevel1->Show();
782   toplevel2->Show();
783
784   reset();
785
786   toplevel1->Activate();
787
788   RunPendingMessages();
789   EXPECT_EQ(toplevel1, widget_activated());
790
791   toplevel2->Activate();
792   RunPendingMessages();
793   EXPECT_EQ(toplevel1, widget_deactivated());
794   EXPECT_EQ(toplevel2, widget_activated());
795   EXPECT_EQ(toplevel2, active());
796
797   toplevel->CloseNow();
798 }
799
800 TEST_F(WidgetObserverTest, DISABLED_VisibilityChange) {
801   Widget* toplevel = CreateTopLevelPlatformWidget();
802
803   Widget* child1 = NewWidget();
804   Widget* child2 = NewWidget();
805
806   toplevel->Show();
807   child1->Show();
808   child2->Show();
809
810   reset();
811
812   child1->Hide();
813   EXPECT_EQ(child1, widget_hidden());
814
815   child2->Hide();
816   EXPECT_EQ(child2, widget_hidden());
817
818   child1->Show();
819   EXPECT_EQ(child1, widget_shown());
820
821   child2->Show();
822   EXPECT_EQ(child2, widget_shown());
823
824   toplevel->CloseNow();
825 }
826
827 TEST_F(WidgetObserverTest, DestroyBubble) {
828   Widget* anchor = CreateTopLevelPlatformWidget();
829   anchor->Show();
830
831   BubbleDelegateView* bubble_delegate =
832       new BubbleDelegateView(anchor->client_view(), BubbleBorder::NONE);
833   Widget* bubble_widget(BubbleDelegateView::CreateBubble(bubble_delegate));
834   bubble_widget->Show();
835   bubble_widget->CloseNow();
836
837   anchor->Hide();
838   anchor->CloseNow();
839 }
840
841 TEST_F(WidgetObserverTest, WidgetBoundsChanged) {
842   Widget* child1 = NewWidget();
843   Widget* child2 = NewWidget();
844
845   child1->OnNativeWidgetMove();
846   EXPECT_EQ(child1, widget_bounds_changed());
847
848   child2->OnNativeWidgetMove();
849   EXPECT_EQ(child2, widget_bounds_changed());
850
851   child1->OnNativeWidgetSizeChanged(gfx::Size());
852   EXPECT_EQ(child1, widget_bounds_changed());
853
854   child2->OnNativeWidgetSizeChanged(gfx::Size());
855   EXPECT_EQ(child2, widget_bounds_changed());
856 }
857
858 // Tests that SetBounds() and GetWindowBoundsInScreen() is symmetric when the
859 // widget is visible and not maximized or fullscreen.
860 TEST_F(WidgetTest, GetWindowBoundsInScreen) {
861   // Choose test coordinates away from edges and dimensions that are "small"
862   // (but not too small) to ensure the OS doesn't try to adjust them.
863   const gfx::Rect kTestBounds(150, 150, 400, 300);
864   const gfx::Size kTestSize(200, 180);
865
866   // First test a toplevel widget.
867   Widget* widget = CreateTopLevelPlatformWidget();
868   widget->Show();
869
870   EXPECT_NE(kTestSize.ToString(),
871             widget->GetWindowBoundsInScreen().size().ToString());
872   widget->SetSize(kTestSize);
873   EXPECT_EQ(kTestSize.ToString(),
874             widget->GetWindowBoundsInScreen().size().ToString());
875
876   EXPECT_NE(kTestBounds.ToString(),
877             widget->GetWindowBoundsInScreen().ToString());
878   widget->SetBounds(kTestBounds);
879   EXPECT_EQ(kTestBounds.ToString(),
880             widget->GetWindowBoundsInScreen().ToString());
881
882   // Changing just the size should not change the origin.
883   widget->SetSize(kTestSize);
884   EXPECT_EQ(kTestBounds.origin().ToString(),
885             widget->GetWindowBoundsInScreen().origin().ToString());
886
887   widget->CloseNow();
888
889   // Same tests with a frameless window.
890   widget = CreateTopLevelFramelessPlatformWidget();
891   widget->Show();
892
893   EXPECT_NE(kTestSize.ToString(),
894             widget->GetWindowBoundsInScreen().size().ToString());
895   widget->SetSize(kTestSize);
896   EXPECT_EQ(kTestSize.ToString(),
897             widget->GetWindowBoundsInScreen().size().ToString());
898
899   EXPECT_NE(kTestBounds.ToString(),
900             widget->GetWindowBoundsInScreen().ToString());
901   widget->SetBounds(kTestBounds);
902   EXPECT_EQ(kTestBounds.ToString(),
903             widget->GetWindowBoundsInScreen().ToString());
904
905   // For a frameless widget, the client bounds should also match.
906   EXPECT_EQ(kTestBounds.ToString(),
907             widget->GetClientAreaBoundsInScreen().ToString());
908
909   // Verify origin is stable for a frameless window as well.
910   widget->SetSize(kTestSize);
911   EXPECT_EQ(kTestBounds.origin().ToString(),
912             widget->GetWindowBoundsInScreen().origin().ToString());
913
914   widget->CloseNow();
915 }
916
917 // Before being enabled on Mac, this was #ifdef(false).
918 // TODO(tapted): Fix this for DesktopNativeWidgets on other platforms.
919 #if defined(OS_MACOSX)
920 // Aura needs shell to maximize/fullscreen window.
921 // NativeWidgetGtk doesn't implement GetRestoredBounds.
922 TEST_F(WidgetTest, GetRestoredBounds) {
923   Widget* toplevel = CreateTopLevelPlatformWidget();
924   EXPECT_EQ(toplevel->GetWindowBoundsInScreen().ToString(),
925             toplevel->GetRestoredBounds().ToString());
926   toplevel->Show();
927   toplevel->Maximize();
928   RunPendingMessages();
929 #if defined(OS_MACOSX)
930   // Current expectation on Mac is to do nothing on Maximize.
931   EXPECT_EQ(toplevel->GetWindowBoundsInScreen().ToString(),
932             toplevel->GetRestoredBounds().ToString());
933 #else
934   EXPECT_NE(toplevel->GetWindowBoundsInScreen().ToString(),
935             toplevel->GetRestoredBounds().ToString());
936 #endif
937   EXPECT_GT(toplevel->GetRestoredBounds().width(), 0);
938   EXPECT_GT(toplevel->GetRestoredBounds().height(), 0);
939
940   toplevel->Restore();
941   RunPendingMessages();
942   EXPECT_EQ(toplevel->GetWindowBoundsInScreen().ToString(),
943             toplevel->GetRestoredBounds().ToString());
944
945   toplevel->SetFullscreen(true);
946   RunPendingMessages();
947   EXPECT_NE(toplevel->GetWindowBoundsInScreen().ToString(),
948             toplevel->GetRestoredBounds().ToString());
949   EXPECT_GT(toplevel->GetRestoredBounds().width(), 0);
950   EXPECT_GT(toplevel->GetRestoredBounds().height(), 0);
951 }
952 #endif
953
954 // Test that window state is not changed after getting out of full screen.
955 TEST_F(WidgetTest, ExitFullscreenRestoreState) {
956   Widget* toplevel = CreateTopLevelPlatformWidget();
957
958   toplevel->Show();
959   RunPendingMessages();
960
961   // This should be a normal state window.
962   EXPECT_EQ(ui::SHOW_STATE_NORMAL, GetWidgetShowState(toplevel));
963
964   toplevel->SetFullscreen(true);
965   EXPECT_EQ(ui::SHOW_STATE_FULLSCREEN, GetWidgetShowState(toplevel));
966   toplevel->SetFullscreen(false);
967   EXPECT_NE(ui::SHOW_STATE_FULLSCREEN, GetWidgetShowState(toplevel));
968
969   // And it should still be in normal state after getting out of full screen.
970   EXPECT_EQ(ui::SHOW_STATE_NORMAL, GetWidgetShowState(toplevel));
971
972 // On Mac, a "maximized" state is indistinguishable from a window that just
973 // fills the screen, so nothing to check there.
974 #if !defined(OS_MACOSX)
975   // Now, make it maximized.
976   toplevel->Maximize();
977   EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, GetWidgetShowState(toplevel));
978
979   toplevel->SetFullscreen(true);
980   EXPECT_EQ(ui::SHOW_STATE_FULLSCREEN, GetWidgetShowState(toplevel));
981   toplevel->SetFullscreen(false);
982   EXPECT_NE(ui::SHOW_STATE_FULLSCREEN, GetWidgetShowState(toplevel));
983
984   // And it stays maximized after getting out of full screen.
985   EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, GetWidgetShowState(toplevel));
986 #endif
987
988   // Clean up.
989   toplevel->Close();
990   RunPendingMessages();
991 }
992
993 // The key-event propagation from Widget happens differently on aura and
994 // non-aura systems because of the difference in IME. So this test works only on
995 // aura.
996 TEST_F(WidgetTest, KeyboardInputEvent) {
997   Widget* toplevel = CreateTopLevelPlatformWidget();
998   View* container = toplevel->client_view();
999
1000   Textfield* textfield = new Textfield();
1001   textfield->SetText(base::ASCIIToUTF16("some text"));
1002   container->AddChildView(textfield);
1003   toplevel->Show();
1004   textfield->RequestFocus();
1005
1006   // The press gets handled. The release doesn't have an effect.
1007   ui::KeyEvent backspace_p(ui::ET_KEY_PRESSED, ui::VKEY_DELETE, ui::EF_NONE);
1008   toplevel->OnKeyEvent(&backspace_p);
1009   EXPECT_TRUE(backspace_p.stopped_propagation());
1010   ui::KeyEvent backspace_r(ui::ET_KEY_RELEASED, ui::VKEY_DELETE, ui::EF_NONE);
1011   toplevel->OnKeyEvent(&backspace_r);
1012   EXPECT_FALSE(backspace_r.handled());
1013
1014   toplevel->Close();
1015 }
1016
1017 // Verifies bubbles result in a focus lost when shown.
1018 // TODO(msw): this tests relies on focus, it needs to be in
1019 // interactive_ui_tests.
1020 TEST_F(WidgetTest, DISABLED_FocusChangesOnBubble) {
1021   // Create a widget, show and activate it and focus the contents view.
1022   View* contents_view = new View;
1023   contents_view->SetFocusable(true);
1024   Widget widget;
1025   Widget::InitParams init_params =
1026       CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
1027   init_params.bounds = gfx::Rect(0, 0, 200, 200);
1028   init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
1029 #if !defined(OS_CHROMEOS)
1030   init_params.native_widget = new PlatformDesktopNativeWidget(&widget);
1031 #endif
1032   widget.Init(init_params);
1033   widget.SetContentsView(contents_view);
1034   widget.Show();
1035   widget.Activate();
1036   contents_view->RequestFocus();
1037   EXPECT_TRUE(contents_view->HasFocus());
1038
1039   // Show a bubble.
1040   BubbleDelegateView* bubble_delegate_view =
1041       new BubbleDelegateView(contents_view, BubbleBorder::TOP_LEFT);
1042   bubble_delegate_view->SetFocusable(true);
1043   BubbleDelegateView::CreateBubble(bubble_delegate_view)->Show();
1044   bubble_delegate_view->RequestFocus();
1045
1046   // |contents_view_| should no longer have focus.
1047   EXPECT_FALSE(contents_view->HasFocus());
1048   EXPECT_TRUE(bubble_delegate_view->HasFocus());
1049
1050   bubble_delegate_view->GetWidget()->CloseNow();
1051
1052   // Closing the bubble should result in focus going back to the contents view.
1053   EXPECT_TRUE(contents_view->HasFocus());
1054 }
1055
1056 class TestBubbleDelegateView : public BubbleDelegateView {
1057  public:
1058   TestBubbleDelegateView(View* anchor)
1059       : BubbleDelegateView(anchor, BubbleBorder::NONE),
1060         reset_controls_called_(false) {}
1061   ~TestBubbleDelegateView() override {}
1062
1063   bool ShouldShowCloseButton() const override {
1064     reset_controls_called_ = true;
1065     return true;
1066   }
1067
1068   mutable bool reset_controls_called_;
1069 };
1070
1071 TEST_F(WidgetTest, BubbleControlsResetOnInit) {
1072   Widget* anchor = CreateTopLevelPlatformWidget();
1073   anchor->Show();
1074
1075   TestBubbleDelegateView* bubble_delegate =
1076       new TestBubbleDelegateView(anchor->client_view());
1077   Widget* bubble_widget(BubbleDelegateView::CreateBubble(bubble_delegate));
1078   EXPECT_TRUE(bubble_delegate->reset_controls_called_);
1079   bubble_widget->Show();
1080   bubble_widget->CloseNow();
1081
1082   anchor->Hide();
1083   anchor->CloseNow();
1084 }
1085
1086 // Desktop native widget Aura tests are for non Chrome OS platforms.
1087 #if !defined(OS_CHROMEOS)
1088 // Test to ensure that after minimize, view width is set to zero.
1089 TEST_F(WidgetTest, TestViewWidthAfterMinimizingWidget) {
1090   // Create a widget.
1091   Widget widget;
1092   Widget::InitParams init_params =
1093       CreateParams(Widget::InitParams::TYPE_WINDOW);
1094   init_params.show_state = ui::SHOW_STATE_NORMAL;
1095   gfx::Rect initial_bounds(0, 0, 300, 400);
1096   init_params.bounds = initial_bounds;
1097   init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
1098   init_params.native_widget = new PlatformDesktopNativeWidget(&widget);
1099   widget.Init(init_params);
1100   NonClientView* non_client_view = widget.non_client_view();
1101   NonClientFrameView* frame_view = new MinimumSizeFrameView(&widget);
1102   non_client_view->SetFrameView(frame_view);
1103   widget.Show();
1104   widget.Minimize();
1105   EXPECT_EQ(0, frame_view->width());
1106 }
1107
1108 // This class validates whether paints are received for a visible Widget.
1109 // To achieve this it overrides the Show and Close methods on the Widget class
1110 // and sets state whether subsequent paints are expected.
1111 class DesktopAuraTestValidPaintWidget : public views::Widget {
1112  public:
1113   DesktopAuraTestValidPaintWidget()
1114     : received_paint_(false),
1115       expect_paint_(true),
1116       received_paint_while_hidden_(false) {}
1117
1118   ~DesktopAuraTestValidPaintWidget() override {}
1119
1120   void InitForTest(Widget::InitParams create_params);
1121
1122   void Show() override {
1123     expect_paint_ = true;
1124     views::Widget::Show();
1125   }
1126
1127   void Close() override {
1128     expect_paint_ = false;
1129     views::Widget::Close();
1130   }
1131
1132   void Hide() {
1133     expect_paint_ = false;
1134     views::Widget::Hide();
1135   }
1136
1137   void OnNativeWidgetPaint(gfx::Canvas* canvas) override {
1138     received_paint_ = true;
1139     EXPECT_TRUE(expect_paint_);
1140     if (!expect_paint_)
1141       received_paint_while_hidden_ = true;
1142     views::Widget::OnNativeWidgetPaint(canvas);
1143   }
1144
1145   bool ReadReceivedPaintAndReset() {
1146     bool result = received_paint_;
1147     received_paint_ = false;
1148     return result;
1149   }
1150
1151   bool received_paint_while_hidden() const {
1152     return received_paint_while_hidden_;
1153   }
1154
1155  private:
1156   bool received_paint_;
1157   bool expect_paint_;
1158   bool received_paint_while_hidden_;
1159
1160   DISALLOW_COPY_AND_ASSIGN(DesktopAuraTestValidPaintWidget);
1161 };
1162
1163 void DesktopAuraTestValidPaintWidget::InitForTest(InitParams init_params) {
1164   init_params.bounds = gfx::Rect(0, 0, 200, 200);
1165   init_params.ownership = InitParams::WIDGET_OWNS_NATIVE_WIDGET;
1166   init_params.native_widget = new PlatformDesktopNativeWidget(this);
1167   Init(init_params);
1168
1169   View* contents_view = new View;
1170   contents_view->SetFocusable(true);
1171   SetContentsView(contents_view);
1172
1173   Show();
1174   Activate();
1175 }
1176
1177 TEST_F(WidgetTest, DesktopNativeWidgetNoPaintAfterCloseTest) {
1178   DesktopAuraTestValidPaintWidget widget;
1179   widget.InitForTest(CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS));
1180   RunPendingMessages();
1181   EXPECT_TRUE(widget.ReadReceivedPaintAndReset());
1182   widget.SchedulePaintInRect(widget.GetRestoredBounds());
1183   widget.Close();
1184   RunPendingMessages();
1185   EXPECT_FALSE(widget.ReadReceivedPaintAndReset());
1186   EXPECT_FALSE(widget.received_paint_while_hidden());
1187 }
1188
1189 TEST_F(WidgetTest, DesktopNativeWidgetNoPaintAfterHideTest) {
1190   DesktopAuraTestValidPaintWidget widget;
1191   widget.InitForTest(CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS));
1192   RunPendingMessages();
1193   EXPECT_TRUE(widget.ReadReceivedPaintAndReset());
1194   widget.SchedulePaintInRect(widget.GetRestoredBounds());
1195   widget.Hide();
1196   RunPendingMessages();
1197   EXPECT_FALSE(widget.ReadReceivedPaintAndReset());
1198   EXPECT_FALSE(widget.received_paint_while_hidden());
1199   widget.Close();
1200 }
1201
1202 // Test to ensure that the aura Window's visiblity state is set to visible if
1203 // the underlying widget is hidden and then shown.
1204 TEST_F(WidgetTest, TestWindowVisibilityAfterHide) {
1205   // Create a widget.
1206   Widget widget;
1207   Widget::InitParams init_params =
1208       CreateParams(Widget::InitParams::TYPE_WINDOW);
1209   init_params.show_state = ui::SHOW_STATE_NORMAL;
1210   gfx::Rect initial_bounds(0, 0, 300, 400);
1211   init_params.bounds = initial_bounds;
1212   init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
1213   init_params.native_widget = new PlatformDesktopNativeWidget(&widget);
1214   widget.Init(init_params);
1215   NonClientView* non_client_view = widget.non_client_view();
1216   NonClientFrameView* frame_view = new MinimumSizeFrameView(&widget);
1217   non_client_view->SetFrameView(frame_view);
1218
1219   widget.Show();
1220   EXPECT_TRUE(IsNativeWindowVisible(widget.GetNativeWindow()));
1221   widget.Hide();
1222   EXPECT_FALSE(IsNativeWindowVisible(widget.GetNativeWindow()));
1223   widget.Show();
1224   EXPECT_TRUE(IsNativeWindowVisible(widget.GetNativeWindow()));
1225 }
1226
1227 // The following code verifies we can correctly destroy a Widget from a mouse
1228 // enter/exit. We could test move/drag/enter/exit but in general we don't run
1229 // nested message loops from such events, nor has the code ever really dealt
1230 // with this situation.
1231
1232 // Generates two moves (first generates enter, second real move), a press, drag
1233 // and release stopping at |last_event_type|.
1234 void GenerateMouseEvents(Widget* widget, ui::EventType last_event_type) {
1235   const gfx::Rect screen_bounds(widget->GetWindowBoundsInScreen());
1236   ui::MouseEvent move_event(ui::ET_MOUSE_MOVED, screen_bounds.CenterPoint(),
1237                             screen_bounds.CenterPoint(), 0, 0);
1238   ui::EventProcessor* dispatcher = WidgetTest::GetEventProcessor(widget);
1239   ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&move_event);
1240   if (last_event_type == ui::ET_MOUSE_ENTERED || details.dispatcher_destroyed)
1241     return;
1242   details = dispatcher->OnEventFromSource(&move_event);
1243   if (last_event_type == ui::ET_MOUSE_MOVED || details.dispatcher_destroyed)
1244     return;
1245
1246   ui::MouseEvent press_event(ui::ET_MOUSE_PRESSED, screen_bounds.CenterPoint(),
1247                              screen_bounds.CenterPoint(), 0, 0);
1248   details = dispatcher->OnEventFromSource(&press_event);
1249   if (last_event_type == ui::ET_MOUSE_PRESSED || details.dispatcher_destroyed)
1250     return;
1251
1252   gfx::Point end_point(screen_bounds.CenterPoint());
1253   end_point.Offset(1, 1);
1254   ui::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED, end_point, end_point, 0, 0);
1255   details = dispatcher->OnEventFromSource(&drag_event);
1256   if (last_event_type == ui::ET_MOUSE_DRAGGED || details.dispatcher_destroyed)
1257     return;
1258
1259   ui::MouseEvent release_event(ui::ET_MOUSE_RELEASED, end_point, end_point, 0,
1260                                0);
1261   details = dispatcher->OnEventFromSource(&release_event);
1262   if (details.dispatcher_destroyed)
1263     return;
1264 }
1265
1266 // Creates a widget and invokes GenerateMouseEvents() with |last_event_type|.
1267 void RunCloseWidgetDuringDispatchTest(WidgetTest* test,
1268                                       ui::EventType last_event_type) {
1269   // |widget| is deleted by CloseWidgetView.
1270   Widget* widget = new Widget;
1271   Widget::InitParams params =
1272       test->CreateParams(Widget::InitParams::TYPE_POPUP);
1273   params.native_widget = new PlatformDesktopNativeWidget(widget);
1274   params.bounds = gfx::Rect(0, 0, 50, 100);
1275   widget->Init(params);
1276   widget->SetContentsView(new CloseWidgetView(last_event_type));
1277   widget->Show();
1278   GenerateMouseEvents(widget, last_event_type);
1279 }
1280
1281 // Verifies deleting the widget from a mouse pressed event doesn't crash.
1282 TEST_F(WidgetTest, CloseWidgetDuringMousePress) {
1283   RunCloseWidgetDuringDispatchTest(this, ui::ET_MOUSE_PRESSED);
1284 }
1285
1286 // Verifies deleting the widget from a mouse released event doesn't crash.
1287 TEST_F(WidgetTest, CloseWidgetDuringMouseReleased) {
1288   RunCloseWidgetDuringDispatchTest(this, ui::ET_MOUSE_RELEASED);
1289 }
1290
1291 #endif  // !defined(OS_CHROMEOS)
1292
1293 // Tests that wheel events generated from scroll events are targetted to the
1294 // views under the cursor when the focused view does not processed them.
1295 TEST_F(WidgetTest, WheelEventsFromScrollEventTarget) {
1296   EventCountView* cursor_view = new EventCountView;
1297   cursor_view->SetBounds(60, 0, 50, 40);
1298
1299   Widget* widget = CreateTopLevelPlatformWidget();
1300   widget->GetRootView()->AddChildView(cursor_view);
1301
1302   // Generate a scroll event on the cursor view.
1303   ui::ScrollEvent scroll(ui::ET_SCROLL,
1304                          gfx::Point(65, 5),
1305                          ui::EventTimeForNow(),
1306                          0,
1307                          0, 20,
1308                          0, 20,
1309                          2);
1310   widget->OnScrollEvent(&scroll);
1311
1312   EXPECT_EQ(1, cursor_view->GetEventCount(ui::ET_SCROLL));
1313   EXPECT_EQ(1, cursor_view->GetEventCount(ui::ET_MOUSEWHEEL));
1314
1315   cursor_view->ResetCounts();
1316
1317   ui::ScrollEvent scroll2(ui::ET_SCROLL,
1318                           gfx::Point(5, 5),
1319                           ui::EventTimeForNow(),
1320                           0,
1321                           0, 20,
1322                           0, 20,
1323                           2);
1324   widget->OnScrollEvent(&scroll2);
1325
1326   EXPECT_EQ(0, cursor_view->GetEventCount(ui::ET_SCROLL));
1327   EXPECT_EQ(0, cursor_view->GetEventCount(ui::ET_MOUSEWHEEL));
1328
1329   widget->CloseNow();
1330 }
1331
1332 // Tests that if a scroll-begin gesture is not handled, then subsequent scroll
1333 // events are not dispatched to any view.
1334 TEST_F(WidgetTest, GestureScrollEventDispatching) {
1335   EventCountView* noscroll_view = new EventCountView;
1336   EventCountView* scroll_view = new ScrollableEventCountView;
1337
1338   noscroll_view->SetBounds(0, 0, 50, 40);
1339   scroll_view->SetBounds(60, 0, 40, 40);
1340
1341   Widget* widget = CreateTopLevelPlatformWidget();
1342   widget->GetRootView()->AddChildView(noscroll_view);
1343   widget->GetRootView()->AddChildView(scroll_view);
1344
1345   {
1346     ui::GestureEvent begin(
1347         5,
1348         5,
1349         0,
1350         base::TimeDelta(),
1351         ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN));
1352     widget->OnGestureEvent(&begin);
1353     ui::GestureEvent update(
1354         25,
1355         15,
1356         0,
1357         base::TimeDelta(),
1358         ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE, 20, 10));
1359     widget->OnGestureEvent(&update);
1360     ui::GestureEvent end(25,
1361                          15,
1362                          0,
1363                          base::TimeDelta(),
1364                          ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END));
1365     widget->OnGestureEvent(&end);
1366
1367     EXPECT_EQ(1, noscroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_BEGIN));
1368     EXPECT_EQ(0, noscroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_UPDATE));
1369     EXPECT_EQ(0, noscroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_END));
1370   }
1371
1372   {
1373     ui::GestureEvent begin(
1374         65,
1375         5,
1376         0,
1377         base::TimeDelta(),
1378         ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN));
1379     widget->OnGestureEvent(&begin);
1380     ui::GestureEvent update(
1381         85,
1382         15,
1383         0,
1384         base::TimeDelta(),
1385         ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE, 20, 10));
1386     widget->OnGestureEvent(&update);
1387     ui::GestureEvent end(85,
1388                          15,
1389                          0,
1390                          base::TimeDelta(),
1391                          ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END));
1392     widget->OnGestureEvent(&end);
1393
1394     EXPECT_EQ(1, scroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_BEGIN));
1395     EXPECT_EQ(1, scroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_UPDATE));
1396     EXPECT_EQ(1, scroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_END));
1397   }
1398
1399   widget->CloseNow();
1400 }
1401
1402 // Tests that event-handlers installed on the RootView get triggered correctly.
1403 // TODO(tdanderson): Clean up this test as part of crbug.com/355680.
1404 TEST_F(WidgetTest, EventHandlersOnRootView) {
1405   Widget* widget = CreateTopLevelNativeWidget();
1406   View* root_view = widget->GetRootView();
1407
1408   scoped_ptr<EventCountView> view(new EventCountView());
1409   view->set_owned_by_client();
1410   view->SetBounds(0, 0, 20, 20);
1411   root_view->AddChildView(view.get());
1412
1413   EventCountHandler h1;
1414   root_view->AddPreTargetHandler(&h1);
1415
1416   EventCountHandler h2;
1417   root_view->AddPostTargetHandler(&h2);
1418
1419   widget->SetBounds(gfx::Rect(0, 0, 100, 100));
1420   widget->Show();
1421
1422   // Dispatch a ui::ET_SCROLL event. The event remains unhandled and should
1423   // bubble up the views hierarchy to be re-dispatched on the root view.
1424   ui::ScrollEvent scroll(ui::ET_SCROLL,
1425                          gfx::Point(5, 5),
1426                          ui::EventTimeForNow(),
1427                          0,
1428                          0, 20,
1429                          0, 20,
1430                          2);
1431   widget->OnScrollEvent(&scroll);
1432   EXPECT_EQ(2, h1.GetEventCount(ui::ET_SCROLL));
1433   EXPECT_EQ(1, view->GetEventCount(ui::ET_SCROLL));
1434   EXPECT_EQ(2, h2.GetEventCount(ui::ET_SCROLL));
1435
1436   // Unhandled scroll events are turned into wheel events and re-dispatched.
1437   EXPECT_EQ(1, h1.GetEventCount(ui::ET_MOUSEWHEEL));
1438   EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSEWHEEL));
1439   EXPECT_EQ(1, h2.GetEventCount(ui::ET_MOUSEWHEEL));
1440
1441   h1.ResetCounts();
1442   view->ResetCounts();
1443   h2.ResetCounts();
1444
1445   // Dispatch a ui::ET_SCROLL_FLING_START event. The event remains unhandled and
1446   // should bubble up the views hierarchy to be re-dispatched on the root view.
1447   ui::ScrollEvent fling(ui::ET_SCROLL_FLING_START,
1448                         gfx::Point(5, 5),
1449                         ui::EventTimeForNow(),
1450                         0,
1451                         0, 20,
1452                         0, 20,
1453                         2);
1454   widget->OnScrollEvent(&fling);
1455   EXPECT_EQ(2, h1.GetEventCount(ui::ET_SCROLL_FLING_START));
1456   EXPECT_EQ(1, view->GetEventCount(ui::ET_SCROLL_FLING_START));
1457   EXPECT_EQ(2, h2.GetEventCount(ui::ET_SCROLL_FLING_START));
1458
1459   // Unhandled scroll events which are not of type ui::ET_SCROLL should not
1460   // be turned into wheel events and re-dispatched.
1461   EXPECT_EQ(0, h1.GetEventCount(ui::ET_MOUSEWHEEL));
1462   EXPECT_EQ(0, view->GetEventCount(ui::ET_MOUSEWHEEL));
1463   EXPECT_EQ(0, h2.GetEventCount(ui::ET_MOUSEWHEEL));
1464
1465   h1.ResetCounts();
1466   view->ResetCounts();
1467   h2.ResetCounts();
1468
1469   // Change the handle mode of |view| so that events are marked as handled at
1470   // the target phase.
1471   view->set_handle_mode(EventCountView::CONSUME_EVENTS);
1472
1473   // Dispatch a ui::ET_GESTURE_TAP_DOWN and a ui::ET_GESTURE_TAP_CANCEL event.
1474   // The events are handled at the target phase and should not reach the
1475   // post-target handler.
1476   ui::GestureEvent tap_down(5,
1477                             5,
1478                             0,
1479                             ui::EventTimeForNow(),
1480                             ui::GestureEventDetails(ui::ET_GESTURE_TAP_DOWN));
1481   widget->OnGestureEvent(&tap_down);
1482   EXPECT_EQ(1, h1.GetEventCount(ui::ET_GESTURE_TAP_DOWN));
1483   EXPECT_EQ(1, view->GetEventCount(ui::ET_GESTURE_TAP_DOWN));
1484   EXPECT_EQ(0, h2.GetEventCount(ui::ET_GESTURE_TAP_DOWN));
1485
1486   ui::GestureEvent tap_cancel(
1487       5,
1488       5,
1489       0,
1490       ui::EventTimeForNow(),
1491       ui::GestureEventDetails(ui::ET_GESTURE_TAP_CANCEL));
1492   widget->OnGestureEvent(&tap_cancel);
1493   EXPECT_EQ(1, h1.GetEventCount(ui::ET_GESTURE_TAP_CANCEL));
1494   EXPECT_EQ(1, view->GetEventCount(ui::ET_GESTURE_TAP_CANCEL));
1495   EXPECT_EQ(0, h2.GetEventCount(ui::ET_GESTURE_TAP_CANCEL));
1496
1497   h1.ResetCounts();
1498   view->ResetCounts();
1499   h2.ResetCounts();
1500
1501   // Dispatch a ui::ET_SCROLL event. The event is handled at the target phase
1502   // and should not reach the post-target handler.
1503   ui::ScrollEvent consumed_scroll(ui::ET_SCROLL,
1504                                   gfx::Point(5, 5),
1505                                   ui::EventTimeForNow(),
1506                                   0,
1507                                   0, 20,
1508                                   0, 20,
1509                                   2);
1510   widget->OnScrollEvent(&consumed_scroll);
1511   EXPECT_EQ(1, h1.GetEventCount(ui::ET_SCROLL));
1512   EXPECT_EQ(1, view->GetEventCount(ui::ET_SCROLL));
1513   EXPECT_EQ(0, h2.GetEventCount(ui::ET_SCROLL));
1514
1515   // Handled scroll events are not turned into wheel events and re-dispatched.
1516   EXPECT_EQ(0, h1.GetEventCount(ui::ET_MOUSEWHEEL));
1517   EXPECT_EQ(0, view->GetEventCount(ui::ET_MOUSEWHEEL));
1518   EXPECT_EQ(0, h2.GetEventCount(ui::ET_MOUSEWHEEL));
1519
1520   widget->CloseNow();
1521 }
1522
1523 TEST_F(WidgetTest, SynthesizeMouseMoveEvent) {
1524   Widget* widget = CreateTopLevelNativeWidget();
1525   View* root_view = widget->GetRootView();
1526
1527   EventCountView* v1 = new EventCountView();
1528   v1->SetBounds(0, 0, 10, 10);
1529   root_view->AddChildView(v1);
1530   EventCountView* v2 = new EventCountView();
1531   v2->SetBounds(0, 10, 10, 10);
1532   root_view->AddChildView(v2);
1533
1534   gfx::Point cursor_location(5, 5);
1535   ui::MouseEvent move(ui::ET_MOUSE_MOVED, cursor_location, cursor_location,
1536                       ui::EF_NONE, ui::EF_NONE);
1537   widget->OnMouseEvent(&move);
1538
1539   EXPECT_EQ(1, v1->GetEventCount(ui::ET_MOUSE_ENTERED));
1540   EXPECT_EQ(0, v2->GetEventCount(ui::ET_MOUSE_ENTERED));
1541
1542   delete v1;
1543   v2->SetBounds(0, 0, 10, 10);
1544   EXPECT_EQ(0, v2->GetEventCount(ui::ET_MOUSE_ENTERED));
1545
1546   widget->SynthesizeMouseMoveEvent();
1547   EXPECT_EQ(1, v2->GetEventCount(ui::ET_MOUSE_ENTERED));
1548 }
1549
1550 namespace {
1551
1552 // ui::EventHandler which handles all mouse press events.
1553 class MousePressEventConsumer : public ui::EventHandler {
1554  public:
1555   explicit MousePressEventConsumer() {
1556   }
1557
1558   ~MousePressEventConsumer() override {}
1559
1560  private:
1561   // ui::EventHandler:
1562   void OnMouseEvent(ui::MouseEvent* event) override {
1563     if (event->type() == ui::ET_MOUSE_PRESSED)
1564       event->SetHandled();
1565   }
1566
1567   DISALLOW_COPY_AND_ASSIGN(MousePressEventConsumer);
1568 };
1569
1570 }  // namespace
1571
1572 // Test that mouse presses and mouse releases are dispatched normally when a
1573 // touch is down.
1574 TEST_F(WidgetTest, MouseEventDispatchWhileTouchIsDown) {
1575   Widget* widget = CreateTopLevelNativeWidget();
1576   widget->Show();
1577   widget->SetSize(gfx::Size(300, 300));
1578
1579   EventCountView* event_count_view = new EventCountView();
1580   event_count_view->SetBounds(0, 0, 300, 300);
1581   widget->GetRootView()->AddChildView(event_count_view);
1582
1583   MousePressEventConsumer consumer;
1584   event_count_view->AddPostTargetHandler(&consumer);
1585
1586   ui::test::EventGenerator generator(GetContext(), widget->GetNativeWindow());
1587   generator.PressTouch();
1588   generator.ClickLeftButton();
1589
1590   EXPECT_EQ(1, event_count_view->GetEventCount(ui::ET_MOUSE_PRESSED));
1591   EXPECT_EQ(1, event_count_view->GetEventCount(ui::ET_MOUSE_RELEASED));
1592
1593   widget->CloseNow();
1594 }
1595
1596 // Used by SingleWindowClosing to count number of times WindowClosing() has
1597 // been invoked.
1598 class ClosingDelegate : public WidgetDelegate {
1599  public:
1600   ClosingDelegate() : count_(0), widget_(NULL) {}
1601
1602   int count() const { return count_; }
1603
1604   void set_widget(views::Widget* widget) { widget_ = widget; }
1605
1606   // WidgetDelegate overrides:
1607   Widget* GetWidget() override { return widget_; }
1608   const Widget* GetWidget() const override { return widget_; }
1609   void WindowClosing() override { count_++; }
1610
1611  private:
1612   int count_;
1613   views::Widget* widget_;
1614
1615   DISALLOW_COPY_AND_ASSIGN(ClosingDelegate);
1616 };
1617
1618 // Verifies WindowClosing() is invoked correctly on the delegate when a Widget
1619 // is closed.
1620 TEST_F(WidgetTest, SingleWindowClosing) {
1621   scoped_ptr<ClosingDelegate> delegate(new ClosingDelegate());
1622   Widget* widget = new Widget();  // Destroyed by CloseNow() below.
1623   Widget::InitParams init_params =
1624       CreateParams(Widget::InitParams::TYPE_WINDOW);
1625   init_params.bounds = gfx::Rect(0, 0, 200, 200);
1626   init_params.delegate = delegate.get();
1627 #if !defined(OS_CHROMEOS)
1628   init_params.native_widget = new PlatformDesktopNativeWidget(widget);
1629 #endif
1630   widget->Init(init_params);
1631   EXPECT_EQ(0, delegate->count());
1632   widget->CloseNow();
1633   EXPECT_EQ(1, delegate->count());
1634 }
1635
1636 class WidgetWindowTitleTest : public WidgetTest {
1637  protected:
1638   void RunTest(bool desktop_native_widget) {
1639     Widget* widget = new Widget();  // Destroyed by CloseNow() below.
1640     Widget::InitParams init_params =
1641         CreateParams(Widget::InitParams::TYPE_WINDOW);
1642     widget->Init(init_params);
1643
1644 #if !defined(OS_CHROMEOS)
1645     if (desktop_native_widget)
1646       init_params.native_widget = new PlatformDesktopNativeWidget(widget);
1647 #else
1648     DCHECK(!desktop_native_widget)
1649         << "DesktopNativeWidget does not exist on non-Aura or on ChromeOS.";
1650 #endif
1651
1652     internal::NativeWidgetPrivate* native_widget =
1653         widget->native_widget_private();
1654
1655     base::string16 empty;
1656     base::string16 s1(base::UTF8ToUTF16("Title1"));
1657     base::string16 s2(base::UTF8ToUTF16("Title2"));
1658     base::string16 s3(base::UTF8ToUTF16("TitleLong"));
1659
1660     // The widget starts with no title, setting empty should not change
1661     // anything.
1662     EXPECT_FALSE(native_widget->SetWindowTitle(empty));
1663     // Setting the title to something non-empty should cause a change.
1664     EXPECT_TRUE(native_widget->SetWindowTitle(s1));
1665     // Setting the title to something else with the same length should cause a
1666     // change.
1667     EXPECT_TRUE(native_widget->SetWindowTitle(s2));
1668     // Setting the title to something else with a different length should cause
1669     // a change.
1670     EXPECT_TRUE(native_widget->SetWindowTitle(s3));
1671     // Setting the title to the same thing twice should not cause a change.
1672     EXPECT_FALSE(native_widget->SetWindowTitle(s3));
1673
1674     widget->CloseNow();
1675   }
1676 };
1677
1678 TEST_F(WidgetWindowTitleTest, SetWindowTitleChanged_NativeWidget) {
1679   // Use the default NativeWidget.
1680   bool desktop_native_widget = false;
1681   RunTest(desktop_native_widget);
1682 }
1683
1684 // DesktopNativeWidget does not exist on non-Aura or on ChromeOS.
1685 #if !defined(OS_CHROMEOS)
1686 TEST_F(WidgetWindowTitleTest, SetWindowTitleChanged_DesktopNativeWidget) {
1687   // Override to use a DesktopNativeWidget.
1688   bool desktop_native_widget = true;
1689   RunTest(desktop_native_widget);
1690 }
1691 #endif  // !OS_CHROMEOS
1692
1693 TEST_F(WidgetTest, WidgetDeleted_InOnMousePressed) {
1694   Widget* widget = new Widget;
1695   Widget::InitParams params =
1696       CreateParams(views::Widget::InitParams::TYPE_POPUP);
1697   widget->Init(params);
1698
1699   widget->SetContentsView(new CloseWidgetView(ui::ET_MOUSE_PRESSED));
1700
1701   widget->SetSize(gfx::Size(100, 100));
1702   widget->Show();
1703
1704   ui::test::EventGenerator generator(GetContext(), widget->GetNativeWindow());
1705
1706   WidgetDeletionObserver deletion_observer(widget);
1707   generator.ClickLeftButton();
1708   EXPECT_FALSE(deletion_observer.IsWidgetAlive());
1709
1710   // Yay we did not crash!
1711 }
1712
1713 TEST_F(WidgetTest, WidgetDeleted_InDispatchGestureEvent) {
1714   Widget* widget = new Widget;
1715   Widget::InitParams params =
1716       CreateParams(views::Widget::InitParams::TYPE_POPUP);
1717   widget->Init(params);
1718
1719   widget->SetContentsView(new CloseWidgetView(ui::ET_GESTURE_TAP_DOWN));
1720
1721   widget->SetSize(gfx::Size(100, 100));
1722   widget->Show();
1723
1724   ui::test::EventGenerator generator(GetContext(), widget->GetNativeWindow());
1725
1726   WidgetDeletionObserver deletion_observer(widget);
1727   generator.GestureTapAt(widget->GetWindowBoundsInScreen().CenterPoint());
1728   EXPECT_FALSE(deletion_observer.IsWidgetAlive());
1729
1730   // Yay we did not crash!
1731 }
1732
1733 // See description of RunGetNativeThemeFromDestructor() for details.
1734 class GetNativeThemeFromDestructorView : public WidgetDelegateView {
1735  public:
1736   GetNativeThemeFromDestructorView() {}
1737   ~GetNativeThemeFromDestructorView() override { VerifyNativeTheme(); }
1738
1739   View* GetContentsView() override { return this; }
1740
1741  private:
1742   void VerifyNativeTheme() {
1743     ASSERT_TRUE(GetNativeTheme() != NULL);
1744   }
1745
1746   DISALLOW_COPY_AND_ASSIGN(GetNativeThemeFromDestructorView);
1747 };
1748
1749 // Verifies GetNativeTheme() from the destructor of a WidgetDelegateView doesn't
1750 // crash. |is_first_run| is true if this is the first call. A return value of
1751 // true indicates this should be run again with a value of false.
1752 // First run uses DesktopNativeWidgetAura (if possible). Second run doesn't.
1753 bool RunGetNativeThemeFromDestructor(const Widget::InitParams& in_params,
1754                                      bool is_first_run) {
1755   bool needs_second_run = false;
1756   // Destroyed by CloseNow() below.
1757   Widget* widget = new Widget;
1758   Widget::InitParams params(in_params);
1759   // Deletes itself when the Widget is destroyed.
1760   params.delegate = new GetNativeThemeFromDestructorView;
1761 #if !defined(OS_CHROMEOS)
1762   if (is_first_run) {
1763     params.native_widget = new PlatformDesktopNativeWidget(widget);
1764     needs_second_run = true;
1765   }
1766 #endif
1767   widget->Init(params);
1768   widget->CloseNow();
1769   return needs_second_run;
1770 }
1771
1772 // See description of RunGetNativeThemeFromDestructor() for details.
1773 TEST_F(WidgetTest, GetNativeThemeFromDestructor) {
1774   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
1775   if (RunGetNativeThemeFromDestructor(params, true))
1776     RunGetNativeThemeFromDestructor(params, false);
1777 }
1778
1779 // Used by HideCloseDestroy. Allows setting a boolean when the widget is
1780 // destroyed.
1781 class CloseDestroysWidget : public Widget {
1782  public:
1783   explicit CloseDestroysWidget(bool* destroyed)
1784       : destroyed_(destroyed) {
1785   }
1786
1787   ~CloseDestroysWidget() override {
1788     if (destroyed_) {
1789       *destroyed_ = true;
1790       base::MessageLoop::current()->QuitNow();
1791     }
1792   }
1793
1794   void Detach() { destroyed_ = NULL; }
1795
1796  private:
1797   // If non-null set to true from destructor.
1798   bool* destroyed_;
1799
1800   DISALLOW_COPY_AND_ASSIGN(CloseDestroysWidget);
1801 };
1802
1803 // An observer that registers that an animation has ended.
1804 class AnimationEndObserver : public ui::ImplicitAnimationObserver {
1805  public:
1806   AnimationEndObserver() : animation_completed_(false) {}
1807   ~AnimationEndObserver() override {}
1808
1809   bool animation_completed() const { return animation_completed_; }
1810
1811   // ui::ImplicitAnimationObserver:
1812   void OnImplicitAnimationsCompleted() override { animation_completed_ = true; }
1813
1814  private:
1815   bool animation_completed_;
1816
1817   DISALLOW_COPY_AND_ASSIGN(AnimationEndObserver);
1818 };
1819
1820 // An observer that registers the bounds of a widget on destruction.
1821 class WidgetBoundsObserver : public WidgetObserver {
1822  public:
1823   WidgetBoundsObserver() {}
1824   ~WidgetBoundsObserver() override {}
1825
1826   gfx::Rect bounds() { return bounds_; }
1827
1828   // WidgetObserver:
1829   void OnWidgetDestroying(Widget* widget) override {
1830     bounds_ = widget->GetWindowBoundsInScreen();
1831   }
1832
1833  private:
1834   gfx::Rect bounds_;
1835
1836   DISALLOW_COPY_AND_ASSIGN(WidgetBoundsObserver);
1837 };
1838
1839 // Verifies Close() results in destroying.
1840 TEST_F(WidgetTest, CloseDestroys) {
1841   bool destroyed = false;
1842   CloseDestroysWidget* widget = new CloseDestroysWidget(&destroyed);
1843   Widget::InitParams params =
1844       CreateParams(views::Widget::InitParams::TYPE_MENU);
1845   params.opacity = Widget::InitParams::OPAQUE_WINDOW;
1846 #if !defined(OS_CHROMEOS)
1847   params.native_widget = new PlatformDesktopNativeWidget(widget);
1848 #endif
1849   widget->Init(params);
1850   widget->Show();
1851   widget->Hide();
1852   widget->Close();
1853   EXPECT_FALSE(destroyed);
1854   // Run the message loop as Close() asynchronously deletes.
1855   base::RunLoop().Run();
1856   EXPECT_TRUE(destroyed);
1857   // Close() should destroy the widget. If not we'll cleanup to avoid leaks.
1858   if (!destroyed) {
1859     widget->Detach();
1860     widget->CloseNow();
1861   }
1862 }
1863
1864 // Tests that killing a widget while animating it does not crash.
1865 TEST_F(WidgetTest, CloseWidgetWhileAnimating) {
1866   scoped_ptr<Widget> widget(new Widget);
1867   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
1868   params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
1869   params.bounds = gfx::Rect(50, 50, 250, 250);
1870   widget->Init(params);
1871   AnimationEndObserver animation_observer;
1872   WidgetBoundsObserver widget_observer;
1873   gfx::Rect bounds(0, 0, 50, 50);
1874   {
1875     // Normal animations for tests have ZERO_DURATION, make sure we are actually
1876     // animating the movement.
1877     ui::ScopedAnimationDurationScaleMode animation_scale_mode(
1878         ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
1879     ui::ScopedLayerAnimationSettings animation_settings(
1880         widget->GetLayer()->GetAnimator());
1881     animation_settings.AddObserver(&animation_observer);
1882     widget->AddObserver(&widget_observer);
1883     widget->Show();
1884
1885     // Animate the bounds change.
1886     widget->SetBounds(bounds);
1887     widget.reset();
1888     EXPECT_FALSE(animation_observer.animation_completed());
1889   }
1890   EXPECT_TRUE(animation_observer.animation_completed());
1891   EXPECT_EQ(widget_observer.bounds(), bounds);
1892 }
1893
1894 // A view that consumes mouse-pressed event and gesture-tap-down events.
1895 class RootViewTestView : public View {
1896  public:
1897   RootViewTestView(): View() {}
1898
1899  private:
1900   bool OnMousePressed(const ui::MouseEvent& event) override { return true; }
1901
1902   void OnGestureEvent(ui::GestureEvent* event) override {
1903     if (event->type() == ui::ET_GESTURE_TAP_DOWN)
1904       event->SetHandled();
1905   }
1906 };
1907
1908 // Checks if RootView::*_handler_ fields are unset when widget is hidden.
1909 // Fails on chromium.webkit Windows bot, see crbug.com/264872.
1910 #if defined(OS_WIN)
1911 #define MAYBE_DisableTestRootViewHandlersWhenHidden\
1912     DISABLED_TestRootViewHandlersWhenHidden
1913 #else
1914 #define MAYBE_DisableTestRootViewHandlersWhenHidden\
1915     TestRootViewHandlersWhenHidden
1916 #endif
1917 TEST_F(WidgetTest, MAYBE_DisableTestRootViewHandlersWhenHidden) {
1918   Widget* widget = CreateTopLevelNativeWidget();
1919   widget->SetBounds(gfx::Rect(0, 0, 300, 300));
1920   View* view = new RootViewTestView();
1921   view->SetBounds(0, 0, 300, 300);
1922   internal::RootView* root_view =
1923       static_cast<internal::RootView*>(widget->GetRootView());
1924   root_view->AddChildView(view);
1925
1926   // Check RootView::mouse_pressed_handler_.
1927   widget->Show();
1928   EXPECT_EQ(NULL, GetMousePressedHandler(root_view));
1929   gfx::Point click_location(45, 15);
1930   ui::MouseEvent press(ui::ET_MOUSE_PRESSED, click_location, click_location,
1931                        ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
1932   widget->OnMouseEvent(&press);
1933   EXPECT_EQ(view, GetMousePressedHandler(root_view));
1934   widget->Hide();
1935   EXPECT_EQ(NULL, GetMousePressedHandler(root_view));
1936
1937   // Check RootView::mouse_move_handler_.
1938   widget->Show();
1939   EXPECT_EQ(NULL, GetMouseMoveHandler(root_view));
1940   gfx::Point move_location(45, 15);
1941   ui::MouseEvent move(ui::ET_MOUSE_MOVED, move_location, move_location, 0, 0);
1942   widget->OnMouseEvent(&move);
1943   EXPECT_EQ(view, GetMouseMoveHandler(root_view));
1944   widget->Hide();
1945   EXPECT_EQ(NULL, GetMouseMoveHandler(root_view));
1946
1947   // Check RootView::gesture_handler_.
1948   widget->Show();
1949   EXPECT_EQ(NULL, GetGestureHandler(root_view));
1950   ui::GestureEvent tap_down(15,
1951                             15,
1952                             0,
1953                             base::TimeDelta(),
1954                             ui::GestureEventDetails(ui::ET_GESTURE_TAP_DOWN));
1955   widget->OnGestureEvent(&tap_down);
1956   EXPECT_EQ(view, GetGestureHandler(root_view));
1957   widget->Hide();
1958   EXPECT_EQ(NULL, GetGestureHandler(root_view));
1959
1960   widget->Close();
1961 }
1962
1963 // Convenience to make constructing a GestureEvent simpler.
1964 class GestureEventForTest : public ui::GestureEvent {
1965  public:
1966   GestureEventForTest(ui::EventType type, int x, int y)
1967       : GestureEvent(x,
1968                      y,
1969                      0,
1970                      base::TimeDelta(),
1971                      ui::GestureEventDetails(type)) {}
1972
1973   GestureEventForTest(ui::GestureEventDetails details, int x, int y)
1974       : GestureEvent(x, y, 0, base::TimeDelta(), details) {}
1975 };
1976
1977 // Tests that the |gesture_handler_| member in RootView is always NULL
1978 // after the dispatch of a ui::ET_GESTURE_END event corresponding to
1979 // the release of the final touch point on the screen, but that
1980 // ui::ET_GESTURE_END events corresponding to the removal of any other touch
1981 // point do not modify |gesture_handler_|.
1982 TEST_F(WidgetTest, GestureEndEvents) {
1983   Widget* widget = CreateTopLevelNativeWidget();
1984   widget->SetBounds(gfx::Rect(0, 0, 300, 300));
1985   EventCountView* view = new EventCountView();
1986   view->SetBounds(0, 0, 300, 300);
1987   internal::RootView* root_view =
1988       static_cast<internal::RootView*>(widget->GetRootView());
1989   root_view->AddChildView(view);
1990   widget->Show();
1991
1992   // If no gesture handler is set, a ui::ET_GESTURE_END event should not set
1993   // the gesture handler.
1994   EXPECT_EQ(NULL, GetGestureHandler(root_view));
1995   GestureEventForTest end(ui::ET_GESTURE_END, 15, 15);
1996   widget->OnGestureEvent(&end);
1997   EXPECT_EQ(NULL, GetGestureHandler(root_view));
1998
1999   // Change the handle mode of |view| to indicate that it would like
2000   // to handle all events, then send a GESTURE_TAP to set the gesture handler.
2001   view->set_handle_mode(EventCountView::CONSUME_EVENTS);
2002   GestureEventForTest tap(ui::ET_GESTURE_TAP, 15, 15);
2003   widget->OnGestureEvent(&tap);
2004   EXPECT_TRUE(tap.handled());
2005   EXPECT_EQ(view, GetGestureHandler(root_view));
2006
2007   // The gesture handler should remain unchanged on a ui::ET_GESTURE_END
2008   // corresponding to a second touch point, but should be reset to NULL by a
2009   // ui::ET_GESTURE_END corresponding to the final touch point.
2010   ui::GestureEventDetails details(ui::ET_GESTURE_END);
2011   details.set_touch_points(2);
2012   GestureEventForTest end_second_touch_point(details, 15, 15);
2013   widget->OnGestureEvent(&end_second_touch_point);
2014   EXPECT_EQ(view, GetGestureHandler(root_view));
2015
2016   end = GestureEventForTest(ui::ET_GESTURE_END, 15, 15);
2017   widget->OnGestureEvent(&end);
2018   EXPECT_TRUE(end.handled());
2019   EXPECT_EQ(NULL, GetGestureHandler(root_view));
2020
2021   // Send a GESTURE_TAP to set the gesture handler, then change the handle
2022   // mode of |view| to indicate that it does not want to handle any
2023   // further events.
2024   tap = GestureEventForTest(ui::ET_GESTURE_TAP, 15, 15);
2025   widget->OnGestureEvent(&tap);
2026   EXPECT_TRUE(tap.handled());
2027   EXPECT_EQ(view, GetGestureHandler(root_view));
2028   view->set_handle_mode(EventCountView::PROPAGATE_EVENTS);
2029
2030   // The gesture handler should remain unchanged on a ui::ET_GESTURE_END
2031   // corresponding to a second touch point, but should be reset to NULL by a
2032   // ui::ET_GESTURE_END corresponding to the final touch point.
2033   end_second_touch_point = GestureEventForTest(details, 15, 15);
2034   widget->OnGestureEvent(&end_second_touch_point);
2035   EXPECT_EQ(view, GetGestureHandler(root_view));
2036
2037   end = GestureEventForTest(ui::ET_GESTURE_END, 15, 15);
2038   widget->OnGestureEvent(&end);
2039   EXPECT_FALSE(end.handled());
2040   EXPECT_EQ(NULL, GetGestureHandler(root_view));
2041
2042   widget->Close();
2043 }
2044
2045 // Tests that gesture events which should not be processed (because
2046 // RootView::OnEventProcessingStarted() has marked them as handled) are not
2047 // dispatched to any views.
2048 TEST_F(WidgetTest, GestureEventsNotProcessed) {
2049   Widget* widget = CreateTopLevelNativeWidget();
2050   widget->SetBounds(gfx::Rect(0, 0, 300, 300));
2051
2052   // Define a hierarchy of four views (coordinates are in
2053   // their parent coordinate space).
2054   // v1 (0, 0, 300, 300)
2055   //   v2 (0, 0, 100, 100)
2056   //     v3 (0, 0, 50, 50)
2057   //       v4(0, 0, 10, 10)
2058   EventCountView* v1 = new EventCountView();
2059   v1->SetBounds(0, 0, 300, 300);
2060   EventCountView* v2 = new EventCountView();
2061   v2->SetBounds(0, 0, 100, 100);
2062   EventCountView* v3 = new EventCountView();
2063   v3->SetBounds(0, 0, 50, 50);
2064   EventCountView* v4 = new EventCountView();
2065   v4->SetBounds(0, 0, 10, 10);
2066   internal::RootView* root_view =
2067       static_cast<internal::RootView*>(widget->GetRootView());
2068   root_view->AddChildView(v1);
2069   v1->AddChildView(v2);
2070   v2->AddChildView(v3);
2071   v3->AddChildView(v4);
2072
2073   widget->Show();
2074
2075   // ui::ET_GESTURE_BEGIN events should never be seen by any view, but
2076   // they should be marked as handled by OnEventProcessingStarted().
2077   GestureEventForTest begin(ui::ET_GESTURE_BEGIN, 5, 5);
2078   widget->OnGestureEvent(&begin);
2079   EXPECT_EQ(0, v1->GetEventCount(ui::ET_GESTURE_BEGIN));
2080   EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_BEGIN));
2081   EXPECT_EQ(0, v3->GetEventCount(ui::ET_GESTURE_BEGIN));
2082   EXPECT_EQ(0, v4->GetEventCount(ui::ET_GESTURE_BEGIN));
2083   EXPECT_EQ(NULL, GetGestureHandler(root_view));
2084   EXPECT_TRUE(begin.handled());
2085   v1->ResetCounts();
2086   v2->ResetCounts();
2087   v3->ResetCounts();
2088   v4->ResetCounts();
2089
2090   // ui::ET_GESTURE_END events should not be seen by any view when there is
2091   // no default gesture handler set, but they should be marked as handled by
2092   // OnEventProcessingStarted().
2093   GestureEventForTest end(ui::ET_GESTURE_END, 5, 5);
2094   widget->OnGestureEvent(&end);
2095   EXPECT_EQ(0, v1->GetEventCount(ui::ET_GESTURE_END));
2096   EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_END));
2097   EXPECT_EQ(0, v3->GetEventCount(ui::ET_GESTURE_END));
2098   EXPECT_EQ(0, v4->GetEventCount(ui::ET_GESTURE_END));
2099   EXPECT_EQ(NULL, GetGestureHandler(root_view));
2100   EXPECT_TRUE(end.handled());
2101   v1->ResetCounts();
2102   v2->ResetCounts();
2103   v3->ResetCounts();
2104   v4->ResetCounts();
2105
2106   // ui::ET_GESTURE_END events not corresponding to the release of the
2107   // final touch point should never be seen by any view, but they should
2108   // be marked as handled by OnEventProcessingStarted().
2109   ui::GestureEventDetails details(ui::ET_GESTURE_END);
2110   details.set_touch_points(2);
2111   GestureEventForTest end_second_touch_point(details, 5, 5);
2112   widget->OnGestureEvent(&end_second_touch_point);
2113   EXPECT_EQ(0, v1->GetEventCount(ui::ET_GESTURE_END));
2114   EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_END));
2115   EXPECT_EQ(0, v3->GetEventCount(ui::ET_GESTURE_END));
2116   EXPECT_EQ(0, v4->GetEventCount(ui::ET_GESTURE_END));
2117   EXPECT_EQ(NULL, GetGestureHandler(root_view));
2118   EXPECT_TRUE(end_second_touch_point.handled());
2119   v1->ResetCounts();
2120   v2->ResetCounts();
2121   v3->ResetCounts();
2122   v4->ResetCounts();
2123
2124   // ui::ET_GESTURE_SCROLL_UPDATE events should never be seen by any view when
2125   // there is no default gesture handler set, but they should be marked as
2126   // handled by OnEventProcessingStarted().
2127   GestureEventForTest scroll_update(ui::ET_GESTURE_SCROLL_UPDATE, 5, 5);
2128   widget->OnGestureEvent(&scroll_update);
2129   EXPECT_EQ(0, v1->GetEventCount(ui::ET_GESTURE_SCROLL_UPDATE));
2130   EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_SCROLL_UPDATE));
2131   EXPECT_EQ(0, v3->GetEventCount(ui::ET_GESTURE_SCROLL_UPDATE));
2132   EXPECT_EQ(0, v4->GetEventCount(ui::ET_GESTURE_SCROLL_UPDATE));
2133   EXPECT_EQ(NULL, GetGestureHandler(root_view));
2134   EXPECT_TRUE(scroll_update.handled());
2135   v1->ResetCounts();
2136   v2->ResetCounts();
2137   v3->ResetCounts();
2138   v4->ResetCounts();
2139
2140   // ui::ET_GESTURE_SCROLL_END events should never be seen by any view when
2141   // there is no default gesture handler set, but they should be marked as
2142   // handled by OnEventProcessingStarted().
2143   GestureEventForTest scroll_end(ui::ET_GESTURE_SCROLL_END, 5, 5);
2144   widget->OnGestureEvent(&scroll_end);
2145   EXPECT_EQ(0, v1->GetEventCount(ui::ET_GESTURE_SCROLL_END));
2146   EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_SCROLL_END));
2147   EXPECT_EQ(0, v3->GetEventCount(ui::ET_GESTURE_SCROLL_END));
2148   EXPECT_EQ(0, v4->GetEventCount(ui::ET_GESTURE_SCROLL_END));
2149   EXPECT_EQ(NULL, GetGestureHandler(root_view));
2150   EXPECT_TRUE(scroll_end.handled());
2151   v1->ResetCounts();
2152   v2->ResetCounts();
2153   v3->ResetCounts();
2154   v4->ResetCounts();
2155
2156   // ui::ET_SCROLL_FLING_START events should never be seen by any view when
2157   // there is no default gesture handler set, but they should be marked as
2158   // handled by OnEventProcessingStarted().
2159   GestureEventForTest scroll_fling_start(ui::ET_SCROLL_FLING_START, 5, 5);
2160   widget->OnGestureEvent(&scroll_fling_start);
2161   EXPECT_EQ(0, v1->GetEventCount(ui::ET_SCROLL_FLING_START));
2162   EXPECT_EQ(0, v2->GetEventCount(ui::ET_SCROLL_FLING_START));
2163   EXPECT_EQ(0, v3->GetEventCount(ui::ET_SCROLL_FLING_START));
2164   EXPECT_EQ(0, v4->GetEventCount(ui::ET_SCROLL_FLING_START));
2165   EXPECT_EQ(NULL, GetGestureHandler(root_view));
2166   EXPECT_TRUE(scroll_fling_start.handled());
2167   v1->ResetCounts();
2168   v2->ResetCounts();
2169   v3->ResetCounts();
2170   v4->ResetCounts();
2171
2172   widget->Close();
2173 }
2174
2175 // Tests that a (non-scroll) gesture event is dispatched to the correct views
2176 // in a view hierarchy and that the default gesture handler in RootView is set
2177 // correctly.
2178 TEST_F(WidgetTest, GestureEventDispatch) {
2179   Widget* widget = CreateTopLevelNativeWidget();
2180   widget->SetBounds(gfx::Rect(0, 0, 300, 300));
2181
2182   // Define a hierarchy of four views (coordinates are in
2183   // their parent coordinate space).
2184   // v1 (0, 0, 300, 300)
2185   //   v2 (0, 0, 100, 100)
2186   //     v3 (0, 0, 50, 50)
2187   //       v4(0, 0, 10, 10)
2188   EventCountView* v1 = new EventCountView();
2189   v1->SetBounds(0, 0, 300, 300);
2190   EventCountView* v2 = new EventCountView();
2191   v2->SetBounds(0, 0, 100, 100);
2192   EventCountView* v3 = new EventCountView();
2193   v3->SetBounds(0, 0, 50, 50);
2194   EventCountView* v4 = new EventCountView();
2195   v4->SetBounds(0, 0, 10, 10);
2196   internal::RootView* root_view =
2197       static_cast<internal::RootView*>(widget->GetRootView());
2198   root_view->AddChildView(v1);
2199   v1->AddChildView(v2);
2200   v2->AddChildView(v3);
2201   v3->AddChildView(v4);
2202
2203   widget->Show();
2204
2205   // No gesture handler is set in the root view and none of the views in the
2206   // view hierarchy handle a ui::ET_GESTURE_TAP event. In this case the tap
2207   // event should be dispatched to all views in the hierarchy, the gesture
2208   // handler should remain unset, and the event should remain unhandled.
2209   GestureEventForTest tap(ui::ET_GESTURE_TAP, 5, 5);
2210   EXPECT_EQ(NULL, GetGestureHandler(root_view));
2211   widget->OnGestureEvent(&tap);
2212   EXPECT_EQ(1, v1->GetEventCount(ui::ET_GESTURE_TAP));
2213   EXPECT_EQ(1, v2->GetEventCount(ui::ET_GESTURE_TAP));
2214   EXPECT_EQ(1, v3->GetEventCount(ui::ET_GESTURE_TAP));
2215   EXPECT_EQ(1, v4->GetEventCount(ui::ET_GESTURE_TAP));
2216   EXPECT_EQ(NULL, GetGestureHandler(root_view));
2217   EXPECT_FALSE(tap.handled());
2218
2219   // No gesture handler is set in the root view and |v1|, |v2|, and |v3| all
2220   // handle a ui::ET_GESTURE_TAP event. In this case the tap event should be
2221   // dispatched to |v4| and |v3|, the gesture handler should be set to |v3|,
2222   // and the event should be marked as handled.
2223   v1->ResetCounts();
2224   v2->ResetCounts();
2225   v3->ResetCounts();
2226   v4->ResetCounts();
2227   v1->set_handle_mode(EventCountView::CONSUME_EVENTS);
2228   v2->set_handle_mode(EventCountView::CONSUME_EVENTS);
2229   v3->set_handle_mode(EventCountView::CONSUME_EVENTS);
2230   tap = GestureEventForTest(ui::ET_GESTURE_TAP, 5, 5);
2231   widget->OnGestureEvent(&tap);
2232   EXPECT_EQ(0, v1->GetEventCount(ui::ET_GESTURE_TAP));
2233   EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_TAP));
2234   EXPECT_EQ(1, v3->GetEventCount(ui::ET_GESTURE_TAP));
2235   EXPECT_EQ(1, v4->GetEventCount(ui::ET_GESTURE_TAP));
2236   EXPECT_EQ(v3, GetGestureHandler(root_view));
2237   EXPECT_TRUE(tap.handled());
2238
2239   // The gesture handler is set to |v3| and all views handle all gesture event
2240   // types. In this case subsequent gesture events should only be dispatched to
2241   // |v3| and marked as handled. The gesture handler should remain as |v3|.
2242   v1->ResetCounts();
2243   v2->ResetCounts();
2244   v3->ResetCounts();
2245   v4->ResetCounts();
2246   v4->set_handle_mode(EventCountView::CONSUME_EVENTS);
2247   tap = GestureEventForTest(ui::ET_GESTURE_TAP, 5, 5);
2248   widget->OnGestureEvent(&tap);
2249   EXPECT_TRUE(tap.handled());
2250   GestureEventForTest show_press(ui::ET_GESTURE_SHOW_PRESS, 5, 5);
2251   widget->OnGestureEvent(&show_press);
2252   tap = GestureEventForTest(ui::ET_GESTURE_TAP, 5, 5);
2253   widget->OnGestureEvent(&tap);
2254   EXPECT_EQ(0, v1->GetEventCount(ui::ET_GESTURE_TAP));
2255   EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_TAP));
2256   EXPECT_EQ(2, v3->GetEventCount(ui::ET_GESTURE_TAP));
2257   EXPECT_EQ(0, v4->GetEventCount(ui::ET_GESTURE_TAP));
2258   EXPECT_EQ(0, v1->GetEventCount(ui::ET_GESTURE_SHOW_PRESS));
2259   EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_SHOW_PRESS));
2260   EXPECT_EQ(1, v3->GetEventCount(ui::ET_GESTURE_SHOW_PRESS));
2261   EXPECT_EQ(0, v4->GetEventCount(ui::ET_GESTURE_SHOW_PRESS));
2262   EXPECT_TRUE(tap.handled());
2263   EXPECT_TRUE(show_press.handled());
2264   EXPECT_EQ(v3, GetGestureHandler(root_view));
2265
2266   // The gesture handler is set to |v3|, but |v3| does not handle
2267   // ui::ET_GESTURE_TAP events. In this case a tap gesture should be dispatched
2268   // only to |v3|, but the event should remain unhandled. The gesture handler
2269   // should remain as |v3|.
2270   v1->ResetCounts();
2271   v2->ResetCounts();
2272   v3->ResetCounts();
2273   v4->ResetCounts();
2274   v3->set_handle_mode(EventCountView::PROPAGATE_EVENTS);
2275   tap = GestureEventForTest(ui::ET_GESTURE_TAP, 5, 5);
2276   widget->OnGestureEvent(&tap);
2277   EXPECT_EQ(0, v1->GetEventCount(ui::ET_GESTURE_TAP));
2278   EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_TAP));
2279   EXPECT_EQ(1, v3->GetEventCount(ui::ET_GESTURE_TAP));
2280   EXPECT_EQ(0, v4->GetEventCount(ui::ET_GESTURE_TAP));
2281   EXPECT_FALSE(tap.handled());
2282   EXPECT_EQ(v3, GetGestureHandler(root_view));
2283
2284   widget->Close();
2285 }
2286
2287 // Tests that gesture scroll events will change the default gesture handler in
2288 // RootView if the current handler to which they are dispatched does not handle
2289 // gesture scroll events.
2290 TEST_F(WidgetTest, ScrollGestureEventDispatch) {
2291   Widget* widget = CreateTopLevelNativeWidget();
2292   widget->SetBounds(gfx::Rect(0, 0, 300, 300));
2293
2294   // Define a hierarchy of four views (coordinates are in
2295   // their parent coordinate space).
2296   // v1 (0, 0, 300, 300)
2297   //   v2 (0, 0, 100, 100)
2298   //     v3 (0, 0, 50, 50)
2299   //       v4(0, 0, 10, 10)
2300   EventCountView* v1 = new EventCountView();
2301   v1->SetBounds(0, 0, 300, 300);
2302   EventCountView* v2 = new EventCountView();
2303   v2->SetBounds(0, 0, 100, 100);
2304   EventCountView* v3 = new EventCountView();
2305   v3->SetBounds(0, 0, 50, 50);
2306   EventCountView* v4 = new EventCountView();
2307   v4->SetBounds(0, 0, 10, 10);
2308   internal::RootView* root_view =
2309       static_cast<internal::RootView*>(widget->GetRootView());
2310   root_view->AddChildView(v1);
2311   v1->AddChildView(v2);
2312   v2->AddChildView(v3);
2313   v3->AddChildView(v4);
2314
2315   widget->Show();
2316
2317   // Change the handle mode of |v3| to indicate that it would like to handle
2318   // gesture events.
2319   v3->set_handle_mode(EventCountView::CONSUME_EVENTS);
2320
2321   // When no gesture handler is set, dispatching a ui::ET_GESTURE_TAP_DOWN
2322   // should bubble up the views hierarchy until it reaches the first view
2323   // that will handle it (|v3|) and then sets the handler to |v3|.
2324   EXPECT_EQ(NULL, GetGestureHandler(root_view));
2325   GestureEventForTest tap_down(ui::ET_GESTURE_TAP_DOWN, 5, 5);
2326   widget->OnGestureEvent(&tap_down);
2327   EXPECT_EQ(0, v1->GetEventCount(ui::ET_GESTURE_TAP_DOWN));
2328   EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_TAP_DOWN));
2329   EXPECT_EQ(1, v3->GetEventCount(ui::ET_GESTURE_TAP_DOWN));
2330   EXPECT_EQ(1, v4->GetEventCount(ui::ET_GESTURE_TAP_DOWN));
2331   EXPECT_EQ(v3, GetGestureHandler(root_view));
2332   EXPECT_TRUE(tap_down.handled());
2333   v1->ResetCounts();
2334   v2->ResetCounts();
2335   v3->ResetCounts();
2336   v4->ResetCounts();
2337
2338   // A ui::ET_GESTURE_TAP_CANCEL event should be dispatched to |v3| directly.
2339   GestureEventForTest tap_cancel(ui::ET_GESTURE_TAP_CANCEL, 5, 5);
2340   widget->OnGestureEvent(&tap_cancel);
2341   EXPECT_EQ(0, v1->GetEventCount(ui::ET_GESTURE_TAP_CANCEL));
2342   EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_TAP_CANCEL));
2343   EXPECT_EQ(1, v3->GetEventCount(ui::ET_GESTURE_TAP_CANCEL));
2344   EXPECT_EQ(0, v4->GetEventCount(ui::ET_GESTURE_TAP_CANCEL));
2345   EXPECT_EQ(v3, GetGestureHandler(root_view));
2346   EXPECT_TRUE(tap_cancel.handled());
2347   v1->ResetCounts();
2348   v2->ResetCounts();
2349   v3->ResetCounts();
2350   v4->ResetCounts();
2351
2352   // Change the handle mode of |v3| to indicate that it would no longer like
2353   // to handle events, and change the mode of |v1| to indicate that it would
2354   // like to handle events.
2355   v3->set_handle_mode(EventCountView::PROPAGATE_EVENTS);
2356   v1->set_handle_mode(EventCountView::CONSUME_EVENTS);
2357
2358   // Dispatch a ui::ET_GESTURE_SCROLL_BEGIN event. Because the current gesture
2359   // handler (|v3|) does not handle scroll events, the event should bubble up
2360   // the views hierarchy until it reaches the first view that will handle
2361   // it (|v1|) and then sets the handler to |v1|.
2362   GestureEventForTest scroll_begin(ui::ET_GESTURE_SCROLL_BEGIN, 5, 5);
2363   widget->OnGestureEvent(&scroll_begin);
2364   EXPECT_EQ(1, v1->GetEventCount(ui::ET_GESTURE_SCROLL_BEGIN));
2365   EXPECT_EQ(1, v2->GetEventCount(ui::ET_GESTURE_SCROLL_BEGIN));
2366   EXPECT_EQ(1, v3->GetEventCount(ui::ET_GESTURE_SCROLL_BEGIN));
2367   EXPECT_EQ(0, v4->GetEventCount(ui::ET_GESTURE_SCROLL_BEGIN));
2368   EXPECT_EQ(v1, GetGestureHandler(root_view));
2369   EXPECT_TRUE(scroll_begin.handled());
2370   v1->ResetCounts();
2371   v2->ResetCounts();
2372   v3->ResetCounts();
2373   v4->ResetCounts();
2374
2375   // A ui::ET_GESTURE_SCROLL_UPDATE event should be dispatched to |v1|
2376   // directly.
2377   GestureEventForTest scroll_update(ui::ET_GESTURE_SCROLL_UPDATE, 5, 5);
2378   widget->OnGestureEvent(&scroll_update);
2379   EXPECT_EQ(1, v1->GetEventCount(ui::ET_GESTURE_SCROLL_UPDATE));
2380   EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_SCROLL_UPDATE));
2381   EXPECT_EQ(0, v3->GetEventCount(ui::ET_GESTURE_SCROLL_UPDATE));
2382   EXPECT_EQ(0, v4->GetEventCount(ui::ET_GESTURE_SCROLL_UPDATE));
2383   EXPECT_EQ(v1, GetGestureHandler(root_view));
2384   EXPECT_TRUE(scroll_update.handled());
2385   v1->ResetCounts();
2386   v2->ResetCounts();
2387   v3->ResetCounts();
2388   v4->ResetCounts();
2389
2390   // A ui::ET_GESTURE_SCROLL_END event should be dispatched to |v1|
2391   // directly and should not reset the gesture handler.
2392   GestureEventForTest scroll_end(ui::ET_GESTURE_SCROLL_END, 5, 5);
2393   widget->OnGestureEvent(&scroll_end);
2394   EXPECT_EQ(1, v1->GetEventCount(ui::ET_GESTURE_SCROLL_END));
2395   EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_SCROLL_END));
2396   EXPECT_EQ(0, v3->GetEventCount(ui::ET_GESTURE_SCROLL_END));
2397   EXPECT_EQ(0, v4->GetEventCount(ui::ET_GESTURE_SCROLL_END));
2398   EXPECT_EQ(v1, GetGestureHandler(root_view));
2399   EXPECT_TRUE(scroll_end.handled());
2400   v1->ResetCounts();
2401   v2->ResetCounts();
2402   v3->ResetCounts();
2403   v4->ResetCounts();
2404
2405   // A ui::ET_GESTURE_PINCH_BEGIN event (which is a non-scroll event) should
2406   // still be dispatched to |v1| directly.
2407   GestureEventForTest pinch_begin(ui::ET_GESTURE_PINCH_BEGIN, 5, 5);
2408   widget->OnGestureEvent(&pinch_begin);
2409   EXPECT_EQ(1, v1->GetEventCount(ui::ET_GESTURE_PINCH_BEGIN));
2410   EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_PINCH_BEGIN));
2411   EXPECT_EQ(0, v3->GetEventCount(ui::ET_GESTURE_PINCH_BEGIN));
2412   EXPECT_EQ(0, v4->GetEventCount(ui::ET_GESTURE_PINCH_BEGIN));
2413   EXPECT_EQ(v1, GetGestureHandler(root_view));
2414   EXPECT_TRUE(pinch_begin.handled());
2415   v1->ResetCounts();
2416   v2->ResetCounts();
2417   v3->ResetCounts();
2418   v4->ResetCounts();
2419
2420   // A ui::ET_GESTURE_END event should be dispatched to |v1| and should
2421   // set the gesture handler to NULL.
2422   GestureEventForTest end(ui::ET_GESTURE_END, 5, 5);
2423   widget->OnGestureEvent(&end);
2424   EXPECT_EQ(1, v1->GetEventCount(ui::ET_GESTURE_END));
2425   EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_END));
2426   EXPECT_EQ(0, v3->GetEventCount(ui::ET_GESTURE_END));
2427   EXPECT_EQ(0, v4->GetEventCount(ui::ET_GESTURE_END));
2428   EXPECT_EQ(NULL, GetGestureHandler(root_view));
2429   EXPECT_TRUE(end.handled());
2430
2431   widget->Close();
2432 }
2433
2434 // A class used in WidgetTest.GestureEventLocationWhileBubbling to verify
2435 // that when a gesture event bubbles up a View hierarchy, the location
2436 // of a gesture event seen by each View is in the local coordinate space
2437 // of that View.
2438 class GestureLocationView : public EventCountView {
2439  public:
2440   GestureLocationView() {}
2441   ~GestureLocationView() override {}
2442
2443   void set_expected_location(gfx::Point expected_location) {
2444     expected_location_ = expected_location;
2445   }
2446
2447   // EventCountView:
2448   void OnGestureEvent(ui::GestureEvent* event) override {
2449     EventCountView::OnGestureEvent(event);
2450
2451     // Verify that the location of |event| is in the local coordinate
2452     // space of |this|.
2453     EXPECT_EQ(expected_location_, event->location());
2454   }
2455
2456  private:
2457   // The expected location of a gesture event dispatched to |this|.
2458   gfx::Point expected_location_;
2459
2460   DISALLOW_COPY_AND_ASSIGN(GestureLocationView);
2461 };
2462
2463 // Verifies that the location of a gesture event is always in the local
2464 // coordinate space of the View receiving the event while bubbling.
2465 TEST_F(WidgetTest, GestureEventLocationWhileBubbling) {
2466   Widget* widget = CreateTopLevelNativeWidget();
2467   widget->SetBounds(gfx::Rect(0, 0, 300, 300));
2468
2469   // Define a hierarchy of three views (coordinates shown below are in the
2470   // coordinate space of the root view, but the coordinates used for
2471   // SetBounds() are in their parent coordinate space).
2472   // v1 (50, 50, 150, 150)
2473   //   v2 (100, 70, 50, 80)
2474   //     v3 (120, 100, 10, 10)
2475   GestureLocationView* v1 = new GestureLocationView();
2476   v1->SetBounds(50, 50, 150, 150);
2477   GestureLocationView* v2 = new GestureLocationView();
2478   v2->SetBounds(50, 20, 50, 80);
2479   GestureLocationView* v3 = new GestureLocationView();
2480   v3->SetBounds(20, 30, 10, 10);
2481   internal::RootView* root_view =
2482       static_cast<internal::RootView*>(widget->GetRootView());
2483   root_view->AddChildView(v1);
2484   v1->AddChildView(v2);
2485   v2->AddChildView(v3);
2486
2487   widget->Show();
2488
2489   // Define a GESTURE_TAP event located at (125, 105) in root view coordinates.
2490   // This event is contained within all of |v1|, |v2|, and |v3|.
2491   gfx::Point location_in_root(125, 105);
2492   GestureEventForTest tap(
2493       ui::ET_GESTURE_TAP, location_in_root.x(), location_in_root.y());
2494
2495   // Calculate the location of the event in the local coordinate spaces
2496   // of each of the views.
2497   gfx::Point location_in_v1(ConvertPointFromWidgetToView(v1, location_in_root));
2498   EXPECT_EQ(gfx::Point(75, 55), location_in_v1);
2499   gfx::Point location_in_v2(ConvertPointFromWidgetToView(v2, location_in_root));
2500   EXPECT_EQ(gfx::Point(25, 35), location_in_v2);
2501   gfx::Point location_in_v3(ConvertPointFromWidgetToView(v3, location_in_root));
2502   EXPECT_EQ(gfx::Point(5, 5), location_in_v3);
2503
2504   // Dispatch the event. When each view receives the event, its location should
2505   // be in the local coordinate space of that view (see the check made by
2506   // GestureLocationView). After dispatch is complete the event's location
2507   // should be in the root coordinate space.
2508   v1->set_expected_location(location_in_v1);
2509   v2->set_expected_location(location_in_v2);
2510   v3->set_expected_location(location_in_v3);
2511   widget->OnGestureEvent(&tap);
2512   EXPECT_EQ(location_in_root, tap.location());
2513
2514   // Verify that each view did in fact see the event.
2515   EventCountView* view1 = v1;
2516   EventCountView* view2 = v2;
2517   EventCountView* view3 = v3;
2518   EXPECT_EQ(1, view1->GetEventCount(ui::ET_GESTURE_TAP));
2519   EXPECT_EQ(1, view2->GetEventCount(ui::ET_GESTURE_TAP));
2520   EXPECT_EQ(1, view3->GetEventCount(ui::ET_GESTURE_TAP));
2521
2522   widget->Close();
2523 }
2524
2525 // Verifies that disabled views are permitted to be set as the default gesture
2526 // handler in RootView. Also verifies that gesture events targeted to a disabled
2527 // view are not actually dispatched to the view, but are still marked as
2528 // handled.
2529 TEST_F(WidgetTest, DisabledGestureEventTarget) {
2530   Widget* widget = CreateTopLevelNativeWidget();
2531   widget->SetBounds(gfx::Rect(0, 0, 300, 300));
2532
2533   // Define a hierarchy of four views (coordinates are in
2534   // their parent coordinate space).
2535   // v1 (0, 0, 300, 300)
2536   //   v2 (0, 0, 100, 100)
2537   //     v3 (0, 0, 50, 50)
2538   //       v4(0, 0, 10, 10)
2539   EventCountView* v1 = new EventCountView();
2540   v1->SetBounds(0, 0, 300, 300);
2541   EventCountView* v2 = new EventCountView();
2542   v2->SetBounds(0, 0, 100, 100);
2543   EventCountView* v3 = new EventCountView();
2544   v3->SetBounds(0, 0, 50, 50);
2545   EventCountView* v4 = new EventCountView();
2546   v4->SetBounds(0, 0, 10, 10);
2547   internal::RootView* root_view =
2548       static_cast<internal::RootView*>(widget->GetRootView());
2549   root_view->AddChildView(v1);
2550   v1->AddChildView(v2);
2551   v2->AddChildView(v3);
2552   v3->AddChildView(v4);
2553
2554   widget->Show();
2555
2556   // |v1|, |v2|, and |v3| all handle gesture events but |v3| is marked as
2557   // disabled.
2558   v1->set_handle_mode(EventCountView::CONSUME_EVENTS);
2559   v2->set_handle_mode(EventCountView::CONSUME_EVENTS);
2560   v3->set_handle_mode(EventCountView::CONSUME_EVENTS);
2561   v3->SetEnabled(false);
2562
2563   // No gesture handler is set in the root view. In this case the tap event
2564   // should be dispatched only to |v4|, the gesture handler should be set to
2565   // |v3|, and the event should be marked as handled.
2566   GestureEventForTest tap(ui::ET_GESTURE_TAP, 5, 5);
2567   widget->OnGestureEvent(&tap);
2568   EXPECT_EQ(0, v1->GetEventCount(ui::ET_GESTURE_TAP));
2569   EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_TAP));
2570   EXPECT_EQ(0, v3->GetEventCount(ui::ET_GESTURE_TAP));
2571   EXPECT_EQ(1, v4->GetEventCount(ui::ET_GESTURE_TAP));
2572   EXPECT_EQ(v3, GetGestureHandler(root_view));
2573   EXPECT_TRUE(tap.handled());
2574   v1->ResetCounts();
2575   v2->ResetCounts();
2576   v3->ResetCounts();
2577   v4->ResetCounts();
2578
2579   // A subsequent gesture event should be marked as handled but not dispatched.
2580   tap = GestureEventForTest(ui::ET_GESTURE_TAP, 5, 5);
2581   widget->OnGestureEvent(&tap);
2582   EXPECT_EQ(0, v1->GetEventCount(ui::ET_GESTURE_TAP));
2583   EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_TAP));
2584   EXPECT_EQ(0, v3->GetEventCount(ui::ET_GESTURE_TAP));
2585   EXPECT_EQ(0, v4->GetEventCount(ui::ET_GESTURE_TAP));
2586   EXPECT_EQ(v3, GetGestureHandler(root_view));
2587   EXPECT_TRUE(tap.handled());
2588   v1->ResetCounts();
2589   v2->ResetCounts();
2590   v3->ResetCounts();
2591   v4->ResetCounts();
2592
2593   // A GESTURE_END should reset the default gesture handler to NULL. It should
2594   // also not be dispatched to |v3| but still marked as handled.
2595   GestureEventForTest end(ui::ET_GESTURE_END, 5, 5);
2596   widget->OnGestureEvent(&end);
2597   EXPECT_EQ(0, v1->GetEventCount(ui::ET_GESTURE_END));
2598   EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_END));
2599   EXPECT_EQ(0, v3->GetEventCount(ui::ET_GESTURE_END));
2600   EXPECT_EQ(0, v4->GetEventCount(ui::ET_GESTURE_END));
2601   EXPECT_EQ(NULL, GetGestureHandler(root_view));
2602   EXPECT_TRUE(end.handled());
2603   v1->ResetCounts();
2604   v2->ResetCounts();
2605   v3->ResetCounts();
2606   v4->ResetCounts();
2607
2608   // Change the handle mode of |v3| to indicate that it would no longer like
2609   // to handle events which are dispatched to it.
2610   v3->set_handle_mode(EventCountView::PROPAGATE_EVENTS);
2611
2612   // No gesture handler is set in the root view. In this case the tap event
2613   // should be dispatched only to |v4| and the event should be marked as
2614   // handled. Furthermore, the gesture handler should be set to
2615   // |v3|; even though |v3| does not explicitly handle events, it is a
2616   // valid target for the tap event because it is disabled.
2617   tap = GestureEventForTest(ui::ET_GESTURE_TAP, 5, 5);
2618   widget->OnGestureEvent(&tap);
2619   EXPECT_EQ(0, v1->GetEventCount(ui::ET_GESTURE_TAP));
2620   EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_TAP));
2621   EXPECT_EQ(0, v3->GetEventCount(ui::ET_GESTURE_TAP));
2622   EXPECT_EQ(1, v4->GetEventCount(ui::ET_GESTURE_TAP));
2623   EXPECT_EQ(v3, GetGestureHandler(root_view));
2624   EXPECT_TRUE(tap.handled());
2625   v1->ResetCounts();
2626   v2->ResetCounts();
2627   v3->ResetCounts();
2628   v4->ResetCounts();
2629
2630   // A GESTURE_END should reset the default gesture handler to NULL. It should
2631   // also not be dispatched to |v3| but still marked as handled.
2632   end = GestureEventForTest(ui::ET_GESTURE_END, 5, 5);
2633   widget->OnGestureEvent(&end);
2634   EXPECT_EQ(0, v1->GetEventCount(ui::ET_GESTURE_END));
2635   EXPECT_EQ(0, v2->GetEventCount(ui::ET_GESTURE_END));
2636   EXPECT_EQ(0, v3->GetEventCount(ui::ET_GESTURE_END));
2637   EXPECT_EQ(0, v4->GetEventCount(ui::ET_GESTURE_END));
2638   EXPECT_EQ(NULL, GetGestureHandler(root_view));
2639   EXPECT_TRUE(end.handled());
2640
2641   widget->Close();
2642 }
2643
2644 // Test the result of Widget::GetAllChildWidgets().
2645 TEST_F(WidgetTest, GetAllChildWidgets) {
2646   // Create the following widget hierarchy:
2647   //
2648   // toplevel
2649   // +-- w1
2650   //     +-- w11
2651   // +-- w2
2652   //     +-- w21
2653   //     +-- w22
2654   Widget* toplevel = CreateTopLevelPlatformWidget();
2655   Widget* w1 = CreateChildPlatformWidget(toplevel->GetNativeView());
2656   Widget* w11 = CreateChildPlatformWidget(w1->GetNativeView());
2657   Widget* w2 = CreateChildPlatformWidget(toplevel->GetNativeView());
2658   Widget* w21 = CreateChildPlatformWidget(w2->GetNativeView());
2659   Widget* w22 = CreateChildPlatformWidget(w2->GetNativeView());
2660
2661   std::set<Widget*> expected;
2662   expected.insert(toplevel);
2663   expected.insert(w1);
2664   expected.insert(w11);
2665   expected.insert(w2);
2666   expected.insert(w21);
2667   expected.insert(w22);
2668
2669   std::set<Widget*> widgets;
2670   Widget::GetAllChildWidgets(toplevel->GetNativeView(), &widgets);
2671
2672   EXPECT_EQ(expected.size(), widgets.size());
2673   EXPECT_TRUE(std::equal(expected.begin(), expected.end(), widgets.begin()));
2674 }
2675
2676 // Used by DestroyChildWidgetsInOrder. On destruction adds the supplied name to
2677 // a vector.
2678 class DestroyedTrackingView : public View {
2679  public:
2680   DestroyedTrackingView(const std::string& name,
2681                         std::vector<std::string>* add_to)
2682       : name_(name),
2683         add_to_(add_to) {
2684   }
2685
2686   ~DestroyedTrackingView() override { add_to_->push_back(name_); }
2687
2688  private:
2689   const std::string name_;
2690   std::vector<std::string>* add_to_;
2691
2692   DISALLOW_COPY_AND_ASSIGN(DestroyedTrackingView);
2693 };
2694
2695 class WidgetChildDestructionTest : public WidgetTest {
2696  public:
2697   WidgetChildDestructionTest() {}
2698
2699   // Creates a top level and a child, destroys the child and verifies the views
2700   // of the child are destroyed before the views of the parent.
2701   void RunDestroyChildWidgetsTest(bool top_level_has_desktop_native_widget_aura,
2702                                   bool child_has_desktop_native_widget_aura) {
2703     // When a View is destroyed its name is added here.
2704     std::vector<std::string> destroyed;
2705
2706     Widget* top_level = new Widget;
2707     Widget::InitParams params =
2708         CreateParams(views::Widget::InitParams::TYPE_WINDOW);
2709 #if !defined(OS_CHROMEOS)
2710     if (top_level_has_desktop_native_widget_aura)
2711       params.native_widget = new PlatformDesktopNativeWidget(top_level);
2712 #endif
2713     top_level->Init(params);
2714     top_level->GetRootView()->AddChildView(
2715         new DestroyedTrackingView("parent", &destroyed));
2716     top_level->Show();
2717
2718     Widget* child = new Widget;
2719     Widget::InitParams child_params =
2720         CreateParams(views::Widget::InitParams::TYPE_POPUP);
2721     child_params.parent = top_level->GetNativeView();
2722 #if !defined(OS_CHROMEOS)
2723     if (child_has_desktop_native_widget_aura)
2724       child_params.native_widget = new PlatformDesktopNativeWidget(child);
2725 #endif
2726     child->Init(child_params);
2727     child->GetRootView()->AddChildView(
2728         new DestroyedTrackingView("child", &destroyed));
2729     child->Show();
2730
2731     // Should trigger destruction of the child too.
2732     top_level->native_widget_private()->CloseNow();
2733
2734     // Child should be destroyed first.
2735     ASSERT_EQ(2u, destroyed.size());
2736     EXPECT_EQ("child", destroyed[0]);
2737     EXPECT_EQ("parent", destroyed[1]);
2738   }
2739
2740  private:
2741   DISALLOW_COPY_AND_ASSIGN(WidgetChildDestructionTest);
2742 };
2743
2744 #if !defined(OS_CHROMEOS)
2745 // See description of RunDestroyChildWidgetsTest(). Parent uses
2746 // DesktopNativeWidgetAura.
2747 TEST_F(WidgetChildDestructionTest,
2748        DestroyChildWidgetsInOrderWithDesktopNativeWidget) {
2749   RunDestroyChildWidgetsTest(true, false);
2750 }
2751
2752 // See description of RunDestroyChildWidgetsTest(). Both parent and child use
2753 // DesktopNativeWidgetAura.
2754 TEST_F(WidgetChildDestructionTest,
2755        DestroyChildWidgetsInOrderWithDesktopNativeWidgetForBoth) {
2756   RunDestroyChildWidgetsTest(true, true);
2757 }
2758 #endif  // !defined(OS_CHROMEOS)
2759
2760 // See description of RunDestroyChildWidgetsTest().
2761 TEST_F(WidgetChildDestructionTest, DestroyChildWidgetsInOrder) {
2762   RunDestroyChildWidgetsTest(false, false);
2763 }
2764
2765 #if !defined(OS_CHROMEOS)
2766 // Provides functionality to create a window modal dialog.
2767 class ModalDialogDelegate : public DialogDelegateView {
2768  public:
2769   ModalDialogDelegate() {}
2770   ~ModalDialogDelegate() override {}
2771
2772   // WidgetDelegate overrides.
2773   ui::ModalType GetModalType() const override { return ui::MODAL_TYPE_WINDOW; }
2774
2775  private:
2776   DISALLOW_COPY_AND_ASSIGN(ModalDialogDelegate);
2777 };
2778
2779 // This test verifies that whether mouse events when a modal dialog is
2780 // displayed are eaten or recieved by the dialog.
2781 TEST_F(WidgetTest, WindowMouseModalityTest) {
2782   // Create a top level widget.
2783   Widget top_level_widget;
2784   Widget::InitParams init_params =
2785       CreateParams(Widget::InitParams::TYPE_WINDOW);
2786   init_params.show_state = ui::SHOW_STATE_NORMAL;
2787   gfx::Rect initial_bounds(0, 0, 500, 500);
2788   init_params.bounds = initial_bounds;
2789   init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
2790   init_params.native_widget =
2791       new PlatformDesktopNativeWidget(&top_level_widget);
2792   top_level_widget.Init(init_params);
2793   top_level_widget.Show();
2794   EXPECT_TRUE(top_level_widget.IsVisible());
2795
2796   // Create a view and validate that a mouse moves makes it to the view.
2797   EventCountView* widget_view = new EventCountView();
2798   widget_view->SetBounds(0, 0, 10, 10);
2799   top_level_widget.GetRootView()->AddChildView(widget_view);
2800
2801   gfx::Point cursor_location_main(5, 5);
2802   ui::MouseEvent move_main(ui::ET_MOUSE_MOVED,
2803                            cursor_location_main,
2804                            cursor_location_main,
2805                            ui::EF_NONE,
2806                            ui::EF_NONE);
2807   ui::EventDispatchDetails details =
2808       GetEventProcessor(&top_level_widget)->OnEventFromSource(&move_main);
2809   ASSERT_FALSE(details.dispatcher_destroyed);
2810
2811   EXPECT_EQ(1, widget_view->GetEventCount(ui::ET_MOUSE_ENTERED));
2812   widget_view->ResetCounts();
2813
2814   // Create a modal dialog and validate that a mouse down message makes it to
2815   // the main view within the dialog.
2816
2817   // This instance will be destroyed when the dialog is destroyed.
2818   ModalDialogDelegate* dialog_delegate = new ModalDialogDelegate;
2819
2820   Widget* modal_dialog_widget = views::DialogDelegate::CreateDialogWidget(
2821       dialog_delegate, NULL, top_level_widget.GetNativeView());
2822   modal_dialog_widget->SetBounds(gfx::Rect(100, 100, 200, 200));
2823   EventCountView* dialog_widget_view = new EventCountView();
2824   dialog_widget_view->SetBounds(0, 0, 50, 50);
2825   modal_dialog_widget->GetRootView()->AddChildView(dialog_widget_view);
2826   modal_dialog_widget->Show();
2827   EXPECT_TRUE(modal_dialog_widget->IsVisible());
2828
2829   gfx::Point cursor_location_dialog(100, 100);
2830   ui::MouseEvent mouse_down_dialog(ui::ET_MOUSE_PRESSED,
2831                                    cursor_location_dialog,
2832                                    cursor_location_dialog,
2833                                    ui::EF_NONE,
2834                                    ui::EF_NONE);
2835   details = GetEventProcessor(&top_level_widget)->OnEventFromSource(
2836       &mouse_down_dialog);
2837   ASSERT_FALSE(details.dispatcher_destroyed);
2838   EXPECT_EQ(1, dialog_widget_view->GetEventCount(ui::ET_MOUSE_PRESSED));
2839
2840   // Send a mouse move message to the main window. It should not be received by
2841   // the main window as the modal dialog is still active.
2842   gfx::Point cursor_location_main2(6, 6);
2843   ui::MouseEvent mouse_down_main(ui::ET_MOUSE_MOVED,
2844                                  cursor_location_main2,
2845                                  cursor_location_main2,
2846                                  ui::EF_NONE,
2847                                  ui::EF_NONE);
2848   details = GetEventProcessor(&top_level_widget)->OnEventFromSource(
2849       &mouse_down_main);
2850   ASSERT_FALSE(details.dispatcher_destroyed);
2851   EXPECT_EQ(0, widget_view->GetEventCount(ui::ET_MOUSE_MOVED));
2852
2853   modal_dialog_widget->CloseNow();
2854   top_level_widget.CloseNow();
2855 }
2856
2857 // Verifies nativeview visbility matches that of Widget visibility when
2858 // SetFullscreen is invoked.
2859 TEST_F(WidgetTest, FullscreenStatePropagated) {
2860   Widget::InitParams init_params =
2861       CreateParams(Widget::InitParams::TYPE_WINDOW);
2862   init_params.show_state = ui::SHOW_STATE_NORMAL;
2863   init_params.bounds = gfx::Rect(0, 0, 500, 500);
2864   init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
2865
2866   {
2867     Widget top_level_widget;
2868     top_level_widget.Init(init_params);
2869     top_level_widget.SetFullscreen(true);
2870     EXPECT_EQ(top_level_widget.IsVisible(),
2871               IsNativeWindowVisible(top_level_widget.GetNativeWindow()));
2872     top_level_widget.CloseNow();
2873   }
2874 #if !defined(OS_CHROMEOS)
2875   {
2876     Widget top_level_widget;
2877     init_params.native_widget =
2878         new PlatformDesktopNativeWidget(&top_level_widget);
2879     top_level_widget.Init(init_params);
2880     top_level_widget.SetFullscreen(true);
2881     EXPECT_EQ(top_level_widget.IsVisible(),
2882               IsNativeWindowVisible(top_level_widget.GetNativeWindow()));
2883     top_level_widget.CloseNow();
2884   }
2885 #endif
2886 }
2887 #if defined(OS_WIN)
2888
2889 // Provides functionality to test widget activation via an activation flag
2890 // which can be set by an accessor.
2891 class ModalWindowTestWidgetDelegate : public WidgetDelegate {
2892  public:
2893   ModalWindowTestWidgetDelegate()
2894       : widget_(NULL),
2895         can_activate_(true) {}
2896
2897   virtual ~ModalWindowTestWidgetDelegate() {}
2898
2899   // Overridden from WidgetDelegate:
2900   virtual void DeleteDelegate() override {
2901     delete this;
2902   }
2903   virtual Widget* GetWidget() override {
2904     return widget_;
2905   }
2906   virtual const Widget* GetWidget() const override {
2907     return widget_;
2908   }
2909   virtual bool CanActivate() const override {
2910     return can_activate_;
2911   }
2912   virtual bool ShouldAdvanceFocusToTopLevelWidget() const override {
2913     return true;
2914   }
2915
2916   void set_can_activate(bool can_activate) {
2917     can_activate_ = can_activate;
2918   }
2919
2920   void set_widget(Widget* widget) {
2921     widget_ = widget;
2922   }
2923
2924  private:
2925   Widget* widget_;
2926   bool can_activate_;
2927
2928   DISALLOW_COPY_AND_ASSIGN(ModalWindowTestWidgetDelegate);
2929 };
2930
2931 // Tests whether we can activate the top level widget when a modal dialog is
2932 // active.
2933 TEST_F(WidgetTest, WindowModalityActivationTest) {
2934   // Destroyed when the top level widget created below is destroyed.
2935   ModalWindowTestWidgetDelegate* widget_delegate =
2936       new ModalWindowTestWidgetDelegate;
2937   // Create a top level widget.
2938   Widget top_level_widget;
2939   Widget::InitParams init_params =
2940       CreateParams(Widget::InitParams::TYPE_WINDOW);
2941   init_params.show_state = ui::SHOW_STATE_NORMAL;
2942   gfx::Rect initial_bounds(0, 0, 500, 500);
2943   init_params.bounds = initial_bounds;
2944   init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
2945   init_params.native_widget = new DesktopNativeWidgetAura(&top_level_widget);
2946   init_params.delegate = widget_delegate;
2947   top_level_widget.Init(init_params);
2948   widget_delegate->set_widget(&top_level_widget);
2949   top_level_widget.Show();
2950   EXPECT_TRUE(top_level_widget.IsVisible());
2951
2952   HWND win32_window = views::HWNDForWidget(&top_level_widget);
2953   EXPECT_TRUE(::IsWindow(win32_window));
2954
2955   // This instance will be destroyed when the dialog is destroyed.
2956   ModalDialogDelegate* dialog_delegate = new ModalDialogDelegate;
2957
2958   // We should be able to activate the window even if the WidgetDelegate
2959   // says no, when a modal dialog is active.
2960   widget_delegate->set_can_activate(false);
2961
2962   Widget* modal_dialog_widget = views::DialogDelegate::CreateDialogWidget(
2963       dialog_delegate, NULL, top_level_widget.GetNativeWindow());
2964   modal_dialog_widget->SetBounds(gfx::Rect(100, 100, 200, 200));
2965   modal_dialog_widget->Show();
2966   EXPECT_TRUE(modal_dialog_widget->IsVisible());
2967
2968   LRESULT activate_result = ::SendMessage(
2969       win32_window,
2970       WM_MOUSEACTIVATE,
2971       reinterpret_cast<WPARAM>(win32_window),
2972       MAKELPARAM(WM_LBUTTONDOWN, HTCLIENT));
2973   EXPECT_EQ(activate_result, MA_ACTIVATE);
2974
2975   modal_dialog_widget->CloseNow();
2976   top_level_widget.CloseNow();
2977 }
2978 #endif  // defined(OS_WIN)
2979 #endif  // !defined(OS_CHROMEOS)
2980
2981 TEST_F(WidgetTest, ShowCreatesActiveWindow) {
2982   Widget* widget = CreateTopLevelPlatformWidget();
2983
2984   widget->Show();
2985   EXPECT_EQ(GetWidgetShowState(widget), ui::SHOW_STATE_NORMAL);
2986
2987   widget->CloseNow();
2988 }
2989
2990 // OSX does not have a per-application "active" window such as provided by
2991 // ::GetActiveWindow() on Windows. There is only a system-wide "keyWindow" which
2992 // is updated asynchronously.
2993 #if defined(OS_MACOSX)
2994 #define MAYBE_ShowInactive DISABLED_ShowInactive
2995 #else
2996 #define MAYBE_ShowInactive ShowInactive
2997 #endif
2998 TEST_F(WidgetTest, MAYBE_ShowInactive) {
2999   Widget* widget = CreateTopLevelPlatformWidget();
3000
3001   widget->ShowInactive();
3002   EXPECT_EQ(GetWidgetShowState(widget), ui::SHOW_STATE_INACTIVE);
3003
3004   widget->CloseNow();
3005 }
3006
3007 TEST_F(WidgetTest, InactiveBeforeShow) {
3008   Widget* widget = CreateTopLevelPlatformWidget();
3009
3010   EXPECT_FALSE(widget->IsActive());
3011   EXPECT_FALSE(widget->IsVisible());
3012
3013   widget->Show();
3014
3015   EXPECT_TRUE(widget->IsActive());
3016   EXPECT_TRUE(widget->IsVisible());
3017
3018   widget->CloseNow();
3019 }
3020
3021 TEST_F(WidgetTest, ShowInactiveAfterShow) {
3022   // Create 2 widgets to ensure window layering does not change.
3023   Widget* widget = CreateTopLevelPlatformWidget();
3024   Widget* widget2 = CreateTopLevelPlatformWidget();
3025
3026   widget2->Show();
3027   EXPECT_FALSE(widget->IsActive());
3028   EXPECT_TRUE(widget2->IsVisible());
3029   EXPECT_TRUE(widget2->IsActive());
3030
3031   widget->Show();
3032   EXPECT_TRUE(widget->IsActive());
3033   EXPECT_FALSE(widget2->IsActive());
3034   widget->ShowInactive();
3035   EXPECT_TRUE(widget->IsActive());
3036   EXPECT_FALSE(widget2->IsActive());
3037   EXPECT_EQ(GetWidgetShowState(widget), ui::SHOW_STATE_NORMAL);
3038
3039   widget2->CloseNow();
3040   widget->CloseNow();
3041 }
3042
3043 TEST_F(WidgetTest, ShowAfterShowInactive) {
3044   Widget* widget = CreateTopLevelPlatformWidget();
3045
3046   widget->ShowInactive();
3047   widget->Show();
3048   EXPECT_EQ(GetWidgetShowState(widget), ui::SHOW_STATE_NORMAL);
3049
3050   widget->CloseNow();
3051 }
3052
3053 #if !defined(OS_CHROMEOS)
3054 TEST_F(WidgetTest, InactiveWidgetDoesNotGrabActivation) {
3055   Widget* widget = CreateTopLevelPlatformWidget();
3056   widget->Show();
3057   EXPECT_EQ(GetWidgetShowState(widget), ui::SHOW_STATE_NORMAL);
3058
3059   Widget widget2;
3060   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
3061   params.native_widget = new PlatformDesktopNativeWidget(&widget2);
3062   params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
3063   widget2.Init(params);
3064   widget2.Show();
3065
3066   EXPECT_EQ(GetWidgetShowState(&widget2), ui::SHOW_STATE_INACTIVE);
3067   EXPECT_EQ(GetWidgetShowState(widget), ui::SHOW_STATE_NORMAL);
3068
3069   widget->CloseNow();
3070   widget2.CloseNow();
3071 }
3072 #endif  // !defined(OS_CHROMEOS)
3073
3074 namespace {
3075
3076 class FullscreenAwareFrame : public views::NonClientFrameView {
3077  public:
3078   explicit FullscreenAwareFrame(views::Widget* widget)
3079       : widget_(widget), fullscreen_layout_called_(false) {}
3080   ~FullscreenAwareFrame() override {}
3081
3082   // views::NonClientFrameView overrides:
3083   gfx::Rect GetBoundsForClientView() const override { return gfx::Rect(); }
3084   gfx::Rect GetWindowBoundsForClientBounds(
3085       const gfx::Rect& client_bounds) const override {
3086     return gfx::Rect();
3087   }
3088   int NonClientHitTest(const gfx::Point& point) override { return HTNOWHERE; }
3089   void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask) override {}
3090   void ResetWindowControls() override {}
3091   void UpdateWindowIcon() override {}
3092   void UpdateWindowTitle() override {}
3093   void SizeConstraintsChanged() override {}
3094
3095   // views::View overrides:
3096   void Layout() override {
3097     if (widget_->IsFullscreen())
3098       fullscreen_layout_called_ = true;
3099   }
3100
3101   bool fullscreen_layout_called() const { return fullscreen_layout_called_; }
3102
3103  private:
3104   views::Widget* widget_;
3105   bool fullscreen_layout_called_;
3106
3107   DISALLOW_COPY_AND_ASSIGN(FullscreenAwareFrame);
3108 };
3109
3110 }  // namespace
3111
3112 // Tests that frame Layout is called when a widget goes fullscreen without
3113 // changing its size or title.
3114 TEST_F(WidgetTest, FullscreenFrameLayout) {
3115   Widget* widget = CreateTopLevelPlatformWidget();
3116   FullscreenAwareFrame* frame = new FullscreenAwareFrame(widget);
3117   widget->non_client_view()->SetFrameView(frame);  // Owns |frame|.
3118
3119   widget->Maximize();
3120   RunPendingMessages();
3121
3122   EXPECT_FALSE(frame->fullscreen_layout_called());
3123   widget->SetFullscreen(true);
3124   widget->Show();
3125   RunPendingMessages();
3126   EXPECT_TRUE(frame->fullscreen_layout_called());
3127
3128   widget->CloseNow();
3129 }
3130
3131 #if !defined(OS_CHROMEOS)
3132 namespace {
3133
3134 // Trivial WidgetObserverTest that invokes Widget::IsActive() from
3135 // OnWindowDestroying.
3136 class IsActiveFromDestroyObserver : public WidgetObserver {
3137  public:
3138   IsActiveFromDestroyObserver() {}
3139   ~IsActiveFromDestroyObserver() override {}
3140   void OnWidgetDestroying(Widget* widget) override { widget->IsActive(); }
3141
3142  private:
3143   DISALLOW_COPY_AND_ASSIGN(IsActiveFromDestroyObserver);
3144 };
3145
3146 }  // namespace
3147
3148 // Verifies Widget::IsActive() invoked from
3149 // WidgetObserver::OnWidgetDestroying() in a child widget doesn't crash.
3150 TEST_F(WidgetTest, IsActiveFromDestroy) {
3151   // Create two widgets, one a child of the other.
3152   IsActiveFromDestroyObserver observer;
3153   Widget parent_widget;
3154   Widget::InitParams parent_params =
3155       CreateParams(Widget::InitParams::TYPE_POPUP);
3156   parent_params.native_widget = new PlatformDesktopNativeWidget(&parent_widget);
3157   parent_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
3158   parent_widget.Init(parent_params);
3159   parent_widget.Show();
3160
3161   Widget child_widget;
3162   Widget::InitParams child_params =
3163       CreateParams(Widget::InitParams::TYPE_POPUP);
3164   child_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
3165   child_params.context = parent_widget.GetNativeWindow();
3166   child_widget.Init(child_params);
3167   child_widget.AddObserver(&observer);
3168   child_widget.Show();
3169
3170   parent_widget.CloseNow();
3171 }
3172 #endif  // !defined(OS_CHROMEOS)
3173
3174 // Tests that events propagate through from the dispatcher with the correct
3175 // event type, and that the different platforms behave the same.
3176 TEST_F(WidgetTest, MouseEventTypesViaGenerator) {
3177   EventCountView* view = new EventCountView;
3178   view->set_handle_mode(EventCountView::CONSUME_EVENTS);
3179   view->SetBounds(10, 10, 50, 40);
3180
3181   Widget* widget = CreateTopLevelFramelessPlatformWidget();
3182   widget->GetRootView()->AddChildView(view);
3183
3184   widget->SetBounds(gfx::Rect(0, 0, 100, 80));
3185   widget->Show();
3186
3187   ui::test::EventGenerator generator(GetContext(), widget->GetNativeWindow());
3188   generator.set_current_location(gfx::Point(20, 20));
3189
3190   generator.ClickLeftButton();
3191   EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_PRESSED));
3192   EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_RELEASED));
3193   EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, view->last_flags());
3194
3195   generator.PressRightButton();
3196   EXPECT_EQ(2, view->GetEventCount(ui::ET_MOUSE_PRESSED));
3197   EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_RELEASED));
3198   EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, view->last_flags());
3199
3200   generator.ReleaseRightButton();
3201   EXPECT_EQ(2, view->GetEventCount(ui::ET_MOUSE_PRESSED));
3202   EXPECT_EQ(2, view->GetEventCount(ui::ET_MOUSE_RELEASED));
3203   EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, view->last_flags());
3204
3205   // Test mouse move events.
3206   EXPECT_EQ(0, view->GetEventCount(ui::ET_MOUSE_MOVED));
3207   EXPECT_EQ(0, view->GetEventCount(ui::ET_MOUSE_ENTERED));
3208
3209   // Move the mouse within the view (20, 20) -> (30, 30).
3210   generator.MoveMouseTo(gfx::Point(30, 30));
3211   EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_MOVED));
3212   EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_ENTERED));
3213   EXPECT_EQ(ui::EF_NONE, view->last_flags());
3214
3215   // Move it again - entered count shouldn't change.
3216   generator.MoveMouseTo(gfx::Point(31, 31));
3217   EXPECT_EQ(2, view->GetEventCount(ui::ET_MOUSE_MOVED));
3218   EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_ENTERED));
3219   EXPECT_EQ(0, view->GetEventCount(ui::ET_MOUSE_EXITED));
3220
3221   // Move it off the view.
3222   generator.MoveMouseTo(gfx::Point(5, 5));
3223   EXPECT_EQ(2, view->GetEventCount(ui::ET_MOUSE_MOVED));
3224   EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_ENTERED));
3225   EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_EXITED));
3226
3227   // Move it back on.
3228   generator.MoveMouseTo(gfx::Point(20, 20));
3229   EXPECT_EQ(3, view->GetEventCount(ui::ET_MOUSE_MOVED));
3230   EXPECT_EQ(2, view->GetEventCount(ui::ET_MOUSE_ENTERED));
3231   EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_EXITED));
3232
3233   // Drargging. Cover HasCapture() and NativeWidgetPrivate::IsMouseButtonDown().
3234   generator.DragMouseTo(gfx::Point(40, 40));
3235   EXPECT_EQ(3, view->GetEventCount(ui::ET_MOUSE_PRESSED));
3236   EXPECT_EQ(3, view->GetEventCount(ui::ET_MOUSE_RELEASED));
3237   EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSE_DRAGGED));
3238   EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, view->last_flags());
3239
3240   widget->CloseNow();
3241 }
3242
3243 // Tests that the root view is correctly set up for Widget types that do not
3244 // require a non-client view, before any other views are added to the widget.
3245 // That is, before Widget::ReorderNativeViews() is called which, if called with
3246 // a root view not set, could cause the root view to get resized to the widget.
3247 TEST_F(WidgetTest, NonClientWindowValidAfterInit) {
3248   Widget* widget = CreateTopLevelFramelessPlatformWidget();
3249   View* root_view = widget->GetRootView();
3250
3251   // Size the root view to exceed the widget bounds.
3252   const gfx::Rect test_rect(0, 0, 500, 500);
3253   root_view->SetBoundsRect(test_rect);
3254
3255   EXPECT_NE(test_rect.size(), widget->GetWindowBoundsInScreen().size());
3256
3257   EXPECT_EQ(test_rect, root_view->bounds());
3258   widget->ReorderNativeViews();
3259   EXPECT_EQ(test_rect, root_view->bounds());
3260
3261   widget->CloseNow();
3262 }
3263
3264 }  // namespace test
3265 }  // namespace views