widget_unittest.cc revision 558790d6acca3451cf3a6b497803a5f07d0bec58
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)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
67dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/bind.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
8ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h"
97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/run_loop.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/events/event_utils.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/native_widget_types.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/point.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/bubble/bubble_delegate.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/textfield/textfield.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/test/test_views_delegate.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/test/views_test_base.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/views_delegate.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/native_widget_delegate.h"
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/views/window/native_frame_view.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_AURA)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/client/aura_constants.h"
257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "ui/aura/env.h"
267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/aura/root_window.h"
277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/aura/test/test_cursor_client.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/test/test_window_delegate.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/native_widget_aura.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_CHROMEOS)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/native_widget_win.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A generic typedef to pick up relevant NativeWidget implementations.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_AURA)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef NativeWidgetAura NativeWidgetPlatform;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef NativeWidgetWin NativeWidgetPlatform;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A widget that assumes mouse capture always works. It won't on Aura in
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// testing, so we mock it.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_AURA)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NativeWidgetCapture : public NativeWidgetPlatform {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit NativeWidgetCapture(internal::NativeWidgetDelegate* delegate)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : NativeWidgetPlatform(delegate),
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mouse_capture_(false) {}
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~NativeWidgetCapture() {}
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetCapture() OVERRIDE {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mouse_capture_ = true;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ReleaseCapture() OVERRIDE {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (mouse_capture_)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate()->OnMouseCaptureLost();
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mouse_capture_ = false;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool HasCapture() const OVERRIDE {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return mouse_capture_;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool mouse_capture_;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NativeWidgetCapture);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A typedef that inserts our mock-capture NativeWidget implementation for
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// relevant platforms.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_AURA)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef NativeWidgetCapture NativeWidgetPlatformForTest;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef NativeWidgetWin NativeWidgetPlatformForTest;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A view that always processes all mouse events.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MouseView : public View {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MouseView()
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : View(),
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        entered_(0),
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        exited_(0),
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pressed_(0) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~MouseView() {}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pressed_++;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entered_++;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exited_++;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return the number of OnMouseEntered calls and reset the counter.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int EnteredCalls() {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i = entered_;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entered_ = 0;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return i;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return the number of OnMouseExited calls and reset the counter.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ExitedCalls() {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i = exited_;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exited_ = 0;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return i;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pressed() const { return pressed_; }
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int entered_;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int exited_;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pressed_;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MouseView);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A view that keeps track of the events it receives, but consumes no events.
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class EventCountView : public View {
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EventCountView() {}
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~EventCountView() {}
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int GetEventCount(ui::EventType type) {
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return event_count_[type];
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ResetCounts() {
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event_count_.clear();
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from ui::EventHandler:
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE {
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RecordEvent(*event);
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RecordEvent(*event);
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE {
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RecordEvent(*event);
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE {
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RecordEvent(*event);
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RecordEvent(*event);
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void RecordEvent(const ui::Event& event) {
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ++event_count_[event.type()];
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::map<ui::EventType, int> event_count_;
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(EventCountView);
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A view that keeps track of the events it receives, and consumes all scroll
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// gesture events.
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ScrollableEventCountView : public EventCountView {
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScrollableEventCountView() {}
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~ScrollableEventCountView() {}
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from ui::EventHandler:
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EventCountView::OnGestureEvent(event);
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    switch (event->type()) {
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case ui::ET_GESTURE_SCROLL_BEGIN:
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case ui::ET_GESTURE_SCROLL_UPDATE:
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case ui::ET_GESTURE_SCROLL_END:
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case ui::ET_SCROLL_FLING_START:
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        event->SetHandled();
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      default:
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ScrollableEventCountView);
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A view that does a capture on gesture-begin events.
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GestureCaptureView : public View {
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GestureCaptureView() {}
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~GestureCaptureView() {}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from View:
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event->type() == ui::ET_GESTURE_BEGIN) {
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetWidget()->SetCapture(this);
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      event->StopPropagation();
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(GestureCaptureView);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// A view that implements GetMinimumSize.
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MinimumSizeFrameView : public NativeFrameView {
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  explicit MinimumSizeFrameView(Widget* frame): NativeFrameView(frame) {}
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~MinimumSizeFrameView() {}
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Overridden from View:
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual gfx::Size GetMinimumSize() OVERRIDE {
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return gfx::Size(300, 400);
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MinimumSizeFrameView);
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// An event handler that simply keeps a count of the different types of events
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// it receives.
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class EventCountHandler : public ui::EventHandler {
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EventCountHandler() {}
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~EventCountHandler() {}
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int GetEventCount(ui::EventType type) {
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return event_count_[type];
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ResetCounts() {
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event_count_.clear();
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from ui::EventHandler:
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnEvent(ui::Event* event) OVERRIDE {
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RecordEvent(*event);
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::EventHandler::OnEvent(event);
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void RecordEvent(const ui::Event& event) {
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ++event_count_[event.type()];
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::map<ui::EventType, int> event_count_;
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(EventCountHandler);
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// A View that shows a different widget, sets capture on that widget, and
2687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// initiates a nested message-loop when it receives a mouse-press event.
2697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochclass NestedLoopCaptureView : public View {
2707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch public:
2717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  explicit NestedLoopCaptureView(Widget* widget) : widget_(widget) {}
2727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual ~NestedLoopCaptureView() {}
2737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch private:
2757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Overridden from View:
2767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE {
2777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // Start a nested loop.
2787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    widget_->Show();
2797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    widget_->SetCapture(widget_->GetContentsView());
2807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    EXPECT_TRUE(widget_->HasCapture());
2817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
2837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    base::MessageLoop::ScopedNestableTaskAllower allow(loop);
2847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    base::RunLoop run_loop;
2867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#if defined(USE_AURA)
2877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    run_loop.set_dispatcher(aura::Env::GetInstance()->GetDispatcher());
2887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif
2897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    run_loop.Run();
2907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return true;
2917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  Widget* widget_;
2947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(NestedLoopCaptureView);
2967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch};
2977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// A View that closes the Widget and exits the current message-loop when it
2997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// receives a mouse-release event.
3007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochclass ExitLoopOnRelease : public View {
3017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch public:
3027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ExitLoopOnRelease() {}
3037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual ~ExitLoopOnRelease() {}
3047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch private:
3067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Overridden from View:
3077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE {
3087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    GetWidget()->Close();
3097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    base::MessageLoop::current()->QuitNow();
3107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
3117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(ExitLoopOnRelease);
3137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch};
3147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class WidgetTest : public ViewsTestBase {
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WidgetTest() {}
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~WidgetTest() {}
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NativeWidget* CreatePlatformNativeWidget(
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      internal::NativeWidgetDelegate* delegate) {
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return new NativeWidgetPlatformForTest(delegate);
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* CreateTopLevelPlatformWidget() {
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Widget* toplevel = new Widget;
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Widget::InitParams toplevel_params =
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CreateParams(Widget::InitParams::TYPE_WINDOW);
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    toplevel_params.native_widget = CreatePlatformNativeWidget(toplevel);
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    toplevel->Init(toplevel_params);
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return toplevel;
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* CreateTopLevelFramelessPlatformWidget() {
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Widget* toplevel = new Widget;
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Widget::InitParams toplevel_params =
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    toplevel_params.native_widget = CreatePlatformNativeWidget(toplevel);
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    toplevel->Init(toplevel_params);
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return toplevel;
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* CreateChildPlatformWidget(gfx::NativeView parent_native_view) {
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Widget* child = new Widget;
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Widget::InitParams child_params =
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CreateParams(Widget::InitParams::TYPE_CONTROL);
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child_params.native_widget = CreatePlatformNativeWidget(child);
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child_params.parent = parent_native_view;
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child->Init(child_params);
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child->SetContentsView(new View);
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return child;
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) && !defined(USE_AURA)
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // On Windows, it is possible for us to have a child window that is
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TYPE_POPUP.
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* CreateChildPopupPlatformWidget(gfx::NativeView parent_native_view) {
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Widget* child = new Widget;
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Widget::InitParams child_params =
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CreateParams(Widget::InitParams::TYPE_POPUP);
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child_params.child = true;
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child_params.native_widget = CreatePlatformNativeWidget(child);
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child_params.parent = parent_native_view;
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child->Init(child_params);
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child->SetContentsView(new View);
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return child;
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* CreateTopLevelNativeWidget() {
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Widget* toplevel = new Widget;
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    toplevel->Init(params);
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return toplevel;
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* CreateChildNativeWidgetWithParent(Widget* parent) {
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Widget* child = new Widget;
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_CONTROL);
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.parent = parent->GetNativeView();
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child->Init(params);
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child->SetContentsView(new View);
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return child;
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* CreateChildNativeWidget() {
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return CreateChildNativeWidgetWithParent(NULL);
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WidgetHasMouseCapture(const Widget* widget) {
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<const internal::NativeWidgetPrivate*>(widget->
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      native_widget())->HasCapture();
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::WindowShowState GetWidgetShowState(const Widget* widget) {
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use IsMaximized/IsMinimized/IsFullScreen instead of GetWindowPlacement
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // because the former is implemented on all platforms but the latter is not.
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return widget->IsFullscreen() ? ui::SHOW_STATE_FULLSCREEN :
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget->IsMaximized() ? ui::SHOW_STATE_MAXIMIZED :
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget->IsMinimized() ? ui::SHOW_STATE_MINIMIZED :
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              ui::SHOW_STATE_NORMAL;
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, WidgetInitParams) {
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(views_delegate().UseTransparentWindows());
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Widgets are not transparent by default.
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget::InitParams init1;
410eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(Widget::InitParams::INFER_OPACITY, init1.opacity);
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Non-window widgets are not transparent either.
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget::InitParams init2(Widget::InitParams::TYPE_MENU);
414eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(Widget::InitParams::INFER_OPACITY, init2.opacity);
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A ViewsDelegate can set windows transparent by default.
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views_delegate().SetUseTransparentWindows(true);
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget::InitParams init3;
419eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(Widget::InitParams::TRANSLUCENT_WINDOW, init3.opacity);
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Non-window widgets stay opaque.
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget::InitParams init4(Widget::InitParams::TYPE_MENU);
423eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(Widget::InitParams::INFER_OPACITY, init4.opacity);
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Widget::GetTopLevelWidget tests.
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, GetTopLevelWidget_Native) {
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a hierarchy of native widgets.
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::NativeView parent = toplevel->GetNativeView();
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* child = CreateChildPlatformWidget(parent);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(toplevel, toplevel->GetTopLevelWidget());
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(toplevel, child->GetTopLevelWidget());
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |child| should be automatically destroyed with |toplevel|.
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests some grab/ungrab events.
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, DISABLED_GrabUngrab) {
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* child1 = CreateChildNativeWidgetWithParent(toplevel);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* child2 = CreateChildNativeWidgetWithParent(toplevel);
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->SetBounds(gfx::Rect(0, 0, 500, 500));
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child1->SetBounds(gfx::Rect(10, 10, 300, 300));
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  View* view = new MouseView();
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view->SetBounds(0, 0, 300, 300);
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child1->GetRootView()->AddChildView(view);
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child2->SetBounds(gfx::Rect(200, 10, 200, 200));
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view = new MouseView();
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view->SetBounds(0, 0, 200, 200);
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child2->GetRootView()->AddChildView(view);
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Show();
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Click on child1
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point p1(45, 45);
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, p1, p1,
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         ui::EF_LEFT_MOUSE_BUTTON);
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnMouseEvent(&pressed);
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(WidgetHasMouseCapture(toplevel));
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(WidgetHasMouseCapture(child1));
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(WidgetHasMouseCapture(child2));
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::MouseEvent released(ui::ET_MOUSE_RELEASED, p1, p1,
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          ui::EF_LEFT_MOUSE_BUTTON);
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnMouseEvent(&released);
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(WidgetHasMouseCapture(toplevel));
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(WidgetHasMouseCapture(child1));
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(WidgetHasMouseCapture(child2));
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Click on child2
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point p2(315, 45);
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::MouseEvent pressed2(ui::ET_MOUSE_PRESSED, p2, p2,
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          ui::EF_LEFT_MOUSE_BUTTON);
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnMouseEvent(&pressed2);
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(pressed2.handled());
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(WidgetHasMouseCapture(toplevel));
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(WidgetHasMouseCapture(child2));
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(WidgetHasMouseCapture(child1));
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::MouseEvent released2(ui::ET_MOUSE_RELEASED, p2, p2,
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           ui::EF_LEFT_MOUSE_BUTTON);
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnMouseEvent(&released2);
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(WidgetHasMouseCapture(toplevel));
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(WidgetHasMouseCapture(child1));
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(WidgetHasMouseCapture(child2));
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests mouse move outside of the window into the "resize controller" and back
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// will still generate an OnMouseEntered and OnMouseExited event..
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, CheckResizeControllerEvents) {
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->SetBounds(gfx::Rect(0, 0, 100, 100));
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MouseView* view = new MouseView();
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view->SetBounds(90, 90, 10, 10);
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->GetRootView()->AddChildView(view);
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Show();
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move to an outside position.
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point p1(200, 200);
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::MouseEvent moved_out(ui::ET_MOUSE_MOVED, p1, p1, ui::EF_NONE);
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnMouseEvent(&moved_out);
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, view->EnteredCalls());
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, view->ExitedCalls());
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move onto the active view.
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point p2(95, 95);
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::MouseEvent moved_over(ui::ET_MOUSE_MOVED, p2, p2, ui::EF_NONE);
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnMouseEvent(&moved_over);
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, view->EnteredCalls());
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, view->ExitedCalls());
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move onto the outer resizing border.
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point p3(102, 95);
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::MouseEvent moved_resizer(ui::ET_MOUSE_MOVED, p3, p3, ui::EF_NONE);
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnMouseEvent(&moved_resizer);
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, view->EnteredCalls());
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, view->ExitedCalls());
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move onto the view again.
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnMouseEvent(&moved_over);
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, view->EnteredCalls());
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, view->ExitedCalls());
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test if a focus manager and an inputmethod work without CHECK failure
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// when window activation changes.
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, ChangeActivation) {
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* top1 = CreateTopLevelPlatformWidget();
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CreateInputMethod before activated
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top1->GetInputMethod();
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top1->Show();
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* top2 = CreateTopLevelPlatformWidget();
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top2->Show();
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top1->Activate();
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create InputMethod after deactivated.
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top2->GetInputMethod();
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top2->Activate();
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top1->Activate();
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top1->CloseNow();
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top2->CloseNow();
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests visibility of child widgets.
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, Visibility) {
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::NativeView parent = toplevel->GetNativeView();
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* child = CreateChildPlatformWidget(parent);
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(toplevel->IsVisible());
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(child->IsVisible());
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child->Show();
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(toplevel->IsVisible());
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(child->IsVisible());
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Show();
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(toplevel->IsVisible());
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(child->IsVisible());
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |child| should be automatically destroyed with |toplevel|.
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) && !defined(USE_AURA)
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// On Windows, it is possible to have child window that are TYPE_POPUP.  Unlike
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// regular child windows, these should be created as hidden and must be shown
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// explicitly.
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, Visibility_ChildPopup) {
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* child_popup = CreateChildPopupPlatformWidget(
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      toplevel->GetNativeView());
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(toplevel->IsVisible());
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(child_popup->IsVisible());
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Show();
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(toplevel->IsVisible());
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(child_popup->IsVisible());
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child_popup->Show();
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(child_popup->IsVisible());
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |child_popup| should be automatically destroyed with |toplevel|.
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Widget ownership tests.
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests various permutations of Widget ownership specified in the
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// InitParams::Ownership param.
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A WidgetTest that supplies a toplevel widget for NativeWidget to parent to.
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WidgetOwnershipTest : public WidgetTest {
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WidgetOwnershipTest() {}
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~WidgetOwnershipTest() {}
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WidgetTest::SetUp();
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    desktop_widget_ = CreateTopLevelPlatformWidget();
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    desktop_widget_->CloseNow();
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WidgetTest::TearDown();
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* desktop_widget_;
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WidgetOwnershipTest);
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A bag of state to monitor destructions.
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct OwnershipTestState {
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState() : widget_deleted(false), native_widget_deleted(false) {}
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool widget_deleted;
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool native_widget_deleted;
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A platform NativeWidget subclass that updates a bag of state when it is
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destroyed.
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OwnershipTestNativeWidget : public NativeWidgetPlatform {
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestNativeWidget(internal::NativeWidgetDelegate* delegate,
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            OwnershipTestState* state)
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : NativeWidgetPlatform(delegate),
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        state_(state) {
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~OwnershipTestNativeWidget() {
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state_->native_widget_deleted = true;
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState* state_;
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OwnershipTestNativeWidget);
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A views NativeWidget subclass that updates a bag of state when it is
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destroyed.
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OwnershipTestNativeWidgetPlatform : public NativeWidgetPlatformForTest {
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestNativeWidgetPlatform(internal::NativeWidgetDelegate* delegate,
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    OwnershipTestState* state)
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : NativeWidgetPlatformForTest(delegate),
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        state_(state) {
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~OwnershipTestNativeWidgetPlatform() {
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state_->native_widget_deleted = true;
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState* state_;
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OwnershipTestNativeWidgetPlatform);
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A Widget subclass that updates a bag of state when it is destroyed.
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OwnershipTestWidget : public Widget {
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit OwnershipTestWidget(OwnershipTestState* state) : state_(state) {}
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~OwnershipTestWidget() {
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state_->widget_deleted = true;
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState* state_;
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OwnershipTestWidget);
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Widget owns its NativeWidget, part 1: NativeWidget is a platform-native
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// widget.
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetOwnershipTest, Ownership_WidgetOwnsPlatformNativeWidget) {
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState state;
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.native_widget =
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new OwnershipTestNativeWidgetPlatform(widget.get(), &state);
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now delete the Widget, which should delete the NativeWidget.
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget.reset();
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.widget_deleted);
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.native_widget_deleted);
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(beng): write test for this ownership scenario and the NativeWidget
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //             being deleted out from under the Widget.
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Widget owns its NativeWidget, part 2: NativeWidget is a NativeWidget.
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetOwnershipTest, Ownership_WidgetOwnsViewsNativeWidget) {
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState state;
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.native_widget =
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new OwnershipTestNativeWidgetPlatform(widget.get(), &state);
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now delete the Widget, which should delete the NativeWidget.
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget.reset();
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.widget_deleted);
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.native_widget_deleted);
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(beng): write test for this ownership scenario and the NativeWidget
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //             being deleted out from under the Widget.
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Widget owns its NativeWidget, part 3: NativeWidget is a NativeWidget,
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destroy the parent view.
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetOwnershipTest,
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       Ownership_WidgetOwnsViewsNativeWidget_DestroyParentView) {
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState state;
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.native_widget =
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new OwnershipTestNativeWidgetPlatform(widget.get(), &state);
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.parent = toplevel->GetNativeView();
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now close the toplevel, which deletes the view hierarchy.
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This shouldn't delete the widget because it shouldn't be deleted
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from the native side.
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(state.widget_deleted);
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(state.native_widget_deleted);
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now delete it explicitly.
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget.reset();
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.widget_deleted);
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.native_widget_deleted);
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NativeWidget owns its Widget, part 1: NativeWidget is a platform-native
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// widget.
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetOwnershipTest, Ownership_PlatformNativeWidgetOwnsWidget) {
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState state;
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget = new OwnershipTestWidget(&state);
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.native_widget =
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new OwnershipTestNativeWidgetPlatform(widget, &state);
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now destroy the native widget.
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->CloseNow();
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.widget_deleted);
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.native_widget_deleted);
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NativeWidget owns its Widget, part 2: NativeWidget is a NativeWidget.
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetOwnershipTest, Ownership_ViewsNativeWidgetOwnsWidget) {
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState state;
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget = new OwnershipTestWidget(&state);
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.native_widget =
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new OwnershipTestNativeWidgetPlatform(widget, &state);
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.parent = toplevel->GetNativeView();
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now destroy the native widget. This is achieved by closing the toplevel.
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The NativeWidget won't be deleted until after a return to the message loop
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so we have to run pending messages before testing the destruction status.
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.widget_deleted);
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.native_widget_deleted);
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NativeWidget owns its Widget, part 3: NativeWidget is a platform-native
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// widget, destroyed out from under it by the OS.
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetOwnershipTest,
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       Ownership_PlatformNativeWidgetOwnsWidget_NativeDestroy) {
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState state;
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget = new OwnershipTestWidget(&state);
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.native_widget =
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new OwnershipTestNativeWidgetPlatform(widget, &state);
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now simulate a destroy of the platform native widget from the OS:
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_AURA)
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete widget->GetNativeView();
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN)
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DestroyWindow(widget->GetNativeView());
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.widget_deleted);
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.native_widget_deleted);
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NativeWidget owns its Widget, part 4: NativeWidget is a NativeWidget,
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destroyed by the view hierarchy that contains it.
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetOwnershipTest,
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       Ownership_ViewsNativeWidgetOwnsWidget_NativeDestroy) {
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState state;
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget = new OwnershipTestWidget(&state);
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.native_widget =
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new OwnershipTestNativeWidgetPlatform(widget, &state);
8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.parent = toplevel->GetNativeView();
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Destroy the widget (achieved by closing the toplevel).
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The NativeWidget won't be deleted until after a return to the message loop
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so we have to run pending messages before testing the destruction status.
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.widget_deleted);
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.native_widget_deleted);
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NativeWidget owns its Widget, part 5: NativeWidget is a NativeWidget,
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// we close it directly.
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetOwnershipTest,
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       Ownership_ViewsNativeWidgetOwnsWidget_Close) {
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwnershipTestState state;
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget = new OwnershipTestWidget(&state);
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.native_widget =
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new OwnershipTestNativeWidgetPlatform(widget, &state);
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.parent = toplevel->GetNativeView();
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Destroy the widget.
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Close();
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The NativeWidget won't be deleted until after a return to the message loop
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so we have to run pending messages before testing the destruction status.
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.widget_deleted);
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.native_widget_deleted);
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Widget owns its NativeWidget and has a WidgetDelegateView as its contents.
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetOwnershipTest,
9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       Ownership_WidgetOwnsNativeWidgetWithWithWidgetDelegateView) {
9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OwnershipTestState state;
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WidgetDelegateView* delegate_view = new WidgetDelegateView;
9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.native_widget =
9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new OwnershipTestNativeWidgetPlatform(widget.get(), &state);
9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.delegate = delegate_view;
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->Init(params);
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->SetContentsView(delegate_view);
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now delete the Widget. There should be no crash or use-after-free.
9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.reset();
9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(state.widget_deleted);
9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(state.native_widget_deleted);
9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Widget observer tests.
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class WidgetObserverTest : public WidgetTest, public WidgetObserver {
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WidgetObserverTest()
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : active_(NULL),
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        widget_closed_(NULL),
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        widget_activated_(NULL),
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        widget_shown_(NULL),
9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        widget_hidden_(NULL),
9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        widget_bounds_changed_(NULL) {
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~WidgetObserverTest() {}
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from WidgetObserver:
9482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWidgetDestroying(Widget* widget) OVERRIDE {
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (active_ == widget)
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      active_ = NULL;
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    widget_closed_ = widget;
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWidgetActivationChanged(Widget* widget,
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         bool active) OVERRIDE {
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (active) {
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (widget_activated_)
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        widget_activated_->Deactivate();
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget_activated_ = widget;
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      active_ = widget;
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (widget_activated_ == widget)
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        widget_activated_ = NULL;
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget_deactivated_ = widget;
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWidgetVisibilityChanged(Widget* widget,
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         bool visible) OVERRIDE {
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (visible)
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget_shown_ = widget;
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget_hidden_ = widget;
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWidgetBoundsChanged(Widget* widget,
9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     const gfx::Rect& new_bounds) OVERRIDE {
9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    widget_bounds_changed_ = widget;
9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void reset() {
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    active_ = NULL;
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    widget_closed_ = NULL;
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    widget_activated_ = NULL;
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    widget_deactivated_ = NULL;
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    widget_shown_ = NULL;
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    widget_hidden_ = NULL;
9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    widget_bounds_changed_ = NULL;
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* NewWidget() {
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Widget* widget = CreateTopLevelNativeWidget();
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    widget->AddObserver(this);
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return widget;
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Widget* active() const { return active_; }
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Widget* widget_closed() const { return widget_closed_; }
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Widget* widget_activated() const { return widget_activated_; }
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Widget* widget_deactivated() const { return widget_deactivated_; }
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Widget* widget_shown() const { return widget_shown_; }
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Widget* widget_hidden() const { return widget_hidden_; }
10032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Widget* widget_bounds_changed() const { return widget_bounds_changed_; }
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* active_;
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget_closed_;
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget_activated_;
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget_deactivated_;
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget_shown_;
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* widget_hidden_;
10132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* widget_bounds_changed_;
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetObserverTest, DISABLED_ActivationChange) {
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel1 = NewWidget();
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel2 = NewWidget();
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel1->Show();
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel2->Show();
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reset();
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel1->Activate();
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(toplevel1, widget_activated());
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel2->Activate();
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(toplevel1, widget_deactivated());
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(toplevel2, widget_activated());
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(toplevel2, active());
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetObserverTest, DISABLED_VisibilityChange) {
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* child1 = NewWidget();
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* child2 = NewWidget();
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Show();
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child1->Show();
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child2->Show();
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reset();
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child1->Hide();
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child1, widget_hidden());
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child2->Hide();
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child2, widget_hidden());
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child1->Show();
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child1, widget_shown());
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child2->Show();
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child2, widget_shown());
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->CloseNow();
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetObserverTest, DestroyBubble) {
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* anchor = CreateTopLevelPlatformWidget();
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  anchor->Show();
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BubbleDelegateView* bubble_delegate =
10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new BubbleDelegateView(anchor->client_view(), BubbleBorder::NONE);
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* bubble_widget(BubbleDelegateView::CreateBubble(bubble_delegate));
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bubble_widget->Show();
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bubble_widget->CloseNow();
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  anchor->Hide();
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  anchor->CloseNow();
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetObserverTest, WidgetBoundsChanged) {
10832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* child1 = NewWidget();
10842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* child2 = NewWidget();
10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child1->OnNativeWidgetMove();
10872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(child1, widget_bounds_changed());
10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->OnNativeWidgetMove();
10902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(child2, widget_bounds_changed());
10912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child1->OnNativeWidgetSizeChanged(gfx::Size());
10932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(child1, widget_bounds_changed());
10942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->OnNativeWidgetSizeChanged(gfx::Size());
10962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(child2, widget_bounds_changed());
10972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(USE_AURA) && defined(OS_WIN)
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Aura needs shell to maximize/fullscreen window.
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NativeWidgetGtk doesn't implement GetRestoredBounds.
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, GetRestoredBounds) {
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(toplevel->GetWindowBoundsInScreen().ToString(),
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            toplevel->GetRestoredBounds().ToString());
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Show();
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Maximize();
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(toplevel->GetWindowBoundsInScreen().ToString(),
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            toplevel->GetRestoredBounds().ToString());
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(toplevel->GetRestoredBounds().width(), 0);
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(toplevel->GetRestoredBounds().height(), 0);
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Restore();
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(toplevel->GetWindowBoundsInScreen().ToString(),
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            toplevel->GetRestoredBounds().ToString());
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->SetFullscreen(true);
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(toplevel->GetWindowBoundsInScreen().ToString(),
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            toplevel->GetRestoredBounds().ToString());
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(toplevel->GetRestoredBounds().width(), 0);
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(toplevel->GetRestoredBounds().height(), 0);
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that window state is not changed after getting out of full screen.
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, ExitFullscreenRestoreState) {
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Show();
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should be a normal state window.
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ui::SHOW_STATE_NORMAL, GetWidgetShowState(toplevel));
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->SetFullscreen(true);
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (GetWidgetShowState(toplevel) != ui::SHOW_STATE_FULLSCREEN)
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunPendingMessages();
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->SetFullscreen(false);
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (GetWidgetShowState(toplevel) == ui::SHOW_STATE_FULLSCREEN)
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunPendingMessages();
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // And it should still be in normal state after getting out of full screen.
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ui::SHOW_STATE_NORMAL, GetWidgetShowState(toplevel));
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now, make it maximized.
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Maximize();
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (GetWidgetShowState(toplevel) != ui::SHOW_STATE_MAXIMIZED)
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunPendingMessages();
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->SetFullscreen(true);
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (GetWidgetShowState(toplevel) != ui::SHOW_STATE_FULLSCREEN)
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunPendingMessages();
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->SetFullscreen(false);
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (GetWidgetShowState(toplevel) == ui::SHOW_STATE_FULLSCREEN)
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunPendingMessages();
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // And it stays maximized after getting out of full screen.
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, GetWidgetShowState(toplevel));
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clean up.
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Close();
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Checks that if a mouse-press triggers a capture on a different widget (which
11697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// consumes the mouse-release event), then the target of the press does not have
11707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// capture.
11717dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochTEST_F(WidgetTest, CaptureWidgetFromMousePress) {
11727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // The test creates two widgets: |first| and |second|.
11737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // The View in |first| makes |second| visible, sets capture on it, and starts
11747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // a nested loop (like a menu does). The View in |second| terminates the
11757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // nested loop and closes the widget.
11767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // The test sends a mouse-press event to |first|, and posts a task to send a
11777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // release event to |second|, to make sure that the release event is
11787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // dispatched after the nested loop starts.
11797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
11807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  Widget* first = CreateTopLevelFramelessPlatformWidget();
11817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  Widget* second = CreateTopLevelFramelessPlatformWidget();
11827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
11837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  View* container = new NestedLoopCaptureView(second);
11847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  first->SetContentsView(container);
11857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
11867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  second->SetContentsView(new ExitLoopOnRelease());
11877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
11887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  first->SetSize(gfx::Size(100, 100));
11897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  first->Show();
11907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
11917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  gfx::Point location(20, 20);
11927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::MessageLoop::current()->PostTask(FROM_HERE,
11937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&Widget::OnMouseEvent,
11947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 base::Unretained(second),
11957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 base::Owned(new ui::MouseEvent(ui::ET_MOUSE_RELEASED,
11967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                                location,
11977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                                location,
11987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                                ui::EF_LEFT_MOUSE_BUTTON))));
11997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ui::MouseEvent press(ui::ET_MOUSE_PRESSED, location, location,
12007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                       ui::EF_LEFT_MOUSE_BUTTON);
12017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  first->OnMouseEvent(&press);
12027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(first->HasCapture());
12037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  first->Close();
12047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  RunPendingMessages();
12057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
12067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, ResetCaptureOnGestureEnd) {
12082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* toplevel = CreateTopLevelFramelessPlatformWidget();
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  View* container = new View;
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->SetContentsView(container);
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  View* gesture = new GestureCaptureView;
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gesture->SetBounds(0, 0, 30, 30);
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  container->AddChildView(gesture);
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MouseView* mouse = new MouseView;
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse->SetBounds(30, 0, 30, 30);
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  container->AddChildView(mouse);
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->SetSize(gfx::Size(100, 100));
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Show();
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start a gesture on |gesture|.
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::GestureEvent begin(ui::ET_GESTURE_BEGIN,
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      15, 15, 0, base::TimeDelta(),
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::GestureEventDetails(ui::ET_GESTURE_BEGIN, 0, 0), 1);
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::GestureEvent end(ui::ET_GESTURE_END,
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      15, 15, 0, base::TimeDelta(),
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::GestureEventDetails(ui::ET_GESTURE_END, 0, 0), 1);
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->OnGestureEvent(&begin);
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now try to click on |mouse|. Since |gesture| will have capture, |mouse|
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will not receive the event.
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point click_location(45, 15);
12352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::MouseEvent press(ui::ET_MOUSE_PRESSED, click_location, click_location,
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::EF_LEFT_MOUSE_BUTTON);
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::MouseEvent release(ui::ET_MOUSE_RELEASED, click_location, click_location,
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::EF_LEFT_MOUSE_BUTTON);
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnMouseEvent(&press);
12422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnMouseEvent(&release);
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, mouse->pressed());
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The end of the gesture should release the capture, and pressing on |mouse|
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should now reach |mouse|.
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->OnGestureEvent(&end);
12482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnMouseEvent(&press);
12492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnMouseEvent(&release);
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, mouse->pressed());
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Close();
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunPendingMessages();
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_AURA)
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The key-event propagation from Widget happens differently on aura and
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// non-aura systems because of the difference in IME. So this test works only on
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// aura.
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WidgetTest, KeyboardInputEvent) {
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* toplevel = CreateTopLevelPlatformWidget();
12622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  View* container = toplevel->client_view();
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Textfield* textfield = new Textfield();
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  textfield->SetText(ASCIIToUTF16("some text"));
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  container->AddChildView(textfield);
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Show();
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  textfield->RequestFocus();
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The press gets handled. The release doesn't have an effect.
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::KeyEvent backspace_p(ui::ET_KEY_PRESSED, ui::VKEY_DELETE, 0, false);
12722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnKeyEvent(&backspace_p);
12732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(backspace_p.stopped_propagation());
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::KeyEvent backspace_r(ui::ET_KEY_RELEASED, ui::VKEY_DELETE, 0, false);
12752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->OnKeyEvent(&backspace_r);
12762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(backspace_r.handled());
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Close();
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Verifies bubbles result in a focus lost when shown.
1282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// TODO(msw): this tests relies on focus, it needs to be in
1283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// interactive_ui_tests.
1284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WidgetTest, DISABLED_FocusChangesOnBubble) {
12852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a widget, show and activate it and focus the contents view.
12862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  View* contents_view = new View;
12872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents_view->set_focusable(true);
12882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget widget;
12892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams init_params =
12902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
12912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.bounds = gfx::Rect(0, 0, 200, 200);
12922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
12932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_CHROMEOS)
12942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.native_widget = new DesktopNativeWidgetAura(&widget);
12952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
12962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Init(init_params);
12972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.SetContentsView(contents_view);
12982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Show();
12992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Activate();
13002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents_view->RequestFocus();
13012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(contents_view->HasFocus());
13022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Show a bubble.
13042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BubbleDelegateView* bubble_delegate_view =
13052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new BubbleDelegateView(contents_view, BubbleBorder::TOP_LEFT);
13062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bubble_delegate_view->set_focusable(true);
13072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BubbleDelegateView::CreateBubble(bubble_delegate_view)->Show();
13082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bubble_delegate_view->RequestFocus();
13092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |contents_view_| should no longer have focus.
13112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(contents_view->HasFocus());
13122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(bubble_delegate_view->HasFocus());
13132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bubble_delegate_view->GetWidget()->CloseNow();
13152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Closing the bubble should result in focus going back to the contents view.
13172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(contents_view->HasFocus());
13182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Desktop native widget Aura tests are for non Chrome OS platforms.
13212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_CHROMEOS)
1322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Test to ensure that after minimize, view width is set to zero.
1323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WidgetTest, TestViewWidthAfterMinimizingWidget) {
1324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a widget.
1325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Widget widget;
1326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Widget::InitParams init_params =
1327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CreateParams(Widget::InitParams::TYPE_WINDOW);
1328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  init_params.show_state = ui::SHOW_STATE_NORMAL;
1329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Rect initial_bounds(0, 0, 300, 400);
1330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  init_params.bounds = initial_bounds;
1331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
1332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  init_params.native_widget = new DesktopNativeWidgetAura(&widget);
1333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget.Init(init_params);
1334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NonClientView* non_client_view = widget.non_client_view();
1335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NonClientFrameView* frame_view = new MinimumSizeFrameView(&widget);
1336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  non_client_view->SetFrameView(frame_view);
1337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget.Show();
1338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget.Minimize();
1339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, frame_view->width());
1340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
13422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This class validates whether paints are received for a visible Widget.
13432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// To achieve this it overrides the Show and Close methods on the Widget class
13442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// and sets state whether subsequent paints are expected.
13452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DesktopAuraTestValidPaintWidget : public views::Widget {
13462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
13472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DesktopAuraTestValidPaintWidget()
13482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : expect_paint_(true),
13492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      received_paint_while_hidden_(false) {
13502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
13512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~DesktopAuraTestValidPaintWidget() {
13532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
13542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void Show() OVERRIDE {
13562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expect_paint_ = true;
13572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    views::Widget::Show();
13582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
13592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void Close() OVERRIDE {
13612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expect_paint_ = false;
13622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    views::Widget::Close();
13632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
13642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Hide() {
13662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expect_paint_ = false;
13672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    views::Widget::Hide();
13682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
13692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnNativeWidgetPaint(gfx::Canvas* canvas) OVERRIDE {
13712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(expect_paint_);
13722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!expect_paint_)
13732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      received_paint_while_hidden_ = true;
13742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    views::Widget::OnNativeWidgetPaint(canvas);
13752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
13762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool received_paint_while_hidden() const {
13782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return received_paint_while_hidden_;
13792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
13802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
13822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool expect_paint_;
13832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool received_paint_while_hidden_;
13842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
13852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetTest, DesktopNativeWidgetAuraNoPaintAfterCloseTest) {
13872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  View* contents_view = new View;
13882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents_view->set_focusable(true);
13892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DesktopAuraTestValidPaintWidget widget;
13902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams init_params =
13912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
13922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.bounds = gfx::Rect(0, 0, 200, 200);
13932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
13942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.native_widget = new DesktopNativeWidgetAura(&widget);
13952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Init(init_params);
13962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.SetContentsView(contents_view);
13972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Show();
13982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Activate();
13992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunPendingMessages();
14002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.SchedulePaintInRect(init_params.bounds);
14012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Close();
14022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunPendingMessages();
14032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(widget.received_paint_while_hidden());
14042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetTest, DesktopNativeWidgetAuraNoPaintAfterHideTest) {
14072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  View* contents_view = new View;
14082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents_view->set_focusable(true);
14092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DesktopAuraTestValidPaintWidget widget;
14102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams init_params =
14112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
14122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.bounds = gfx::Rect(0, 0, 200, 200);
14132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
14142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.native_widget = new DesktopNativeWidgetAura(&widget);
14152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Init(init_params);
14162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.SetContentsView(contents_view);
14172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Show();
14182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Activate();
14192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunPendingMessages();
14202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.SchedulePaintInRect(init_params.bounds);
14212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Hide();
14222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunPendingMessages();
14232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(widget.received_paint_while_hidden());
14242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget.Close();
14252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This class provides functionality to test whether the destruction of full
14282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// screen child windows occurs correctly in desktop AURA without crashing.
14292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// It provides facilities to test the following cases:-
14302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1. Child window destroyed which should lead to the destruction of the
14312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//    parent.
14322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 2. Parent window destroyed which should lead to the child being destroyed.
14332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DesktopAuraFullscreenChildWindowDestructionTest
14342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public views::TestViewsDelegate,
14352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      public aura::WindowObserver {
14362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
14372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DesktopAuraFullscreenChildWindowDestructionTest()
14382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : full_screen_widget_(NULL),
14392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        child_window_(NULL),
14402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        parent_destroyed_(false),
14412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        child_destroyed_(false) {}
14422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1443b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual ~DesktopAuraFullscreenChildWindowDestructionTest() {
14442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(parent_destroyed_);
14452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(child_destroyed_);
14462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    full_screen_widget_ = NULL;
14472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child_window_ = NULL;
14482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // views::TestViewsDelegate overrides.
14512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnBeforeWidgetInit(
14522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Widget::InitParams* params,
14532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      internal::NativeWidgetDelegate* delegate) OVERRIDE {
14542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!params->native_widget)
14552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      params->native_widget = new views::DesktopNativeWidgetAura(delegate);
14562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void CreateFullscreenChildWindow(const gfx::Rect& bounds) {
14592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Widget::InitParams init_params;
14602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    init_params.type = Widget::InitParams::TYPE_WINDOW;
14612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    init_params.bounds = bounds;
14622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
14632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    init_params.layer_type = ui::LAYER_NOT_DRAWN;
14642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    widget_.Init(init_params);
14662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child_window_ = new aura::Window(&child_window_delegate_);
14682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child_window_->SetType(aura::client::WINDOW_TYPE_NORMAL);
14692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child_window_->Init(ui::LAYER_TEXTURED);
14702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child_window_->SetName("TestFullscreenChildWindow");
14712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child_window_->SetProperty(aura::client::kShowStateKey,
14722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              ui::SHOW_STATE_FULLSCREEN);
14732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child_window_->SetDefaultParentByRootWindow(
14742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        widget_.GetNativeView()->GetRootWindow(), gfx::Rect(0, 0, 1900, 1600));
14752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child_window_->Show();
14762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child_window_->AddObserver(this);
14772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(child_window_->parent() != NULL);
14792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child_window_->parent()->AddObserver(this);
14802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    full_screen_widget_ =
14822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        views::Widget::GetWidgetForNativeView(child_window_->parent());
14832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(full_screen_widget_ != NULL);
14842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void DestroyChildWindow() {
14872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(child_window_ != NULL);
14882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete child_window_;
14892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void DestroyParentWindow() {
14922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(full_screen_widget_ != NULL);
14932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    full_screen_widget_->CloseNow();
14942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
14972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    window->RemoveObserver(this);
14982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (window == child_window_) {
14992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      child_destroyed_ = true;
15002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (window == full_screen_widget_->GetNativeView()) {
15012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      parent_destroyed_ = true;
15022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
15032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ADD_FAILURE() << "Unexpected window destroyed callback: " << window;
15042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
15052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
15062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
15082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  views::Widget widget_;
15092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  views::Widget* full_screen_widget_;
15102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::Window* child_window_;
15112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool parent_destroyed_;
15122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool child_destroyed_;
15132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::test::TestWindowDelegate child_window_delegate_;
15142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DesktopAuraFullscreenChildWindowDestructionTest);
15162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
15172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetTest, DesktopAuraFullscreenChildDestroyedBeforeParentTest) {
15192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ViewsDelegate::views_delegate = NULL;
15202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DesktopAuraFullscreenChildWindowDestructionTest full_screen_child_test;
15212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(full_screen_child_test.CreateFullscreenChildWindow(
15222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(0, 0, 200, 200)));
15232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunPendingMessages();
15252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(full_screen_child_test.DestroyChildWindow());
15262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunPendingMessages();
15272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetTest, DesktopAuraFullscreenChildParentDestroyed) {
15302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ViewsDelegate::views_delegate = NULL;
15312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DesktopAuraFullscreenChildWindowDestructionTest full_screen_child_test;
15332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(full_screen_child_test.CreateFullscreenChildWindow(
15342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(0, 0, 200, 200)));
15352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunPendingMessages();
15372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(full_screen_child_test.DestroyParentWindow());
15382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunPendingMessages();
15392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Test to ensure that the aura Window's visiblity state is set to visible if
1542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the underlying widget is hidden and then shown.
1543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WidgetTest, TestWindowVisibilityAfterHide) {
1544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a widget.
1545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Widget widget;
1546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Widget::InitParams init_params =
1547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CreateParams(Widget::InitParams::TYPE_WINDOW);
1548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  init_params.show_state = ui::SHOW_STATE_NORMAL;
1549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Rect initial_bounds(0, 0, 300, 400);
1550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  init_params.bounds = initial_bounds;
1551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
1552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  init_params.native_widget = new DesktopNativeWidgetAura(&widget);
1553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget.Init(init_params);
1554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NonClientView* non_client_view = widget.non_client_view();
1555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NonClientFrameView* frame_view = new MinimumSizeFrameView(&widget);
1556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  non_client_view->SetFrameView(frame_view);
1557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget.Hide();
1559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(widget.GetNativeView()->IsVisible());
1560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget.Show();
1561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(widget.GetNativeView()->IsVisible());
1562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
15642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // !defined(OS_CHROMEOS)
15652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Tests that wheel events generated from scroll events are targetted to the
15672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// views under the cursor when the focused view does not processed them.
15682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetTest, WheelEventsFromScrollEventTarget) {
15692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EventCountView* cursor_view = new EventCountView;
15702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cursor_view->SetBounds(60, 0, 50, 40);
15712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* widget = CreateTopLevelPlatformWidget();
15732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->GetRootView()->AddChildView(cursor_view);
15742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Generate a scroll event on the cursor view.
15762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::ScrollEvent scroll(ui::ET_SCROLL,
15772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         gfx::Point(65, 5),
15782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         ui::EventTimeForNow(),
15792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         0,
15802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         0, 20,
15812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         0, 20,
15822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         2);
15832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->OnScrollEvent(&scroll);
15842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, cursor_view->GetEventCount(ui::ET_SCROLL));
15862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, cursor_view->GetEventCount(ui::ET_MOUSEWHEEL));
15872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cursor_view->ResetCounts();
15892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::ScrollEvent scroll2(ui::ET_SCROLL,
15912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          gfx::Point(5, 5),
15922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          ui::EventTimeForNow(),
15932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          0,
15942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          0, 20,
15952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          0, 20,
15962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          2);
15972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->OnScrollEvent(&scroll2);
15982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, cursor_view->GetEventCount(ui::ET_SCROLL));
16002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, cursor_view->GetEventCount(ui::ET_MOUSEWHEEL));
16012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->CloseNow();
16032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
16042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(USE_AURA)
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests that if a scroll-begin gesture is not handled, then subsequent scroll
16082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// events are not dispatched to any view.
16092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetTest, GestureScrollEventDispatching) {
16102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EventCountView* noscroll_view = new EventCountView;
16112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EventCountView* scroll_view = new ScrollableEventCountView;
16122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  noscroll_view->SetBounds(0, 0, 50, 40);
16142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scroll_view->SetBounds(60, 0, 40, 40);
16152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* widget = CreateTopLevelPlatformWidget();
16172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->GetRootView()->AddChildView(noscroll_view);
16182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->GetRootView()->AddChildView(scroll_view);
16192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
16212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::GestureEvent begin(ui::ET_GESTURE_SCROLL_BEGIN,
16222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        5, 5, 0, base::TimeDelta(),
16232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 0, 0),
16242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        1);
16252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    widget->OnGestureEvent(&begin);
16262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::GestureEvent update(ui::ET_GESTURE_SCROLL_UPDATE,
16272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        25, 15, 0, base::TimeDelta(),
16282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE, 20, 10),
16292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        1);
16302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    widget->OnGestureEvent(&update);
16312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::GestureEvent end(ui::ET_GESTURE_SCROLL_END,
16322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        25, 15, 0, base::TimeDelta(),
16332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END, 0, 0),
16342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        1);
16352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    widget->OnGestureEvent(&end);
16362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, noscroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_BEGIN));
16382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, noscroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_UPDATE));
16392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, noscroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_END));
16402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
16412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
16432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::GestureEvent begin(ui::ET_GESTURE_SCROLL_BEGIN,
16442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        65, 5, 0, base::TimeDelta(),
16452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 0, 0),
16462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        1);
16472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    widget->OnGestureEvent(&begin);
16482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::GestureEvent update(ui::ET_GESTURE_SCROLL_UPDATE,
16492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        85, 15, 0, base::TimeDelta(),
16502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE, 20, 10),
16512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        1);
16522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    widget->OnGestureEvent(&update);
16532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::GestureEvent end(ui::ET_GESTURE_SCROLL_END,
16542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        85, 15, 0, base::TimeDelta(),
16552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END, 0, 0),
16562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        1);
16572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    widget->OnGestureEvent(&end);
16582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, scroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_BEGIN));
16602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, scroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_UPDATE));
16612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1, scroll_view->GetEventCount(ui::ET_GESTURE_SCROLL_END));
16622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
16632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->CloseNow();
16652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
16662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests that event-handlers installed on the RootView get triggered correctly.
16682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetTest, EventHandlersOnRootView) {
16692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* widget = CreateTopLevelNativeWidget();
16702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  View* root_view = widget->GetRootView();
16712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EventCountView* view = new EventCountView;
16732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  view->SetBounds(0, 0, 20, 20);
16742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_view->AddChildView(view);
16752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EventCountHandler h1;
16772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_view->AddPreTargetHandler(&h1);
16782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EventCountHandler h2;
16802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_view->AddPostTargetHandler(&h2);
16812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->SetBounds(gfx::Rect(0, 0, 100, 100));
16832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->Show();
16842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::TouchEvent pressed(ui::ET_TOUCH_PRESSED,
16862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         gfx::Point(10, 10),
16872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         0, 0,
16882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         ui::EventTimeForNow(),
16892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         1.0, 0.0, 1.0, 0.0);
16902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->OnTouchEvent(&pressed);
16912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h1.GetEventCount(ui::ET_TOUCH_PRESSED));
16922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, view->GetEventCount(ui::ET_TOUCH_PRESSED));
16932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h2.GetEventCount(ui::ET_TOUCH_PRESSED));
16942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::GestureEvent begin(ui::ET_GESTURE_BEGIN,
16962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      5, 5, 0, ui::EventTimeForNow(),
16972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui::GestureEventDetails(ui::ET_GESTURE_BEGIN, 0, 0), 1);
16982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::GestureEvent end(ui::ET_GESTURE_END,
16992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      5, 5, 0, ui::EventTimeForNow(),
17002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui::GestureEventDetails(ui::ET_GESTURE_END, 0, 0), 1);
17012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->OnGestureEvent(&begin);
17022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h1.GetEventCount(ui::ET_GESTURE_BEGIN));
17032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, view->GetEventCount(ui::ET_GESTURE_BEGIN));
17042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h2.GetEventCount(ui::ET_GESTURE_BEGIN));
17052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::TouchEvent released(ui::ET_TOUCH_RELEASED,
17072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          gfx::Point(10, 10),
17082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          0, 0,
17092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          ui::EventTimeForNow(),
17102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          1.0, 0.0, 1.0, 0.0);
17112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->OnTouchEvent(&released);
17122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h1.GetEventCount(ui::ET_TOUCH_RELEASED));
17132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, view->GetEventCount(ui::ET_TOUCH_RELEASED));
17142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h2.GetEventCount(ui::ET_TOUCH_RELEASED));
17152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->OnGestureEvent(&end);
17172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h1.GetEventCount(ui::ET_GESTURE_END));
17182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, view->GetEventCount(ui::ET_GESTURE_END));
17192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h2.GetEventCount(ui::ET_GESTURE_END));
17202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::ScrollEvent scroll(ui::ET_SCROLL,
17222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         gfx::Point(5, 5),
17232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         ui::EventTimeForNow(),
17242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         0,
17252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         0, 20,
17262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         0, 20,
17272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         2);
17282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->OnScrollEvent(&scroll);
17292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h1.GetEventCount(ui::ET_SCROLL));
17302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, view->GetEventCount(ui::ET_SCROLL));
17312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, h2.GetEventCount(ui::ET_SCROLL));
17322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->CloseNow();
17342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
17352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WidgetTest, SynthesizeMouseMoveEvent) {
1737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Widget* widget = CreateTopLevelNativeWidget();
1738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  View* root_view = widget->GetRootView();
1739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EventCountView* v1 = new EventCountView();
1741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  v1->SetBounds(0, 0, 10, 10);
1742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  root_view->AddChildView(v1);
1743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EventCountView* v2 = new EventCountView();
1744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  v2->SetBounds(0, 10, 10, 10);
1745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  root_view->AddChildView(v2);
1746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1747c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Point cursor_location(5, 5);
1748c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ui::MouseEvent move(ui::ET_MOUSE_MOVED, cursor_location, cursor_location,
1749c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                      ui::EF_NONE);
1750c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget->OnMouseEvent(&move);
1751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1752c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, v1->GetEventCount(ui::ET_MOUSE_ENTERED));
1753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, v2->GetEventCount(ui::ET_MOUSE_ENTERED));
1754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  delete v1;
1756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  v2->SetBounds(0, 0, 10, 10);
1757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, v2->GetEventCount(ui::ET_MOUSE_ENTERED));
1758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget->SynthesizeMouseMoveEvent();
1760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, v2->GetEventCount(ui::ET_MOUSE_ENTERED));
1761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
17637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(WidgetTest, MouseEventsHandled) {
17647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  Widget* widget = CreateTopLevelNativeWidget();
17657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  View* root_view = widget->GetRootView();
17667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
17677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(USE_AURA)
1768eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  aura::test::TestCursorClient cursor_client(
1769eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      widget->GetNativeView()->GetRootWindow());
17707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
17717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
17727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EventCountView* v1 = new EventCountView();
17737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  v1->SetBounds(0, 0, 10, 10);
17747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  root_view->AddChildView(v1);
17757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EventCountView* v2 = new EventCountView();
17767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  v2->SetBounds(0, 10, 10, 10);
17777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  root_view->AddChildView(v2);
17787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
17797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  gfx::Point cursor_location1(5, 5);
17807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ui::MouseEvent move1(ui::ET_MOUSE_MOVED, cursor_location1, cursor_location1,
17817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       ui::EF_NONE);
17827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  widget->OnMouseEvent(&move1);
17837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(1, v1->GetEventCount(ui::ET_MOUSE_ENTERED));
17847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, v2->GetEventCount(ui::ET_MOUSE_ENTERED));
17857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, v1->GetEventCount(ui::ET_MOUSE_EXITED));
17867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, v2->GetEventCount(ui::ET_MOUSE_EXITED));
17877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  v1->ResetCounts();
17887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  v2->ResetCounts();
17897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
17907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  gfx::Point cursor_location2(5, 15);
17917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ui::MouseEvent move2(ui::ET_MOUSE_MOVED, cursor_location2, cursor_location2,
17927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       ui::EF_NONE);
17937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  widget->OnMouseEvent(&move2);
17947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, v1->GetEventCount(ui::ET_MOUSE_ENTERED));
17957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(1, v2->GetEventCount(ui::ET_MOUSE_ENTERED));
17967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(1, v1->GetEventCount(ui::ET_MOUSE_EXITED));
17977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, v2->GetEventCount(ui::ET_MOUSE_EXITED));
17987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  v1->ResetCounts();
17997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  v2->ResetCounts();
18007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
18017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(USE_AURA)
18027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // In Aura, we suppress mouse events if mouse events are disabled.
18037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  cursor_client.DisableMouseEvents();
18047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
18057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  widget->OnMouseEvent(&move1);
18067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, v1->GetEventCount(ui::ET_MOUSE_ENTERED));
18077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, v2->GetEventCount(ui::ET_MOUSE_ENTERED));
18087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, v1->GetEventCount(ui::ET_MOUSE_EXITED));
18097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, v2->GetEventCount(ui::ET_MOUSE_EXITED));
18107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  v1->ResetCounts();
18117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  v2->ResetCounts();
18127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
18137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  widget->OnMouseEvent(&move2);
18147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, v1->GetEventCount(ui::ET_MOUSE_ENTERED));
18157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, v2->GetEventCount(ui::ET_MOUSE_ENTERED));
18167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, v1->GetEventCount(ui::ET_MOUSE_EXITED));
18177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, v2->GetEventCount(ui::ET_MOUSE_EXITED));
18187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif
18197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
18207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
18212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Used by SingleWindowClosing to count number of times WindowClosing() has
18222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// been invoked.
18232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ClosingDelegate : public WidgetDelegate {
18242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
18252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ClosingDelegate() : count_(0), widget_(NULL) {}
18262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int count() const { return count_; }
18282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void set_widget(views::Widget* widget) { widget_ = widget; }
18302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // WidgetDelegate overrides:
18322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual Widget* GetWidget() OVERRIDE { return widget_; }
18332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual const Widget* GetWidget() const OVERRIDE { return widget_; }
18342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void WindowClosing() OVERRIDE {
18352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    count_++;
18362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
18372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
18392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int count_;
18402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  views::Widget* widget_;
18412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ClosingDelegate);
18432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
18442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Verifies WindowClosing() is invoked correctly on the delegate when a Widget
18462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// is closed.
18472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetTest, SingleWindowClosing) {
18482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ClosingDelegate> delegate(new ClosingDelegate());
18492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget* widget = new Widget();  // Destroyed by CloseNow() below.
18502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams init_params =
18512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateParams(Widget::InitParams::TYPE_WINDOW);
18522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.bounds = gfx::Rect(0, 0, 200, 200);
18532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.delegate = delegate.get();
18542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_AURA) && !defined(OS_CHROMEOS)
18552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  init_params.native_widget = new DesktopNativeWidgetAura(widget);
18562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
18572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->Init(init_params);
18582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, delegate->count());
18592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->CloseNow();
18602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, delegate->count());
18612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
18622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Used by SetTopLevelCorrectly to track calls to OnBeforeWidgetInit().
18642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class VerifyTopLevelDelegate : public TestViewsDelegate {
18652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
18662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyTopLevelDelegate()
18672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : on_before_init_called_(false),
18682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        is_top_level_(false) {
18692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
18702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool on_before_init_called() const { return on_before_init_called_; }
18722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_top_level() const { return is_top_level_; }
18732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnBeforeWidgetInit(
18752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Widget::InitParams* params,
18762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      internal::NativeWidgetDelegate* delegate) OVERRIDE {
18772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    on_before_init_called_ = true;
18782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    is_top_level_ = params->top_level;
18792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
18802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
18822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool on_before_init_called_;
18832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_top_level_;
18842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(VerifyTopLevelDelegate);
18862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
18872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Verifies |top_level| is correctly passed to
18892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ViewsDelegate::OnBeforeWidgetInit().
18902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WidgetTest, SetTopLevelCorrectly) {
18912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  set_views_delegate(NULL);
18922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyTopLevelDelegate* delegate = new VerifyTopLevelDelegate;
18932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  set_views_delegate(delegate);  // ViewsTestBase takes ownership.
18942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Widget> widget(new Widget);
18952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params =
18962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateParams(views::Widget::InitParams::TYPE_POPUP);
18972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
18982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->Init(params);
18992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(delegate->on_before_init_called());
19002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(delegate->is_top_level());
19012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
19022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1903c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// A scumbag View that deletes its owning widget OnMousePressed.
1904c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class WidgetDeleterView : public View {
1905c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
1906c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  WidgetDeleterView() : View() {}
1907c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1908c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Overridden from View.
1909c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE {
1910c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    delete GetWidget();
1911c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
1912c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1914c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
1915c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WidgetDeleterView);
1916c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
1917c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1918c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WidgetTest, TestWidgetDeletedInOnMousePressed) {
1919c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Widget* widget = new Widget;
1920c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Widget::InitParams params =
1921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CreateParams(views::Widget::InitParams::TYPE_POPUP);
1922c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
1923c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget->Init(params);
1924c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1925c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget->SetContentsView(new WidgetDeleterView);
1926c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1927c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget->SetSize(gfx::Size(100, 100));
1928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget->Show();
1929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Point click_location(45, 15);
1931c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ui::MouseEvent press(ui::ET_MOUSE_PRESSED, click_location, click_location,
1932c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ui::EF_LEFT_MOUSE_BUTTON);
1933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  widget->OnMouseEvent(&press);
1934c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Yay we did not crash!
1936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1937c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1938558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// See description of RunGetNativeThemeFromDestructor() for details.
1939558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochclass GetNativeThemeFromDestructorView : public WidgetDelegateView {
1940558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch public:
1941558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  GetNativeThemeFromDestructorView() {}
1942558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  virtual ~GetNativeThemeFromDestructorView() {
1943558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    VerifyNativeTheme();
1944558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
1945558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1946558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  virtual View* GetContentsView() OVERRIDE {
1947558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return this;
1948558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
1949558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1950558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch private:
1951558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  void VerifyNativeTheme() {
1952558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    ASSERT_TRUE(GetNativeTheme() != NULL);
1953558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
1954558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1955558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(GetNativeThemeFromDestructorView);
1956558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch};
1957558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1958558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// Verifies GetNativeTheme() from the destructor of a WidgetDelegateView doesn't
1959558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// crash. |is_first_run| is true if this is the first call. A return value of
1960558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// true indicates this should be run again with a value of false.
1961558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// First run uses DesktopNativeWidgetAura (if possible). Second run doesn't.
1962558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochbool RunGetNativeThemeFromDestructor(const Widget::InitParams& in_params,
1963558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                     bool is_first_run) {
1964558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  bool needs_second_run = false;
1965558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Destroyed by CloseNow() below.
1966558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  Widget* widget = new Widget;
1967558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  Widget::InitParams params(in_params);
1968558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Deletes itself when the Widget is destroyed.
1969558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  params.delegate = new GetNativeThemeFromDestructorView;
1970558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#if defined(USE_AURA) && !defined(OS_CHROMEOS)
1971558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (is_first_run) {
1972558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    params.native_widget = new DesktopNativeWidgetAura(widget);
1973558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    needs_second_run = true;
1974558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
1975558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#endif
1976558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  widget->Init(params);
1977558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  widget->CloseNow();
1978558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return needs_second_run;
1979558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
1980558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1981558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// See description of RunGetNativeThemeFromDestructor() for details.
1982558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_F(WidgetTest, GetNativeThemeFromDestructor) {
1983558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
1984558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (RunGetNativeThemeFromDestructor(params, true))
1985558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    RunGetNativeThemeFromDestructor(params, false);
1986558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
1987558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace views
1990