15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <algorithm>
63551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <set>
73551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/bind.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
11ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h"
127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/run_loop.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
157da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)#include "ui/base/hit_test.h"
16d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event_utils.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/native_widget_types.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/point.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/bubble/bubble_delegate.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/textfield/textfield.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/test/test_views_delegate.h"
2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/views/test/widget_test.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/views_delegate.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/native_widget_delegate.h"
25a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "ui/views/widget/root_view.h"
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/views/window/dialog_delegate.h"
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/views/window/native_frame_view.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_AURA)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/client/aura_constants.h"
311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ui/aura/client/window_tree_client.h"
327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/aura/root_window.h"
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/test/test_window_delegate.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/native_widget_aura.h"
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_CHROMEOS)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/native_widget_win.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_WIN)
444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/views/win/hwnd_util.h"
454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views {
48a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace test {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A view that keeps track of the events it receives, but consumes no events.
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class EventCountView : public View {
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EventCountView() {}
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~EventCountView() {}
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int GetEventCount(ui::EventType type) {
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return event_count_[type];
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ResetCounts() {
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event_count_.clear();
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from ui::EventHandler:
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE {
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RecordEvent(*event);
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RecordEvent(*event);
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE {
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RecordEvent(*event);
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE {
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RecordEvent(*event);
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RecordEvent(*event);
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void RecordEvent(const ui::Event& event) {
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ++event_count_[event.type()];
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::map<ui::EventType, int> event_count_;
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(EventCountView);
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A view that keeps track of the events it receives, and consumes all scroll
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// gesture events.
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ScrollableEventCountView : public EventCountView {
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScrollableEventCountView() {}
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~ScrollableEventCountView() {}
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from ui::EventHandler:
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EventCountView::OnGestureEvent(event);
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    switch (event->type()) {
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case ui::ET_GESTURE_SCROLL_BEGIN:
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case ui::ET_GESTURE_SCROLL_UPDATE:
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case ui::ET_GESTURE_SCROLL_END:
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case ui::ET_SCROLL_FLING_START:
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        event->SetHandled();
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      default:
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ScrollableEventCountView);
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// A view that implements GetMinimumSize.
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MinimumSizeFrameView : public NativeFrameView {
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  explicit MinimumSizeFrameView(Widget* frame): NativeFrameView(frame) {}
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~MinimumSizeFrameView() {}
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Overridden from View:
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual gfx::Size GetMinimumSize() OVERRIDE {
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return gfx::Size(300, 400);
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MinimumSizeFrameView);
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// An event handler that simply keeps a count of the different types of events
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// it receives.
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class EventCountHandler : public ui::EventHandler {
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EventCountHandler() {}
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~EventCountHandler() {}
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int GetEventCount(ui::EventType type) {
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return event_count_[type];
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ResetCounts() {
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event_count_.clear();
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from ui::EventHandler:
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnEvent(ui::Event* event) OVERRIDE {
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RecordEvent(*event);
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::EventHandler::OnEvent(event);
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void RecordEvent(const ui::Event& event) {
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ++event_count_[event.type()];
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::map<ui::EventType, int> event_count_;
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(EventCountHandler);
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::WindowShowState GetWidgetShowState(const Widget* widget) {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use IsMaximized/IsMinimized/IsFullScreen instead of GetWindowPlacement
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // because the former is implemented on all platforms but the latter is not.
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return widget->IsFullscreen() ? ui::SHOW_STATE_FULLSCREEN :
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget->IsMaximized() ? ui::SHOW_STATE_MAXIMIZED :
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget->IsMinimized() ? ui::SHOW_STATE_MINIMIZED :
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              ui::SHOW_STATE_NORMAL;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, WidgetInitParams) {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(views_delegate().UseTransparentWindows());
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Widgets are not transparent by default.
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget::InitParams init1;
179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(Widget::InitParams::INFER_OPACITY, init1.opacity);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Non-window widgets are not transparent either.
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget::InitParams init2(Widget::InitParams::TYPE_MENU);
183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(Widget::InitParams::INFER_OPACITY, init2.opacity);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A ViewsDelegate can set windows transparent by default.
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views_delegate().SetUseTransparentWindows(true);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget::InitParams init3;
188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(Widget::InitParams::TRANSLUCENT_WINDOW, init3.opacity);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Non-window widgets stay opaque.
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget::InitParams init4(Widget::InitParams::TYPE_MENU);
192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(Widget::InitParams::INFER_OPACITY, init4.opacity);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Widget::GetTopLevelWidget tests.
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, GetTopLevelWidget_Native) {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a hierarchy of native widgets.
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::NativeView parent = toplevel->GetNativeView();
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* child = CreateChildPlatformWidget(parent);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(toplevel, toplevel->GetTopLevelWidget());
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(toplevel, child->GetTopLevelWidget());
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |child| should be automatically destroyed with |toplevel|.
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test if a focus manager and an inputmethod work without CHECK failure
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// when window activation changes.
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, ChangeActivation) {
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* top1 = CreateTopLevelPlatformWidget();
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CreateInputMethod before activated
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top1->GetInputMethod();
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top1->Show();
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* top2 = CreateTopLevelPlatformWidget();
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top2->Show();
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top1->Activate();
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create InputMethod after deactivated.
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top2->GetInputMethod();
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top2->Activate();
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top1->Activate();
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top1->CloseNow();
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top2->CloseNow();
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests visibility of child widgets.
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, Visibility) {
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::NativeView parent = toplevel->GetNativeView();
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* child = CreateChildPlatformWidget(parent);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(toplevel->IsVisible());
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(child->IsVisible());
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child->Show();
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(toplevel->IsVisible());
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(child->IsVisible());
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Show();
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(toplevel->IsVisible());
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(child->IsVisible());
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |child| should be automatically destroyed with |toplevel|.
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) && !defined(USE_AURA)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// On Windows, it is possible to have child window that are TYPE_POPUP.  Unlike
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// regular child windows, these should be created as hidden and must be shown
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// explicitly.
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, Visibility_ChildPopup) {
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* child_popup = CreateChildPopupPlatformWidget(
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      toplevel->GetNativeView());
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(toplevel->IsVisible());
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(child_popup->IsVisible());
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Show();
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(toplevel->IsVisible());
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(child_popup->IsVisible());
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child_popup->Show();
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(child_popup->IsVisible());
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |child_popup| should be automatically destroyed with |toplevel|.
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Widget ownership tests.
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests various permutations of Widget ownership specified in the
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// InitParams::Ownership param.
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A WidgetTest that supplies a toplevel widget for NativeWidget to parent to.
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WidgetOwnershipTest : public WidgetTest {
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WidgetOwnershipTest() {}
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~WidgetOwnershipTest() {}
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WidgetTest::SetUp();
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    desktop_widget_ = CreateTopLevelPlatformWidget();
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    desktop_widget_->CloseNow();
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WidgetTest::TearDown();
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* desktop_widget_;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WidgetOwnershipTest);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A bag of state to monitor destructions.
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct OwnershipTestState {
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState() : widget_deleted(false), native_widget_deleted(false) {}
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool widget_deleted;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool native_widget_deleted;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A platform NativeWidget subclass that updates a bag of state when it is
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destroyed.
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OwnershipTestNativeWidget : public NativeWidgetPlatform {
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestNativeWidget(internal::NativeWidgetDelegate* delegate,
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            OwnershipTestState* state)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : NativeWidgetPlatform(delegate),
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        state_(state) {
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~OwnershipTestNativeWidget() {
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state_->native_widget_deleted = true;
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState* state_;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OwnershipTestNativeWidget);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A views NativeWidget subclass that updates a bag of state when it is
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destroyed.
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OwnershipTestNativeWidgetPlatform : public NativeWidgetPlatformForTest {
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestNativeWidgetPlatform(internal::NativeWidgetDelegate* delegate,
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    OwnershipTestState* state)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : NativeWidgetPlatformForTest(delegate),
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        state_(state) {
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~OwnershipTestNativeWidgetPlatform() {
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state_->native_widget_deleted = true;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState* state_;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OwnershipTestNativeWidgetPlatform);
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A Widget subclass that updates a bag of state when it is destroyed.
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OwnershipTestWidget : public Widget {
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit OwnershipTestWidget(OwnershipTestState* state) : state_(state) {}
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~OwnershipTestWidget() {
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state_->widget_deleted = true;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState* state_;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OwnershipTestWidget);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Widget owns its NativeWidget, part 1: NativeWidget is a platform-native
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// widget.
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetOwnershipTest, Ownership_WidgetOwnsPlatformNativeWidget) {
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState state;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.native_widget =
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new OwnershipTestNativeWidgetPlatform(widget.get(), &state);
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now delete the Widget, which should delete the NativeWidget.
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget.reset();
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.widget_deleted);
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.native_widget_deleted);
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(beng): write test for this ownership scenario and the NativeWidget
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //             being deleted out from under the Widget.
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Widget owns its NativeWidget, part 2: NativeWidget is a NativeWidget.
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetOwnershipTest, Ownership_WidgetOwnsViewsNativeWidget) {
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState state;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.native_widget =
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new OwnershipTestNativeWidgetPlatform(widget.get(), &state);
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now delete the Widget, which should delete the NativeWidget.
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget.reset();
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.widget_deleted);
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.native_widget_deleted);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(beng): write test for this ownership scenario and the NativeWidget
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //             being deleted out from under the Widget.
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Widget owns its NativeWidget, part 3: NativeWidget is a NativeWidget,
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destroy the parent view.
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetOwnershipTest,
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       Ownership_WidgetOwnsViewsNativeWidget_DestroyParentView) {
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState state;
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.native_widget =
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new OwnershipTestNativeWidgetPlatform(widget.get(), &state);
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.parent = toplevel->GetNativeView();
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now close the toplevel, which deletes the view hierarchy.
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This shouldn't delete the widget because it shouldn't be deleted
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from the native side.
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(state.widget_deleted);
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(state.native_widget_deleted);
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now delete it explicitly.
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget.reset();
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.widget_deleted);
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.native_widget_deleted);
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NativeWidget owns its Widget, part 1: NativeWidget is a platform-native
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// widget.
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetOwnershipTest, Ownership_PlatformNativeWidgetOwnsWidget) {
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState state;
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget = new OwnershipTestWidget(&state);
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.native_widget =
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new OwnershipTestNativeWidgetPlatform(widget, &state);
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now destroy the native widget.
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->CloseNow();
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.widget_deleted);
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.native_widget_deleted);
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NativeWidget owns its Widget, part 2: NativeWidget is a NativeWidget.
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetOwnershipTest, Ownership_ViewsNativeWidgetOwnsWidget) {
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState state;
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget = new OwnershipTestWidget(&state);
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.native_widget =
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new OwnershipTestNativeWidgetPlatform(widget, &state);
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.parent = toplevel->GetNativeView();
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now destroy the native widget. This is achieved by closing the toplevel.
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The NativeWidget won't be deleted until after a return to the message loop
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so we have to run pending messages before testing the destruction status.
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.widget_deleted);
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.native_widget_deleted);
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NativeWidget owns its Widget, part 3: NativeWidget is a platform-native
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// widget, destroyed out from under it by the OS.
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetOwnershipTest,
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       Ownership_PlatformNativeWidgetOwnsWidget_NativeDestroy) {
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState state;
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget = new OwnershipTestWidget(&state);
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.native_widget =
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new OwnershipTestNativeWidgetPlatform(widget, &state);
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now simulate a destroy of the platform native widget from the OS:
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_AURA)
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete widget->GetNativeView();
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN)
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DestroyWindow(widget->GetNativeView());
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.widget_deleted);
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.native_widget_deleted);
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NativeWidget owns its Widget, part 4: NativeWidget is a NativeWidget,
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destroyed by the view hierarchy that contains it.
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetOwnershipTest,
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       Ownership_ViewsNativeWidgetOwnsWidget_NativeDestroy) {
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState state;
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget = new OwnershipTestWidget(&state);
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.native_widget =
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new OwnershipTestNativeWidgetPlatform(widget, &state);
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.parent = toplevel->GetNativeView();
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Destroy the widget (achieved by closing the toplevel).
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The NativeWidget won't be deleted until after a return to the message loop
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so we have to run pending messages before testing the destruction status.
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.widget_deleted);
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.native_widget_deleted);
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NativeWidget owns its Widget, part 5: NativeWidget is a NativeWidget,
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// we close it directly.
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetOwnershipTest,
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       Ownership_ViewsNativeWidgetOwnsWidget_Close) {
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState state;
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget = new OwnershipTestWidget(&state);
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.native_widget =
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new OwnershipTestNativeWidgetPlatform(widget, &state);
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.parent = toplevel->GetNativeView();
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Destroy the widget.
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Close();
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The NativeWidget won't be deleted until after a return to the message loop
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so we have to run pending messages before testing the destruction status.
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.widget_deleted);
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.native_widget_deleted);
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Widget owns its NativeWidget and has a WidgetDelegateView as its contents.
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetOwnershipTest,
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       Ownership_WidgetOwnsNativeWidgetWithWithWidgetDelegateView) {
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OwnershipTestState state;
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WidgetDelegateView* delegate_view = new WidgetDelegateView;
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.native_widget =
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new OwnershipTestNativeWidgetPlatform(widget.get(), &state);
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.delegate = delegate_view;
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->Init(params);
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->SetContentsView(delegate_view);
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now delete the Widget. There should be no crash or use-after-free.
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.reset();
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(state.widget_deleted);
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(state.native_widget_deleted);
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
5943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Test to verify using various Widget methods doesn't crash when the underlying
5953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// NativeView is destroyed.
5963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)//
5973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class WidgetWithDestroyedNativeViewTest : public ViewsTestBase {
5983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public:
5993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  WidgetWithDestroyedNativeViewTest() {}
6003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual ~WidgetWithDestroyedNativeViewTest() {}
6013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void InvokeWidgetMethods(Widget* widget) {
6033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetNativeView();
6043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetNativeWindow();
6053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ui::Accelerator accelerator;
6063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetAccelerator(0, &accelerator);
6073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetTopLevelWidget();
6083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetWindowBoundsInScreen();
6093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetClientAreaBoundsInScreen();
6103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->SetBounds(gfx::Rect(0, 0, 100, 80));
6113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->SetSize(gfx::Size(10, 11));
6123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->SetBoundsConstrained(gfx::Rect(0, 0, 120, 140));
6133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->SetVisibilityChangedAnimationsEnabled(false);
6143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->StackAtTop();
6153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->IsClosed();
6163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->Close();
6173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->Show();
6183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->Hide();
6193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->Activate();
6203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->Deactivate();
6213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->IsActive();
6223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->DisableInactiveRendering();
6233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->SetAlwaysOnTop(true);
6244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    widget->IsAlwaysOnTop();
6253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->Maximize();
6263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->Minimize();
6273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->Restore();
6283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->IsMaximized();
6293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->IsFullscreen();
6303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->SetOpacity(0);
6313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->SetUseDragFrame(true);
6323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->FlashFrame(true);
6333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->IsVisible();
6343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetThemeProvider();
6353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetNativeTheme();
6363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetFocusManager();
6373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetInputMethod();
6383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->SchedulePaintInRect(gfx::Rect(0, 0, 1, 2));
6393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->IsMouseEventsEnabled();
6403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->SetNativeWindowProperty("xx", widget);
6413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetNativeWindowProperty("xx");
6423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetFocusTraversable();
6433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetLayer();
6443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->ReorderNativeViews();
6453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->SetCapture(widget->GetRootView());
6463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->ReleaseCapture();
6473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->HasCapture();
6483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetWorkAreaBoundsInScreen();
6493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // These three crash with NativeWidgetWin, so I'm assuming we don't need
6503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // them to work for the other NativeWidget impls.
6513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // widget->CenterWindow(gfx::Size(50, 60));
6523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // widget->GetRestoredBounds();
6533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // widget->ShowInactive();
6543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
6553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private:
6573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WidgetWithDestroyedNativeViewTest);
6583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
6593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_F(WidgetWithDestroyedNativeViewTest, Test) {
6613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {
6623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    Widget widget;
6633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
6643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
6653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget.Init(params);
6663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget.Show();
6673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget.native_widget_private()->CloseNow();
6693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    InvokeWidgetMethods(&widget);
6703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
6713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(USE_AURA) && !defined(OS_CHROMEOS)
6723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {
6733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    Widget widget;
6743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
6753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    params.native_widget = new DesktopNativeWidgetAura(&widget);
6763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
6773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget.Init(params);
6783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget.Show();
6793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget.native_widget_private()->CloseNow();
6813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    InvokeWidgetMethods(&widget);
6823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
6833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif
6843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
6853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Widget observer tests.
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class WidgetObserverTest : public WidgetTest, public WidgetObserver {
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WidgetObserverTest()
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : active_(NULL),
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        widget_closed_(NULL),
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        widget_activated_(NULL),
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        widget_shown_(NULL),
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        widget_hidden_(NULL),
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        widget_bounds_changed_(NULL) {
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~WidgetObserverTest() {}
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from WidgetObserver:
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWidgetDestroying(Widget* widget) OVERRIDE {
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (active_ == widget)
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      active_ = NULL;
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    widget_closed_ = widget;
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWidgetActivationChanged(Widget* widget,
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         bool active) OVERRIDE {
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (active) {
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (widget_activated_)
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        widget_activated_->Deactivate();
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget_activated_ = widget;
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      active_ = widget;
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (widget_activated_ == widget)
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        widget_activated_ = NULL;
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget_deactivated_ = widget;
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWidgetVisibilityChanged(Widget* widget,
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         bool visible) OVERRIDE {
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (visible)
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget_shown_ = widget;
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget_hidden_ = widget;
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWidgetBoundsChanged(Widget* widget,
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     const gfx::Rect& new_bounds) OVERRIDE {
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    widget_bounds_changed_ = widget;
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void reset() {
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    active_ = NULL;
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    widget_closed_ = NULL;
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    widget_activated_ = NULL;
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    widget_deactivated_ = NULL;
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    widget_shown_ = NULL;
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    widget_hidden_ = NULL;
7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    widget_bounds_changed_ = NULL;
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* NewWidget() {
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Widget* widget = CreateTopLevelNativeWidget();
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    widget->AddObserver(this);
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return widget;
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Widget* active() const { return active_; }
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Widget* widget_closed() const { return widget_closed_; }
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Widget* widget_activated() const { return widget_activated_; }
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Widget* widget_deactivated() const { return widget_deactivated_; }
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Widget* widget_shown() const { return widget_shown_; }
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Widget* widget_hidden() const { return widget_hidden_; }
7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Widget* widget_bounds_changed() const { return widget_bounds_changed_; }
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* active_;
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget_closed_;
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget_activated_;
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget_deactivated_;
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget_shown_;
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget_hidden_;
7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* widget_bounds_changed_;
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetObserverTest, DISABLED_ActivationChange) {
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel1 = NewWidget();
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel2 = NewWidget();
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel1->Show();
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel2->Show();
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reset();
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel1->Activate();
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(toplevel1, widget_activated());
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel2->Activate();
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(toplevel1, widget_deactivated());
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(toplevel2, widget_activated());
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(toplevel2, active());
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetObserverTest, DISABLED_VisibilityChange) {
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* child1 = NewWidget();
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* child2 = NewWidget();
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Show();
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child1->Show();
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child2->Show();
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reset();
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child1->Hide();
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child1, widget_hidden());
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child2->Hide();
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child2, widget_hidden());
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child1->Show();
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child1, widget_shown());
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child2->Show();
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child2, widget_shown());
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetObserverTest, DestroyBubble) {
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* anchor = CreateTopLevelPlatformWidget();
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  anchor->Show();
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BubbleDelegateView* bubble_delegate =
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new BubbleDelegateView(anchor->client_view(), BubbleBorder::NONE);
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* bubble_widget(BubbleDelegateView::CreateBubble(bubble_delegate));
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bubble_widget->Show();
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bubble_widget->CloseNow();
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  anchor->Hide();
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  anchor->CloseNow();
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetObserverTest, WidgetBoundsChanged) {
8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* child1 = NewWidget();
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* child2 = NewWidget();
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child1->OnNativeWidgetMove();
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(child1, widget_bounds_changed());
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->OnNativeWidgetMove();
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(child2, widget_bounds_changed());
8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child1->OnNativeWidgetSizeChanged(gfx::Size());
8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(child1, widget_bounds_changed());
8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->OnNativeWidgetSizeChanged(gfx::Size());
8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(child2, widget_bounds_changed());
8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(USE_AURA) && defined(OS_WIN)
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Aura needs shell to maximize/fullscreen window.
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NativeWidgetGtk doesn't implement GetRestoredBounds.
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, GetRestoredBounds) {
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(toplevel->GetWindowBoundsInScreen().ToString(),
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            toplevel->GetRestoredBounds().ToString());
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Show();
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Maximize();
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(toplevel->GetWindowBoundsInScreen().ToString(),
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            toplevel->GetRestoredBounds().ToString());
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(toplevel->GetRestoredBounds().width(), 0);
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(toplevel->GetRestoredBounds().height(), 0);
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Restore();
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(toplevel->GetWindowBoundsInScreen().ToString(),
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            toplevel->GetRestoredBounds().ToString());
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->SetFullscreen(true);
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(toplevel->GetWindowBoundsInScreen().ToString(),
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            toplevel->GetRestoredBounds().ToString());
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(toplevel->GetRestoredBounds().width(), 0);
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(toplevel->GetRestoredBounds().height(), 0);
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that window state is not changed after getting out of full screen.
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, ExitFullscreenRestoreState) {
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Show();
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should be a normal state window.
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ui::SHOW_STATE_NORMAL, GetWidgetShowState(toplevel));
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->SetFullscreen(true);
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (GetWidgetShowState(toplevel) != ui::SHOW_STATE_FULLSCREEN)
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunPendingMessages();
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->SetFullscreen(false);
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (GetWidgetShowState(toplevel) == ui::SHOW_STATE_FULLSCREEN)
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunPendingMessages();
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // And it should still be in normal state after getting out of full screen.
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ui::SHOW_STATE_NORMAL, GetWidgetShowState(toplevel));
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now, make it maximized.
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Maximize();
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (GetWidgetShowState(toplevel) != ui::SHOW_STATE_MAXIMIZED)
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunPendingMessages();
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->SetFullscreen(true);
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (GetWidgetShowState(toplevel) != ui::SHOW_STATE_FULLSCREEN)
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunPendingMessages();
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->SetFullscreen(false);
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (GetWidgetShowState(toplevel) == ui::SHOW_STATE_FULLSCREEN)
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunPendingMessages();
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // And it stays maximized after getting out of full screen.
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, GetWidgetShowState(toplevel));
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clean up.
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Close();
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_AURA)
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The key-event propagation from Widget happens differently on aura and
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// non-aura systems because of the difference in IME. So this test works only on
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// aura.
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, KeyboardInputEvent) {
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  View* container = toplevel->client_view();
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Textfield* textfield = new Textfield();
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  textfield->SetText(ASCIIToUTF16("some text"));
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  container->AddChildView(textfield);
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Show();
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  textfield->RequestFocus();
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The press gets handled. The release doesn't have an effect.
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::KeyEvent backspace_p(ui::ET_KEY_PRESSED, ui::VKEY_DELETE, 0, false);
9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnKeyEvent(&backspace_p);
9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(backspace_p.stopped_propagation());
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::KeyEvent backspace_r(ui::ET_KEY_RELEASED, ui::VKEY_DELETE, 0, false);
9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnKeyEvent(&backspace_r);
9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(backspace_r.handled());
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Close();
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Verifies bubbles result in a focus lost when shown.
950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// TODO(msw): this tests relies on focus, it needs to be in
951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// interactive_ui_tests.
952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WidgetTest, DISABLED_FocusChangesOnBubble) {
9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a widget, show and activate it and focus the contents view.
9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  View* contents_view = new View;
955d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  contents_view->SetFocusable(true);
9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget widget;
9572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams init_params =
9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.bounds = gfx::Rect(0, 0, 200, 200);
9602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_CHROMEOS)
9622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.native_widget = new DesktopNativeWidgetAura(&widget);
9632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
9642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Init(init_params);
9652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.SetContentsView(contents_view);
9662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Show();
9672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Activate();
9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents_view->RequestFocus();
9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(contents_view->HasFocus());
9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Show a bubble.
9722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BubbleDelegateView* bubble_delegate_view =
9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new BubbleDelegateView(contents_view, BubbleBorder::TOP_LEFT);
974d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  bubble_delegate_view->SetFocusable(true);
9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BubbleDelegateView::CreateBubble(bubble_delegate_view)->Show();
9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bubble_delegate_view->RequestFocus();
9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |contents_view_| should no longer have focus.
9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(contents_view->HasFocus());
9802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(bubble_delegate_view->HasFocus());
9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bubble_delegate_view->GetWidget()->CloseNow();
9832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Closing the bubble should result in focus going back to the contents view.
9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(contents_view->HasFocus());
9862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Desktop native widget Aura tests are for non Chrome OS platforms.
9892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_CHROMEOS)
990c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Test to ensure that after minimize, view width is set to zero.
991c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WidgetTest, TestViewWidthAfterMinimizingWidget) {
992c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a widget.
993c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Widget widget;
994c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Widget::InitParams init_params =
995c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CreateParams(Widget::InitParams::TYPE_WINDOW);
996c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  init_params.show_state = ui::SHOW_STATE_NORMAL;
997c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Rect initial_bounds(0, 0, 300, 400);
998c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  init_params.bounds = initial_bounds;
999c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
1000c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  init_params.native_widget = new DesktopNativeWidgetAura(&widget);
1001c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget.Init(init_params);
1002c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NonClientView* non_client_view = widget.non_client_view();
1003c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NonClientFrameView* frame_view = new MinimumSizeFrameView(&widget);
1004c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  non_client_view->SetFrameView(frame_view);
1005c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget.Show();
1006c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget.Minimize();
1007c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, frame_view->width());
1008c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1009c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
10102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This class validates whether paints are received for a visible Widget.
10112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// To achieve this it overrides the Show and Close methods on the Widget class
10122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// and sets state whether subsequent paints are expected.
10132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DesktopAuraTestValidPaintWidget : public views::Widget {
10142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
10152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DesktopAuraTestValidPaintWidget()
10162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : expect_paint_(true),
10172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      received_paint_while_hidden_(false) {
10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~DesktopAuraTestValidPaintWidget() {
10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void Show() OVERRIDE {
10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expect_paint_ = true;
10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    views::Widget::Show();
10262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void Close() OVERRIDE {
10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expect_paint_ = false;
10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    views::Widget::Close();
10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Hide() {
10342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expect_paint_ = false;
10352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    views::Widget::Hide();
10362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnNativeWidgetPaint(gfx::Canvas* canvas) OVERRIDE {
10392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(expect_paint_);
10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!expect_paint_)
10412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      received_paint_while_hidden_ = true;
10422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    views::Widget::OnNativeWidgetPaint(canvas);
10432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool received_paint_while_hidden() const {
10462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return received_paint_while_hidden_;
10472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
10502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool expect_paint_;
10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool received_paint_while_hidden_;
10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetTest, DesktopNativeWidgetAuraNoPaintAfterCloseTest) {
10552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  View* contents_view = new View;
1056d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  contents_view->SetFocusable(true);
10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DesktopAuraTestValidPaintWidget widget;
10582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams init_params =
10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.bounds = gfx::Rect(0, 0, 200, 200);
10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
10622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.native_widget = new DesktopNativeWidgetAura(&widget);
10632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Init(init_params);
10642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.SetContentsView(contents_view);
10652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Show();
10662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Activate();
10672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunPendingMessages();
10682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.SchedulePaintInRect(init_params.bounds);
10692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Close();
10702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunPendingMessages();
10712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(widget.received_paint_while_hidden());
10722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetTest, DesktopNativeWidgetAuraNoPaintAfterHideTest) {
10752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  View* contents_view = new View;
1076d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  contents_view->SetFocusable(true);
10772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DesktopAuraTestValidPaintWidget widget;
10782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams init_params =
10792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
10802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.bounds = gfx::Rect(0, 0, 200, 200);
10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
10822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.native_widget = new DesktopNativeWidgetAura(&widget);
10832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Init(init_params);
10842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.SetContentsView(contents_view);
10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Show();
10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Activate();
10872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunPendingMessages();
10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.SchedulePaintInRect(init_params.bounds);
10892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Hide();
10902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunPendingMessages();
10912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(widget.received_paint_while_hidden());
10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Close();
10932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1095424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// This class provides functionality to create fullscreen and top level popup
1096424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// windows. It additionally tests whether the destruction of these windows
1097424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// occurs correctly in desktop AURA without crashing.
10982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// It provides facilities to test the following cases:-
10992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1. Child window destroyed which should lead to the destruction of the
11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//    parent.
11012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 2. Parent window destroyed which should lead to the child being destroyed.
1102424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)class DesktopAuraTopLevelWindowTest
11032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public views::TestViewsDelegate,
11042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      public aura::WindowObserver {
11052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1106424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DesktopAuraTopLevelWindowTest()
1107424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      : top_level_widget_(NULL),
1108424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        owned_window_(NULL),
1109424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        owner_destroyed_(false),
1110424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        owned_window_destroyed_(false) {}
11112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1112424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual ~DesktopAuraTopLevelWindowTest() {
1113424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    EXPECT_TRUE(owner_destroyed_);
1114424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    EXPECT_TRUE(owned_window_destroyed_);
1115424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    top_level_widget_ = NULL;
1116424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    owned_window_ = NULL;
11172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // views::TestViewsDelegate overrides.
11202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnBeforeWidgetInit(
11212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Widget::InitParams* params,
11222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      internal::NativeWidgetDelegate* delegate) OVERRIDE {
11232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!params->native_widget)
11242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      params->native_widget = new views::DesktopNativeWidgetAura(delegate);
11252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1127424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void CreateTopLevelWindow(const gfx::Rect& bounds, bool fullscreen) {
11282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Widget::InitParams init_params;
11292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    init_params.type = Widget::InitParams::TYPE_WINDOW;
11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    init_params.bounds = bounds;
11312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
11322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    init_params.layer_type = ui::LAYER_NOT_DRAWN;
1133424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    init_params.accept_events = fullscreen;
11342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    widget_.Init(init_params);
11362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1137424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    owned_window_ = new aura::Window(&child_window_delegate_);
1138424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    owned_window_->SetType(aura::client::WINDOW_TYPE_NORMAL);
1139424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    owned_window_->SetName("TestTopLevelWindow");
1140424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (fullscreen) {
1141424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      owned_window_->SetProperty(aura::client::kShowStateKey,
1142424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                 ui::SHOW_STATE_FULLSCREEN);
1143424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    } else {
1144424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      owned_window_->SetType(aura::client::WINDOW_TYPE_MENU);
1145424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    }
1146424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    owned_window_->Init(ui::LAYER_TEXTURED);
11471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    aura::client::ParentWindowWithContext(
11481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        owned_window_,
11491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        widget_.GetNativeView()->GetRootWindow(),
11501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        gfx::Rect(0, 0, 1900, 1600));
1151424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    owned_window_->Show();
1152424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    owned_window_->AddObserver(this);
11532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1154424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ASSERT_TRUE(owned_window_->parent() != NULL);
1155424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    owned_window_->parent()->AddObserver(this);
11562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1157424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    top_level_widget_ =
1158424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        views::Widget::GetWidgetForNativeView(owned_window_->parent());
1159424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ASSERT_TRUE(top_level_widget_ != NULL);
11602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1162424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void DestroyOwnedWindow() {
1163424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ASSERT_TRUE(owned_window_ != NULL);
1164424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    delete owned_window_;
11652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1167424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void DestroyOwnerWindow() {
1168424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ASSERT_TRUE(top_level_widget_ != NULL);
1169424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    top_level_widget_->CloseNow();
11702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
11732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    window->RemoveObserver(this);
1174424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (window == owned_window_) {
1175424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      owned_window_destroyed_ = true;
1176424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    } else if (window == top_level_widget_->GetNativeView()) {
1177424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      owner_destroyed_ = true;
11782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
11792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ADD_FAILURE() << "Unexpected window destroyed callback: " << window;
11802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
11812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
118381843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)  aura::Window* owned_window() {
118481843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)    return owned_window_;
118581843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)  }
118681843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)
118781843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)  views::Widget* top_level_widget() {
118881843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)    return top_level_widget_;
118981843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)  }
119081843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)
11912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
11922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  views::Widget widget_;
1193424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  views::Widget* top_level_widget_;
1194424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  aura::Window* owned_window_;
1195424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool owner_destroyed_;
1196424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool owned_window_destroyed_;
11972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::test::TestWindowDelegate child_window_delegate_;
11982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1199424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DesktopAuraTopLevelWindowTest);
12002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
12012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1202424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(WidgetTest, DesktopAuraFullscreenWindowDestroyedBeforeOwnerTest) {
12032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ViewsDelegate::views_delegate = NULL;
1204424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DesktopAuraTopLevelWindowTest fullscreen_window;
1205424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(fullscreen_window.CreateTopLevelWindow(
1206424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      gfx::Rect(0, 0, 200, 200), true));
12072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunPendingMessages();
1209424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(fullscreen_window.DestroyOwnedWindow());
12102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunPendingMessages();
12112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1213424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(WidgetTest, DesktopAuraFullscreenWindowOwnerDestroyed) {
12142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ViewsDelegate::views_delegate = NULL;
12152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1216424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DesktopAuraTopLevelWindowTest fullscreen_window;
1217424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(fullscreen_window.CreateTopLevelWindow(
1218424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      gfx::Rect(0, 0, 200, 200), true));
1219424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1220424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  RunPendingMessages();
1221424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(fullscreen_window.DestroyOwnerWindow());
1222424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  RunPendingMessages();
1223424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
1224424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1225424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(WidgetTest, DesktopAuraTopLevelOwnedPopupTest) {
1226424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ViewsDelegate::views_delegate = NULL;
1227424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DesktopAuraTopLevelWindowTest popup_window;
1228424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(popup_window.CreateTopLevelWindow(
1229424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      gfx::Rect(0, 0, 200, 200), false));
12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunPendingMessages();
1232424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(popup_window.DestroyOwnedWindow());
12332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunPendingMessages();
12342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
123681843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)#if defined(OS_WIN)
123781843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)// TODO(ananta)
123881843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)// Fix this test to work on Linux Aura. Need to implement the
123981843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)// views::DesktopRootWindowHostX11::SetSize function
124081843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)// This test validates that when a top level owned popup Aura window is
124181843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)// resized, the widget is resized as well.
124281843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)TEST_F(WidgetTest, DesktopAuraTopLevelOwnedPopupResizeTest) {
124381843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)  ViewsDelegate::views_delegate = NULL;
124481843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)  DesktopAuraTopLevelWindowTest popup_window;
124581843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(popup_window.CreateTopLevelWindow(
124681843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)      gfx::Rect(0, 0, 200, 200), false));
124781843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)
124881843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)  gfx::Rect new_size(0, 0, 400, 400);
124981843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)  popup_window.owned_window()->SetBounds(new_size);
125081843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)
125181843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)  EXPECT_EQ(popup_window.top_level_widget()->GetNativeView()->bounds().size(),
125281843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)            new_size.size());
125381843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)  RunPendingMessages();
125481843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(popup_window.DestroyOwnedWindow());
125581843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)  RunPendingMessages();
125681843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)}
125781843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)#endif
125881843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)
1259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Test to ensure that the aura Window's visiblity state is set to visible if
1260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the underlying widget is hidden and then shown.
1261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WidgetTest, TestWindowVisibilityAfterHide) {
1262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a widget.
1263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Widget widget;
1264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Widget::InitParams init_params =
1265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CreateParams(Widget::InitParams::TYPE_WINDOW);
1266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  init_params.show_state = ui::SHOW_STATE_NORMAL;
1267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Rect initial_bounds(0, 0, 300, 400);
1268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  init_params.bounds = initial_bounds;
1269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
1270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  init_params.native_widget = new DesktopNativeWidgetAura(&widget);
1271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget.Init(init_params);
1272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NonClientView* non_client_view = widget.non_client_view();
1273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NonClientFrameView* frame_view = new MinimumSizeFrameView(&widget);
1274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  non_client_view->SetFrameView(frame_view);
1275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget.Hide();
1277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(widget.GetNativeView()->IsVisible());
1278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget.Show();
1279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(widget.GetNativeView()->IsVisible());
1280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1282424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// The following code verifies we can correctly destroy a Widget from a mouse
1283424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// enter/exit. We could test move/drag/enter/exit but in general we don't run
1284424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// nested message loops from such events, nor has the code ever really dealt
1285424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// with this situation.
1286424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1287424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Class that closes the widget (which ends up deleting it immediately) when the
1288424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// appropriate event is received.
1289424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)class CloseWidgetView : public View {
1290424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) public:
1291424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  explicit CloseWidgetView(ui::EventType event_type)
1292424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      : event_type_(event_type) {
1293424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
1294424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1295424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // View overrides:
1296424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE {
1297424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (!CloseWidget(event))
1298424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      View::OnMousePressed(event);
1299424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return true;
1300424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
1301424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE {
1302424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (!CloseWidget(event))
1303424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      View::OnMouseDragged(event);
1304424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return true;
1305424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
1306424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE {
1307424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (!CloseWidget(event))
1308424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      View::OnMouseReleased(event);
1309424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
1310424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual void OnMouseMoved(const ui::MouseEvent& event) OVERRIDE {
1311424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (!CloseWidget(event))
1312424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      View::OnMouseMoved(event);
1313424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
1314424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE {
1315424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (!CloseWidget(event))
1316424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      View::OnMouseEntered(event);
1317424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
1318424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1319424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) private:
1320424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool CloseWidget(const ui::LocatedEvent& event) {
1321424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (event.type() == event_type_) {
1322424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      // Go through NativeWidgetPrivate to simulate what happens if the OS
1323424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      // deletes the NativeWindow out from under us.
1324424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      GetWidget()->native_widget_private()->CloseNow();
1325424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      return true;
1326424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    }
1327424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return false;
1328424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
1329424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1330424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  const ui::EventType event_type_;
1331424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1332424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CloseWidgetView);
1333424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
1334424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1335424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Generates two moves (first generates enter, second real move), a press, drag
1336424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// and release stopping at |last_event_type|.
1337424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void GenerateMouseEvents(Widget* widget, ui::EventType last_event_type) {
1338424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  const gfx::Rect screen_bounds(widget->GetWindowBoundsInScreen());
1339424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ui::MouseEvent move_event(ui::ET_MOUSE_MOVED, screen_bounds.CenterPoint(),
1340424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                            screen_bounds.CenterPoint(), 0);
1341424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  aura::RootWindowHostDelegate* rwhd =
13421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      widget->GetNativeWindow()->GetDispatcher()->AsRootWindowHostDelegate();
1343424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  rwhd->OnHostMouseEvent(&move_event);
1344424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (last_event_type == ui::ET_MOUSE_ENTERED)
1345424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return;
1346424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  rwhd->OnHostMouseEvent(&move_event);
1347424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (last_event_type == ui::ET_MOUSE_MOVED)
1348424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return;
1349424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1350424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ui::MouseEvent press_event(ui::ET_MOUSE_PRESSED, screen_bounds.CenterPoint(),
1351424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                             screen_bounds.CenterPoint(), 0);
1352424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  rwhd->OnHostMouseEvent(&press_event);
1353424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (last_event_type == ui::ET_MOUSE_PRESSED)
1354424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return;
1355424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1356424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  gfx::Point end_point(screen_bounds.CenterPoint());
1357424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  end_point.Offset(1, 1);
1358424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ui::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED, end_point, end_point, 0);
1359424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  rwhd->OnHostMouseEvent(&drag_event);
1360424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (last_event_type == ui::ET_MOUSE_DRAGGED)
1361424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return;
1362424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1363424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ui::MouseEvent release_event(ui::ET_MOUSE_RELEASED, end_point, end_point, 0);
1364424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  rwhd->OnHostMouseEvent(&release_event);
1365424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
1366424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1367424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Creates a widget and invokes GenerateMouseEvents() with |last_event_type|.
1368424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void RunCloseWidgetDuringDispatchTest(WidgetTest* test,
1369424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                      ui::EventType last_event_type) {
1370424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // |widget| is deleted by CloseWidgetView.
1371424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  Widget* widget = new Widget;
1372424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  Widget::InitParams params =
1373424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      test->CreateParams(Widget::InitParams::TYPE_POPUP);
1374424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  params.native_widget = new DesktopNativeWidgetAura(widget);
1375424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  params.bounds = gfx::Rect(0, 0, 50, 100);
1376424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  widget->Init(params);
1377424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  widget->SetContentsView(new CloseWidgetView(last_event_type));
1378424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  widget->Show();
1379424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  GenerateMouseEvents(widget, last_event_type);
1380424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
1381424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1382424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Verifies deleting the widget from a mouse pressed event doesn't crash.
1383424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(WidgetTest, CloseWidgetDuringMousePress) {
1384424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  RunCloseWidgetDuringDispatchTest(this, ui::ET_MOUSE_PRESSED);
1385424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
1386424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1387424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Verifies deleting the widget from a mouse released event doesn't crash.
1388424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(WidgetTest, CloseWidgetDuringMouseReleased) {
1389424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  RunCloseWidgetDuringDispatchTest(this, ui::ET_MOUSE_RELEASED);
1390424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
1391424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
13922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // !defined(OS_CHROMEOS)
13932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Tests that wheel events generated from scroll events are targetted to the
13952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// views under the cursor when the focused view does not processed them.
13962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetTest, WheelEventsFromScrollEventTarget) {
13972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EventCountView* cursor_view = new EventCountView;
13982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cursor_view->SetBounds(60, 0, 50, 40);
13992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* widget = CreateTopLevelPlatformWidget();
14012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->GetRootView()->AddChildView(cursor_view);
14022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Generate a scroll event on the cursor view.
14042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::ScrollEvent scroll(ui::ET_SCROLL,
14052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         gfx::Point(65, 5),
14062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         ui::EventTimeForNow(),
14072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         0,
14082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         0, 20,
14092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         0, 20,
14102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         2);
14112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->OnScrollEvent(&scroll);
14122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, cursor_view->GetEventCount(ui::ET_SCROLL));
14142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, cursor_view->GetEventCount(ui::ET_MOUSEWHEEL));
14152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cursor_view->ResetCounts();
14172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::ScrollEvent scroll2(ui::ET_SCROLL,
14192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          gfx::Point(5, 5),
14202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          ui::EventTimeForNow(),
14212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          0,
14222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          0, 20,
14232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          0, 20,
14242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          2);
14252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->OnScrollEvent(&scroll2);
14262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, cursor_view->GetEventCount(ui::ET_SCROLL));
14282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, cursor_view->GetEventCount(ui::ET_MOUSEWHEEL));
14292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->CloseNow();
14312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(USE_AURA)
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests that if a scroll-begin gesture is not handled, then subsequent scroll
14362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// events are not dispatched to any view.
14372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetTest, GestureScrollEventDispatching) {
14382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EventCountView* noscroll_view = new EventCountView;
14392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EventCountView* scroll_view = new ScrollableEventCountView;
14402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  noscroll_view->SetBounds(0, 0, 50, 40);
14422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scroll_view->SetBounds(60, 0, 40, 40);
14432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* widget = CreateTopLevelPlatformWidget();
14452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->GetRootView()->AddChildView(noscroll_view);
14462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->GetRootView()->AddChildView(scroll_view);
14472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
14492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::GestureEvent begin(ui::ET_GESTURE_SCROLL_BEGIN,
14502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        5, 5, 0, base::TimeDelta(),
14512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 0, 0),
14522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        1);
14532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    widget->OnGestureEvent(&begin);
14542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::GestureEvent update(ui::ET_GESTURE_SCROLL_UPDATE,
14552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        25, 15, 0, base::TimeDelta(),
14562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE, 20, 10),
14572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        1);
14582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    widget->OnGestureEvent(&update);
14592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::GestureEvent end(ui::ET_GESTURE_SCROLL_END,
14602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        25, 15, 0, base::TimeDelta(),
14612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END, 0, 0),
14622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        1);
14632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    widget->OnGestureEvent(&end);
14642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, noscroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_BEGIN));
14662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, noscroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_UPDATE));
14672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, noscroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_END));
14682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
14712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::GestureEvent begin(ui::ET_GESTURE_SCROLL_BEGIN,
14722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        65, 5, 0, base::TimeDelta(),
14732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 0, 0),
14742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        1);
14752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    widget->OnGestureEvent(&begin);
14762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::GestureEvent update(ui::ET_GESTURE_SCROLL_UPDATE,
14772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        85, 15, 0, base::TimeDelta(),
14782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE, 20, 10),
14792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        1);
14802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    widget->OnGestureEvent(&update);
14812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::GestureEvent end(ui::ET_GESTURE_SCROLL_END,
14822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        85, 15, 0, base::TimeDelta(),
14832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END, 0, 0),
14842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        1);
14852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    widget->OnGestureEvent(&end);
14862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, scroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_BEGIN));
14882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, scroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_UPDATE));
14892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, scroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_END));
14902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->CloseNow();
14932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests that event-handlers installed on the RootView get triggered correctly.
14962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetTest, EventHandlersOnRootView) {
14972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* widget = CreateTopLevelNativeWidget();
14982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  View* root_view = widget->GetRootView();
14992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EventCountView* view = new EventCountView;
15012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  view->SetBounds(0, 0, 20, 20);
15022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_view->AddChildView(view);
15032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EventCountHandler h1;
15052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_view->AddPreTargetHandler(&h1);
15062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EventCountHandler h2;
15082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_view->AddPostTargetHandler(&h2);
15092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->SetBounds(gfx::Rect(0, 0, 100, 100));
15112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->Show();
15122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::TouchEvent pressed(ui::ET_TOUCH_PRESSED,
15142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         gfx::Point(10, 10),
15152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         0, 0,
15162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         ui::EventTimeForNow(),
15172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         1.0, 0.0, 1.0, 0.0);
15182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->OnTouchEvent(&pressed);
15192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h1.GetEventCount(ui::ET_TOUCH_PRESSED));
15202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, view->GetEventCount(ui::ET_TOUCH_PRESSED));
15212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h2.GetEventCount(ui::ET_TOUCH_PRESSED));
15222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::GestureEvent begin(ui::ET_GESTURE_BEGIN,
15242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      5, 5, 0, ui::EventTimeForNow(),
15252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui::GestureEventDetails(ui::ET_GESTURE_BEGIN, 0, 0), 1);
15262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::GestureEvent end(ui::ET_GESTURE_END,
15272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      5, 5, 0, ui::EventTimeForNow(),
15282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui::GestureEventDetails(ui::ET_GESTURE_END, 0, 0), 1);
15292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->OnGestureEvent(&begin);
15302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h1.GetEventCount(ui::ET_GESTURE_BEGIN));
15312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, view->GetEventCount(ui::ET_GESTURE_BEGIN));
15322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h2.GetEventCount(ui::ET_GESTURE_BEGIN));
15332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::TouchEvent released(ui::ET_TOUCH_RELEASED,
15352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          gfx::Point(10, 10),
15362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          0, 0,
15372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          ui::EventTimeForNow(),
15382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          1.0, 0.0, 1.0, 0.0);
15392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->OnTouchEvent(&released);
15402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h1.GetEventCount(ui::ET_TOUCH_RELEASED));
15412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, view->GetEventCount(ui::ET_TOUCH_RELEASED));
15422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h2.GetEventCount(ui::ET_TOUCH_RELEASED));
15432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->OnGestureEvent(&end);
15452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h1.GetEventCount(ui::ET_GESTURE_END));
15462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, view->GetEventCount(ui::ET_GESTURE_END));
15472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h2.GetEventCount(ui::ET_GESTURE_END));
15482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::ScrollEvent scroll(ui::ET_SCROLL,
15502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         gfx::Point(5, 5),
15512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         ui::EventTimeForNow(),
15522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         0,
15532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         0, 20,
15542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         0, 20,
15552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         2);
15562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->OnScrollEvent(&scroll);
15572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h1.GetEventCount(ui::ET_SCROLL));
15582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, view->GetEventCount(ui::ET_SCROLL));
15592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h2.GetEventCount(ui::ET_SCROLL));
15602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->CloseNow();
15622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WidgetTest, SynthesizeMouseMoveEvent) {
1565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Widget* widget = CreateTopLevelNativeWidget();
1566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  View* root_view = widget->GetRootView();
1567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EventCountView* v1 = new EventCountView();
1569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  v1->SetBounds(0, 0, 10, 10);
1570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  root_view->AddChildView(v1);
1571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EventCountView* v2 = new EventCountView();
1572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  v2->SetBounds(0, 10, 10, 10);
1573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  root_view->AddChildView(v2);
1574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Point cursor_location(5, 5);
1576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ui::MouseEvent move(ui::ET_MOUSE_MOVED, cursor_location, cursor_location,
1577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                      ui::EF_NONE);
1578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget->OnMouseEvent(&move);
1579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, v1->GetEventCount(ui::ET_MOUSE_ENTERED));
1581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, v2->GetEventCount(ui::ET_MOUSE_ENTERED));
1582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  delete v1;
1584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  v2->SetBounds(0, 0, 10, 10);
1585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, v2->GetEventCount(ui::ET_MOUSE_ENTERED));
1586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget->SynthesizeMouseMoveEvent();
1588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, v2->GetEventCount(ui::ET_MOUSE_ENTERED));
1589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
15912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Used by SingleWindowClosing to count number of times WindowClosing() has
15922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// been invoked.
15932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ClosingDelegate : public WidgetDelegate {
15942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
15952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ClosingDelegate() : count_(0), widget_(NULL) {}
15962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int count() const { return count_; }
15982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void set_widget(views::Widget* widget) { widget_ = widget; }
16002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // WidgetDelegate overrides:
16022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual Widget* GetWidget() OVERRIDE { return widget_; }
16032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual const Widget* GetWidget() const OVERRIDE { return widget_; }
16042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void WindowClosing() OVERRIDE {
16052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    count_++;
16062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
16072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
16092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int count_;
16102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  views::Widget* widget_;
16112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ClosingDelegate);
16132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
16142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Verifies WindowClosing() is invoked correctly on the delegate when a Widget
16162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// is closed.
16172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetTest, SingleWindowClosing) {
16182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ClosingDelegate> delegate(new ClosingDelegate());
16192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* widget = new Widget();  // Destroyed by CloseNow() below.
16202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams init_params =
16212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateParams(Widget::InitParams::TYPE_WINDOW);
16222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.bounds = gfx::Rect(0, 0, 200, 200);
16232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.delegate = delegate.get();
16242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_AURA) && !defined(OS_CHROMEOS)
16252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.native_widget = new DesktopNativeWidgetAura(widget);
16262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
16272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->Init(init_params);
16282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, delegate->count());
16292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->CloseNow();
16302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, delegate->count());
16312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
16322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1633a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class WidgetWindowTitleTest : public WidgetTest {
1634a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) protected:
1635a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void RunTest(bool desktop_native_widget) {
1636a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    Widget* widget = new Widget();  // Destroyed by CloseNow() below.
1637a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    Widget::InitParams init_params =
1638a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        CreateParams(Widget::InitParams::TYPE_WINDOW);
1639a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    widget->Init(init_params);
1640a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1641a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if defined(USE_AURA) && !defined(OS_CHROMEOS)
1642a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (desktop_native_widget)
1643a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      init_params.native_widget = new DesktopNativeWidgetAura(widget);
1644a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#else
1645a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DCHECK(!desktop_native_widget)
1646a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        << "DesktopNativeWidget does not exist on non-Aura or on ChromeOS.";
1647a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif
1648a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1649a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    internal::NativeWidgetPrivate* native_widget =
1650a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        widget->native_widget_private();
1651a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1652a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    string16 empty;
1653a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    string16 s1(UTF8ToUTF16("Title1"));
1654a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    string16 s2(UTF8ToUTF16("Title2"));
1655a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    string16 s3(UTF8ToUTF16("TitleLong"));
1656a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1657a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // The widget starts with no title, setting empty should not change
1658a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // anything.
1659a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_FALSE(native_widget->SetWindowTitle(empty));
1660a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Setting the title to something non-empty should cause a change.
1661a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_TRUE(native_widget->SetWindowTitle(s1));
1662a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Setting the title to something else with the same length should cause a
1663a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // change.
1664a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_TRUE(native_widget->SetWindowTitle(s2));
1665a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Setting the title to something else with a different length should cause
1666a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // a change.
1667a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_TRUE(native_widget->SetWindowTitle(s3));
1668a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Setting the title to the same thing twice should not cause a change.
1669a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_FALSE(native_widget->SetWindowTitle(s3));
1670a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1671a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    widget->CloseNow();
1672a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
1673a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
1674a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1675a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(WidgetWindowTitleTest, SetWindowTitleChanged_NativeWidget) {
1676a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Use the default NativeWidget.
1677a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool desktop_native_widget = false;
1678a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RunTest(desktop_native_widget);
1679a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
1680a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1681a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// DesktopNativeWidget does not exist on non-Aura or on ChromeOS.
1682a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if defined(USE_AURA) && !defined(OS_CHROMEOS)
1683a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(WidgetWindowTitleTest, SetWindowTitleChanged_DesktopNativeWidget) {
1684a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Override to use a DesktopNativeWidget.
1685a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool desktop_native_widget = true;
1686a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RunTest(desktop_native_widget);
1687a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
1688a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif  // USE_AURA && !OS_CHROMEOS
1689a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
16902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Used by SetTopLevelCorrectly to track calls to OnBeforeWidgetInit().
16912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class VerifyTopLevelDelegate : public TestViewsDelegate {
16922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
16932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyTopLevelDelegate()
16942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : on_before_init_called_(false),
16952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        is_top_level_(false) {
16962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
16972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool on_before_init_called() const { return on_before_init_called_; }
16992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_top_level() const { return is_top_level_; }
17002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnBeforeWidgetInit(
17022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Widget::InitParams* params,
17032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      internal::NativeWidgetDelegate* delegate) OVERRIDE {
17042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    on_before_init_called_ = true;
17052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    is_top_level_ = params->top_level;
17062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
17072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
17092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool on_before_init_called_;
17102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_top_level_;
17112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(VerifyTopLevelDelegate);
17132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
17142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Verifies |top_level| is correctly passed to
17162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ViewsDelegate::OnBeforeWidgetInit().
17172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetTest, SetTopLevelCorrectly) {
17182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  set_views_delegate(NULL);
17192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyTopLevelDelegate* delegate = new VerifyTopLevelDelegate;
17202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  set_views_delegate(delegate);  // ViewsTestBase takes ownership.
17212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Widget> widget(new Widget);
17222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params =
17232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateParams(views::Widget::InitParams::TYPE_POPUP);
17242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
17252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->Init(params);
17262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(delegate->on_before_init_called());
17272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(delegate->is_top_level());
17282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
17292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1730c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// A scumbag View that deletes its owning widget OnMousePressed.
1731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class WidgetDeleterView : public View {
1732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
1733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  WidgetDeleterView() : View() {}
1734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Overridden from View.
1736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE {
1737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    delete GetWidget();
1738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
1739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
1742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WidgetDeleterView);
1743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
1744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WidgetTest, TestWidgetDeletedInOnMousePressed) {
1746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Widget* widget = new Widget;
1747c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Widget::InitParams params =
1748c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CreateParams(views::Widget::InitParams::TYPE_POPUP);
1749c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
1750c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget->Init(params);
1751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1752c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget->SetContentsView(new WidgetDeleterView);
1753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget->SetSize(gfx::Size(100, 100));
1755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget->Show();
1756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Point click_location(45, 15);
1758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ui::MouseEvent press(ui::ET_MOUSE_PRESSED, click_location, click_location,
1759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ui::EF_LEFT_MOUSE_BUTTON);
1760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget->OnMouseEvent(&press);
1761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Yay we did not crash!
1763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1765558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// See description of RunGetNativeThemeFromDestructor() for details.
1766558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochclass GetNativeThemeFromDestructorView : public WidgetDelegateView {
1767558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch public:
1768558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  GetNativeThemeFromDestructorView() {}
1769558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  virtual ~GetNativeThemeFromDestructorView() {
1770558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    VerifyNativeTheme();
1771558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
1772558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1773558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  virtual View* GetContentsView() OVERRIDE {
1774558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return this;
1775558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
1776558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1777558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch private:
1778558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  void VerifyNativeTheme() {
1779558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    ASSERT_TRUE(GetNativeTheme() != NULL);
1780558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
1781558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1782558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(GetNativeThemeFromDestructorView);
1783558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch};
1784558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1785558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// Verifies GetNativeTheme() from the destructor of a WidgetDelegateView doesn't
1786558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// crash. |is_first_run| is true if this is the first call. A return value of
1787558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// true indicates this should be run again with a value of false.
1788558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// First run uses DesktopNativeWidgetAura (if possible). Second run doesn't.
1789558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochbool RunGetNativeThemeFromDestructor(const Widget::InitParams& in_params,
1790558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                     bool is_first_run) {
1791558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  bool needs_second_run = false;
1792558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Destroyed by CloseNow() below.
1793558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  Widget* widget = new Widget;
1794558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  Widget::InitParams params(in_params);
1795558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Deletes itself when the Widget is destroyed.
1796558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  params.delegate = new GetNativeThemeFromDestructorView;
1797558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#if defined(USE_AURA) && !defined(OS_CHROMEOS)
1798558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (is_first_run) {
1799558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    params.native_widget = new DesktopNativeWidgetAura(widget);
1800558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    needs_second_run = true;
1801558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
1802558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#endif
1803558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  widget->Init(params);
1804558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  widget->CloseNow();
1805558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return needs_second_run;
1806558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
1807558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1808558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// See description of RunGetNativeThemeFromDestructor() for details.
1809558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_F(WidgetTest, GetNativeThemeFromDestructor) {
1810558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
1811558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (RunGetNativeThemeFromDestructor(params, true))
1812558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    RunGetNativeThemeFromDestructor(params, false);
1813558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
1814558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1815a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Used by HideCloseDestroy. Allows setting a boolean when the widget is
1816a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// destroyed.
1817a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)class CloseDestroysWidget : public Widget {
1818a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) public:
1819a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  explicit CloseDestroysWidget(bool* destroyed)
1820a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      : destroyed_(destroyed) {
1821a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
1822a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1823a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  virtual ~CloseDestroysWidget() {
1824a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (destroyed_) {
1825a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      *destroyed_ = true;
1826a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      base::MessageLoop::current()->QuitNow();
1827a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
1828a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
1829a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1830a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  void Detach() { destroyed_ = NULL; }
1831a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1832a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) private:
1833a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // If non-null set to true from destructor.
1834a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  bool* destroyed_;
1835a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1836a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CloseDestroysWidget);
1837a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)};
1838a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1839a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Verifies Close() results in destroying.
1840a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(WidgetTest, CloseDestroys) {
1841a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  bool destroyed = false;
1842a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CloseDestroysWidget* widget = new CloseDestroysWidget(&destroyed);
1843a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Widget::InitParams params =
1844a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      CreateParams(views::Widget::InitParams::TYPE_MENU);
1845a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  params.opacity = Widget::InitParams::OPAQUE_WINDOW;
1846a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#if defined(USE_AURA) && !defined(OS_CHROMEOS)
1847a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  params.native_widget = new DesktopNativeWidgetAura(widget);
1848a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#endif
1849a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->Init(params);
1850a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->Show();
1851a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->Hide();
1852a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->Close();
1853a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Run the message loop as Close() asynchronously deletes.
1854a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  RunPendingMessages();
1855a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_TRUE(destroyed);
1856a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Close() should destroy the widget. If not we'll cleanup to avoid leaks.
1857a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!destroyed) {
1858a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    widget->Detach();
1859a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    widget->CloseNow();
1860a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
1861a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
1862a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1863a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// A view that consumes mouse-pressed event and gesture-tap-down events.
1864a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)class RootViewTestView : public View {
1865a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) public:
1866a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  RootViewTestView(): View() {}
1867a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1868a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) private:
1869a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE {
1870a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return true;
1871a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
1872a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1873a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
1874a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (event->type() == ui::ET_GESTURE_TAP_DOWN)
1875a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      event->SetHandled();
1876a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
1877a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)};
1878a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1879a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Checks if RootView::*_handler_ fields are unset when widget is hidden.
18803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Fails on chromium.webkit Windows bot, see crbug.com/264872.
18813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(OS_WIN)
18823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#define MAYBE_DisableTestRootViewHandlersWhenHidden\
18833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    DISABLED_TestRootViewHandlersWhenHidden
18843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#else
18853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#define MAYBE_DisableTestRootViewHandlersWhenHidden\
18863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    TestRootViewHandlersWhenHidden
18873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif
18883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_F(WidgetTest, MAYBE_DisableTestRootViewHandlersWhenHidden) {
1889a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Widget* widget = CreateTopLevelNativeWidget();
1890a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->SetBounds(gfx::Rect(0, 0, 300, 300));
1891a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  View* view = new RootViewTestView();
1892a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  view->SetBounds(0, 0, 300, 300);
1893a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  internal::RootView* root_view =
1894a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      static_cast<internal::RootView*>(widget->GetRootView());
1895a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  root_view->AddChildView(view);
1896a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1897a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Check RootView::mouse_pressed_handler_.
1898a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->Show();
1899a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(NULL, GetMousePressedHandler(root_view));
1900a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  gfx::Point click_location(45, 15);
1901a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ui::MouseEvent press(ui::ET_MOUSE_PRESSED, click_location, click_location,
1902a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      ui::EF_LEFT_MOUSE_BUTTON);
1903a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->OnMouseEvent(&press);
1904a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(view, GetMousePressedHandler(root_view));
1905a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->Hide();
1906a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(NULL, GetMousePressedHandler(root_view));
1907a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1908a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Check RootView::mouse_move_handler_.
1909a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->Show();
1910a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(NULL, GetMouseMoveHandler(root_view));
1911a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  gfx::Point move_location(45, 15);
1912a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ui::MouseEvent move(ui::ET_MOUSE_MOVED, move_location, move_location, 0);
1913a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->OnMouseEvent(&move);
1914a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(view, GetMouseMoveHandler(root_view));
1915a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->Hide();
1916a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(NULL, GetMouseMoveHandler(root_view));
1917a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1918a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Check RootView::gesture_handler_.
1919a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->Show();
1920a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(NULL, GetGestureHandler(root_view));
1921a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ui::GestureEvent tap_down(
1922a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      ui::ET_GESTURE_TAP_DOWN,
1923a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      15,
1924a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      15,
1925a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      0,
1926a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      base::TimeDelta(),
1927a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      ui::GestureEventDetails(ui::ET_GESTURE_TAP_DOWN, 0, 0),
1928a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      1);
1929a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->OnGestureEvent(&tap_down);
1930a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(view, GetGestureHandler(root_view));
1931a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->Hide();
1932a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(NULL, GetGestureHandler(root_view));
1933a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1934a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->Close();
1935a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
1936a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
19373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Test the result of Widget::GetAllChildWidgets().
19383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_F(WidgetTest, GetAllChildWidgets) {
19393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Create the following widget hierarchy:
19403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  //
19413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // toplevel
19423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // +-- w1
19433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  //     +-- w11
19443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // +-- w2
19453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  //     +-- w21
19463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  //     +-- w22
19473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
19483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Widget* w1 = CreateChildPlatformWidget(toplevel->GetNativeView());
19493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Widget* w11 = CreateChildPlatformWidget(w1->GetNativeView());
19503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Widget* w2 = CreateChildPlatformWidget(toplevel->GetNativeView());
19513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Widget* w21 = CreateChildPlatformWidget(w2->GetNativeView());
19523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Widget* w22 = CreateChildPlatformWidget(w2->GetNativeView());
19533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::set<Widget*> expected;
19553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  expected.insert(toplevel);
19563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  expected.insert(w1);
19573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  expected.insert(w11);
19583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  expected.insert(w2);
19593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  expected.insert(w21);
19603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  expected.insert(w22);
19613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::set<Widget*> widgets;
19633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Widget::GetAllChildWidgets(toplevel->GetNativeView(), &widgets);
19643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(expected.size(), widgets.size());
19663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(std::equal(expected.begin(), expected.end(), widgets.begin()));
19673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
19683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Used by DestroyChildWidgetsInOrder. On destruction adds the supplied name to
19704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// a vector.
19714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class DestroyedTrackingView : public View {
19724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
19734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DestroyedTrackingView(const std::string& name,
19744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                        std::vector<std::string>* add_to)
19754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      : name_(name),
19764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        add_to_(add_to) {
19774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
19784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
19794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual ~DestroyedTrackingView() {
19804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    add_to_->push_back(name_);
19814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
19824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
19834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
19844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const std::string name_;
19854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<std::string>* add_to_;
19864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
19874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DestroyedTrackingView);
19884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
19894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
19904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class WidgetChildDestructionTest : public WidgetTest {
19914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
19924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  WidgetChildDestructionTest() {}
19934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
19944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Creates a top level and a child, destroys the child and verifies the views
19954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // of the child are destroyed before the views of the parent.
19964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void RunDestroyChildWidgetsTest(bool top_level_has_desktop_native_widget_aura,
19974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                  bool child_has_desktop_native_widget_aura) {
19984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // When a View is destroyed its name is added here.
19994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    std::vector<std::string> destroyed;
20004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
20014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    Widget* top_level = new Widget;
20024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    Widget::InitParams params =
20034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        CreateParams(views::Widget::InitParams::TYPE_WINDOW);
20044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(USE_AURA) && !defined(OS_CHROMEOS)
20054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (top_level_has_desktop_native_widget_aura)
20064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      params.native_widget = new DesktopNativeWidgetAura(top_level);
20074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
20084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    top_level->Init(params);
20094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    top_level->GetRootView()->AddChildView(
20104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        new DestroyedTrackingView("parent", &destroyed));
20114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    top_level->Show();
20124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
20134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    Widget* child = new Widget;
20144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    Widget::InitParams child_params =
20154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        CreateParams(views::Widget::InitParams::TYPE_POPUP);
20164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    child_params.parent = top_level->GetNativeView();
20174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(USE_AURA) && !defined(OS_CHROMEOS)
20184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (child_has_desktop_native_widget_aura)
20194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      child_params.native_widget = new DesktopNativeWidgetAura(child);
20204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
20214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    child->Init(child_params);
20224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    child->GetRootView()->AddChildView(
20234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        new DestroyedTrackingView("child", &destroyed));
20244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    child->Show();
20254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
20264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Should trigger destruction of the child too.
20274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    top_level->native_widget_private()->CloseNow();
20284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
20294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Child should be destroyed first.
20304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ASSERT_EQ(2u, destroyed.size());
20314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_EQ("child", destroyed[0]);
20324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_EQ("parent", destroyed[1]);
20334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
20344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
20354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
20364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WidgetChildDestructionTest);
20374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
20384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
20394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(USE_AURA) && !defined(OS_CHROMEOS)
20404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// See description of RunDestroyChildWidgetsTest(). Parent uses
20414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// DesktopNativeWidgetAura.
20424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(WidgetChildDestructionTest,
20434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)       DestroyChildWidgetsInOrderWithDesktopNativeWidget) {
20444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RunDestroyChildWidgetsTest(true, false);
20454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
20464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
20474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// See description of RunDestroyChildWidgetsTest(). Both parent and child use
20484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// DesktopNativeWidgetAura.
20494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(WidgetChildDestructionTest,
20504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)       DestroyChildWidgetsInOrderWithDesktopNativeWidgetForBoth) {
20514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RunDestroyChildWidgetsTest(true, true);
20524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
20534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
20544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
20554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// See description of RunDestroyChildWidgetsTest().
20564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(WidgetChildDestructionTest, DestroyChildWidgetsInOrder) {
20574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RunDestroyChildWidgetsTest(false, false);
20584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
20594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
20604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(USE_AURA) && !defined(OS_CHROMEOS)
20614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Provides functionality to create a window modal dialog.
20624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class ModalDialogDelegate : public DialogDelegateView {
20634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
20644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ModalDialogDelegate() {}
20654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual ~ModalDialogDelegate() {}
20664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
20674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // WidgetDelegate overrides.
20684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual ui::ModalType GetModalType() const OVERRIDE {
20694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return ui::MODAL_TYPE_WINDOW;
20704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
20714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
20724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
20734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ModalDialogDelegate);
20744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
20754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
20764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// This test verifies that whether mouse events when a modal dialog is
20774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// displayed are eaten or recieved by the dialog.
20784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(WidgetTest, WindowMouseModalityTest) {
20794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Create a top level widget.
20804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Widget top_level_widget;
20814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Widget::InitParams init_params =
20824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      CreateParams(Widget::InitParams::TYPE_WINDOW);
20834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  init_params.show_state = ui::SHOW_STATE_NORMAL;
20844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  gfx::Rect initial_bounds(0, 0, 500, 500);
20854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  init_params.bounds = initial_bounds;
20864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
20874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  init_params.native_widget = new DesktopNativeWidgetAura(&top_level_widget);
20884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  top_level_widget.Init(init_params);
20894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  top_level_widget.Show();
20904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(top_level_widget.IsVisible());
20914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
20924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Create a view and validate that a mouse moves makes it to the view.
20934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EventCountView* widget_view = new EventCountView();
20944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  widget_view->SetBounds(0, 0, 10, 10);
20954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  top_level_widget.GetRootView()->AddChildView(widget_view);
20964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
20974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  gfx::Point cursor_location_main(5, 5);
20984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ui::MouseEvent move_main(ui::ET_MOUSE_MOVED,
20994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           cursor_location_main,
21004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           cursor_location_main,
21014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           ui::EF_NONE);
21021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  top_level_widget.GetNativeView()->GetDispatcher()->
21034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      AsRootWindowHostDelegate()->OnHostMouseEvent(&move_main);
21044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
21054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(1, widget_view->GetEventCount(ui::ET_MOUSE_ENTERED));
21064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  widget_view->ResetCounts();
21074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
21084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Create a modal dialog and validate that a mouse down message makes it to
21094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // the main view within the dialog.
21104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
21114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // This instance will be destroyed when the dialog is destroyed.
21124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ModalDialogDelegate* dialog_delegate = new ModalDialogDelegate;
21134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
21144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Widget* modal_dialog_widget = views::DialogDelegate::CreateDialogWidget(
21154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      dialog_delegate, NULL, top_level_widget.GetNativeWindow());
21164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  modal_dialog_widget->SetBounds(gfx::Rect(100, 100, 200, 200));
21174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EventCountView* dialog_widget_view = new EventCountView();
21184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  dialog_widget_view->SetBounds(0, 0, 50, 50);
21194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  modal_dialog_widget->GetRootView()->AddChildView(dialog_widget_view);
21204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  modal_dialog_widget->Show();
21214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(modal_dialog_widget->IsVisible());
21224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
21234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  gfx::Point cursor_location_dialog(100, 100);
21244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ui::MouseEvent mouse_down_dialog(ui::ET_MOUSE_PRESSED,
21254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                   cursor_location_dialog,
21264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                   cursor_location_dialog,
21274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                   ui::EF_NONE);
21281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  top_level_widget.GetNativeView()->GetDispatcher()->
21294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      AsRootWindowHostDelegate()->OnHostMouseEvent(&mouse_down_dialog);
21304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(1, dialog_widget_view->GetEventCount(ui::ET_MOUSE_PRESSED));
21314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
21324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Send a mouse move message to the main window. It should not be received by
21334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // the main window as the modal dialog is still active.
21344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  gfx::Point cursor_location_main2(6, 6);
21354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ui::MouseEvent mouse_down_main(ui::ET_MOUSE_MOVED,
21364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 cursor_location_main2,
21374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 cursor_location_main2,
21384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 ui::EF_NONE);
21391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  top_level_widget.GetNativeView()->GetDispatcher()->
21404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      AsRootWindowHostDelegate()->OnHostMouseEvent(&mouse_down_main);
21414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(0, widget_view->GetEventCount(ui::ET_MOUSE_MOVED));
21424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
21434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  modal_dialog_widget->CloseNow();
21444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  top_level_widget.CloseNow();
21454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
21464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if defined(USE_AURA)
2148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Verifies nativeview visbility matches that of Widget visibility when
2149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// SetFullscreen is invoked.
2150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(WidgetTest, FullscreenStatePropagated) {
2151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Widget::InitParams init_params =
2152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      CreateParams(Widget::InitParams::TYPE_WINDOW);
2153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  init_params.show_state = ui::SHOW_STATE_NORMAL;
2154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  init_params.bounds = gfx::Rect(0, 0, 500, 500);
2155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
2156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2157a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  {
2158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    Widget top_level_widget;
2159a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    top_level_widget.Init(init_params);
2160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    top_level_widget.SetFullscreen(true);
2161a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(top_level_widget.IsVisible(),
2162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              top_level_widget.GetNativeView()->IsVisible());
2163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    top_level_widget.CloseNow();
2164a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
2165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2166a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if !defined(OS_CHROMEOS)
2167a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  {
2168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    Widget top_level_widget;
2169a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    init_params.native_widget = new DesktopNativeWidgetAura(&top_level_widget);
2170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    top_level_widget.Init(init_params);
2171a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    top_level_widget.SetFullscreen(true);
2172a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(top_level_widget.IsVisible(),
2173a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              top_level_widget.GetNativeView()->IsVisible());
2174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    top_level_widget.CloseNow();
2175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
2176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif
2177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
2178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif
2179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
21804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_WIN)
21814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
21824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Provides functionality to test widget activation via an activation flag
21834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// which can be set by an accessor.
21844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class ModalWindowTestWidgetDelegate : public WidgetDelegate {
21854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
21864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ModalWindowTestWidgetDelegate()
21874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      : widget_(NULL),
21884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        can_activate_(true) {}
21894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
21904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual ~ModalWindowTestWidgetDelegate() {}
21914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
21924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Overridden from WidgetDelegate:
21934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void DeleteDelegate() OVERRIDE {
21944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    delete this;
21954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
21964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual Widget* GetWidget() OVERRIDE {
21974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return widget_;
21984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
21994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual const Widget* GetWidget() const OVERRIDE {
22004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return widget_;
22014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
22024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual bool CanActivate() const OVERRIDE {
22034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return can_activate_;
22044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
22054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual bool ShouldAdvanceFocusToTopLevelWidget() const OVERRIDE {
22064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return true;
22074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
22084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
22094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void set_can_activate(bool can_activate) {
22104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    can_activate_ = can_activate;
22114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
22124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
22134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void set_widget(Widget* widget) {
22144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    widget_ = widget;
22154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
22164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
22174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
22184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Widget* widget_;
22194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool can_activate_;
22204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
22214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ModalWindowTestWidgetDelegate);
22224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
22234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
22244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Tests whether we can activate the top level widget when a modal dialog is
22254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// active.
22264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(WidgetTest, WindowModalityActivationTest) {
22274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Destroyed when the top level widget created below is destroyed.
22284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ModalWindowTestWidgetDelegate* widget_delegate =
22294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      new ModalWindowTestWidgetDelegate;
22304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Create a top level widget.
22314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Widget top_level_widget;
22324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Widget::InitParams init_params =
22334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      CreateParams(Widget::InitParams::TYPE_WINDOW);
22344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  init_params.show_state = ui::SHOW_STATE_NORMAL;
22354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  gfx::Rect initial_bounds(0, 0, 500, 500);
22364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  init_params.bounds = initial_bounds;
22374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
22384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  init_params.native_widget = new DesktopNativeWidgetAura(&top_level_widget);
22394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  init_params.delegate = widget_delegate;
22404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  top_level_widget.Init(init_params);
22414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  widget_delegate->set_widget(&top_level_widget);
22424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  top_level_widget.Show();
22434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(top_level_widget.IsVisible());
22444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
22454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  HWND win32_window = views::HWNDForWidget(&top_level_widget);
22464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(::IsWindow(win32_window));
22474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
22484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // This instance will be destroyed when the dialog is destroyed.
22494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ModalDialogDelegate* dialog_delegate = new ModalDialogDelegate;
22504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
22514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // We should be able to activate the window even if the WidgetDelegate
22524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // says no, when a modal dialog is active.
22534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  widget_delegate->set_can_activate(false);
22544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
22554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Widget* modal_dialog_widget = views::DialogDelegate::CreateDialogWidget(
22564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      dialog_delegate, NULL, top_level_widget.GetNativeWindow());
22574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  modal_dialog_widget->SetBounds(gfx::Rect(100, 100, 200, 200));
22584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  modal_dialog_widget->Show();
22594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(modal_dialog_widget->IsVisible());
22604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
22614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  LRESULT activate_result = ::SendMessage(
22624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      win32_window,
22634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      WM_MOUSEACTIVATE,
22644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      reinterpret_cast<WPARAM>(win32_window),
22654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      MAKELPARAM(WM_LBUTTONDOWN, HTCLIENT));
22664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(activate_result, MA_ACTIVATE);
22674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
22684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  modal_dialog_widget->CloseNow();
22694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  top_level_widget.CloseNow();
22704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
22714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
22724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
22734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
22747da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)namespace {
22757da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)
22767da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)class FullscreenAwareFrame : public views::NonClientFrameView {
22777da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles) public:
22787da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  explicit FullscreenAwareFrame(views::Widget* widget)
22797da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)      : widget_(widget), fullscreen_layout_called_(false) {}
22807da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  virtual ~FullscreenAwareFrame() {}
22817da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)
22827da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  // views::NonClientFrameView overrides:
22837da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  virtual gfx::Rect GetBoundsForClientView() const OVERRIDE {
22847da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)    return gfx::Rect();
22857da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  }
22867da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  virtual gfx::Rect GetWindowBoundsForClientBounds(
22877da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)      const gfx::Rect& client_bounds) const OVERRIDE {
22887da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)    return gfx::Rect();
22897da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  }
22907da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  virtual int NonClientHitTest(const gfx::Point& point) OVERRIDE {
22917da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)    return HTNOWHERE;
22927da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  }
22937da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  virtual void GetWindowMask(const gfx::Size& size,
22947da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)                             gfx::Path* window_mask) OVERRIDE {}
22957da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  virtual void ResetWindowControls() OVERRIDE {}
22967da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  virtual void UpdateWindowIcon() OVERRIDE {}
22977da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  virtual void UpdateWindowTitle() OVERRIDE {}
22987da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)
22997da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  // views::View overrides:
23007da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  virtual void Layout() OVERRIDE {
23017da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)    if (widget_->IsFullscreen())
23027da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)      fullscreen_layout_called_ = true;
23037da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  }
23047da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)
23057da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  bool fullscreen_layout_called() const { return fullscreen_layout_called_; }
23067da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)
23077da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles) private:
23087da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  views::Widget* widget_;
23097da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  bool fullscreen_layout_called_;
23107da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)
23117da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FullscreenAwareFrame);
23127da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)};
23137da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)
23147da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)}  // namespace
23157da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)
23167da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)// Tests that frame Layout is called when a widget goes fullscreen without
23177da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)// changing its size or title.
23187da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)TEST_F(WidgetTest, FullscreenFrameLayout) {
23197da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  Widget* widget = CreateTopLevelPlatformWidget();
23207da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  FullscreenAwareFrame* frame = new FullscreenAwareFrame(widget);
23217da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  widget->non_client_view()->SetFrameView(frame);  // Owns |frame|.
23227da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)
23237da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  widget->Maximize();
23247da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  RunPendingMessages();
23257da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)
23267da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  EXPECT_FALSE(frame->fullscreen_layout_called());
23277da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  widget->SetFullscreen(true);
23287da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  widget->Show();
23297da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  RunPendingMessages();
23307da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  EXPECT_TRUE(frame->fullscreen_layout_called());
23317da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)
23327da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)  widget->CloseNow();
23337da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)}
23347da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles)
2335e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch#if !defined(OS_CHROMEOS)
2336e6402284a6517cc047655bc051a7f1269e182040Ben Murdochnamespace {
2337e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch
2338e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch// Trivial WidgetObserverTest that invokes Widget::IsActive() from
2339e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch// OnWindowDestroying.
2340e6402284a6517cc047655bc051a7f1269e182040Ben Murdochclass IsActiveFromDestroyObserver : public WidgetObserver {
2341e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch public:
2342e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch  IsActiveFromDestroyObserver() {}
2343e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch  virtual ~IsActiveFromDestroyObserver() {}
2344e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch  virtual void OnWidgetDestroying(Widget* widget) OVERRIDE {
2345e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch    widget->IsActive();
2346e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch  }
2347e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch
2348e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch private:
2349e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(IsActiveFromDestroyObserver);
2350e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch};
2351e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch
2352e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch}  // namespace
2353e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch
2354e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch// Verifies Widget::IsActive() invoked from
2355e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch// WidgetObserver::OnWidgetDestroying() in a child widget doesn't crash.
2356e6402284a6517cc047655bc051a7f1269e182040Ben MurdochTEST_F(WidgetTest, IsActiveFromDestroy) {
2357e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch  // Create two widgets, one a child of the other.
2358e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch  IsActiveFromDestroyObserver observer;
2359e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch  Widget parent_widget;
2360e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch  Widget::InitParams parent_params =
2361e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch      CreateParams(Widget::InitParams::TYPE_POPUP);
2362e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch  parent_params.native_widget = new DesktopNativeWidgetAura(&parent_widget);
2363e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch  parent_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
2364e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch  parent_widget.Init(parent_params);
2365e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch  parent_widget.Show();
2366e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch
2367e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch  Widget child_widget;
2368e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch  Widget::InitParams child_params =
2369e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch      CreateParams(Widget::InitParams::TYPE_POPUP);
2370e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch  child_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
2371e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch  child_params.context = parent_widget.GetNativeView();
2372e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch  child_widget.Init(child_params);
2373e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch  child_widget.AddObserver(&observer);
2374e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch  child_widget.Show();
2375e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch
2376e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch  parent_widget.CloseNow();
2377e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch}
2378e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch#endif
2379e6402284a6517cc047655bc051a7f1269e182040Ben Murdoch
2380a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}  // namespace test
23815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace views
2382