widget_unittest.cc revision 424c4d7b64af9d0d8fd9624f381f469654d5e3d2
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"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/events/event_utils.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/native_widget_types.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/point.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/bubble/bubble_delegate.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/textfield/textfield.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/test/test_views_delegate.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/test/views_test_base.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/views_delegate.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/native_widget_delegate.h"
24a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "ui/views/widget/root_view.h"
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/views/window/native_frame_view.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_AURA)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/client/aura_constants.h"
297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "ui/aura/env.h"
307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/aura/root_window.h"
317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/aura/test/test_cursor_client.h"
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/test/test_window_delegate.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/native_widget_aura.h"
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_CHROMEOS)
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/native_widget_win.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views {
43a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace test {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A generic typedef to pick up relevant NativeWidget implementations.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_AURA)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef NativeWidgetAura NativeWidgetPlatform;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef NativeWidgetWin NativeWidgetPlatform;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A widget that assumes mouse capture always works. It won't on Aura in
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// testing, so we mock it.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_AURA)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NativeWidgetCapture : public NativeWidgetPlatform {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit NativeWidgetCapture(internal::NativeWidgetDelegate* delegate)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : NativeWidgetPlatform(delegate),
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mouse_capture_(false) {}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~NativeWidgetCapture() {}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetCapture() OVERRIDE {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mouse_capture_ = true;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ReleaseCapture() OVERRIDE {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (mouse_capture_)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate()->OnMouseCaptureLost();
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mouse_capture_ = false;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool HasCapture() const OVERRIDE {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return mouse_capture_;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool mouse_capture_;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NativeWidgetCapture);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A typedef that inserts our mock-capture NativeWidget implementation for
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// relevant platforms.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_AURA)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef NativeWidgetCapture NativeWidgetPlatformForTest;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef NativeWidgetWin NativeWidgetPlatformForTest;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A view that always processes all mouse events.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MouseView : public View {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MouseView()
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : View(),
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        entered_(0),
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        exited_(0),
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pressed_(0) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~MouseView() {}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pressed_++;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entered_++;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exited_++;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return the number of OnMouseEntered calls and reset the counter.
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int EnteredCalls() {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i = entered_;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entered_ = 0;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return i;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return the number of OnMouseExited calls and reset the counter.
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ExitedCalls() {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i = exited_;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exited_ = 0;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return i;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pressed() const { return pressed_; }
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int entered_;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int exited_;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pressed_;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MouseView);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A view that keeps track of the events it receives, but consumes no events.
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class EventCountView : public View {
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EventCountView() {}
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~EventCountView() {}
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int GetEventCount(ui::EventType type) {
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return event_count_[type];
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ResetCounts() {
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event_count_.clear();
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from ui::EventHandler:
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE {
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RecordEvent(*event);
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RecordEvent(*event);
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE {
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RecordEvent(*event);
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE {
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RecordEvent(*event);
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RecordEvent(*event);
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void RecordEvent(const ui::Event& event) {
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ++event_count_[event.type()];
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::map<ui::EventType, int> event_count_;
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(EventCountView);
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A view that keeps track of the events it receives, and consumes all scroll
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// gesture events.
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ScrollableEventCountView : public EventCountView {
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScrollableEventCountView() {}
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~ScrollableEventCountView() {}
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from ui::EventHandler:
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EventCountView::OnGestureEvent(event);
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    switch (event->type()) {
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case ui::ET_GESTURE_SCROLL_BEGIN:
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case ui::ET_GESTURE_SCROLL_UPDATE:
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case ui::ET_GESTURE_SCROLL_END:
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case ui::ET_SCROLL_FLING_START:
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        event->SetHandled();
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      default:
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ScrollableEventCountView);
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A view that does a capture on gesture-begin events.
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GestureCaptureView : public View {
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GestureCaptureView() {}
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~GestureCaptureView() {}
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from View:
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event->type() == ui::ET_GESTURE_BEGIN) {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetWidget()->SetCapture(this);
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      event->StopPropagation();
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(GestureCaptureView);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// A view that implements GetMinimumSize.
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MinimumSizeFrameView : public NativeFrameView {
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  explicit MinimumSizeFrameView(Widget* frame): NativeFrameView(frame) {}
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~MinimumSizeFrameView() {}
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Overridden from View:
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual gfx::Size GetMinimumSize() OVERRIDE {
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return gfx::Size(300, 400);
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MinimumSizeFrameView);
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// An event handler that simply keeps a count of the different types of events
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// it receives.
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class EventCountHandler : public ui::EventHandler {
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EventCountHandler() {}
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~EventCountHandler() {}
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int GetEventCount(ui::EventType type) {
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return event_count_[type];
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ResetCounts() {
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event_count_.clear();
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from ui::EventHandler:
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnEvent(ui::Event* event) OVERRIDE {
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RecordEvent(*event);
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::EventHandler::OnEvent(event);
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void RecordEvent(const ui::Event& event) {
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ++event_count_[event.type()];
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::map<ui::EventType, int> event_count_;
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(EventCountHandler);
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// A View that shows a different widget, sets capture on that widget, and
2727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// initiates a nested message-loop when it receives a mouse-press event.
2737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochclass NestedLoopCaptureView : public View {
2747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch public:
2757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  explicit NestedLoopCaptureView(Widget* widget) : widget_(widget) {}
2767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual ~NestedLoopCaptureView() {}
2777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch private:
2797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Overridden from View:
2807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE {
2817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // Start a nested loop.
2827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    widget_->Show();
2837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    widget_->SetCapture(widget_->GetContentsView());
2847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    EXPECT_TRUE(widget_->HasCapture());
2857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
2877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    base::MessageLoop::ScopedNestableTaskAllower allow(loop);
2887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    base::RunLoop run_loop;
2907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#if defined(USE_AURA)
2917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    run_loop.set_dispatcher(aura::Env::GetInstance()->GetDispatcher());
2927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif
2937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    run_loop.Run();
2947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return true;
2957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  Widget* widget_;
2987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(NestedLoopCaptureView);
3007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch};
3017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// A View that closes the Widget and exits the current message-loop when it
3037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// receives a mouse-release event.
3047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochclass ExitLoopOnRelease : public View {
3057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch public:
3067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ExitLoopOnRelease() {}
3077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual ~ExitLoopOnRelease() {}
3087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch private:
3107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Overridden from View:
3117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE {
3127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    GetWidget()->Close();
3137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    base::MessageLoop::current()->QuitNow();
3147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
3157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(ExitLoopOnRelease);
3177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch};
3187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class WidgetTest : public ViewsTestBase {
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WidgetTest() {}
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~WidgetTest() {}
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NativeWidget* CreatePlatformNativeWidget(
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      internal::NativeWidgetDelegate* delegate) {
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return new NativeWidgetPlatformForTest(delegate);
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* CreateTopLevelPlatformWidget() {
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Widget* toplevel = new Widget;
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Widget::InitParams toplevel_params =
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CreateParams(Widget::InitParams::TYPE_WINDOW);
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    toplevel_params.native_widget = CreatePlatformNativeWidget(toplevel);
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    toplevel->Init(toplevel_params);
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return toplevel;
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* CreateTopLevelFramelessPlatformWidget() {
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Widget* toplevel = new Widget;
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Widget::InitParams toplevel_params =
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    toplevel_params.native_widget = CreatePlatformNativeWidget(toplevel);
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    toplevel->Init(toplevel_params);
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return toplevel;
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* CreateChildPlatformWidget(gfx::NativeView parent_native_view) {
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Widget* child = new Widget;
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Widget::InitParams child_params =
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CreateParams(Widget::InitParams::TYPE_CONTROL);
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child_params.native_widget = CreatePlatformNativeWidget(child);
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child_params.parent = parent_native_view;
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child->Init(child_params);
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child->SetContentsView(new View);
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return child;
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) && !defined(USE_AURA)
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // On Windows, it is possible for us to have a child window that is
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TYPE_POPUP.
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* CreateChildPopupPlatformWidget(gfx::NativeView parent_native_view) {
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Widget* child = new Widget;
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Widget::InitParams child_params =
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CreateParams(Widget::InitParams::TYPE_POPUP);
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child_params.child = true;
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child_params.native_widget = CreatePlatformNativeWidget(child);
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child_params.parent = parent_native_view;
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child->Init(child_params);
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child->SetContentsView(new View);
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return child;
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* CreateTopLevelNativeWidget() {
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Widget* toplevel = new Widget;
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    toplevel->Init(params);
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return toplevel;
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* CreateChildNativeWidgetWithParent(Widget* parent) {
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Widget* child = new Widget;
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_CONTROL);
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.parent = parent->GetNativeView();
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child->Init(params);
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child->SetContentsView(new View);
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return child;
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* CreateChildNativeWidget() {
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return CreateChildNativeWidgetWithParent(NULL);
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
393a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
394a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  View* GetMousePressedHandler(internal::RootView* root_view) {
395a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return root_view->mouse_pressed_handler_;
396a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
397a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
398a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  View* GetMouseMoveHandler(internal::RootView* root_view) {
399a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return root_view->mouse_move_handler_;
400a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
401a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
402a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  View* GetGestureHandler(internal::RootView* root_view) {
403a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return root_view->gesture_handler_;
404a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WidgetHasMouseCapture(const Widget* widget) {
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<const internal::NativeWidgetPrivate*>(widget->
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      native_widget())->HasCapture();
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::WindowShowState GetWidgetShowState(const Widget* widget) {
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use IsMaximized/IsMinimized/IsFullScreen instead of GetWindowPlacement
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // because the former is implemented on all platforms but the latter is not.
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return widget->IsFullscreen() ? ui::SHOW_STATE_FULLSCREEN :
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget->IsMaximized() ? ui::SHOW_STATE_MAXIMIZED :
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget->IsMinimized() ? ui::SHOW_STATE_MINIMIZED :
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              ui::SHOW_STATE_NORMAL;
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, WidgetInitParams) {
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(views_delegate().UseTransparentWindows());
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Widgets are not transparent by default.
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget::InitParams init1;
426eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(Widget::InitParams::INFER_OPACITY, init1.opacity);
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Non-window widgets are not transparent either.
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget::InitParams init2(Widget::InitParams::TYPE_MENU);
430eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(Widget::InitParams::INFER_OPACITY, init2.opacity);
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A ViewsDelegate can set windows transparent by default.
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views_delegate().SetUseTransparentWindows(true);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget::InitParams init3;
435eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(Widget::InitParams::TRANSLUCENT_WINDOW, init3.opacity);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Non-window widgets stay opaque.
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget::InitParams init4(Widget::InitParams::TYPE_MENU);
439eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(Widget::InitParams::INFER_OPACITY, init4.opacity);
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Widget::GetTopLevelWidget tests.
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, GetTopLevelWidget_Native) {
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a hierarchy of native widgets.
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::NativeView parent = toplevel->GetNativeView();
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* child = CreateChildPlatformWidget(parent);
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(toplevel, toplevel->GetTopLevelWidget());
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(toplevel, child->GetTopLevelWidget());
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |child| should be automatically destroyed with |toplevel|.
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests some grab/ungrab events.
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, DISABLED_GrabUngrab) {
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* child1 = CreateChildNativeWidgetWithParent(toplevel);
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* child2 = CreateChildNativeWidgetWithParent(toplevel);
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->SetBounds(gfx::Rect(0, 0, 500, 500));
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child1->SetBounds(gfx::Rect(10, 10, 300, 300));
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  View* view = new MouseView();
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view->SetBounds(0, 0, 300, 300);
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child1->GetRootView()->AddChildView(view);
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child2->SetBounds(gfx::Rect(200, 10, 200, 200));
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view = new MouseView();
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view->SetBounds(0, 0, 200, 200);
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child2->GetRootView()->AddChildView(view);
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Show();
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Click on child1
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point p1(45, 45);
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, p1, p1,
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         ui::EF_LEFT_MOUSE_BUTTON);
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnMouseEvent(&pressed);
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(WidgetHasMouseCapture(toplevel));
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(WidgetHasMouseCapture(child1));
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(WidgetHasMouseCapture(child2));
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::MouseEvent released(ui::ET_MOUSE_RELEASED, p1, p1,
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          ui::EF_LEFT_MOUSE_BUTTON);
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnMouseEvent(&released);
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(WidgetHasMouseCapture(toplevel));
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(WidgetHasMouseCapture(child1));
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(WidgetHasMouseCapture(child2));
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Click on child2
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point p2(315, 45);
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::MouseEvent pressed2(ui::ET_MOUSE_PRESSED, p2, p2,
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          ui::EF_LEFT_MOUSE_BUTTON);
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnMouseEvent(&pressed2);
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(pressed2.handled());
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(WidgetHasMouseCapture(toplevel));
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(WidgetHasMouseCapture(child2));
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(WidgetHasMouseCapture(child1));
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::MouseEvent released2(ui::ET_MOUSE_RELEASED, p2, p2,
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           ui::EF_LEFT_MOUSE_BUTTON);
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnMouseEvent(&released2);
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(WidgetHasMouseCapture(toplevel));
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(WidgetHasMouseCapture(child1));
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(WidgetHasMouseCapture(child2));
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests mouse move outside of the window into the "resize controller" and back
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// will still generate an OnMouseEntered and OnMouseExited event..
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, CheckResizeControllerEvents) {
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->SetBounds(gfx::Rect(0, 0, 100, 100));
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MouseView* view = new MouseView();
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view->SetBounds(90, 90, 10, 10);
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->GetRootView()->AddChildView(view);
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Show();
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move to an outside position.
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point p1(200, 200);
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::MouseEvent moved_out(ui::ET_MOUSE_MOVED, p1, p1, ui::EF_NONE);
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnMouseEvent(&moved_out);
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, view->EnteredCalls());
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, view->ExitedCalls());
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move onto the active view.
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point p2(95, 95);
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::MouseEvent moved_over(ui::ET_MOUSE_MOVED, p2, p2, ui::EF_NONE);
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnMouseEvent(&moved_over);
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, view->EnteredCalls());
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, view->ExitedCalls());
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move onto the outer resizing border.
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point p3(102, 95);
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::MouseEvent moved_resizer(ui::ET_MOUSE_MOVED, p3, p3, ui::EF_NONE);
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnMouseEvent(&moved_resizer);
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, view->EnteredCalls());
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, view->ExitedCalls());
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move onto the view again.
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnMouseEvent(&moved_over);
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, view->EnteredCalls());
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, view->ExitedCalls());
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test if a focus manager and an inputmethod work without CHECK failure
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// when window activation changes.
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, ChangeActivation) {
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* top1 = CreateTopLevelPlatformWidget();
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CreateInputMethod before activated
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top1->GetInputMethod();
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top1->Show();
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* top2 = CreateTopLevelPlatformWidget();
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top2->Show();
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top1->Activate();
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create InputMethod after deactivated.
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top2->GetInputMethod();
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top2->Activate();
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top1->Activate();
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top1->CloseNow();
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top2->CloseNow();
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests visibility of child widgets.
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, Visibility) {
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::NativeView parent = toplevel->GetNativeView();
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* child = CreateChildPlatformWidget(parent);
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(toplevel->IsVisible());
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(child->IsVisible());
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child->Show();
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(toplevel->IsVisible());
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(child->IsVisible());
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Show();
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(toplevel->IsVisible());
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(child->IsVisible());
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |child| should be automatically destroyed with |toplevel|.
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) && !defined(USE_AURA)
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// On Windows, it is possible to have child window that are TYPE_POPUP.  Unlike
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// regular child windows, these should be created as hidden and must be shown
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// explicitly.
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, Visibility_ChildPopup) {
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* child_popup = CreateChildPopupPlatformWidget(
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      toplevel->GetNativeView());
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(toplevel->IsVisible());
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(child_popup->IsVisible());
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Show();
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(toplevel->IsVisible());
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(child_popup->IsVisible());
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child_popup->Show();
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(child_popup->IsVisible());
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |child_popup| should be automatically destroyed with |toplevel|.
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Widget ownership tests.
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests various permutations of Widget ownership specified in the
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// InitParams::Ownership param.
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A WidgetTest that supplies a toplevel widget for NativeWidget to parent to.
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WidgetOwnershipTest : public WidgetTest {
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WidgetOwnershipTest() {}
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~WidgetOwnershipTest() {}
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WidgetTest::SetUp();
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    desktop_widget_ = CreateTopLevelPlatformWidget();
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    desktop_widget_->CloseNow();
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WidgetTest::TearDown();
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* desktop_widget_;
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WidgetOwnershipTest);
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A bag of state to monitor destructions.
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct OwnershipTestState {
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState() : widget_deleted(false), native_widget_deleted(false) {}
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool widget_deleted;
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool native_widget_deleted;
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A platform NativeWidget subclass that updates a bag of state when it is
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destroyed.
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OwnershipTestNativeWidget : public NativeWidgetPlatform {
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestNativeWidget(internal::NativeWidgetDelegate* delegate,
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            OwnershipTestState* state)
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : NativeWidgetPlatform(delegate),
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        state_(state) {
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~OwnershipTestNativeWidget() {
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state_->native_widget_deleted = true;
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState* state_;
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OwnershipTestNativeWidget);
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A views NativeWidget subclass that updates a bag of state when it is
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destroyed.
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OwnershipTestNativeWidgetPlatform : public NativeWidgetPlatformForTest {
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestNativeWidgetPlatform(internal::NativeWidgetDelegate* delegate,
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    OwnershipTestState* state)
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : NativeWidgetPlatformForTest(delegate),
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        state_(state) {
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~OwnershipTestNativeWidgetPlatform() {
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state_->native_widget_deleted = true;
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState* state_;
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OwnershipTestNativeWidgetPlatform);
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A Widget subclass that updates a bag of state when it is destroyed.
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OwnershipTestWidget : public Widget {
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit OwnershipTestWidget(OwnershipTestState* state) : state_(state) {}
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~OwnershipTestWidget() {
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state_->widget_deleted = true;
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState* state_;
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OwnershipTestWidget);
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Widget owns its NativeWidget, part 1: NativeWidget is a platform-native
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// widget.
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetOwnershipTest, Ownership_WidgetOwnsPlatformNativeWidget) {
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState state;
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.native_widget =
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new OwnershipTestNativeWidgetPlatform(widget.get(), &state);
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now delete the Widget, which should delete the NativeWidget.
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget.reset();
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.widget_deleted);
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.native_widget_deleted);
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(beng): write test for this ownership scenario and the NativeWidget
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //             being deleted out from under the Widget.
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Widget owns its NativeWidget, part 2: NativeWidget is a NativeWidget.
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetOwnershipTest, Ownership_WidgetOwnsViewsNativeWidget) {
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState state;
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.native_widget =
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new OwnershipTestNativeWidgetPlatform(widget.get(), &state);
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now delete the Widget, which should delete the NativeWidget.
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget.reset();
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.widget_deleted);
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.native_widget_deleted);
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(beng): write test for this ownership scenario and the NativeWidget
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //             being deleted out from under the Widget.
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Widget owns its NativeWidget, part 3: NativeWidget is a NativeWidget,
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destroy the parent view.
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetOwnershipTest,
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       Ownership_WidgetOwnsViewsNativeWidget_DestroyParentView) {
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState state;
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.native_widget =
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new OwnershipTestNativeWidgetPlatform(widget.get(), &state);
7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.parent = toplevel->GetNativeView();
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now close the toplevel, which deletes the view hierarchy.
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This shouldn't delete the widget because it shouldn't be deleted
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from the native side.
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(state.widget_deleted);
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(state.native_widget_deleted);
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now delete it explicitly.
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget.reset();
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.widget_deleted);
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.native_widget_deleted);
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NativeWidget owns its Widget, part 1: NativeWidget is a platform-native
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// widget.
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetOwnershipTest, Ownership_PlatformNativeWidgetOwnsWidget) {
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState state;
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget = new OwnershipTestWidget(&state);
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.native_widget =
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new OwnershipTestNativeWidgetPlatform(widget, &state);
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now destroy the native widget.
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->CloseNow();
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.widget_deleted);
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.native_widget_deleted);
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NativeWidget owns its Widget, part 2: NativeWidget is a NativeWidget.
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetOwnershipTest, Ownership_ViewsNativeWidgetOwnsWidget) {
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState state;
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget = new OwnershipTestWidget(&state);
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.native_widget =
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new OwnershipTestNativeWidgetPlatform(widget, &state);
8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.parent = toplevel->GetNativeView();
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now destroy the native widget. This is achieved by closing the toplevel.
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The NativeWidget won't be deleted until after a return to the message loop
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so we have to run pending messages before testing the destruction status.
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.widget_deleted);
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.native_widget_deleted);
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NativeWidget owns its Widget, part 3: NativeWidget is a platform-native
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// widget, destroyed out from under it by the OS.
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetOwnershipTest,
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       Ownership_PlatformNativeWidgetOwnsWidget_NativeDestroy) {
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState state;
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget = new OwnershipTestWidget(&state);
8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.native_widget =
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new OwnershipTestNativeWidgetPlatform(widget, &state);
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now simulate a destroy of the platform native widget from the OS:
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_AURA)
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete widget->GetNativeView();
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN)
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DestroyWindow(widget->GetNativeView());
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.widget_deleted);
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.native_widget_deleted);
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NativeWidget owns its Widget, part 4: NativeWidget is a NativeWidget,
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destroyed by the view hierarchy that contains it.
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetOwnershipTest,
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       Ownership_ViewsNativeWidgetOwnsWidget_NativeDestroy) {
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState state;
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget = new OwnershipTestWidget(&state);
8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.native_widget =
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new OwnershipTestNativeWidgetPlatform(widget, &state);
8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.parent = toplevel->GetNativeView();
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Destroy the widget (achieved by closing the toplevel).
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The NativeWidget won't be deleted until after a return to the message loop
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so we have to run pending messages before testing the destruction status.
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.widget_deleted);
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.native_widget_deleted);
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NativeWidget owns its Widget, part 5: NativeWidget is a NativeWidget,
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// we close it directly.
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetOwnershipTest,
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       Ownership_ViewsNativeWidgetOwnsWidget_Close) {
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState state;
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget = new OwnershipTestWidget(&state);
9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.native_widget =
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new OwnershipTestNativeWidgetPlatform(widget, &state);
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.parent = toplevel->GetNativeView();
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Destroy the widget.
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Close();
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The NativeWidget won't be deleted until after a return to the message loop
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so we have to run pending messages before testing the destruction status.
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.widget_deleted);
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.native_widget_deleted);
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Widget owns its NativeWidget and has a WidgetDelegateView as its contents.
9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetOwnershipTest,
9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       Ownership_WidgetOwnsNativeWidgetWithWithWidgetDelegateView) {
9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OwnershipTestState state;
9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WidgetDelegateView* delegate_view = new WidgetDelegateView;
9292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.native_widget =
9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new OwnershipTestNativeWidgetPlatform(widget.get(), &state);
9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.delegate = delegate_view;
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->Init(params);
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->SetContentsView(delegate_view);
9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now delete the Widget. There should be no crash or use-after-free.
9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.reset();
9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(state.widget_deleted);
9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(state.native_widget_deleted);
9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
9473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Test to verify using various Widget methods doesn't crash when the underlying
9483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// NativeView is destroyed.
9493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)//
9503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class WidgetWithDestroyedNativeViewTest : public ViewsTestBase {
9513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public:
9523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  WidgetWithDestroyedNativeViewTest() {}
9533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual ~WidgetWithDestroyedNativeViewTest() {}
9543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
9553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void InvokeWidgetMethods(Widget* widget) {
9563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetNativeView();
9573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetNativeWindow();
9583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ui::Accelerator accelerator;
9593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetAccelerator(0, &accelerator);
9603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetTopLevelWidget();
9613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetWindowBoundsInScreen();
9623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetClientAreaBoundsInScreen();
9633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->SetBounds(gfx::Rect(0, 0, 100, 80));
9643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->SetSize(gfx::Size(10, 11));
9653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->SetBoundsConstrained(gfx::Rect(0, 0, 120, 140));
9663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->SetVisibilityChangedAnimationsEnabled(false);
9673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->StackAtTop();
9683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->IsClosed();
9693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->Close();
9703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->Show();
9713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->Hide();
9723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->Activate();
9733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->Deactivate();
9743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->IsActive();
9753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->DisableInactiveRendering();
9763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->SetAlwaysOnTop(true);
9773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->Maximize();
9783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->Minimize();
9793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->Restore();
9803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->IsMaximized();
9813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->IsFullscreen();
9823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->SetOpacity(0);
9833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->SetUseDragFrame(true);
9843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->FlashFrame(true);
9853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->IsVisible();
9863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetThemeProvider();
9873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetNativeTheme();
9883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetFocusManager();
9893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetInputMethod();
9903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->SchedulePaintInRect(gfx::Rect(0, 0, 1, 2));
9913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->IsMouseEventsEnabled();
9923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->SetNativeWindowProperty("xx", widget);
9933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetNativeWindowProperty("xx");
9943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetFocusTraversable();
9953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetLayer();
9963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->ReorderNativeViews();
9973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->SetCapture(widget->GetRootView());
9983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->ReleaseCapture();
9993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->HasCapture();
10003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->TooltipTextChanged(widget->GetRootView());
10013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget->GetWorkAreaBoundsInScreen();
10023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // These three crash with NativeWidgetWin, so I'm assuming we don't need
10033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // them to work for the other NativeWidget impls.
10043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // widget->CenterWindow(gfx::Size(50, 60));
10053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // widget->GetRestoredBounds();
10063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // widget->ShowInactive();
10073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
10083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
10093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private:
10103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WidgetWithDestroyedNativeViewTest);
10113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
10123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
10133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_F(WidgetWithDestroyedNativeViewTest, Test) {
10143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {
10153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    Widget widget;
10163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
10173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
10183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget.Init(params);
10193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget.Show();
10203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
10213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget.native_widget_private()->CloseNow();
10223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    InvokeWidgetMethods(&widget);
10233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
10243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(USE_AURA) && !defined(OS_CHROMEOS)
10253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {
10263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    Widget widget;
10273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
10283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    params.native_widget = new DesktopNativeWidgetAura(&widget);
10293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
10303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget.Init(params);
10313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget.Show();
10323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
10333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    widget.native_widget_private()->CloseNow();
10343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    InvokeWidgetMethods(&widget);
10353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
10363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif
10373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
10383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
10393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Widget observer tests.
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class WidgetObserverTest : public WidgetTest, public WidgetObserver {
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WidgetObserverTest()
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : active_(NULL),
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        widget_closed_(NULL),
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        widget_activated_(NULL),
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        widget_shown_(NULL),
10502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        widget_hidden_(NULL),
10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        widget_bounds_changed_(NULL) {
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~WidgetObserverTest() {}
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from WidgetObserver:
10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWidgetDestroying(Widget* widget) OVERRIDE {
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (active_ == widget)
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      active_ = NULL;
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    widget_closed_ = widget;
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWidgetActivationChanged(Widget* widget,
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         bool active) OVERRIDE {
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (active) {
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (widget_activated_)
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        widget_activated_->Deactivate();
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget_activated_ = widget;
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      active_ = widget;
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (widget_activated_ == widget)
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        widget_activated_ = NULL;
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget_deactivated_ = widget;
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWidgetVisibilityChanged(Widget* widget,
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         bool visible) OVERRIDE {
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (visible)
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget_shown_ = widget;
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget_hidden_ = widget;
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWidgetBoundsChanged(Widget* widget,
10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     const gfx::Rect& new_bounds) OVERRIDE {
10872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    widget_bounds_changed_ = widget;
10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void reset() {
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    active_ = NULL;
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    widget_closed_ = NULL;
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    widget_activated_ = NULL;
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    widget_deactivated_ = NULL;
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    widget_shown_ = NULL;
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    widget_hidden_ = NULL;
10972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    widget_bounds_changed_ = NULL;
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* NewWidget() {
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Widget* widget = CreateTopLevelNativeWidget();
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    widget->AddObserver(this);
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return widget;
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Widget* active() const { return active_; }
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Widget* widget_closed() const { return widget_closed_; }
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Widget* widget_activated() const { return widget_activated_; }
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Widget* widget_deactivated() const { return widget_deactivated_; }
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Widget* widget_shown() const { return widget_shown_; }
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Widget* widget_hidden() const { return widget_hidden_; }
11122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Widget* widget_bounds_changed() const { return widget_bounds_changed_; }
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* active_;
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget_closed_;
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget_activated_;
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget_deactivated_;
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget_shown_;
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget_hidden_;
11222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* widget_bounds_changed_;
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetObserverTest, DISABLED_ActivationChange) {
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel1 = NewWidget();
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel2 = NewWidget();
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel1->Show();
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel2->Show();
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reset();
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel1->Activate();
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(toplevel1, widget_activated());
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel2->Activate();
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(toplevel1, widget_deactivated());
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(toplevel2, widget_activated());
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(toplevel2, active());
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetObserverTest, DISABLED_VisibilityChange) {
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* child1 = NewWidget();
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* child2 = NewWidget();
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Show();
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child1->Show();
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child2->Show();
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reset();
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child1->Hide();
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child1, widget_hidden());
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child2->Hide();
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child2, widget_hidden());
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child1->Show();
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child1, widget_shown());
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child2->Show();
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child2, widget_shown());
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetObserverTest, DestroyBubble) {
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* anchor = CreateTopLevelPlatformWidget();
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  anchor->Show();
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BubbleDelegateView* bubble_delegate =
11822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new BubbleDelegateView(anchor->client_view(), BubbleBorder::NONE);
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* bubble_widget(BubbleDelegateView::CreateBubble(bubble_delegate));
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bubble_widget->Show();
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bubble_widget->CloseNow();
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  anchor->Hide();
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  anchor->CloseNow();
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetObserverTest, WidgetBoundsChanged) {
11922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* child1 = NewWidget();
11932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* child2 = NewWidget();
11942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child1->OnNativeWidgetMove();
11962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(child1, widget_bounds_changed());
11972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->OnNativeWidgetMove();
11992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(child2, widget_bounds_changed());
12002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child1->OnNativeWidgetSizeChanged(gfx::Size());
12022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(child1, widget_bounds_changed());
12032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->OnNativeWidgetSizeChanged(gfx::Size());
12052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(child2, widget_bounds_changed());
12062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(USE_AURA) && defined(OS_WIN)
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Aura needs shell to maximize/fullscreen window.
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NativeWidgetGtk doesn't implement GetRestoredBounds.
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, GetRestoredBounds) {
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(toplevel->GetWindowBoundsInScreen().ToString(),
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            toplevel->GetRestoredBounds().ToString());
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Show();
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Maximize();
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(toplevel->GetWindowBoundsInScreen().ToString(),
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            toplevel->GetRestoredBounds().ToString());
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(toplevel->GetRestoredBounds().width(), 0);
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(toplevel->GetRestoredBounds().height(), 0);
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Restore();
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(toplevel->GetWindowBoundsInScreen().ToString(),
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            toplevel->GetRestoredBounds().ToString());
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->SetFullscreen(true);
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(toplevel->GetWindowBoundsInScreen().ToString(),
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            toplevel->GetRestoredBounds().ToString());
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(toplevel->GetRestoredBounds().width(), 0);
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(toplevel->GetRestoredBounds().height(), 0);
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that window state is not changed after getting out of full screen.
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, ExitFullscreenRestoreState) {
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Show();
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should be a normal state window.
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ui::SHOW_STATE_NORMAL, GetWidgetShowState(toplevel));
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->SetFullscreen(true);
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (GetWidgetShowState(toplevel) != ui::SHOW_STATE_FULLSCREEN)
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunPendingMessages();
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->SetFullscreen(false);
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (GetWidgetShowState(toplevel) == ui::SHOW_STATE_FULLSCREEN)
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunPendingMessages();
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // And it should still be in normal state after getting out of full screen.
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ui::SHOW_STATE_NORMAL, GetWidgetShowState(toplevel));
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now, make it maximized.
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Maximize();
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (GetWidgetShowState(toplevel) != ui::SHOW_STATE_MAXIMIZED)
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunPendingMessages();
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->SetFullscreen(true);
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (GetWidgetShowState(toplevel) != ui::SHOW_STATE_FULLSCREEN)
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunPendingMessages();
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->SetFullscreen(false);
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (GetWidgetShowState(toplevel) == ui::SHOW_STATE_FULLSCREEN)
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunPendingMessages();
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // And it stays maximized after getting out of full screen.
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, GetWidgetShowState(toplevel));
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clean up.
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Close();
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Checks that if a mouse-press triggers a capture on a different widget (which
12787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// consumes the mouse-release event), then the target of the press does not have
12797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// capture.
12803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Fails on chromium.webkit Windows bot, see crbug.com/264872.
12813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(OS_WIN)
12823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#define MAYBE_DisableCaptureWidgetFromMousePress\
12833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    DISABLED_CaptureWidgetFromMousePress
12843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#else
12853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#define MAYBE_DisableCaptureWidgetFromMousePress\
12863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    CaptureWidgetFromMousePress
12873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif
12883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_F(WidgetTest, MAYBE_DisableCaptureWidgetFromMousePress) {
12897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // The test creates two widgets: |first| and |second|.
12907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // The View in |first| makes |second| visible, sets capture on it, and starts
12917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // a nested loop (like a menu does). The View in |second| terminates the
12927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // nested loop and closes the widget.
12937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // The test sends a mouse-press event to |first|, and posts a task to send a
12947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // release event to |second|, to make sure that the release event is
12957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // dispatched after the nested loop starts.
12967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
12977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  Widget* first = CreateTopLevelFramelessPlatformWidget();
12987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  Widget* second = CreateTopLevelFramelessPlatformWidget();
12997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
13007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  View* container = new NestedLoopCaptureView(second);
13017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  first->SetContentsView(container);
13027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
13037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  second->SetContentsView(new ExitLoopOnRelease());
13047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
13057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  first->SetSize(gfx::Size(100, 100));
13067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  first->Show();
13077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
13087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  gfx::Point location(20, 20);
13097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::MessageLoop::current()->PostTask(FROM_HERE,
13107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&Widget::OnMouseEvent,
13117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 base::Unretained(second),
13127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 base::Owned(new ui::MouseEvent(ui::ET_MOUSE_RELEASED,
13137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                                location,
13147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                                location,
13157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                                ui::EF_LEFT_MOUSE_BUTTON))));
13167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ui::MouseEvent press(ui::ET_MOUSE_PRESSED, location, location,
13177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                       ui::EF_LEFT_MOUSE_BUTTON);
13187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  first->OnMouseEvent(&press);
13197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(first->HasCapture());
13207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  first->Close();
13217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  RunPendingMessages();
13227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
13237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, ResetCaptureOnGestureEnd) {
13252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* toplevel = CreateTopLevelFramelessPlatformWidget();
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  View* container = new View;
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->SetContentsView(container);
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  View* gesture = new GestureCaptureView;
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gesture->SetBounds(0, 0, 30, 30);
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  container->AddChildView(gesture);
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MouseView* mouse = new MouseView;
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse->SetBounds(30, 0, 30, 30);
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  container->AddChildView(mouse);
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->SetSize(gfx::Size(100, 100));
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Show();
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start a gesture on |gesture|.
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::GestureEvent begin(ui::ET_GESTURE_BEGIN,
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      15, 15, 0, base::TimeDelta(),
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::GestureEventDetails(ui::ET_GESTURE_BEGIN, 0, 0), 1);
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::GestureEvent end(ui::ET_GESTURE_END,
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      15, 15, 0, base::TimeDelta(),
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::GestureEventDetails(ui::ET_GESTURE_END, 0, 0), 1);
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->OnGestureEvent(&begin);
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now try to click on |mouse|. Since |gesture| will have capture, |mouse|
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will not receive the event.
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point click_location(45, 15);
13522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::MouseEvent press(ui::ET_MOUSE_PRESSED, click_location, click_location,
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::EF_LEFT_MOUSE_BUTTON);
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::MouseEvent release(ui::ET_MOUSE_RELEASED, click_location, click_location,
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::EF_LEFT_MOUSE_BUTTON);
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnMouseEvent(&press);
13592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnMouseEvent(&release);
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, mouse->pressed());
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The end of the gesture should release the capture, and pressing on |mouse|
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should now reach |mouse|.
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->OnGestureEvent(&end);
13652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnMouseEvent(&press);
13662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnMouseEvent(&release);
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, mouse->pressed());
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Close();
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_AURA)
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The key-event propagation from Widget happens differently on aura and
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// non-aura systems because of the difference in IME. So this test works only on
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// aura.
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, KeyboardInputEvent) {
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
13792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  View* container = toplevel->client_view();
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Textfield* textfield = new Textfield();
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  textfield->SetText(ASCIIToUTF16("some text"));
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  container->AddChildView(textfield);
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Show();
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  textfield->RequestFocus();
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The press gets handled. The release doesn't have an effect.
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::KeyEvent backspace_p(ui::ET_KEY_PRESSED, ui::VKEY_DELETE, 0, false);
13892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnKeyEvent(&backspace_p);
13902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(backspace_p.stopped_propagation());
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::KeyEvent backspace_r(ui::ET_KEY_RELEASED, ui::VKEY_DELETE, 0, false);
13922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnKeyEvent(&backspace_r);
13932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(backspace_r.handled());
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Close();
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Verifies bubbles result in a focus lost when shown.
1399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// TODO(msw): this tests relies on focus, it needs to be in
1400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// interactive_ui_tests.
1401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WidgetTest, DISABLED_FocusChangesOnBubble) {
14022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a widget, show and activate it and focus the contents view.
14032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  View* contents_view = new View;
14042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents_view->set_focusable(true);
14052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget widget;
14062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams init_params =
14072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
14082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.bounds = gfx::Rect(0, 0, 200, 200);
14092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
14102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_CHROMEOS)
14112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.native_widget = new DesktopNativeWidgetAura(&widget);
14122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
14132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Init(init_params);
14142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.SetContentsView(contents_view);
14152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Show();
14162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Activate();
14172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents_view->RequestFocus();
14182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(contents_view->HasFocus());
14192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Show a bubble.
14212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BubbleDelegateView* bubble_delegate_view =
14222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new BubbleDelegateView(contents_view, BubbleBorder::TOP_LEFT);
14232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bubble_delegate_view->set_focusable(true);
14242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BubbleDelegateView::CreateBubble(bubble_delegate_view)->Show();
14252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bubble_delegate_view->RequestFocus();
14262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |contents_view_| should no longer have focus.
14282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(contents_view->HasFocus());
14292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(bubble_delegate_view->HasFocus());
14302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bubble_delegate_view->GetWidget()->CloseNow();
14322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Closing the bubble should result in focus going back to the contents view.
14342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(contents_view->HasFocus());
14352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Desktop native widget Aura tests are for non Chrome OS platforms.
14382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_CHROMEOS)
1439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Test to ensure that after minimize, view width is set to zero.
1440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WidgetTest, TestViewWidthAfterMinimizingWidget) {
1441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a widget.
1442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Widget widget;
1443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Widget::InitParams init_params =
1444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CreateParams(Widget::InitParams::TYPE_WINDOW);
1445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  init_params.show_state = ui::SHOW_STATE_NORMAL;
1446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Rect initial_bounds(0, 0, 300, 400);
1447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  init_params.bounds = initial_bounds;
1448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
1449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  init_params.native_widget = new DesktopNativeWidgetAura(&widget);
1450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget.Init(init_params);
1451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NonClientView* non_client_view = widget.non_client_view();
1452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NonClientFrameView* frame_view = new MinimumSizeFrameView(&widget);
1453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  non_client_view->SetFrameView(frame_view);
1454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget.Show();
1455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget.Minimize();
1456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, frame_view->width());
1457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
14592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This class validates whether paints are received for a visible Widget.
14602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// To achieve this it overrides the Show and Close methods on the Widget class
14612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// and sets state whether subsequent paints are expected.
14622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DesktopAuraTestValidPaintWidget : public views::Widget {
14632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
14642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DesktopAuraTestValidPaintWidget()
14652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : expect_paint_(true),
14662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      received_paint_while_hidden_(false) {
14672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~DesktopAuraTestValidPaintWidget() {
14702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void Show() OVERRIDE {
14732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expect_paint_ = true;
14742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    views::Widget::Show();
14752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void Close() OVERRIDE {
14782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expect_paint_ = false;
14792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    views::Widget::Close();
14802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Hide() {
14832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expect_paint_ = false;
14842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    views::Widget::Hide();
14852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnNativeWidgetPaint(gfx::Canvas* canvas) OVERRIDE {
14882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(expect_paint_);
14892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!expect_paint_)
14902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      received_paint_while_hidden_ = true;
14912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    views::Widget::OnNativeWidgetPaint(canvas);
14922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool received_paint_while_hidden() const {
14952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return received_paint_while_hidden_;
14962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
14992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool expect_paint_;
15002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool received_paint_while_hidden_;
15012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
15022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetTest, DesktopNativeWidgetAuraNoPaintAfterCloseTest) {
15042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  View* contents_view = new View;
15052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents_view->set_focusable(true);
15062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DesktopAuraTestValidPaintWidget widget;
15072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams init_params =
15082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
15092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.bounds = gfx::Rect(0, 0, 200, 200);
15102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
15112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.native_widget = new DesktopNativeWidgetAura(&widget);
15122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Init(init_params);
15132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.SetContentsView(contents_view);
15142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Show();
15152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Activate();
15162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunPendingMessages();
15172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.SchedulePaintInRect(init_params.bounds);
15182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Close();
15192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunPendingMessages();
15202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(widget.received_paint_while_hidden());
15212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetTest, DesktopNativeWidgetAuraNoPaintAfterHideTest) {
15242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  View* contents_view = new View;
15252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents_view->set_focusable(true);
15262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DesktopAuraTestValidPaintWidget widget;
15272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams init_params =
15282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
15292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.bounds = gfx::Rect(0, 0, 200, 200);
15302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
15312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.native_widget = new DesktopNativeWidgetAura(&widget);
15322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Init(init_params);
15332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.SetContentsView(contents_view);
15342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Show();
15352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Activate();
15362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunPendingMessages();
15372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.SchedulePaintInRect(init_params.bounds);
15382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Hide();
15392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunPendingMessages();
15402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(widget.received_paint_while_hidden());
15412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Close();
15422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1544424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// This class provides functionality to create fullscreen and top level popup
1545424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// windows. It additionally tests whether the destruction of these windows
1546424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// occurs correctly in desktop AURA without crashing.
15472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// It provides facilities to test the following cases:-
15482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1. Child window destroyed which should lead to the destruction of the
15492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//    parent.
15502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 2. Parent window destroyed which should lead to the child being destroyed.
1551424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)class DesktopAuraTopLevelWindowTest
15522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public views::TestViewsDelegate,
15532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      public aura::WindowObserver {
15542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1555424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DesktopAuraTopLevelWindowTest()
1556424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      : top_level_widget_(NULL),
1557424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        owned_window_(NULL),
1558424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        owner_destroyed_(false),
1559424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        owned_window_destroyed_(false) {}
15602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1561424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual ~DesktopAuraTopLevelWindowTest() {
1562424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    EXPECT_TRUE(owner_destroyed_);
1563424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    EXPECT_TRUE(owned_window_destroyed_);
1564424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    top_level_widget_ = NULL;
1565424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    owned_window_ = NULL;
15662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
15672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // views::TestViewsDelegate overrides.
15692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnBeforeWidgetInit(
15702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Widget::InitParams* params,
15712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      internal::NativeWidgetDelegate* delegate) OVERRIDE {
15722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!params->native_widget)
15732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      params->native_widget = new views::DesktopNativeWidgetAura(delegate);
15742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
15752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1576424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void CreateTopLevelWindow(const gfx::Rect& bounds, bool fullscreen) {
15772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Widget::InitParams init_params;
15782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    init_params.type = Widget::InitParams::TYPE_WINDOW;
15792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    init_params.bounds = bounds;
15802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
15812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    init_params.layer_type = ui::LAYER_NOT_DRAWN;
1582424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    init_params.accept_events = fullscreen;
15832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    widget_.Init(init_params);
15852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1586424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    owned_window_ = new aura::Window(&child_window_delegate_);
1587424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    owned_window_->SetType(aura::client::WINDOW_TYPE_NORMAL);
1588424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    owned_window_->SetName("TestTopLevelWindow");
1589424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (fullscreen) {
1590424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      owned_window_->SetProperty(aura::client::kShowStateKey,
1591424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                 ui::SHOW_STATE_FULLSCREEN);
1592424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    } else {
1593424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      owned_window_->SetType(aura::client::WINDOW_TYPE_MENU);
1594424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    }
1595424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    owned_window_->Init(ui::LAYER_TEXTURED);
1596424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    owned_window_->SetDefaultParentByRootWindow(
15972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        widget_.GetNativeView()->GetRootWindow(), gfx::Rect(0, 0, 1900, 1600));
1598424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    owned_window_->Show();
1599424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    owned_window_->AddObserver(this);
16002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1601424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ASSERT_TRUE(owned_window_->parent() != NULL);
1602424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    owned_window_->parent()->AddObserver(this);
16032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1604424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    top_level_widget_ =
1605424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        views::Widget::GetWidgetForNativeView(owned_window_->parent());
1606424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ASSERT_TRUE(top_level_widget_ != NULL);
16072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
16082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1609424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void DestroyOwnedWindow() {
1610424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ASSERT_TRUE(owned_window_ != NULL);
1611424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    delete owned_window_;
16122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
16132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1614424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void DestroyOwnerWindow() {
1615424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ASSERT_TRUE(top_level_widget_ != NULL);
1616424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    top_level_widget_->CloseNow();
16172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
16182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
16202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    window->RemoveObserver(this);
1621424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (window == owned_window_) {
1622424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      owned_window_destroyed_ = true;
1623424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    } else if (window == top_level_widget_->GetNativeView()) {
1624424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      owner_destroyed_ = true;
16252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
16262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ADD_FAILURE() << "Unexpected window destroyed callback: " << window;
16272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
16282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
16292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
16312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  views::Widget widget_;
1632424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  views::Widget* top_level_widget_;
1633424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  aura::Window* owned_window_;
1634424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool owner_destroyed_;
1635424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool owned_window_destroyed_;
16362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::test::TestWindowDelegate child_window_delegate_;
16372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1638424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DesktopAuraTopLevelWindowTest);
16392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
16402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1641424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(WidgetTest, DesktopAuraFullscreenWindowDestroyedBeforeOwnerTest) {
16422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ViewsDelegate::views_delegate = NULL;
1643424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DesktopAuraTopLevelWindowTest fullscreen_window;
1644424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(fullscreen_window.CreateTopLevelWindow(
1645424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      gfx::Rect(0, 0, 200, 200), true));
16462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunPendingMessages();
1648424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(fullscreen_window.DestroyOwnedWindow());
16492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunPendingMessages();
16502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
16512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1652424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(WidgetTest, DesktopAuraFullscreenWindowOwnerDestroyed) {
16532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ViewsDelegate::views_delegate = NULL;
16542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1655424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DesktopAuraTopLevelWindowTest fullscreen_window;
1656424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(fullscreen_window.CreateTopLevelWindow(
1657424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      gfx::Rect(0, 0, 200, 200), true));
1658424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1659424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  RunPendingMessages();
1660424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(fullscreen_window.DestroyOwnerWindow());
1661424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  RunPendingMessages();
1662424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
1663424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1664424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(WidgetTest, DesktopAuraTopLevelOwnedPopupTest) {
1665424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ViewsDelegate::views_delegate = NULL;
1666424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DesktopAuraTopLevelWindowTest popup_window;
1667424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(popup_window.CreateTopLevelWindow(
1668424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      gfx::Rect(0, 0, 200, 200), false));
16692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunPendingMessages();
1671424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(popup_window.DestroyOwnedWindow());
16722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunPendingMessages();
16732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
16742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Test to ensure that the aura Window's visiblity state is set to visible if
1676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the underlying widget is hidden and then shown.
1677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WidgetTest, TestWindowVisibilityAfterHide) {
1678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a widget.
1679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Widget widget;
1680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Widget::InitParams init_params =
1681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CreateParams(Widget::InitParams::TYPE_WINDOW);
1682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  init_params.show_state = ui::SHOW_STATE_NORMAL;
1683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Rect initial_bounds(0, 0, 300, 400);
1684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  init_params.bounds = initial_bounds;
1685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
1686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  init_params.native_widget = new DesktopNativeWidgetAura(&widget);
1687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget.Init(init_params);
1688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NonClientView* non_client_view = widget.non_client_view();
1689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NonClientFrameView* frame_view = new MinimumSizeFrameView(&widget);
1690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  non_client_view->SetFrameView(frame_view);
1691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget.Hide();
1693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(widget.GetNativeView()->IsVisible());
1694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget.Show();
1695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(widget.GetNativeView()->IsVisible());
1696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1698424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// The following code verifies we can correctly destroy a Widget from a mouse
1699424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// enter/exit. We could test move/drag/enter/exit but in general we don't run
1700424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// nested message loops from such events, nor has the code ever really dealt
1701424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// with this situation.
1702424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1703424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Class that closes the widget (which ends up deleting it immediately) when the
1704424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// appropriate event is received.
1705424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)class CloseWidgetView : public View {
1706424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) public:
1707424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  explicit CloseWidgetView(ui::EventType event_type)
1708424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      : event_type_(event_type) {
1709424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
1710424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1711424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // View overrides:
1712424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE {
1713424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (!CloseWidget(event))
1714424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      View::OnMousePressed(event);
1715424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return true;
1716424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
1717424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE {
1718424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (!CloseWidget(event))
1719424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      View::OnMouseDragged(event);
1720424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return true;
1721424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
1722424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE {
1723424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (!CloseWidget(event))
1724424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      View::OnMouseReleased(event);
1725424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
1726424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual void OnMouseMoved(const ui::MouseEvent& event) OVERRIDE {
1727424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (!CloseWidget(event))
1728424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      View::OnMouseMoved(event);
1729424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
1730424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE {
1731424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (!CloseWidget(event))
1732424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      View::OnMouseEntered(event);
1733424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
1734424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1735424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) private:
1736424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool CloseWidget(const ui::LocatedEvent& event) {
1737424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (event.type() == event_type_) {
1738424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      // Go through NativeWidgetPrivate to simulate what happens if the OS
1739424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      // deletes the NativeWindow out from under us.
1740424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      GetWidget()->native_widget_private()->CloseNow();
1741424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      return true;
1742424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    }
1743424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return false;
1744424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
1745424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1746424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  const ui::EventType event_type_;
1747424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1748424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CloseWidgetView);
1749424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
1750424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1751424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Generates two moves (first generates enter, second real move), a press, drag
1752424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// and release stopping at |last_event_type|.
1753424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void GenerateMouseEvents(Widget* widget, ui::EventType last_event_type) {
1754424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  const gfx::Rect screen_bounds(widget->GetWindowBoundsInScreen());
1755424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ui::MouseEvent move_event(ui::ET_MOUSE_MOVED, screen_bounds.CenterPoint(),
1756424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                            screen_bounds.CenterPoint(), 0);
1757424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  aura::RootWindowHostDelegate* rwhd =
1758424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      widget->GetNativeWindow()->GetRootWindow()->AsRootWindowHostDelegate();
1759424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  rwhd->OnHostMouseEvent(&move_event);
1760424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (last_event_type == ui::ET_MOUSE_ENTERED)
1761424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return;
1762424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  rwhd->OnHostMouseEvent(&move_event);
1763424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (last_event_type == ui::ET_MOUSE_MOVED)
1764424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return;
1765424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1766424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ui::MouseEvent press_event(ui::ET_MOUSE_PRESSED, screen_bounds.CenterPoint(),
1767424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                             screen_bounds.CenterPoint(), 0);
1768424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  rwhd->OnHostMouseEvent(&press_event);
1769424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (last_event_type == ui::ET_MOUSE_PRESSED)
1770424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return;
1771424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1772424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  gfx::Point end_point(screen_bounds.CenterPoint());
1773424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  end_point.Offset(1, 1);
1774424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ui::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED, end_point, end_point, 0);
1775424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  rwhd->OnHostMouseEvent(&drag_event);
1776424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (last_event_type == ui::ET_MOUSE_DRAGGED)
1777424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return;
1778424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1779424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ui::MouseEvent release_event(ui::ET_MOUSE_RELEASED, end_point, end_point, 0);
1780424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  rwhd->OnHostMouseEvent(&release_event);
1781424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
1782424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1783424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Creates a widget and invokes GenerateMouseEvents() with |last_event_type|.
1784424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void RunCloseWidgetDuringDispatchTest(WidgetTest* test,
1785424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                      ui::EventType last_event_type) {
1786424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // |widget| is deleted by CloseWidgetView.
1787424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  Widget* widget = new Widget;
1788424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  Widget::InitParams params =
1789424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      test->CreateParams(Widget::InitParams::TYPE_POPUP);
1790424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  params.native_widget = new DesktopNativeWidgetAura(widget);
1791424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  params.bounds = gfx::Rect(0, 0, 50, 100);
1792424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  widget->Init(params);
1793424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  widget->SetContentsView(new CloseWidgetView(last_event_type));
1794424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  widget->Show();
1795424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  GenerateMouseEvents(widget, last_event_type);
1796424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
1797424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1798424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Verifies deleting the widget from a mouse pressed event doesn't crash.
1799424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(WidgetTest, CloseWidgetDuringMousePress) {
1800424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  RunCloseWidgetDuringDispatchTest(this, ui::ET_MOUSE_PRESSED);
1801424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
1802424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1803424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Verifies deleting the widget from a mouse released event doesn't crash.
1804424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(WidgetTest, CloseWidgetDuringMouseReleased) {
1805424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  RunCloseWidgetDuringDispatchTest(this, ui::ET_MOUSE_RELEASED);
1806424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
1807424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
18082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // !defined(OS_CHROMEOS)
18092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Tests that wheel events generated from scroll events are targetted to the
18112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// views under the cursor when the focused view does not processed them.
18122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetTest, WheelEventsFromScrollEventTarget) {
18132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EventCountView* cursor_view = new EventCountView;
18142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cursor_view->SetBounds(60, 0, 50, 40);
18152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* widget = CreateTopLevelPlatformWidget();
18172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->GetRootView()->AddChildView(cursor_view);
18182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1819c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Generate a scroll event on the cursor view.
18202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::ScrollEvent scroll(ui::ET_SCROLL,
18212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         gfx::Point(65, 5),
18222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         ui::EventTimeForNow(),
18232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         0,
18242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         0, 20,
18252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         0, 20,
18262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         2);
18272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->OnScrollEvent(&scroll);
18282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, cursor_view->GetEventCount(ui::ET_SCROLL));
18302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, cursor_view->GetEventCount(ui::ET_MOUSEWHEEL));
18312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cursor_view->ResetCounts();
18332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::ScrollEvent scroll2(ui::ET_SCROLL,
18352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          gfx::Point(5, 5),
18362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          ui::EventTimeForNow(),
18372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          0,
18382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          0, 20,
18392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          0, 20,
18402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          2);
18412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->OnScrollEvent(&scroll2);
18422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, cursor_view->GetEventCount(ui::ET_SCROLL));
18442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, cursor_view->GetEventCount(ui::ET_MOUSEWHEEL));
18452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->CloseNow();
18472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
18482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(USE_AURA)
18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests that if a scroll-begin gesture is not handled, then subsequent scroll
18522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// events are not dispatched to any view.
18532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetTest, GestureScrollEventDispatching) {
18542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EventCountView* noscroll_view = new EventCountView;
18552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EventCountView* scroll_view = new ScrollableEventCountView;
18562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  noscroll_view->SetBounds(0, 0, 50, 40);
18582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scroll_view->SetBounds(60, 0, 40, 40);
18592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* widget = CreateTopLevelPlatformWidget();
18612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->GetRootView()->AddChildView(noscroll_view);
18622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->GetRootView()->AddChildView(scroll_view);
18632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
18652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::GestureEvent begin(ui::ET_GESTURE_SCROLL_BEGIN,
18662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        5, 5, 0, base::TimeDelta(),
18672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 0, 0),
18682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        1);
18692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    widget->OnGestureEvent(&begin);
18702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::GestureEvent update(ui::ET_GESTURE_SCROLL_UPDATE,
18712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        25, 15, 0, base::TimeDelta(),
18722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE, 20, 10),
18732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        1);
18742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    widget->OnGestureEvent(&update);
18752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::GestureEvent end(ui::ET_GESTURE_SCROLL_END,
18762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        25, 15, 0, base::TimeDelta(),
18772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END, 0, 0),
18782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        1);
18792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    widget->OnGestureEvent(&end);
18802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, noscroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_BEGIN));
18822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, noscroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_UPDATE));
18832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, noscroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_END));
18842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
18852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
18872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::GestureEvent begin(ui::ET_GESTURE_SCROLL_BEGIN,
18882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        65, 5, 0, base::TimeDelta(),
18892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 0, 0),
18902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        1);
18912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    widget->OnGestureEvent(&begin);
18922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::GestureEvent update(ui::ET_GESTURE_SCROLL_UPDATE,
18932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        85, 15, 0, base::TimeDelta(),
18942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE, 20, 10),
18952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        1);
18962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    widget->OnGestureEvent(&update);
18972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::GestureEvent end(ui::ET_GESTURE_SCROLL_END,
18982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        85, 15, 0, base::TimeDelta(),
18992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END, 0, 0),
19002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        1);
19012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    widget->OnGestureEvent(&end);
19022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, scroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_BEGIN));
19042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, scroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_UPDATE));
19052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, scroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_END));
19062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
19072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->CloseNow();
19092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
19102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests that event-handlers installed on the RootView get triggered correctly.
19122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetTest, EventHandlersOnRootView) {
19132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* widget = CreateTopLevelNativeWidget();
19142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  View* root_view = widget->GetRootView();
19152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EventCountView* view = new EventCountView;
19172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  view->SetBounds(0, 0, 20, 20);
19182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_view->AddChildView(view);
19192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EventCountHandler h1;
19212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_view->AddPreTargetHandler(&h1);
19222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EventCountHandler h2;
19242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_view->AddPostTargetHandler(&h2);
19252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->SetBounds(gfx::Rect(0, 0, 100, 100));
19272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->Show();
19282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::TouchEvent pressed(ui::ET_TOUCH_PRESSED,
19302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         gfx::Point(10, 10),
19312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         0, 0,
19322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         ui::EventTimeForNow(),
19332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         1.0, 0.0, 1.0, 0.0);
19342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->OnTouchEvent(&pressed);
19352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h1.GetEventCount(ui::ET_TOUCH_PRESSED));
19362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, view->GetEventCount(ui::ET_TOUCH_PRESSED));
19372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h2.GetEventCount(ui::ET_TOUCH_PRESSED));
19382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::GestureEvent begin(ui::ET_GESTURE_BEGIN,
19402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      5, 5, 0, ui::EventTimeForNow(),
19412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui::GestureEventDetails(ui::ET_GESTURE_BEGIN, 0, 0), 1);
19422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::GestureEvent end(ui::ET_GESTURE_END,
19432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      5, 5, 0, ui::EventTimeForNow(),
19442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui::GestureEventDetails(ui::ET_GESTURE_END, 0, 0), 1);
19452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->OnGestureEvent(&begin);
19462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h1.GetEventCount(ui::ET_GESTURE_BEGIN));
19472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, view->GetEventCount(ui::ET_GESTURE_BEGIN));
19482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h2.GetEventCount(ui::ET_GESTURE_BEGIN));
19492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::TouchEvent released(ui::ET_TOUCH_RELEASED,
19512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          gfx::Point(10, 10),
19522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          0, 0,
19532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          ui::EventTimeForNow(),
19542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          1.0, 0.0, 1.0, 0.0);
19552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->OnTouchEvent(&released);
19562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h1.GetEventCount(ui::ET_TOUCH_RELEASED));
19572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, view->GetEventCount(ui::ET_TOUCH_RELEASED));
19582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h2.GetEventCount(ui::ET_TOUCH_RELEASED));
19592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->OnGestureEvent(&end);
19612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h1.GetEventCount(ui::ET_GESTURE_END));
19622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, view->GetEventCount(ui::ET_GESTURE_END));
19632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h2.GetEventCount(ui::ET_GESTURE_END));
19642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::ScrollEvent scroll(ui::ET_SCROLL,
19662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         gfx::Point(5, 5),
19672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         ui::EventTimeForNow(),
19682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         0,
19692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         0, 20,
19702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         0, 20,
19712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         2);
19722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->OnScrollEvent(&scroll);
19732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h1.GetEventCount(ui::ET_SCROLL));
19742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, view->GetEventCount(ui::ET_SCROLL));
19752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h2.GetEventCount(ui::ET_SCROLL));
19762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->CloseNow();
19782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
19792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1980c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WidgetTest, SynthesizeMouseMoveEvent) {
1981c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Widget* widget = CreateTopLevelNativeWidget();
1982c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  View* root_view = widget->GetRootView();
1983c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1984c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EventCountView* v1 = new EventCountView();
1985c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  v1->SetBounds(0, 0, 10, 10);
1986c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  root_view->AddChildView(v1);
1987c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EventCountView* v2 = new EventCountView();
1988c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  v2->SetBounds(0, 10, 10, 10);
1989c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  root_view->AddChildView(v2);
1990c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1991c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Point cursor_location(5, 5);
1992c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ui::MouseEvent move(ui::ET_MOUSE_MOVED, cursor_location, cursor_location,
1993c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                      ui::EF_NONE);
1994c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget->OnMouseEvent(&move);
1995c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1996c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, v1->GetEventCount(ui::ET_MOUSE_ENTERED));
1997c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, v2->GetEventCount(ui::ET_MOUSE_ENTERED));
1998c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1999c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  delete v1;
2000c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  v2->SetBounds(0, 0, 10, 10);
2001c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, v2->GetEventCount(ui::ET_MOUSE_ENTERED));
2002c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2003c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget->SynthesizeMouseMoveEvent();
2004c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, v2->GetEventCount(ui::ET_MOUSE_ENTERED));
2005c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2006c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
20077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(WidgetTest, MouseEventsHandled) {
20087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  Widget* widget = CreateTopLevelNativeWidget();
20097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  View* root_view = widget->GetRootView();
20107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
20117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(USE_AURA)
2012eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  aura::test::TestCursorClient cursor_client(
2013eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      widget->GetNativeView()->GetRootWindow());
20147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
20157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
20167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EventCountView* v1 = new EventCountView();
20177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  v1->SetBounds(0, 0, 10, 10);
20187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  root_view->AddChildView(v1);
20197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EventCountView* v2 = new EventCountView();
20207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  v2->SetBounds(0, 10, 10, 10);
20217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  root_view->AddChildView(v2);
20227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
20237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  gfx::Point cursor_location1(5, 5);
20247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ui::MouseEvent move1(ui::ET_MOUSE_MOVED, cursor_location1, cursor_location1,
20257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       ui::EF_NONE);
20267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  widget->OnMouseEvent(&move1);
20277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(1, v1->GetEventCount(ui::ET_MOUSE_ENTERED));
20287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, v2->GetEventCount(ui::ET_MOUSE_ENTERED));
20297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, v1->GetEventCount(ui::ET_MOUSE_EXITED));
20307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, v2->GetEventCount(ui::ET_MOUSE_EXITED));
20317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  v1->ResetCounts();
20327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  v2->ResetCounts();
20337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
20347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  gfx::Point cursor_location2(5, 15);
20357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ui::MouseEvent move2(ui::ET_MOUSE_MOVED, cursor_location2, cursor_location2,
20367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       ui::EF_NONE);
20377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  widget->OnMouseEvent(&move2);
20387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, v1->GetEventCount(ui::ET_MOUSE_ENTERED));
20397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(1, v2->GetEventCount(ui::ET_MOUSE_ENTERED));
20407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(1, v1->GetEventCount(ui::ET_MOUSE_EXITED));
20417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, v2->GetEventCount(ui::ET_MOUSE_EXITED));
20427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  v1->ResetCounts();
20437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  v2->ResetCounts();
20447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
20457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(USE_AURA)
20467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // In Aura, we suppress mouse events if mouse events are disabled.
20477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  cursor_client.DisableMouseEvents();
20487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
20497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  widget->OnMouseEvent(&move1);
20507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, v1->GetEventCount(ui::ET_MOUSE_ENTERED));
20517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, v2->GetEventCount(ui::ET_MOUSE_ENTERED));
20527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, v1->GetEventCount(ui::ET_MOUSE_EXITED));
20537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, v2->GetEventCount(ui::ET_MOUSE_EXITED));
20547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  v1->ResetCounts();
20557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  v2->ResetCounts();
20567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
20577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  widget->OnMouseEvent(&move2);
20587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, v1->GetEventCount(ui::ET_MOUSE_ENTERED));
20597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, v2->GetEventCount(ui::ET_MOUSE_ENTERED));
20607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, v1->GetEventCount(ui::ET_MOUSE_EXITED));
20617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, v2->GetEventCount(ui::ET_MOUSE_EXITED));
20627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
20637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
20647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
20652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Used by SingleWindowClosing to count number of times WindowClosing() has
20662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// been invoked.
20672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ClosingDelegate : public WidgetDelegate {
20682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
20692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ClosingDelegate() : count_(0), widget_(NULL) {}
20702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int count() const { return count_; }
20722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void set_widget(views::Widget* widget) { widget_ = widget; }
20742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // WidgetDelegate overrides:
20762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual Widget* GetWidget() OVERRIDE { return widget_; }
20772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual const Widget* GetWidget() const OVERRIDE { return widget_; }
20782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void WindowClosing() OVERRIDE {
20792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    count_++;
20802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
20812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
20832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int count_;
20842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  views::Widget* widget_;
20852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ClosingDelegate);
20872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
20882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Verifies WindowClosing() is invoked correctly on the delegate when a Widget
20902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// is closed.
20912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetTest, SingleWindowClosing) {
20922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ClosingDelegate> delegate(new ClosingDelegate());
20932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* widget = new Widget();  // Destroyed by CloseNow() below.
20942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams init_params =
20952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateParams(Widget::InitParams::TYPE_WINDOW);
20962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.bounds = gfx::Rect(0, 0, 200, 200);
20972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.delegate = delegate.get();
20982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_AURA) && !defined(OS_CHROMEOS)
20992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.native_widget = new DesktopNativeWidgetAura(widget);
21002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
21012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->Init(init_params);
21022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, delegate->count());
21032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->CloseNow();
21042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, delegate->count());
21052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
21062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Used by SetTopLevelCorrectly to track calls to OnBeforeWidgetInit().
21082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class VerifyTopLevelDelegate : public TestViewsDelegate {
21092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
21102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyTopLevelDelegate()
21112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : on_before_init_called_(false),
21122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        is_top_level_(false) {
21132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
21142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool on_before_init_called() const { return on_before_init_called_; }
21162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_top_level() const { return is_top_level_; }
21172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnBeforeWidgetInit(
21192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Widget::InitParams* params,
21202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      internal::NativeWidgetDelegate* delegate) OVERRIDE {
21212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    on_before_init_called_ = true;
21222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    is_top_level_ = params->top_level;
21232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
21242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
21262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool on_before_init_called_;
21272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_top_level_;
21282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(VerifyTopLevelDelegate);
21302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
21312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Verifies |top_level| is correctly passed to
21332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ViewsDelegate::OnBeforeWidgetInit().
21342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetTest, SetTopLevelCorrectly) {
21352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  set_views_delegate(NULL);
21362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyTopLevelDelegate* delegate = new VerifyTopLevelDelegate;
21372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  set_views_delegate(delegate);  // ViewsTestBase takes ownership.
21382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Widget> widget(new Widget);
21392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params =
21402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateParams(views::Widget::InitParams::TYPE_POPUP);
21412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
21422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->Init(params);
21432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(delegate->on_before_init_called());
21442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(delegate->is_top_level());
21452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
21462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// A scumbag View that deletes its owning widget OnMousePressed.
2148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class WidgetDeleterView : public View {
2149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
2150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  WidgetDeleterView() : View() {}
2151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Overridden from View.
2153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE {
2154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    delete GetWidget();
2155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
2156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
2157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
2159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WidgetDeleterView);
2160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
2161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WidgetTest, TestWidgetDeletedInOnMousePressed) {
2163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Widget* widget = new Widget;
2164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Widget::InitParams params =
2165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CreateParams(views::Widget::InitParams::TYPE_POPUP);
2166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
2167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget->Init(params);
2168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget->SetContentsView(new WidgetDeleterView);
2170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget->SetSize(gfx::Size(100, 100));
2172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget->Show();
2173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Point click_location(45, 15);
2175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ui::MouseEvent press(ui::ET_MOUSE_PRESSED, click_location, click_location,
2176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ui::EF_LEFT_MOUSE_BUTTON);
2177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget->OnMouseEvent(&press);
2178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Yay we did not crash!
2180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2182558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// See description of RunGetNativeThemeFromDestructor() for details.
2183558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochclass GetNativeThemeFromDestructorView : public WidgetDelegateView {
2184558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch public:
2185558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  GetNativeThemeFromDestructorView() {}
2186558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  virtual ~GetNativeThemeFromDestructorView() {
2187558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    VerifyNativeTheme();
2188558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
2189558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
2190558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  virtual View* GetContentsView() OVERRIDE {
2191558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return this;
2192558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
2193558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
2194558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch private:
2195558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  void VerifyNativeTheme() {
2196558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    ASSERT_TRUE(GetNativeTheme() != NULL);
2197558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
2198558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
2199558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(GetNativeThemeFromDestructorView);
2200558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch};
2201558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
2202558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// Verifies GetNativeTheme() from the destructor of a WidgetDelegateView doesn't
2203558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// crash. |is_first_run| is true if this is the first call. A return value of
2204558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// true indicates this should be run again with a value of false.
2205558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// First run uses DesktopNativeWidgetAura (if possible). Second run doesn't.
2206558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochbool RunGetNativeThemeFromDestructor(const Widget::InitParams& in_params,
2207558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                     bool is_first_run) {
2208558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  bool needs_second_run = false;
2209558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Destroyed by CloseNow() below.
2210558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  Widget* widget = new Widget;
2211558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  Widget::InitParams params(in_params);
2212558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Deletes itself when the Widget is destroyed.
2213558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  params.delegate = new GetNativeThemeFromDestructorView;
2214558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#if defined(USE_AURA) && !defined(OS_CHROMEOS)
2215558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (is_first_run) {
2216558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    params.native_widget = new DesktopNativeWidgetAura(widget);
2217558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    needs_second_run = true;
2218558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
2219558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#endif
2220558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  widget->Init(params);
2221558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  widget->CloseNow();
2222558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return needs_second_run;
2223558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
2224558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
2225558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// See description of RunGetNativeThemeFromDestructor() for details.
2226558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_F(WidgetTest, GetNativeThemeFromDestructor) {
2227558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
2228558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (RunGetNativeThemeFromDestructor(params, true))
2229558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    RunGetNativeThemeFromDestructor(params, false);
2230558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
2231558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
2232a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Used by HideCloseDestroy. Allows setting a boolean when the widget is
2233a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// destroyed.
2234a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)class CloseDestroysWidget : public Widget {
2235a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) public:
2236a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  explicit CloseDestroysWidget(bool* destroyed)
2237a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      : destroyed_(destroyed) {
2238a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
2239a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2240a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  virtual ~CloseDestroysWidget() {
2241a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (destroyed_) {
2242a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      *destroyed_ = true;
2243a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      base::MessageLoop::current()->QuitNow();
2244a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
2245a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
2246a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2247a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  void Detach() { destroyed_ = NULL; }
2248a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2249a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) private:
2250a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // If non-null set to true from destructor.
2251a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  bool* destroyed_;
2252a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2253a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CloseDestroysWidget);
2254a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)};
2255a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2256a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Verifies Close() results in destroying.
2257a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(WidgetTest, CloseDestroys) {
2258a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  bool destroyed = false;
2259a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CloseDestroysWidget* widget = new CloseDestroysWidget(&destroyed);
2260a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Widget::InitParams params =
2261a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      CreateParams(views::Widget::InitParams::TYPE_MENU);
2262a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  params.opacity = Widget::InitParams::OPAQUE_WINDOW;
2263a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#if defined(USE_AURA) && !defined(OS_CHROMEOS)
2264a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  params.native_widget = new DesktopNativeWidgetAura(widget);
2265a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#endif
2266a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->Init(params);
2267a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->Show();
2268a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->Hide();
2269a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->Close();
2270a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Run the message loop as Close() asynchronously deletes.
2271a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  RunPendingMessages();
2272a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_TRUE(destroyed);
2273a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Close() should destroy the widget. If not we'll cleanup to avoid leaks.
2274a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!destroyed) {
2275a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    widget->Detach();
2276a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    widget->CloseNow();
2277a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
2278a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
2279a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2280a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// A view that consumes mouse-pressed event and gesture-tap-down events.
2281a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)class RootViewTestView : public View {
2282a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) public:
2283a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  RootViewTestView(): View() {}
2284a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2285a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) private:
2286a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE {
2287a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return true;
2288a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
2289a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2290a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
2291a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (event->type() == ui::ET_GESTURE_TAP_DOWN)
2292a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      event->SetHandled();
2293a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
2294a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)};
2295a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2296a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Checks if RootView::*_handler_ fields are unset when widget is hidden.
22973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Fails on chromium.webkit Windows bot, see crbug.com/264872.
22983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(OS_WIN)
22993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#define MAYBE_DisableTestRootViewHandlersWhenHidden\
23003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    DISABLED_TestRootViewHandlersWhenHidden
23013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#else
23023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#define MAYBE_DisableTestRootViewHandlersWhenHidden\
23033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    TestRootViewHandlersWhenHidden
23043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif
23053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_F(WidgetTest, MAYBE_DisableTestRootViewHandlersWhenHidden) {
2306a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Widget* widget = CreateTopLevelNativeWidget();
2307a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->SetBounds(gfx::Rect(0, 0, 300, 300));
2308a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  View* view = new RootViewTestView();
2309a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  view->SetBounds(0, 0, 300, 300);
2310a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  internal::RootView* root_view =
2311a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      static_cast<internal::RootView*>(widget->GetRootView());
2312a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  root_view->AddChildView(view);
2313a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2314a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Check RootView::mouse_pressed_handler_.
2315a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->Show();
2316a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(NULL, GetMousePressedHandler(root_view));
2317a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  gfx::Point click_location(45, 15);
2318a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ui::MouseEvent press(ui::ET_MOUSE_PRESSED, click_location, click_location,
2319a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      ui::EF_LEFT_MOUSE_BUTTON);
2320a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->OnMouseEvent(&press);
2321a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(view, GetMousePressedHandler(root_view));
2322a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->Hide();
2323a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(NULL, GetMousePressedHandler(root_view));
2324a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2325a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Check RootView::mouse_move_handler_.
2326a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->Show();
2327a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(NULL, GetMouseMoveHandler(root_view));
2328a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  gfx::Point move_location(45, 15);
2329a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ui::MouseEvent move(ui::ET_MOUSE_MOVED, move_location, move_location, 0);
2330a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->OnMouseEvent(&move);
2331a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(view, GetMouseMoveHandler(root_view));
2332a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->Hide();
2333a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(NULL, GetMouseMoveHandler(root_view));
2334a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2335a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Check RootView::gesture_handler_.
2336a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->Show();
2337a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(NULL, GetGestureHandler(root_view));
2338a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ui::GestureEvent tap_down(
2339a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      ui::ET_GESTURE_TAP_DOWN,
2340a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      15,
2341a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      15,
2342a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      0,
2343a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      base::TimeDelta(),
2344a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      ui::GestureEventDetails(ui::ET_GESTURE_TAP_DOWN, 0, 0),
2345a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      1);
2346a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->OnGestureEvent(&tap_down);
2347a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(view, GetGestureHandler(root_view));
2348a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->Hide();
2349a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(NULL, GetGestureHandler(root_view));
2350a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2351a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  widget->Close();
2352a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
2353a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
23543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Test the result of Widget::GetAllChildWidgets().
23553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_F(WidgetTest, GetAllChildWidgets) {
23563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Create the following widget hierarchy:
23573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  //
23583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // toplevel
23593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // +-- w1
23603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  //     +-- w11
23613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // +-- w2
23623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  //     +-- w21
23633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  //     +-- w22
23643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
23653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Widget* w1 = CreateChildPlatformWidget(toplevel->GetNativeView());
23663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Widget* w11 = CreateChildPlatformWidget(w1->GetNativeView());
23673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Widget* w2 = CreateChildPlatformWidget(toplevel->GetNativeView());
23683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Widget* w21 = CreateChildPlatformWidget(w2->GetNativeView());
23693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Widget* w22 = CreateChildPlatformWidget(w2->GetNativeView());
23703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
23713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::set<Widget*> expected;
23723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  expected.insert(toplevel);
23733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  expected.insert(w1);
23743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  expected.insert(w11);
23753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  expected.insert(w2);
23763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  expected.insert(w21);
23773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  expected.insert(w22);
23783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
23793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::set<Widget*> widgets;
23803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Widget::GetAllChildWidgets(toplevel->GetNativeView(), &widgets);
23813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
23823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(expected.size(), widgets.size());
23833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(std::equal(expected.begin(), expected.end(), widgets.begin()));
23843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
23853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2386a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}  // namespace test
23875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace views
2388