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