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 "ui/views/widget/native_widget_aura.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
10ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/client/aura_constants.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/env.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/layout_manager.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/root_window.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/test/aura_test_helper.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window.h"
18d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/screen.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/fill_layout.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/root_view.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget_delegate.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NativeWidgetAura* Init(aura::Window* parent, Widget* widget) {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.parent = parent;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<NativeWidgetAura*>(widget->native_widget());
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NativeWidgetAuraTest : public testing::Test {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NativeWidgetAuraTest() {}
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~NativeWidgetAuraTest() {}
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // testing::Test overrides:
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    aura_test_helper_.reset(new aura::test::AuraTestHelper(&message_loop_));
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    aura_test_helper_->SetUp();
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    root_window()->SetBounds(gfx::Rect(0, 0, 640, 480));
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    dispatcher()->SetHostSize(gfx::Size(640, 480));
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() OVERRIDE {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_loop_.RunUntilIdle();
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    aura_test_helper_->TearDown();
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  aura::Window* root_window() { return aura_test_helper_->root_window(); }
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  aura::RootWindow* dispatcher() { return aura_test_helper_->dispatcher(); }
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoopForUI message_loop_;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::test::AuraTestHelper> aura_test_helper_;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NativeWidgetAuraTest);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NativeWidgetAuraTest, CenterWindowLargeParent) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make a parent window larger than the host represented by rootwindow.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> parent(new aura::Window(NULL));
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent->Init(ui::LAYER_NOT_DRAWN);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent->SetBounds(gfx::Rect(0, 0, 1024, 800));
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Widget>  widget(new Widget());
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NativeWidgetAura* window = Init(parent.get(), widget.get());
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window->CenterWindow(gfx::Size(100, 100));
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Rect( (640 - 100) / 2,
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       (480 - 100) / 2,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       100, 100),
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            window->GetNativeWindow()->bounds());
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->CloseNow();
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NativeWidgetAuraTest, CenterWindowSmallParent) {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make a parent window smaller than the host represented by rootwindow.
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> parent(new aura::Window(NULL));
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent->Init(ui::LAYER_NOT_DRAWN);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent->SetBounds(gfx::Rect(0, 0, 480, 320));
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Widget> widget(new Widget());
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NativeWidgetAura* window = Init(parent.get(), widget.get());
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window->CenterWindow(gfx::Size(100, 100));
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Rect( (480 - 100) / 2,
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       (320 - 100) / 2,
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       100, 100),
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            window->GetNativeWindow()->bounds());
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->CloseNow();
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies CenterWindow() constrains to parent size.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NativeWidgetAuraTest, CenterWindowSmallParentNotAtOrigin) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make a parent window smaller than the host represented by rootwindow and
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // offset it slightly from the origin.
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> parent(new aura::Window(NULL));
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent->Init(ui::LAYER_NOT_DRAWN);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent->SetBounds(gfx::Rect(20, 40, 480, 320));
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Widget> widget(new Widget());
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NativeWidgetAura* window = Init(parent.get(), widget.get());
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window->CenterWindow(gfx::Size(500, 600));
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |window| should be no bigger than |parent|.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("20,40 480x320", window->GetNativeWindow()->bounds().ToString());
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->CloseNow();
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Used by ShowMaximizedDoesntBounceAround. See it for details.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestLayoutManager : public aura::LayoutManager {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestLayoutManager() {}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWindowResized() OVERRIDE {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This simulates what happens when adding a maximized window.
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetChildBoundsDirect(child, gfx::Rect(0, 0, 300, 300));
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWindowRemovedFromLayout(aura::Window* child) OVERRIDE {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnChildWindowVisibilityChanged(aura::Window* child,
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              bool visible) OVERRIDE {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetChildBounds(aura::Window* child,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const gfx::Rect& requested_bounds) OVERRIDE {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestLayoutManager);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This simulates BrowserView, which creates a custom RootView so that
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OnNativeWidgetSizeChanged that is invoked during Init matters.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestWidget : public views::Widget {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestWidget() : did_size_change_more_than_once_(false) {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the size changes to a non-empty size, and then to another
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // size.
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool did_size_change_more_than_once() const {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return did_size_change_more_than_once_;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnNativeWidgetSizeChanged(const gfx::Size& new_size) OVERRIDE {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (last_size_.IsEmpty())
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_size_ = new_size;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else if (!did_size_change_more_than_once_ && new_size != last_size_)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      did_size_change_more_than_once_ = true;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Widget::OnNativeWidgetSizeChanged(new_size);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool did_size_change_more_than_once_;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size last_size_;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestWidget);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies the size of the widget doesn't change more than once during Init if
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the window ends up maximized. This is important as otherwise
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RenderWidgetHostViewAura ends up getting resized during construction, which
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// leads to noticable flashes.
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NativeWidgetAuraTest, ShowMaximizedDoesntBounceAround) {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  root_window()->SetBounds(gfx::Rect(0, 0, 640, 480));
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  root_window()->SetLayoutManager(new TestLayoutManager);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWidget> widget(new TestWidget());
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget::InitParams params(Widget::InitParams::TYPE_WINDOW);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.parent = NULL;
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.context = root_window();
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.show_state = ui::SHOW_STATE_MAXIMIZED;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.bounds = gfx::Rect(10, 10, 100, 200);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(widget->did_size_change_more_than_once());
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->CloseNow();
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NativeWidgetAuraTest, GetClientAreaScreenBounds) {
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a widget.
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget::InitParams params(Widget::InitParams::TYPE_WINDOW);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.context = root_window();
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.bounds.SetRect(10, 20, 300, 400);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Widget> widget(new Widget());
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For Aura, client area bounds match window bounds.
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect client_bounds = widget->GetClientAreaBoundsInScreen();
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(10, client_bounds.x());
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(20, client_bounds.y());
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(300, client_bounds.width());
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(400, client_bounds.height());
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// View subclass that tracks whether it has gotten a gesture event.
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GestureTrackingView : public views::View {
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GestureTrackingView()
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : got_gesture_event_(false),
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        consume_gesture_event_(true) {}
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_consume_gesture_event(bool value) {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    consume_gesture_event_ = value;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void clear_got_gesture_event() {
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    got_gesture_event_ = false;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool got_gesture_event() const {
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return got_gesture_event_;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // View overrides:
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    got_gesture_event_ = true;
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (consume_gesture_event_)
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      event->StopPropagation();
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Was OnGestureEvent() invoked?
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool got_gesture_event_;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Dictates what OnGestureEvent() returns.
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool consume_gesture_event_;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(GestureTrackingView);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies a capture isn't set on touch press and that the view that gets
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the press gets the release.
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NativeWidgetAuraTest, DontCaptureOnGesture) {
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create two views (both sized the same). |child| is configured not to
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // consume the gesture event.
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GestureTrackingView* view = new GestureTrackingView();
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GestureTrackingView* child = new GestureTrackingView();
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child->set_consume_gesture_event(false);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view->SetLayoutManager(new FillLayout);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view->AddChildView(child);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWidget> widget(new TestWidget());
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.context = root_window();
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.bounds = gfx::Rect(0, 0, 100, 200);
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->SetContentsView(view);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Show();
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(41, 51), 1,
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           base::TimeDelta());
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press);
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Both views should get the press.
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(view->got_gesture_event());
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(child->got_gesture_event());
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view->clear_got_gesture_event();
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child->clear_got_gesture_event();
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Touch events should not automatically grab capture.
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(widget->HasCapture());
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Release touch. Only |view| should get the release since that it consumed
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the press.
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(250, 251), 1,
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             base::TimeDelta());
274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release);
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(view->got_gesture_event());
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(child->got_gesture_event());
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view->clear_got_gesture_event();
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Work around for bug in NativeWidgetAura.
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO: fix bug and remove this.
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Close();
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NativeWidgetAuraTest, ReleaseCaptureOnTouchRelease) {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GestureTrackingView* view = new GestureTrackingView();
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWidget> widget(new TestWidget());
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.context = root_window();
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.bounds = gfx::Rect(0, 0, 100, 200);
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Init(params);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->SetContentsView(view);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Show();
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(41, 51), 1,
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           base::TimeDelta());
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(view->got_gesture_event());
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view->clear_got_gesture_event();
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the capture.
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->SetCapture(view);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(widget->HasCapture());
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generate a release, this should trigger releasing capture.
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(41, 51), 1,
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             base::TimeDelta());
307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(view->got_gesture_event());
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view->clear_got_gesture_event();
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(widget->HasCapture());
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Work around for bug in NativeWidgetAura.
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO: fix bug and remove this.
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Close();
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies views with layers are targeted for events properly.
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NativeWidgetAuraTest, PreferViewLayersToChildWindows) {
319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Create two widgets: |parent| and |child|. |child| is a child of |parent|.
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::View* parent_root = new views::View;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Widget> parent(new Widget());
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget::InitParams parent_params(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent_params.ownership =
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parent_params.context = root_window();
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent->Init(parent_params);
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent->SetContentsView(parent_root);
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent->SetBounds(gfx::Rect(0, 0, 400, 400));
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent->Show();
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Widget> child(new Widget());
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget::InitParams child_params(Widget::InitParams::TYPE_CONTROL);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child_params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child_params.parent = parent->GetNativeWindow();
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child->Init(child_params);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child->SetBounds(gfx::Rect(0, 0, 200, 200));
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child->Show();
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Point is over |child|.
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child->GetNativeWindow(),
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            parent->GetNativeWindow()->GetEventHandlerForPoint(
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                gfx::Point(50, 50)));
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Create a view with a layer and stack it at the bottom (below |child|).
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::View* view_with_layer = new views::View;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent_root->AddChildView(view_with_layer);
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view_with_layer->SetBounds(0, 0, 50, 50);
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view_with_layer->SetPaintToLayer(true);
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Make sure that |child| still gets the event.
351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(child->GetNativeWindow(),
352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            parent->GetNativeWindow()->GetEventHandlerForPoint(
353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                gfx::Point(20, 20)));
354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Move |view_with_layer| to the top and make sure it gets the
356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // event when the point is within |view_with_layer|'s bounds.
357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  view_with_layer->layer()->parent()->StackAtTop(
358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      view_with_layer->layer());
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(parent->GetNativeWindow(),
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            parent->GetNativeWindow()->GetEventHandlerForPoint(
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                gfx::Point(20, 20)));
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Point is over |child|, it should get the event.
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child->GetNativeWindow(),
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            parent->GetNativeWindow()->GetEventHandlerForPoint(
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                gfx::Point(70, 70)));
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete view_with_layer;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view_with_layer = NULL;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child->GetNativeWindow(),
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            parent->GetNativeWindow()->GetEventHandlerForPoint(
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                gfx::Point(20, 20)));
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Work around for bug in NativeWidgetAura.
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO: fix bug and remove this.
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent->Close();
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Verifies that widget->FlashFrame() sets aura::client::kDrawAttentionKey,
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// and activating the window clears it.
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(NativeWidgetAuraTest, FlashFrame) {
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Widget> widget(new Widget());
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params(Widget::InitParams::TYPE_WINDOW);
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.context = root_window();
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->Init(params);
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::Window* window = widget->GetNativeWindow();
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(window->GetProperty(aura::client::kDrawAttentionKey));
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->FlashFrame(true);
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(window->GetProperty(aura::client::kDrawAttentionKey));
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->FlashFrame(false);
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(window->GetProperty(aura::client::kDrawAttentionKey));
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->FlashFrame(true);
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(window->GetProperty(aura::client::kDrawAttentionKey));
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->Activate();
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(window->GetProperty(aura::client::kDrawAttentionKey));
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(NativeWidgetAuraTest, NoCrashOnThemeAfterClose) {
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<aura::Window> parent(new aura::Window(NULL));
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parent->Init(ui::LAYER_NOT_DRAWN);
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parent->SetBounds(gfx::Rect(0, 0, 480, 320));
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Widget> widget(new Widget());
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NativeWidgetAura* window = Init(parent.get(), widget.get());
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window->Show();
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window->Close();
408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  widget->GetNativeTheme();  // Shouldn't crash.
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace views
414