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/aura/window.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <string>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility>
94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <vector>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
135e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/string_util.h"
155e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/client/capture_client.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/client/focus_change_observer.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/client/visibility_client.h"
201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ui/aura/client/window_tree_client.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/test/aura_test_base.h"
225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/aura/test/aura_test_utils.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/test/test_window_delegate.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/test/test_windows.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/test/window_test_api.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window_delegate.h"
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window_observer.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window_property.h"
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/aura/window_tree_host.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/hit_test.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer.h"
3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ui/compositor/layer_animation_observer.h"
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/compositor/scoped_animation_duration_scale_mode.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/scoped_layer_animation_settings.h"
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/compositor/test/test_layers.h"
37d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event.h"
38d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event_utils.h"
3968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/events/gestures/gesture_configuration.h"
40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/keycodes/keyboard_codes.h"
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/events/test/event_generator.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/screen.h"
44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/gfx/skia_util.h"
45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/gfx/vector2d.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DECLARE_WINDOW_PROPERTY_TYPE(const char*)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DECLARE_WINDOW_PROPERTY_TYPE(int)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace aura {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace test {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WindowTest : public AuraTestBase {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WindowTest() : max_separation_(0) {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AuraTestBase::SetUp();
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO: there needs to be an easier way to do this.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    max_separation_ = ui::GestureConfiguration::
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        max_separation_for_gesture_touches_in_pixels();
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::GestureConfiguration::
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        set_max_separation_for_gesture_touches_in_pixels(0);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() OVERRIDE {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AuraTestBase::TearDown();
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::GestureConfiguration::
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        set_max_separation_for_gesture_touches_in_pixels(max_separation_);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int max_separation_;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WindowTest);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Used for verifying destruction methods are invoked.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DestroyTrackingDelegateImpl : public TestWindowDelegate {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DestroyTrackingDelegateImpl()
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : destroying_count_(0),
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        destroyed_count_(0),
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        in_destroying_(false) {}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void clear_destroying_count() { destroying_count_ = 0; }
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int destroying_count() const { return destroying_count_; }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void clear_destroyed_count() { destroyed_count_ = 0; }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int destroyed_count() const { return destroyed_count_; }
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool in_destroying() const { return in_destroying_; }
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void OnWindowDestroying(Window* window) OVERRIDE {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(in_destroying_);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    in_destroying_ = true;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    destroying_count_++;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void OnWindowDestroyed(Window* window) OVERRIDE {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(in_destroying_);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    in_destroying_ = false;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    destroyed_count_++;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int destroying_count_;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int destroyed_count_;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool in_destroying_;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DestroyTrackingDelegateImpl);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Used to verify that when OnWindowDestroying is invoked the parent is also
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is in the process of being destroyed.
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ChildWindowDelegateImpl : public DestroyTrackingDelegateImpl {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit ChildWindowDelegateImpl(
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DestroyTrackingDelegateImpl* parent_delegate)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : parent_delegate_(parent_delegate) {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void OnWindowDestroying(Window* window) OVERRIDE {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(parent_delegate_->in_destroying());
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DestroyTrackingDelegateImpl::OnWindowDestroying(window);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DestroyTrackingDelegateImpl* parent_delegate_;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ChildWindowDelegateImpl);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Used to verify that a Window is removed from its parent when
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OnWindowDestroyed is called.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DestroyOrphanDelegate : public TestWindowDelegate {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DestroyOrphanDelegate() : window_(NULL) {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_window(Window* window) { window_ = window; }
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void OnWindowDestroyed(Window* window) OVERRIDE {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(window_->parent());
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Window* window_;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DestroyOrphanDelegate);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Used in verifying mouse capture.
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CaptureWindowDelegateImpl : public TestWindowDelegate {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptureWindowDelegateImpl() {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ResetCounts();
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ResetCounts() {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    capture_changed_event_count_ = 0;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    capture_lost_count_ = 0;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mouse_event_count_ = 0;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    touch_event_count_ = 0;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gesture_event_count_ = 0;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int capture_changed_event_count() const {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return capture_changed_event_count_;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int capture_lost_count() const { return capture_lost_count_; }
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int mouse_event_count() const { return mouse_event_count_; }
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int touch_event_count() const { return touch_event_count_; }
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int gesture_event_count() const { return gesture_event_count_; }
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event->type() == ui::ET_MOUSE_CAPTURE_CHANGED)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      capture_changed_event_count_++;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mouse_event_count_++;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    touch_event_count_++;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gesture_event_count_++;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnCaptureLost() OVERRIDE {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    capture_lost_count_++;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int capture_changed_event_count_;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int capture_lost_count_;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int mouse_event_count_;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int touch_event_count_;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int gesture_event_count_;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CaptureWindowDelegateImpl);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Keeps track of the location of the gesture.
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GestureTrackPositionDelegate : public TestWindowDelegate {
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GestureTrackPositionDelegate() {}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    position_ = event->location();
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event->StopPropagation();
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const gfx::Point& position() const { return position_; }
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point position_;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(GestureTrackPositionDelegate);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::TimeDelta getTime() {
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ui::EventTimeForNow();
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SelfEventHandlingWindowDelegate : public TestWindowDelegate {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SelfEventHandlingWindowDelegate() {}
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool ShouldDescendIntoChildForEventHandling(
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Window* child,
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const gfx::Point& location) OVERRIDE {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SelfEventHandlingWindowDelegate);
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The delegate deletes itself when the window is being destroyed.
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DestroyWindowDelegate : public TestWindowDelegate {
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DestroyWindowDelegate() {}
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~DestroyWindowDelegate() {}
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from WindowDelegate.
248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void OnWindowDestroyed(Window* window) OVERRIDE {
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete this;
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DestroyWindowDelegate);
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, GetChildById) {
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w11(CreateTestWindowWithId(11, w1.get()));
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w111(CreateTestWindowWithId(111, w11.get()));
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w12(CreateTestWindowWithId(12, w1.get()));
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, w1->GetChildById(57));
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(w12.get(), w1->GetChildById(12));
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(w111.get(), w1->GetChildById(111));
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that Window::Contains correctly handles children, grandchildren,
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and not containing NULL or parents.
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, Contains) {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Window parent(NULL);
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  parent.Init(aura::WINDOW_LAYER_NOT_DRAWN);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Window child1(NULL);
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  child1.Init(aura::WINDOW_LAYER_NOT_DRAWN);
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Window child2(NULL);
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  child2.Init(aura::WINDOW_LAYER_NOT_DRAWN);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parent.AddChild(&child1);
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child1.AddChild(&child2);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parent.Contains(&parent));
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parent.Contains(&child1));
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parent.Contains(&child2));
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(parent.Contains(NULL));
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(child1.Contains(&parent));
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(child2.Contains(&child1));
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, ContainsPointInRoot) {
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w(
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindow(SK_ColorWHITE, 1, gfx::Rect(10, 10, 5, 5),
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       root_window()));
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(w->ContainsPointInRoot(gfx::Point(9, 9)));
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(w->ContainsPointInRoot(gfx::Point(10, 10)));
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(w->ContainsPointInRoot(gfx::Point(14, 14)));
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(w->ContainsPointInRoot(gfx::Point(15, 15)));
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(w->ContainsPointInRoot(gfx::Point(20, 20)));
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, ContainsPoint) {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w(
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindow(SK_ColorWHITE, 1, gfx::Rect(10, 10, 5, 5),
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       root_window()));
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(w->ContainsPoint(gfx::Point(0, 0)));
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(w->ContainsPoint(gfx::Point(4, 4)));
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(w->ContainsPoint(gfx::Point(5, 5)));
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(w->ContainsPoint(gfx::Point(10, 10)));
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, ConvertPointToWindow) {
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Window::ConvertPointToWindow is mostly identical to
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Layer::ConvertPointToLayer, except NULL values for |source| are permitted,
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in which case the function just returns.
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point reference_point(100, 100);
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point test_point = reference_point;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Window::ConvertPointToTarget(NULL, w1.get(), &test_point);
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(reference_point, test_point);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, MoveCursorTo) {
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w1(
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindow(SK_ColorWHITE, 1, gfx::Rect(10, 10, 500, 500),
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       root_window()));
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w11(
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestWindow(SK_ColorGREEN, 11, gfx::Rect(5, 5, 100, 100), w1.get()));
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w111(
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestWindow(SK_ColorCYAN, 111, gfx::Rect(5, 5, 75, 75), w11.get()));
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w1111(
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestWindow(SK_ColorRED, 1111, gfx::Rect(5, 5, 50, 50), w111.get()));
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Window* root = root_window();
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  root->MoveCursorTo(gfx::Point(10, 10));
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("10,10",
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Screen::GetScreenFor(root)->GetCursorScreenPoint().ToString());
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->MoveCursorTo(gfx::Point(10, 10));
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("20,20",
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Screen::GetScreenFor(root)->GetCursorScreenPoint().ToString());
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w11->MoveCursorTo(gfx::Point(10, 10));
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("25,25",
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Screen::GetScreenFor(root)->GetCursorScreenPoint().ToString());
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w111->MoveCursorTo(gfx::Point(10, 10));
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("30,30",
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Screen::GetScreenFor(root)->GetCursorScreenPoint().ToString());
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1111->MoveCursorTo(gfx::Point(10, 10));
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("35,35",
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Screen::GetScreenFor(root)->GetCursorScreenPoint().ToString());
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, ContainsMouse) {
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w(
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindow(SK_ColorWHITE, 1, gfx::Rect(10, 10, 500, 500),
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       root_window()));
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w->Show();
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WindowTestApi w_test_api(w.get());
357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Window* root = root_window();
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  root->MoveCursorTo(gfx::Point(10, 10));
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(w_test_api.ContainsMouse());
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  root->MoveCursorTo(gfx::Point(9, 10));
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(w_test_api.ContainsMouse());
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test Window::ConvertPointToWindow() with transform to root_window.
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, MoveCursorToWithTransformRootWindow) {
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Transform transform;
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  transform.Translate(100.0, 100.0);
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  transform.Rotate(90.0);
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  transform.Scale(2.0, 5.0);
370a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  host()->SetRootTransform(transform);
371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  host()->MoveCursorTo(gfx::Point(10, 10));
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_WIN)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(yoshiki): fix this to build on Windows. See crbug.com/133413.OD
3745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ("50,120", QueryLatestMousePositionRequestInHost(host()).ToString());
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ("10,10", gfx::Screen::GetScreenFor(
377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      root_window())->GetCursorScreenPoint().ToString());
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests Window::ConvertPointToWindow() with transform to non-root windows.
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, MoveCursorToWithTransformWindow) {
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w1(
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindow(SK_ColorWHITE, 1, gfx::Rect(10, 10, 500, 500),
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       root_window()));
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Transform transform1;
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  transform1.Scale(2, 2);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->SetTransform(transform1);
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->MoveCursorTo(gfx::Point(10, 10));
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("30,30",
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Screen::GetScreenFor(w1.get())->GetCursorScreenPoint().ToString());
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Transform transform2;
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  transform2.Translate(-10, 20);
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->SetTransform(transform2);
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->MoveCursorTo(gfx::Point(10, 10));
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("10,40",
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Screen::GetScreenFor(w1.get())->GetCursorScreenPoint().ToString());
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Transform transform3;
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  transform3.Rotate(90.0);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->SetTransform(transform3);
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->MoveCursorTo(gfx::Point(5, 5));
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("5,15",
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Screen::GetScreenFor(w1.get())->GetCursorScreenPoint().ToString());
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Transform transform4;
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  transform4.Translate(100.0, 100.0);
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  transform4.Rotate(90.0);
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  transform4.Scale(2.0, 5.0);
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->SetTransform(transform4);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->MoveCursorTo(gfx::Point(10, 10));
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("60,130",
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Screen::GetScreenFor(w1.get())->GetCursorScreenPoint().ToString());
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test Window::ConvertPointToWindow() with complex transforms to both root and
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// non-root windows.
419eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Test Window::ConvertPointToWindow() with transform to root_window.
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, MoveCursorToWithComplexTransform) {
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w1(
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindow(SK_ColorWHITE, 1, gfx::Rect(10, 10, 500, 500),
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       root_window()));
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w11(
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestWindow(SK_ColorGREEN, 11, gfx::Rect(5, 5, 100, 100), w1.get()));
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w111(
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestWindow(SK_ColorCYAN, 111, gfx::Rect(5, 5, 75, 75), w11.get()));
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w1111(
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestWindow(SK_ColorRED, 1111, gfx::Rect(5, 5, 50, 50), w111.get()));
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Window* root = root_window();
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The root window expects transforms that produce integer rects.
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform root_transform;
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_transform.Translate(60.0, 70.0);
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_transform.Rotate(-90.0);
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_transform.Translate(-50.0, -50.0);
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_transform.Scale(2.0, 3.0);
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform transform;
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  transform.Translate(10.0, 20.0);
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  transform.Rotate(10.0);
4434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  transform.Scale(0.3f, 0.5f);
444a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  host()->SetRootTransform(root_transform);
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->SetTransform(transform);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w11->SetTransform(transform);
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w111->SetTransform(transform);
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1111->SetTransform(transform);
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1111->MoveCursorTo(gfx::Point(10, 10));
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_WIN)
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(yoshiki): fix this to build on Windows. See crbug.com/133413.
4545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ("169,80", QueryLatestMousePositionRequestInHost(host()).ToString());
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("20,53",
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Screen::GetScreenFor(root)->GetCursorScreenPoint().ToString());
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, GetEventHandlerForPoint) {
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w1(
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindow(SK_ColorWHITE, 1, gfx::Rect(10, 10, 500, 500),
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       root_window()));
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w11(
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestWindow(SK_ColorGREEN, 11, gfx::Rect(5, 5, 100, 100), w1.get()));
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w111(
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestWindow(SK_ColorCYAN, 111, gfx::Rect(5, 5, 75, 75), w11.get()));
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w1111(
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestWindow(SK_ColorRED, 1111, gfx::Rect(5, 5, 50, 50), w111.get()));
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w12(
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestWindow(SK_ColorMAGENTA, 12, gfx::Rect(10, 420, 25, 25),
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       w1.get()));
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w121(
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestWindow(SK_ColorYELLOW, 121, gfx::Rect(5, 5, 5, 5), w12.get()));
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w13(
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestWindow(SK_ColorGRAY, 13, gfx::Rect(5, 470, 50, 50), w1.get()));
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Window* root = root_window();
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->parent()->SetBounds(gfx::Rect(500, 500));
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, root->GetEventHandlerForPoint(gfx::Point(5, 5)));
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(w1.get(), root->GetEventHandlerForPoint(gfx::Point(11, 11)));
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(w11.get(), root->GetEventHandlerForPoint(gfx::Point(16, 16)));
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(w111.get(), root->GetEventHandlerForPoint(gfx::Point(21, 21)));
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(w1111.get(), root->GetEventHandlerForPoint(gfx::Point(26, 26)));
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(w12.get(), root->GetEventHandlerForPoint(gfx::Point(21, 431)));
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(w121.get(), root->GetEventHandlerForPoint(gfx::Point(26, 436)));
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(w13.get(), root->GetEventHandlerForPoint(gfx::Point(26, 481)));
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, GetEventHandlerForPointWithOverride) {
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If our child is flush to our top-left corner he gets events just inside the
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // window edges.
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> parent(
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindow(SK_ColorWHITE, 1, gfx::Rect(10, 20, 400, 500),
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       root_window()));
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> child(
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestWindow(SK_ColorRED, 2, gfx::Rect(0, 0, 60, 70), parent.get()));
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child.get(), parent->GetEventHandlerForPoint(gfx::Point(0, 0)));
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child.get(), parent->GetEventHandlerForPoint(gfx::Point(1, 1)));
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We can override the hit test bounds of the parent to make the parent grab
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // events along that edge.
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent->set_hit_test_bounds_override_inner(gfx::Insets(1, 1, 1, 1));
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(parent.get(), parent->GetEventHandlerForPoint(gfx::Point(0, 0)));
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child.get(),  parent->GetEventHandlerForPoint(gfx::Point(1, 1)));
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, GetEventHandlerForPointWithOverrideDescendingOrder) {
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SelfEventHandlingWindowDelegate> parent_delegate(
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new SelfEventHandlingWindowDelegate);
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> parent(CreateTestWindowWithDelegate(
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      parent_delegate.get(), 1, gfx::Rect(10, 20, 400, 500), root_window()));
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> child(
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestWindow(SK_ColorRED, 2, gfx::Rect(0, 0, 390, 480),
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       parent.get()));
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We can override ShouldDescendIntoChildForEventHandling to make the parent
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // grab all events.
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(parent.get(), parent->GetEventHandlerForPoint(gfx::Point(0, 0)));
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(parent.get(), parent->GetEventHandlerForPoint(gfx::Point(50, 50)));
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, GetTopWindowContainingPoint) {
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Window* root = root_window();
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  root->SetBounds(gfx::Rect(0, 0, 300, 300));
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w1(
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindow(SK_ColorWHITE, 1, gfx::Rect(10, 10, 100, 100),
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       root_window()));
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w11(
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestWindow(SK_ColorGREEN, 11, gfx::Rect(0, 0, 120, 120), w1.get()));
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w2(
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindow(SK_ColorRED, 2, gfx::Rect(5, 5, 55, 55),
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       root_window()));
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w3(
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestWindowWithDelegate(
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          NULL, 3, gfx::Rect(200, 200, 100, 100), root_window()));
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w31(
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestWindow(SK_ColorCYAN, 31, gfx::Rect(0, 0, 50, 50), w3.get()));
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w311(
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestWindow(SK_ColorBLUE, 311, gfx::Rect(0, 0, 10, 10), w31.get()));
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, root->GetTopWindowContainingPoint(gfx::Point(0, 0)));
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(w2.get(), root->GetTopWindowContainingPoint(gfx::Point(5, 5)));
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(w2.get(), root->GetTopWindowContainingPoint(gfx::Point(10, 10)));
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(w2.get(), root->GetTopWindowContainingPoint(gfx::Point(59, 59)));
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(w1.get(), root->GetTopWindowContainingPoint(gfx::Point(60, 60)));
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(w1.get(), root->GetTopWindowContainingPoint(gfx::Point(109, 109)));
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, root->GetTopWindowContainingPoint(gfx::Point(110, 110)));
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(w31.get(), root->GetTopWindowContainingPoint(gfx::Point(200, 200)));
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(w31.get(), root->GetTopWindowContainingPoint(gfx::Point(220, 220)));
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, root->GetTopWindowContainingPoint(gfx::Point(260, 260)));
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, GetToplevelWindow) {
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const gfx::Rect kBounds(0, 0, 10, 10);
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestWindowDelegate delegate;
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w11(
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestWindowWithDelegate(&delegate, 11, kBounds, w1.get()));
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w111(CreateTestWindowWithId(111, w11.get()));
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w1111(
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestWindowWithDelegate(&delegate, 1111, kBounds, w111.get()));
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(root_window()->GetToplevelWindow() == NULL);
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(w1->GetToplevelWindow() == NULL);
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(w11.get(), w11->GetToplevelWindow());
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(w11.get(), w111->GetToplevelWindow());
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(w11.get(), w1111->GetToplevelWindow());
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AddedToRootWindowObserver : public WindowObserver {
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddedToRootWindowObserver() : called_(false) {}
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWindowAddedToRootWindow(Window* window) OVERRIDE {
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    called_ = true;
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool called() const { return called_; }
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool called_;
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AddedToRootWindowObserver);
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, WindowAddedToRootWindowShouldNotifyChildAndNotParent) {
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddedToRootWindowObserver parent_observer;
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddedToRootWindowObserver child_observer;
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Window> parent_window(CreateTestWindowWithId(1, root_window()));
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> child_window(new Window(NULL));
5965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  child_window->Init(aura::WINDOW_LAYER_TEXTURED);
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child_window->Show();
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent_window->AddObserver(&parent_observer);
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child_window->AddObserver(&child_observer);
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent_window->AddChild(child_window.get());
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(parent_observer.called());
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(child_observer.called());
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent_window->RemoveObserver(&parent_observer);
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child_window->RemoveObserver(&child_observer);
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Various destruction assertions.
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, DestroyTest) {
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DestroyTrackingDelegateImpl parent_delegate;
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChildWindowDelegateImpl child_delegate(&parent_delegate);
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<Window> parent(
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CreateTestWindowWithDelegate(&parent_delegate, 0, gfx::Rect(),
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     root_window()));
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateTestWindowWithDelegate(&child_delegate, 0, gfx::Rect(), parent.get());
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Both the parent and child should have been destroyed.
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, parent_delegate.destroying_count());
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, parent_delegate.destroyed_count());
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, child_delegate.destroying_count());
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, child_delegate.destroyed_count());
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that a window is orphaned before OnWindowDestroyed is called.
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, OrphanedBeforeOnDestroyed) {
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestWindowDelegate parent_delegate;
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DestroyOrphanDelegate child_delegate;
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<Window> parent(
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CreateTestWindowWithDelegate(&parent_delegate, 0, gfx::Rect(),
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     root_window()));
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<Window> child(CreateTestWindowWithDelegate(&child_delegate, 0,
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          gfx::Rect(), parent.get()));
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    child_delegate.set_window(child.get());
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure StackChildAtTop moves both the window and layer to the front.
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, StackChildAtTop) {
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Window parent(NULL);
6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  parent.Init(aura::WINDOW_LAYER_NOT_DRAWN);
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Window child1(NULL);
6475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  child1.Init(aura::WINDOW_LAYER_NOT_DRAWN);
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Window child2(NULL);
6495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  child2.Init(aura::WINDOW_LAYER_NOT_DRAWN);
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parent.AddChild(&child1);
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parent.AddChild(&child2);
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2u, parent.children().size());
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(&child1, parent.children()[0]);
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(&child2, parent.children()[1]);
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2u, parent.layer()->children().size());
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child1.layer(), parent.layer()->children()[0]);
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child2.layer(), parent.layer()->children()[1]);
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent.StackChildAtTop(&child1);
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2u, parent.children().size());
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(&child1, parent.children()[1]);
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(&child2, parent.children()[0]);
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2u, parent.layer()->children().size());
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child1.layer(), parent.layer()->children()[1]);
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child2.layer(), parent.layer()->children()[0]);
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure StackChildBelow works.
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, StackChildBelow) {
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Window parent(NULL);
6725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  parent.Init(aura::WINDOW_LAYER_NOT_DRAWN);
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Window child1(NULL);
6745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  child1.Init(aura::WINDOW_LAYER_NOT_DRAWN);
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child1.set_id(1);
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Window child2(NULL);
6775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  child2.Init(aura::WINDOW_LAYER_NOT_DRAWN);
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child2.set_id(2);
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Window child3(NULL);
6805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  child3.Init(aura::WINDOW_LAYER_NOT_DRAWN);
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child3.set_id(3);
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parent.AddChild(&child1);
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parent.AddChild(&child2);
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parent.AddChild(&child3);
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("1 2 3", ChildWindowIDsAsString(&parent));
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent.StackChildBelow(&child1, &child2);
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("1 2 3", ChildWindowIDsAsString(&parent));
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent.StackChildBelow(&child2, &child1);
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("2 1 3", ChildWindowIDsAsString(&parent));
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent.StackChildBelow(&child3, &child2);
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("3 2 1", ChildWindowIDsAsString(&parent));
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent.StackChildBelow(&child3, &child1);
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("2 3 1", ChildWindowIDsAsString(&parent));
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Various assertions for StackChildAbove.
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, StackChildAbove) {
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Window parent(NULL);
7045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  parent.Init(aura::WINDOW_LAYER_NOT_DRAWN);
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Window child1(NULL);
7065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  child1.Init(aura::WINDOW_LAYER_NOT_DRAWN);
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Window child2(NULL);
7085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  child2.Init(aura::WINDOW_LAYER_NOT_DRAWN);
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Window child3(NULL);
7105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  child3.Init(aura::WINDOW_LAYER_NOT_DRAWN);
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parent.AddChild(&child1);
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parent.AddChild(&child2);
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move 1 in front of 2.
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent.StackChildAbove(&child1, &child2);
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2u, parent.children().size());
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(&child2, parent.children()[0]);
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(&child1, parent.children()[1]);
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2u, parent.layer()->children().size());
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child2.layer(), parent.layer()->children()[0]);
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child1.layer(), parent.layer()->children()[1]);
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add 3, resulting in order [2, 1, 3], then move 2 in front of 1, resulting
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in [1, 2, 3].
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parent.AddChild(&child3);
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent.StackChildAbove(&child2, &child1);
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3u, parent.children().size());
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(&child1, parent.children()[0]);
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(&child2, parent.children()[1]);
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(&child3, parent.children()[2]);
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3u, parent.layer()->children().size());
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child1.layer(), parent.layer()->children()[0]);
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child2.layer(), parent.layer()->children()[1]);
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child3.layer(), parent.layer()->children()[2]);
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move 1 in front of 3, resulting in [2, 3, 1].
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent.StackChildAbove(&child1, &child3);
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3u, parent.children().size());
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(&child2, parent.children()[0]);
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(&child3, parent.children()[1]);
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(&child1, parent.children()[2]);
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3u, parent.layer()->children().size());
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child2.layer(), parent.layer()->children()[0]);
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child3.layer(), parent.layer()->children()[1]);
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child1.layer(), parent.layer()->children()[2]);
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Moving 1 in front of 2 should lower it, resulting in [2, 1, 3].
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent.StackChildAbove(&child1, &child2);
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3u, parent.children().size());
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(&child2, parent.children()[0]);
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(&child1, parent.children()[1]);
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(&child3, parent.children()[2]);
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3u, parent.layer()->children().size());
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child2.layer(), parent.layer()->children()[0]);
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child1.layer(), parent.layer()->children()[1]);
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(child3.layer(), parent.layer()->children()[2]);
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Various capture assertions.
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, CaptureTests) {
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptureWindowDelegateImpl delegate;
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> window(CreateTestWindowWithDelegate(
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &delegate, 0, gfx::Rect(0, 0, 20, 20), root_window()));
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(window->HasCapture());
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate.ResetCounts();
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do a capture.
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window->SetCapture();
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(window->HasCapture());
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, delegate.capture_lost_count());
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, delegate.capture_changed_event_count());
7745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::test::EventGenerator generator(root_window(), gfx::Point(50, 50));
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.PressLeftButton();
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, delegate.mouse_event_count());
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.ReleaseLeftButton();
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, delegate.mouse_event_count());
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate.ResetCounts();
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::TouchEvent touchev(
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::ET_TOUCH_PRESSED, gfx::Point(50, 50), 0, getTime());
7845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DispatchEventUsingWindowDispatcher(&touchev);
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, delegate.touch_event_count());
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate.ResetCounts();
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window->ReleaseCapture();
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(window->HasCapture());
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, delegate.capture_lost_count());
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, delegate.capture_changed_event_count());
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, delegate.mouse_event_count());
793c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, delegate.touch_event_count());
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.PressLeftButton();
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, delegate.mouse_event_count());
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::TouchEvent touchev2(
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::ET_TOUCH_PRESSED, gfx::Point(250, 250), 1, getTime());
8005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DispatchEventUsingWindowDispatcher(&touchev2);
801c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, delegate.touch_event_count());
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Removing the capture window from parent should reset the capture window
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in the root window.
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window->SetCapture();
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(window.get(), aura::client::GetCaptureWindow(root_window()));
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window->parent()->RemoveChild(window.get());
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(window->HasCapture());
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, aura::client::GetCaptureWindow(root_window()));
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, TouchCaptureCancelsOtherTouches) {
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptureWindowDelegateImpl delegate1;
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w1(CreateTestWindowWithDelegate(
815c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &delegate1, 0, gfx::Rect(0, 0, 50, 50), root_window()));
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptureWindowDelegateImpl delegate2;
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w2(CreateTestWindowWithDelegate(
818c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &delegate2, 0, gfx::Rect(50, 50, 50, 50), root_window()));
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Press on w1.
8216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ui::TouchEvent press1(
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 0, getTime());
8236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DispatchEventUsingWindowDispatcher(&press1);
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We will get both GESTURE_BEGIN and GESTURE_TAP_DOWN.
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, delegate1.gesture_event_count());
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate1.ResetCounts();
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
828c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Capturing to w2 should cause the touch to be canceled.
829c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  w2->SetCapture();
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, delegate1.touch_event_count());
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, delegate2.touch_event_count());
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate1.ResetCounts();
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate2.ResetCounts();
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Events now go to w2.
836c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(10, 20), 0, getTime());
8375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DispatchEventUsingWindowDispatcher(&move);
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, delegate1.gesture_event_count());
839c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, delegate1.touch_event_count());
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, delegate2.gesture_event_count());
8411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(1, delegate2.touch_event_count());
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::TouchEvent release(
844c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ui::ET_TOUCH_RELEASED, gfx::Point(10, 20), 0, getTime());
8455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DispatchEventUsingWindowDispatcher(&release);
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, delegate1.gesture_event_count());
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, delegate2.gesture_event_count());
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A new press is captured by w2.
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::TouchEvent press2(
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 0, getTime());
8525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DispatchEventUsingWindowDispatcher(&press2);
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, delegate1.gesture_event_count());
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We will get both GESTURE_BEGIN and GESTURE_TAP_DOWN.
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, delegate2.gesture_event_count());
856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  delegate1.ResetCounts();
857c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  delegate2.ResetCounts();
858c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
859c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // And releasing capture changes nothing.
860c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  w2->ReleaseCapture();
861c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, delegate1.gesture_event_count());
862c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, delegate1.touch_event_count());
863c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, delegate2.gesture_event_count());
864c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, delegate2.touch_event_count());
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, TouchCaptureDoesntCancelCapturedTouches) {
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptureWindowDelegateImpl delegate;
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> window(CreateTestWindowWithDelegate(
870c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &delegate, 0, gfx::Rect(0, 0, 50, 50), root_window()));
8715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::TimeDelta time = getTime();
8725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const int kTimeDelta = 100;
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::TouchEvent press(
8755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 0, time);
8765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DispatchEventUsingWindowDispatcher(&press);
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We will get both GESTURE_BEGIN and GESTURE_TAP_DOWN.
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, delegate.gesture_event_count());
880c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, delegate.touch_event_count());
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate.ResetCounts();
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window->SetCapture();
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, delegate.gesture_event_count());
885c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, delegate.touch_event_count());
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate.ResetCounts();
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
888c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // On move We will get TOUCH_MOVED, GESTURE_TAP_CANCEL,
889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // GESTURE_SCROLL_START and GESTURE_SCROLL_UPDATE.
8905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  time += base::TimeDelta::FromMilliseconds(kTimeDelta);
8915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(10, 20), 0, time);
8925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DispatchEventUsingWindowDispatcher(&move);
893c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, delegate.touch_event_count());
894c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(3, delegate.gesture_event_count());
895c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  delegate.ResetCounts();
896c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
897c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Release capture shouldn't change anything.
898c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  window->ReleaseCapture();
899c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, delegate.touch_event_count());
900c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, delegate.gesture_event_count());
901c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  delegate.ResetCounts();
902c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
903c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // On move we still get TOUCH_MOVED and GESTURE_SCROLL_UPDATE.
9045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  time += base::TimeDelta::FromMilliseconds(kTimeDelta);
9055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(10, 30), 0, time);
9065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DispatchEventUsingWindowDispatcher(&move2);
907c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, delegate.touch_event_count());
908c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, delegate.gesture_event_count());
909c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  delegate.ResetCounts();
910c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
911c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // And on release we get TOUCH_RELEASED, GESTURE_SCROLL_END, GESTURE_END
9125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  time += base::TimeDelta::FromMilliseconds(kTimeDelta);
913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ui::TouchEvent release(
9145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ui::ET_TOUCH_RELEASED, gfx::Point(10, 20), 0, time);
9155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DispatchEventUsingWindowDispatcher(&release);
916c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, delegate.touch_event_count());
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, delegate.gesture_event_count());
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
920c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Assertions around SetCapture() and touch/gestures.
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, TransferCaptureTouchEvents) {
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Touch on |w1|.
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptureWindowDelegateImpl d1;
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w1(CreateTestWindowWithDelegate(
9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &d1, 0, gfx::Rect(0, 0, 20, 20), root_window()));
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::TouchEvent p1(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 0, getTime());
9285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DispatchEventUsingWindowDispatcher(&p1);
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We will get both GESTURE_BEGIN and GESTURE_TAP_DOWN.
930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, d1.touch_event_count());
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, d1.gesture_event_count());
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  d1.ResetCounts();
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Touch on |w2| with a different id.
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptureWindowDelegateImpl d2;
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w2(CreateTestWindowWithDelegate(
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &d2, 0, gfx::Rect(40, 0, 40, 20), root_window()));
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::TouchEvent p2(ui::ET_TOUCH_PRESSED, gfx::Point(41, 10), 1, getTime());
9395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DispatchEventUsingWindowDispatcher(&p2);
940c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, d1.touch_event_count());
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, d1.gesture_event_count());
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We will get both GESTURE_BEGIN and GESTURE_TAP_DOWN for new target window.
943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, d2.touch_event_count());
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, d2.gesture_event_count());
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  d1.ResetCounts();
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  d2.ResetCounts();
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set capture on |w2|, this should send a cancel (TAP_CANCEL, END) to |w1|
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // but not |w2|.
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w2->SetCapture();
951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, d1.touch_event_count());
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, d1.gesture_event_count());
953c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, d2.touch_event_count());
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, d2.gesture_event_count());
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  d1.ResetCounts();
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  d2.ResetCounts();
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptureWindowDelegateImpl d3;
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w3(CreateTestWindowWithDelegate(
9602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &d3, 0, gfx::Rect(0, 0, 100, 101), root_window()));
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set capture on w3. No new events should be received.
962c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Note this difference in behavior between the first and second capture
963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // is confusing and error prone.  http://crbug.com/236930
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w3->SetCapture();
965c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, d1.touch_event_count());
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, d1.gesture_event_count());
967c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, d2.touch_event_count());
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, d2.gesture_event_count());
969c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, d3.touch_event_count());
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, d3.gesture_event_count());
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move touch id originally associated with |w2|. Since capture was transfered
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from 2 to 3 only |w3| should get the event.
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::TouchEvent m3(ui::ET_TOUCH_MOVED, gfx::Point(110, 105), 1, getTime());
9755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DispatchEventUsingWindowDispatcher(&m3);
976c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, d1.touch_event_count());
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, d1.gesture_event_count());
978c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, d2.touch_event_count());
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, d2.gesture_event_count());
980c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // |w3| gets a TOUCH_MOVE, TAP_CANCEL and two scroll related events.
981c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, d3.touch_event_count());
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, d3.gesture_event_count());
983c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  d1.ResetCounts();
984c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  d2.ResetCounts();
985c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  d3.ResetCounts();
986c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
987c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // When we release capture, no touches are canceled.
988c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  w3->ReleaseCapture();
989c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, d1.touch_event_count());
990c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, d1.gesture_event_count());
991c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, d2.touch_event_count());
992c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, d2.gesture_event_count());
993c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, d3.touch_event_count());
994c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, d3.gesture_event_count());
995c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
996c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // And when we move the touch again, |w3| still gets the events.
997c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ui::TouchEvent m4(ui::ET_TOUCH_MOVED, gfx::Point(120, 105), 1, getTime());
9985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DispatchEventUsingWindowDispatcher(&m4);
999c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, d1.touch_event_count());
1000c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, d1.gesture_event_count());
1001c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, d2.touch_event_count());
1002c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, d2.gesture_event_count());
1003c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, d3.touch_event_count());
1004c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, d3.gesture_event_count());
1005c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  d1.ResetCounts();
1006c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  d2.ResetCounts();
1007c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  d3.ResetCounts();
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Changes capture while capture is already ongoing.
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, ChangeCaptureWhileMouseDown) {
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptureWindowDelegateImpl delegate;
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> window(CreateTestWindowWithDelegate(
10142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &delegate, 0, gfx::Rect(0, 0, 20, 20), root_window()));
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptureWindowDelegateImpl delegate2;
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w2(CreateTestWindowWithDelegate(
10172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &delegate2, 0, gfx::Rect(20, 20, 20, 20), root_window()));
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Execute the scheduled draws so that mouse events are not
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // aggregated.
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(window->HasCapture());
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do a capture.
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate.ResetCounts();
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window->SetCapture();
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(window->HasCapture());
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, delegate.capture_lost_count());
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, delegate.capture_changed_event_count());
10315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::test::EventGenerator generator(root_window(), gfx::Point(50, 50));
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.PressLeftButton();
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, delegate.capture_lost_count());
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, delegate.capture_changed_event_count());
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, delegate.mouse_event_count());
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set capture to |w2|, should implicitly unset capture for |window|.
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate.ResetCounts();
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate2.ResetCounts();
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w2->SetCapture();
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.MoveMouseTo(gfx::Point(40, 40), 2);
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, delegate.capture_lost_count());
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, delegate.capture_changed_event_count());
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, delegate.mouse_event_count());
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, delegate2.mouse_event_count());
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies capture is reset when a window is destroyed.
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, ReleaseCaptureOnDestroy) {
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptureWindowDelegateImpl delegate;
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> window(CreateTestWindowWithDelegate(
10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &delegate, 0, gfx::Rect(0, 0, 20, 20), root_window()));
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(window->HasCapture());
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do a capture.
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window->SetCapture();
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(window->HasCapture());
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Destroy the window.
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window.reset();
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the root window doesn't reference the window anymore.
1064a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(NULL, host()->dispatcher()->mouse_pressed_handler());
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, aura::client::GetCaptureWindow(root_window()));
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, GetBoundsInRootWindow) {
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> viewport(CreateTestWindowWithBounds(
10702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(0, 0, 300, 300), root_window()));
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> child(CreateTestWindowWithBounds(
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Rect(0, 0, 100, 100), viewport.get()));
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sanity check.
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,0 100x100", child->GetBoundsInRootWindow().ToString());
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The |child| window's screen bounds should move along with the |viewport|.
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  viewport->SetBounds(gfx::Rect(-100, -100, 300, 300));
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("-100,-100 100x100", child->GetBoundsInRootWindow().ToString());
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The |child| window is moved to the 0,0 in screen coordinates.
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |GetBoundsInRootWindow()| should return 0,0.
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child->SetBounds(gfx::Rect(100, 100, 100, 100));
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,0 100x100", child->GetBoundsInRootWindow().ToString());
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MouseEnterExitWindowDelegate : public TestWindowDelegate {
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MouseEnterExitWindowDelegate() : entered_(false), exited_(false) {}
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (event->type()) {
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case ui::ET_MOUSE_ENTERED:
1093eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        EXPECT_TRUE(event->flags() & ui::EF_IS_SYNTHESIZED);
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        entered_ = true;
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case ui::ET_MOUSE_EXITED:
1097eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        EXPECT_TRUE(event->flags() & ui::EF_IS_SYNTHESIZED);
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        exited_ = true;
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool entered() const { return entered_; }
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool exited() const { return exited_; }
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear the entered / exited states.
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ResetExpectations() {
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entered_ = false;
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exited_ = false;
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool entered_;
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool exited_;
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MouseEnterExitWindowDelegate);
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies that the WindowDelegate receives MouseExit and MouseEnter events for
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// mouse transitions from window to window.
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, MouseEnterExit) {
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MouseEnterExitWindowDelegate d1;
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w1(
11272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindowWithDelegate(&d1, 1, gfx::Rect(10, 10, 50, 50),
11282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   root_window()));
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MouseEnterExitWindowDelegate d2;
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w2(
11312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindowWithDelegate(&d2, 2, gfx::Rect(70, 70, 50, 50),
11322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   root_window()));
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::test::EventGenerator generator(root_window());
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.MoveMouseToCenterOf(w1.get());
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(d1.entered());
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(d1.exited());
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(d2.entered());
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(d2.exited());
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.MoveMouseToCenterOf(w2.get());
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(d1.entered());
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(d1.exited());
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(d2.entered());
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(d2.exited());
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Verifies that the WindowDelegate receives MouseExit from ET_MOUSE_EXITED.
11495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(WindowTest, WindowTreeHostExit) {
11502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MouseEnterExitWindowDelegate d1;
11512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Window> w1(
11522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindowWithDelegate(&d1, 1, gfx::Rect(10, 10, 50, 50),
11532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   root_window()));
11542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::test::EventGenerator generator(root_window());
11562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator.MoveMouseToCenterOf(w1.get());
11572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(d1.entered());
11582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(d1.exited());
11592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  d1.ResetExpectations();
11602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::MouseEvent exit_event(
11625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ui::ET_MOUSE_EXITED, gfx::Point(), gfx::Point(), 0, 0);
11635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DispatchEventUsingWindowDispatcher(&exit_event);
11642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(d1.entered());
11652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(d1.exited());
11662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies that the WindowDelegate receives MouseExit and MouseEnter events for
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// mouse transitions from window to window, even if the entered window sets
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and releases capture.
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, MouseEnterExitWithClick) {
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MouseEnterExitWindowDelegate d1;
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w1(
11742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindowWithDelegate(&d1, 1, gfx::Rect(10, 10, 50, 50),
11752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   root_window()));
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MouseEnterExitWindowDelegate d2;
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w2(
11782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindowWithDelegate(&d2, 2, gfx::Rect(70, 70, 50, 50),
11792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   root_window()));
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::test::EventGenerator generator(root_window());
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.MoveMouseToCenterOf(w1.get());
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(d1.entered());
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(d1.exited());
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(d2.entered());
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(d2.exited());
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Emmulate what Views does on a click by grabbing and releasing capture.
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.PressLeftButton();
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->SetCapture();
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->ReleaseCapture();
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.ReleaseLeftButton();
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.MoveMouseToCenterOf(w2.get());
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(d1.entered());
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(d1.exited());
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(d2.entered());
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(d2.exited());
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
120190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(WindowTest, MouseEnterExitWhenDeleteWithCapture) {
120290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  MouseEnterExitWindowDelegate delegate;
120390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<Window> window(
120490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      CreateTestWindowWithDelegate(&delegate, 1, gfx::Rect(10, 10, 50, 50),
120590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                   root_window()));
120690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
12075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::test::EventGenerator generator(root_window());
120890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  generator.MoveMouseToCenterOf(window.get());
120990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(delegate.entered());
121090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(delegate.exited());
121190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
121290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Emmulate what Views does on a click by grabbing and releasing capture.
121390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  generator.PressLeftButton();
121490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  window->SetCapture();
121590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
121690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  delegate.ResetExpectations();
121790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  generator.MoveMouseTo(0, 0);
121890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(delegate.entered());
121990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(delegate.exited());
122090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
122190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  delegate.ResetExpectations();
122290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  window.reset();
122390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(delegate.entered());
122490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(delegate.exited());
122590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
122690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies that enter / exits are sent if windows appear and are deleted
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// under the current mouse position..
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, MouseEnterExitWithDelete) {
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MouseEnterExitWindowDelegate d1;
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w1(
12322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindowWithDelegate(&d1, 1, gfx::Rect(10, 10, 50, 50),
12332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   root_window()));
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::test::EventGenerator generator(root_window());
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.MoveMouseToCenterOf(w1.get());
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(d1.entered());
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(d1.exited());
12395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  d1.ResetExpectations();
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
124190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  MouseEnterExitWindowDelegate d2;
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<Window> w2(
12442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CreateTestWindowWithDelegate(&d2, 2, gfx::Rect(10, 10, 50, 50),
12452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     root_window()));
12465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Enters / exits can be sent asynchronously.
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunAllPendingInMessageLoop();
12485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_FALSE(d1.entered());
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(d1.exited());
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(d2.entered());
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(d2.exited());
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    d1.ResetExpectations();
12535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    d2.ResetExpectations();
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Enters / exits can be sent asynchronously.
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
125790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(d2.exited());
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(d1.entered());
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies that enter / exits are sent if windows appear and are hidden
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// under the current mouse position..
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, MouseEnterExitWithHide) {
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MouseEnterExitWindowDelegate d1;
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w1(
12662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindowWithDelegate(&d1, 1, gfx::Rect(10, 10, 50, 50),
12672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   root_window()));
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::test::EventGenerator generator(root_window());
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.MoveMouseToCenterOf(w1.get());
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(d1.entered());
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(d1.exited());
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MouseEnterExitWindowDelegate d2;
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w2(
12762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindowWithDelegate(&d2, 2, gfx::Rect(10, 10, 50, 50),
12772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   root_window()));
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enters / exits can be send asynchronously.
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(d1.entered());
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(d1.exited());
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(d2.entered());
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(d2.exited());
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  d1.ResetExpectations();
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w2->Hide();
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enters / exits can be send asynchronously.
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
128990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(d2.exited());
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(d1.entered());
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
129390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(WindowTest, MouseEnterExitWithParentHide) {
129490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  MouseEnterExitWindowDelegate d1;
129590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<Window> w1(
129690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      CreateTestWindowWithDelegate(&d1, 1, gfx::Rect(10, 10, 50, 50),
129790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                   root_window()));
129890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  MouseEnterExitWindowDelegate d2;
129990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Window* w2 = CreateTestWindowWithDelegate(&d2, 2, gfx::Rect(10, 10, 50, 50),
130090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                            w1.get());
13015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::test::EventGenerator generator(root_window());
130290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  generator.MoveMouseToCenterOf(w2);
130390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Enters / exits can be send asynchronously.
130490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  RunAllPendingInMessageLoop();
130590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(d2.entered());
130690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(d2.exited());
130790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
130890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  d2.ResetExpectations();
130990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  w1->Hide();
131090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  RunAllPendingInMessageLoop();
131190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(d2.entered());
131290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(d2.exited());
131390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
131490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  w1.reset();
131590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
131690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
131790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(WindowTest, MouseEnterExitWithParentDelete) {
131890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  MouseEnterExitWindowDelegate d1;
131990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<Window> w1(
132090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      CreateTestWindowWithDelegate(&d1, 1, gfx::Rect(10, 10, 50, 50),
132190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                   root_window()));
132290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  MouseEnterExitWindowDelegate d2;
132390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Window* w2 = CreateTestWindowWithDelegate(&d2, 2, gfx::Rect(10, 10, 50, 50),
132490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                            w1.get());
13255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::test::EventGenerator generator(root_window());
132690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  generator.MoveMouseToCenterOf(w2);
132790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
132890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Enters / exits can be send asynchronously.
132990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  RunAllPendingInMessageLoop();
133090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(d2.entered());
133190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(d2.exited());
133290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
133390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  d2.ResetExpectations();
133490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  w1.reset();
133590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  RunAllPendingInMessageLoop();
133690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(d2.entered());
133790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(d2.exited());
133890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
133990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates a window with a delegate (w111) that can handle events at a lower
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// z-index than a window without a delegate (w12). w12 is sized to fill the
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// entire bounds of the container. This test verifies that
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GetEventHandlerForPoint() skips w12 even though its bounds contain the event,
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// because it has no children that can handle the event and it has no delegate
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// allowing it to handle the event itself.
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, GetEventHandlerForPoint_NoDelegate) {
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestWindowDelegate d111;
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w1(CreateTestWindowWithDelegate(NULL, 1,
13492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(0, 0, 500, 500), root_window()));
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w11(CreateTestWindowWithDelegate(NULL, 11,
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Rect(0, 0, 500, 500), w1.get()));
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w111(CreateTestWindowWithDelegate(&d111, 111,
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Rect(50, 50, 450, 450), w11.get()));
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w12(CreateTestWindowWithDelegate(NULL, 12,
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Rect(0, 0, 500, 500), w1.get()));
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point target_point = w111->bounds().CenterPoint();
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(w111.get(), w1->GetEventHandlerForPoint(target_point));
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VisibilityWindowDelegate : public TestWindowDelegate {
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisibilityWindowDelegate()
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : shown_(0),
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        hidden_(0) {
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int shown() const { return shown_; }
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int hidden() const { return hidden_; }
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Clear() {
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shown_ = 0;
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hidden_ = 0;
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWindowTargetVisibilityChanged(bool visible) OVERRIDE {
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (visible)
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      shown_++;
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hidden_++;
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int shown_;
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int hidden_;
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(VisibilityWindowDelegate);
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies show/hide propagate correctly to children and the layer.
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, Visibility) {
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisibilityWindowDelegate d;
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisibilityWindowDelegate d2;
13932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Window> w1(CreateTestWindowWithDelegate(&d, 1, gfx::Rect(),
13942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                     root_window()));
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w2(
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestWindowWithDelegate(&d2, 2, gfx::Rect(),  w1.get()));
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w3(CreateTestWindowWithId(3, w2.get()));
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create shows all the windows.
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(w1->IsVisible());
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(w2->IsVisible());
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(w3->IsVisible());
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, d.shown());
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  d.Clear();
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->Hide();
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(w1->IsVisible());
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(w2->IsVisible());
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(w3->IsVisible());
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, d.hidden());
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, d.shown());
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w2->Show();
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(w1->IsVisible());
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(w2->IsVisible());
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(w3->IsVisible());
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w3->Hide();
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(w1->IsVisible());
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(w2->IsVisible());
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(w3->IsVisible());
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  d.Clear();
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->Show();
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(w1->IsVisible());
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(w2->IsVisible());
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(w3->IsVisible());
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, d.hidden());
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, d.shown());
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w3->Show();
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(w1->IsVisible());
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(w2->IsVisible());
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(w3->IsVisible());
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that if an ancestor isn't visible and we change the visibility of a
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // child window that OnChildWindowVisibilityChanged() is still invoked.
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->Hide();
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  d2.Clear();
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w2->Hide();
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, d2.hidden());
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, d2.shown());
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  d2.Clear();
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w2->Show();
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, d2.hidden());
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, d2.shown());
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, IgnoreEventsTest) {
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestWindowDelegate d11;
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestWindowDelegate d12;
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestWindowDelegate d111;
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestWindowDelegate d121;
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w1(CreateTestWindowWithDelegate(NULL, 1,
14552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(0, 0, 500, 500), root_window()));
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w11(CreateTestWindowWithDelegate(&d11, 11,
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Rect(0, 0, 500, 500), w1.get()));
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w111(CreateTestWindowWithDelegate(&d111, 111,
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Rect(50, 50, 450, 450), w11.get()));
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w12(CreateTestWindowWithDelegate(&d12, 12,
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Rect(0, 0, 500, 500), w1.get()));
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w121(CreateTestWindowWithDelegate(&d121, 121,
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Rect(150, 150, 50, 50), w12.get()));
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(w12.get(), w1->GetEventHandlerForPoint(gfx::Point(10, 10)));
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w12->set_ignore_events(true);
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(w11.get(), w1->GetEventHandlerForPoint(gfx::Point(10, 10)));
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w12->set_ignore_events(false);
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(w121.get(), w1->GetEventHandlerForPoint(gfx::Point(160, 160)));
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w121->set_ignore_events(true);
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(w12.get(), w1->GetEventHandlerForPoint(gfx::Point(160, 160)));
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w12->set_ignore_events(true);
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(w111.get(), w1->GetEventHandlerForPoint(gfx::Point(160, 160)));
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w111->set_ignore_events(true);
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(w11.get(), w1->GetEventHandlerForPoint(gfx::Point(160, 160)));
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests transformation on the root window.
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, Transform) {
1481a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  gfx::Size size = host()->GetBounds().size();
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Rect(size),
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            gfx::Screen::GetScreenFor(root_window())->GetDisplayNearestPoint(
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                gfx::Point()).bounds());
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Rotate it clock-wise 90 degrees.
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Transform transform;
14882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  transform.Translate(size.height(), 0);
14892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  transform.Rotate(90.0);
1490a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  host()->SetRootTransform(transform);
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The size should be the transformed size.
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size transformed_size(size.height(), size.width());
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(transformed_size.ToString(),
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            root_window()->bounds().size().ToString());
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Rect(transformed_size).ToString(),
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Screen::GetScreenFor(root_window())->GetDisplayNearestPoint(
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          gfx::Point()).bounds().ToString());
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Host size shouldn't change.
1502a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(size.ToString(), host()->GetBounds().size().ToString());
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, TransformGesture) {
1506a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  gfx::Size size = host()->GetBounds().size();
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<GestureTrackPositionDelegate> delegate(
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new GestureTrackPositionDelegate);
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> window(CreateTestWindowWithDelegate(delegate.get(), -1234,
15112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(0, 0, 20, 20), root_window()));
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Rotate the root-window clock-wise 90 degrees.
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Transform transform;
15152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  transform.Translate(size.height(), 0.0);
15162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  transform.Rotate(90.0);
1517a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  host()->SetRootTransform(transform);
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::TouchEvent press(
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::ET_TOUCH_PRESSED, gfx::Point(size.height() - 10, 10), 0, getTime());
15215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DispatchEventUsingWindowDispatcher(&press);
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Point(10, 10).ToString(), delegate->position().ToString());
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DEFINE_WINDOW_PROPERTY_KEY(int, kIntKey, -2);
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DEFINE_WINDOW_PROPERTY_KEY(const char*, kStringKey, "squeamish");
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, Property) {
15312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Window> w(CreateTestWindowWithId(0, root_window()));
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char native_prop_key[] = "fnord";
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Non-existent properties should return the default values.
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-2, w->GetProperty(kIntKey));
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string("squeamish"), w->GetProperty(kStringKey));
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, w->GetNativeWindowProperty(native_prop_key));
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A set property value should be returned again (even if it's the default
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // value).
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w->SetProperty(kIntKey, INT_MAX);
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(INT_MAX, w->GetProperty(kIntKey));
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w->SetProperty(kIntKey, -2);
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-2, w->GetProperty(kIntKey));
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w->SetProperty(kIntKey, INT_MIN);
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(INT_MIN, w->GetProperty(kIntKey));
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w->SetProperty(kStringKey, static_cast<const char*>(NULL));
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, w->GetProperty(kStringKey));
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w->SetProperty(kStringKey, "squeamish");
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string("squeamish"), w->GetProperty(kStringKey));
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w->SetProperty(kStringKey, "ossifrage");
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string("ossifrage"), w->GetProperty(kStringKey));
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w->SetNativeWindowProperty(native_prop_key, &*w);
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(&*w, w->GetNativeWindowProperty(native_prop_key));
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w->SetNativeWindowProperty(native_prop_key, NULL);
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, w->GetNativeWindowProperty(native_prop_key));
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ClearProperty should restore the default value.
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w->ClearProperty(kIntKey);
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-2, w->GetProperty(kIntKey));
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w->ClearProperty(kStringKey);
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string("squeamish"), w->GetProperty(kStringKey));
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestProperty {
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestProperty() {}
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~TestProperty() {
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_deleted_ = this;
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static TestProperty* last_deleted() { return last_deleted_; }
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static TestProperty* last_deleted_;
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestProperty);
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TestProperty* TestProperty::last_deleted_ = NULL;
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DEFINE_OWNED_WINDOW_PROPERTY_KEY(TestProperty, kOwnedKey, NULL);
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, OwnedProperty) {
15902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Window> w(CreateTestWindowWithId(0, root_window()));
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, w->GetProperty(kOwnedKey));
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestProperty* p1 = new TestProperty();
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w->SetProperty(kOwnedKey, p1);
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(p1, w->GetProperty(kOwnedKey));
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, TestProperty::last_deleted());
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestProperty* p2 = new TestProperty();
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w->SetProperty(kOwnedKey, p2);
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(p2, w->GetProperty(kOwnedKey));
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(p1, TestProperty::last_deleted());
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w->ClearProperty(kOwnedKey);
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, w->GetProperty(kOwnedKey));
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(p2, TestProperty::last_deleted());
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestProperty* p3 = new TestProperty();
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w->SetProperty(kOwnedKey, p3);
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(p3, w->GetProperty(kOwnedKey));
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(p2, TestProperty::last_deleted());
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w.reset();
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(p3, TestProperty::last_deleted());
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, SetBoundsInternalShouldCheckTargetBounds) {
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We cannot short-circuit animations in this test.
16165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::ScopedAnimationDurationScaleMode test_duration_mode(
16175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w1(
16202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindowWithBounds(gfx::Rect(0, 0, 100, 100), root_window()));
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(!w1->layer());
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->layer()->GetAnimator()->set_disable_timer_for_test(true);
162446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ui::LayerAnimator* animator = w1->layer()->GetAnimator();
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,0 100x100", w1->bounds().ToString());
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,0 100x100", w1->layer()->GetTargetBounds().ToString());
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Animate to a different position.
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::ScopedLayerAnimationSettings settings(w1->layer()->GetAnimator());
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    w1->SetBounds(gfx::Rect(100, 100, 100, 100));
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,0 100x100", w1->bounds().ToString());
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("100,100 100x100", w1->layer()->GetTargetBounds().ToString());
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Animate back to the first position. The animation hasn't started yet, so
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the current bounds are still (0, 0, 100, 100), but the target bounds are
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (100, 100, 100, 100). If we step the animator ahead, we should find that
16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we're at (0, 0, 100, 100). That is, the second animation should be applied.
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::ScopedLayerAnimationSettings settings(w1->layer()->GetAnimator());
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    w1->SetBounds(gfx::Rect(0, 0, 100, 100));
16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,0 100x100", w1->bounds().ToString());
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,0 100x100", w1->layer()->GetTargetBounds().ToString());
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Confirm that the target bounds are reached.
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeTicks start_time =
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      w1->layer()->GetAnimator()->last_step_time();
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  animator->Step(start_time + base::TimeDelta::FromMilliseconds(1000));
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,0 100x100", w1->bounds().ToString());
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::pair<const void*, intptr_t> PropertyChangeInfo;
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WindowObserverTest : public WindowTest,
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           public WindowObserver {
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct VisibilityInfo {
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool window_visible;
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool visible_param;
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WindowObserverTest()
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : added_count_(0),
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        removed_count_(0),
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        destroyed_count_(0),
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        old_property_value_(-3) {
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~WindowObserverTest() {}
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const VisibilityInfo* GetVisibilityInfo() const {
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return visibility_info_.get();
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ResetVisibilityInfo() {
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    visibility_info_.reset();
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns a description of the WindowObserver methods that have been invoked.
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string WindowObserverCountStateAndClear() {
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string result(
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::StringPrintf("added=%d removed=%d",
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        added_count_, removed_count_));
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    added_count_ = removed_count_ = 0;
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result;
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int DestroyedCountAndClear() {
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int result = destroyed_count_;
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    destroyed_count_ = 0;
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result;
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return a tuple of the arguments passed in OnPropertyChanged callback.
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PropertyChangeInfo PropertyChangeInfoAndClear() {
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PropertyChangeInfo result(property_key_, old_property_value_);
17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    property_key_ = NULL;
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    old_property_value_ = -3;
17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result;
17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string TransformNotificationsAndClear() {
17111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::string result;
17121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    for (std::vector<std::pair<int, int> >::iterator it =
17131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            transform_notifications_.begin();
17141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        it != transform_notifications_.end();
17151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        ++it) {
17161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::StringAppendF(&result, "(%d,%d)", it->first, it->second);
17171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
17181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    transform_notifications_.clear();
17191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return result;
17201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
17211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWindowAdded(Window* new_window) OVERRIDE {
17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    added_count_++;
17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWillRemoveWindow(Window* window) OVERRIDE {
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    removed_count_++;
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWindowVisibilityChanged(Window* window,
17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         bool visible) OVERRIDE {
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    visibility_info_.reset(new VisibilityInfo);
17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    visibility_info_->window_visible = window->IsVisible();
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    visibility_info_->visible_param = visible;
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWindowDestroyed(Window* window) OVERRIDE {
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(window->parent());
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    destroyed_count_++;
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWindowPropertyChanged(Window* window,
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const void* key,
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       intptr_t old) OVERRIDE {
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    property_key_ = key;
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    old_property_value_ = old;
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void OnAncestorWindowTransformed(Window* source,
17511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                           Window* window) OVERRIDE {
17521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    transform_notifications_.push_back(
17531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        std::make_pair(source->id(), window->id()));
17541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
17551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int added_count_;
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int removed_count_;
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int destroyed_count_;
17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<VisibilityInfo> visibility_info_;
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const void* property_key_;
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  intptr_t old_property_value_;
17621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<std::pair<int, int> > transform_notifications_;
17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WindowObserverTest);
17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Various assertions for WindowObserver.
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowObserverTest, WindowObserver) {
17692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->AddObserver(this);
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a new window as a child of w1, our observer should be notified.
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w2(CreateTestWindowWithId(2, w1.get()));
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("added=1 removed=0", WindowObserverCountStateAndClear());
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delete w2, which should result in the remove notification.
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w2.reset();
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("added=0 removed=1", WindowObserverCountStateAndClear());
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a window that isn't parented to w1, we shouldn't get any
17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // notification.
17822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Window> w3(CreateTestWindowWithId(3, root_window()));
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("added=0 removed=0", WindowObserverCountStateAndClear());
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Similarly destroying w3 shouldn't notify us either.
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w3.reset();
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("added=0 removed=0", WindowObserverCountStateAndClear());
17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->RemoveObserver(this);
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test if OnWindowVisibilityChagned is invoked with expected
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// parameters.
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowObserverTest, WindowVisibility) {
17942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w2(CreateTestWindowWithId(1, w1.get()));
17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w2->AddObserver(this);
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Hide should make the window invisible and the passed visible
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // parameter is false.
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w2->Hide();
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(!GetVisibilityInfo());
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(!GetVisibilityInfo());
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetVisibilityInfo())
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(GetVisibilityInfo()->window_visible);
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(GetVisibilityInfo()->visible_param);
18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If parent isn't visible, showing window won't make the window visible, but
18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // passed visible value must be true.
18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->Hide();
18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResetVisibilityInfo();
18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(!GetVisibilityInfo());
18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w2->Show();
18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(!GetVisibilityInfo());
18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetVisibilityInfo())
18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(GetVisibilityInfo()->window_visible);
18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetVisibilityInfo()->visible_param);
18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If parent is visible, showing window will make the window
18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // visible and the passed visible value is true.
18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->Show();
18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w2->Hide();
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResetVisibilityInfo();
18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w2->Show();
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(!GetVisibilityInfo());
18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetVisibilityInfo())
18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetVisibilityInfo()->window_visible);
18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetVisibilityInfo()->visible_param);
18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test if OnWindowDestroyed is invoked as expected.
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowObserverTest, WindowDestroyed) {
18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delete a window should fire a destroyed notification.
18362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->AddObserver(this);
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1.reset();
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, DestroyedCountAndClear());
18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Observe on child and delete parent window should fire a notification.
18422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Window> parent(CreateTestWindowWithId(1, root_window()));
18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Window* child = CreateTestWindowWithId(1, parent.get());  // owned by parent
18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  child->AddObserver(this);
18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent.reset();
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, DestroyedCountAndClear());
18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowObserverTest, PropertyChanged) {
18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Setting property should fire a property change notification.
18512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->AddObserver(this);
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const WindowProperty<int> prop = {-2};
18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char native_prop_key[] = "fnord";
18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->SetProperty(&prop, 1);
18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(PropertyChangeInfo(&prop, -2), PropertyChangeInfoAndClear());
18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->SetProperty(&prop, -2);
18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(PropertyChangeInfo(&prop, 1), PropertyChangeInfoAndClear());
18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->SetProperty(&prop, 3);
18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(PropertyChangeInfo(&prop, -2), PropertyChangeInfoAndClear());
18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->ClearProperty(&prop);
18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(PropertyChangeInfo(&prop, 3), PropertyChangeInfoAndClear());
18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->SetNativeWindowProperty(native_prop_key, &*w1);
18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(PropertyChangeInfo(native_prop_key, 0),
18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            PropertyChangeInfoAndClear());
18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->SetNativeWindowProperty(native_prop_key, NULL);
18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(PropertyChangeInfo(native_prop_key,
18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               reinterpret_cast<intptr_t>(&*w1)),
18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            PropertyChangeInfoAndClear());
18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sanity check to see if |PropertyChangeInfoAndClear| really clears.
18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(PropertyChangeInfo(
18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<const void*>(NULL), -3), PropertyChangeInfoAndClear());
18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(WindowObserverTest, AncestorTransformed) {
18801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Create following window hierarchy:
18811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  //   root_window
18821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  //   +-- w1
18831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  //       +-- w2
18841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  //       +-- w3
18851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  //           +-- w4
18861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Then, apply a transform to |w1| and ensure all its descendants are
18871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // notified.
18881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
18891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  w1->AddObserver(this);
18901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<Window> w2(CreateTestWindowWithId(2, w1.get()));
18911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  w2->AddObserver(this);
18921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<Window> w3(CreateTestWindowWithId(3, w1.get()));
18931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  w3->AddObserver(this);
18941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<Window> w4(CreateTestWindowWithId(4, w3.get()));
18951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  w4->AddObserver(this);
18961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
18971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(std::string(), TransformNotificationsAndClear());
18981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
18991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gfx::Transform transform;
19001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  transform.Translate(10, 10);
19011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  w1->SetTransform(transform);
19021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
19031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ("(1,1)(1,2)(1,3)(1,4)", TransformNotificationsAndClear());
19041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
19051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, AcquireLayer) {
19072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Window> window1(CreateTestWindowWithId(1, root_window()));
19082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Window> window2(CreateTestWindowWithId(2, root_window()));
19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::Layer* parent = window1->parent()->layer();
19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2U, parent->children().size());
19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WindowTestApi window1_test_api(window1.get());
19132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WindowTestApi window2_test_api(window2.get());
19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(window1_test_api.OwnsLayer());
19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(window2_test_api.OwnsLayer());
19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After acquisition, window1 should not own its layer, but it should still
19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be available to the window.
19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ui::Layer> window1_layer(window1->AcquireLayer());
19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(window1_test_api.OwnsLayer());
19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(window1_layer.get() == window1->layer());
19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
192423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // The acquired layer's owner should be set NULL and re-acquring
192523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // should return NULL.
192623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_FALSE(window1_layer->owner());
192723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_ptr<ui::Layer> window1_layer_reacquired(window1->AcquireLayer());
192823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_FALSE(window1_layer_reacquired.get());
192923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Upon destruction, window1's layer should still be valid, and in the layer
19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // hierarchy, but window2's should be gone, and no longer in the hierarchy.
19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window1.reset();
19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window2.reset();
19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should be set by the window's destructor.
19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(window1_layer->delegate() == NULL);
19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1U, parent->children().size());
19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that properties which should persist from the old layer to the new
19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// layer actually do.
19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, RecreateLayer) {
19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set properties to non default values.
19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Window w(new ColorTestWindowDelegate(SK_ColorWHITE));
19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w.set_id(1);
19465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w.Init(aura::WINDOW_LAYER_SOLID_COLOR);
19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w.SetBounds(gfx::Rect(0, 0, 100, 100));
19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::Layer* layer = w.layer();
19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layer->SetVisible(false);
19512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetMasksToBounds(true);
19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::Layer child_layer;
19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layer->Add(&child_layer);
19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ui::Layer> old_layer(w.RecreateLayer());
19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layer = w.layer();
19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ui::LAYER_SOLID_COLOR, layer->type());
19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(layer->visible());
19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, layer->children().size());
19612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer->GetMasksToBounds());
1962a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ("0,0 100x100", w.bounds().ToString());
1963a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ("0,0 100x100", layer->bounds().ToString());
19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
196690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Verify that RecreateLayer() stacks the old layer above the newly creatd
196790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// layer.
196890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(WindowTest, RecreateLayerZOrder) {
196990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<Window> w(
197090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      CreateTestWindow(SK_ColorWHITE, 1, gfx::Rect(0, 0, 100, 100),
197190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       root_window()));
197290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<ui::Layer> old_layer(w->RecreateLayer());
197390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
197490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const std::vector<ui::Layer*>& child_layers =
197590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      root_window()->layer()->children();
197690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_EQ(2u, child_layers.size());
197790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(w->layer(), child_layers[0]);
197890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(old_layer.get(), child_layers[1]);
197990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
198090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure that acquiring a layer then recreating a layer does not crash
19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and that RecreateLayer returns null.
19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, AcquireThenRecreateLayer) {
19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w(
19852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindow(SK_ColorWHITE, 1, gfx::Rect(0, 0, 100, 100),
19862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       root_window()));
19870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<ui::Layer> acquired_layer(w->AcquireLayer());
19880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<ui::Layer> doubly_acquired_layer(w->RecreateLayer());
19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, doubly_acquired_layer.get());
19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Destroy window before layer gets destroyed.
19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w.reset();
19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(WindowTest, StackWindowAtBottomBelowWindowWhoseLayerHasNoDelegate) {
1996f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<Window> window1(CreateTestWindowWithId(1, root_window()));
1997f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  window1->layer()->set_name("1");
1998f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<Window> window2(CreateTestWindowWithId(2, root_window()));
1999f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  window2->layer()->set_name("2");
2000f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<Window> window3(CreateTestWindowWithId(3, root_window()));
2001f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  window3->layer()->set_name("3");
2002f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2003f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ("1 2 3", ChildWindowIDsAsString(root_window()));
2004f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ("1 2 3",
2005f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            ui::test::ChildLayerNamesAsString(*root_window()->layer()));
2006f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  window1->layer()->set_delegate(NULL);
2007f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  root_window()->StackChildAtBottom(window3.get());
2008f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2009f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Window 3 should have moved to the bottom.
2010f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ("3 1 2", ChildWindowIDsAsString(root_window()));
2011f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ("3 1 2",
2012f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            ui::test::ChildLayerNamesAsString(*root_window()->layer()));
2013f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
2014f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestVisibilityClient : public client::VisibilityClient {
20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2017f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  explicit TestVisibilityClient(Window* root_window)
20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : ignore_visibility_changes_(false) {
20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    client::SetVisibilityClient(root_window, this);
20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~TestVisibilityClient() {
20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_ignore_visibility_changes(bool ignore_visibility_changes) {
20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ignore_visibility_changes_ = ignore_visibility_changes;
20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from client::VisibilityClient:
20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void UpdateLayerVisibility(aura::Window* window,
20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     bool visible) OVERRIDE {
20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ignore_visibility_changes_)
20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      window->layer()->SetVisible(visible);
20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ignore_visibility_changes_;
20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestVisibilityClient);
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, VisibilityClientIsVisible) {
20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestVisibilityClient client(root_window());
20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Window> window(CreateTestWindowWithId(1, root_window()));
20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(window->IsVisible());
20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(window->layer()->visible());
20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window->Hide();
20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(window->IsVisible());
20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(window->layer()->visible());
20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window->Show();
20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client.set_ignore_visibility_changes(true);
20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window->Hide();
20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(window->IsVisible());
20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(window->layer()->visible());
20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests mouse events on window change.
20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, MouseEventsOnWindowChange) {
2060a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  gfx::Size size = host()->GetBounds().size();
20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::test::EventGenerator generator(root_window());
20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.MoveMouseTo(50, 50);
20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EventCountDelegate d1;
20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w1(CreateTestWindowWithDelegate(&d1, 1,
20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Rect(0, 0, 100, 100), root_window()));
20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The format of result is "Enter/Mouse/Leave".
20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("1 1 0", d1.GetMouseMotionCountsAndReset());
20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Adding new window.
20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EventCountDelegate d11;
20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w11(CreateTestWindowWithDelegate(
20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &d11, 1, gfx::Rect(0, 0, 100, 100), w1.get()));
20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0 0 1", d1.GetMouseMotionCountsAndReset());
20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("1 1 0", d11.GetMouseMotionCountsAndReset());
20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move bounds.
20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w11->SetBounds(gfx::Rect(0, 0, 10, 10));
20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("1 1 0", d1.GetMouseMotionCountsAndReset());
20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0 0 1", d11.GetMouseMotionCountsAndReset());
20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w11->SetBounds(gfx::Rect(0, 0, 60, 60));
20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0 0 1", d1.GetMouseMotionCountsAndReset());
20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("1 1 0", d11.GetMouseMotionCountsAndReset());
20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Detach, then re-attach.
20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->RemoveChild(w11.get());
20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("1 1 0", d1.GetMouseMotionCountsAndReset());
20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Window is detached, so no event is set.
209690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ("0 0 1", d11.GetMouseMotionCountsAndReset());
20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->AddChild(w11.get());
20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0 0 1", d1.GetMouseMotionCountsAndReset());
21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Window is detached, so no event is set.
21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("1 1 0", d11.GetMouseMotionCountsAndReset());
21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Visibility Change
21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w11->Hide();
21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("1 1 0", d1.GetMouseMotionCountsAndReset());
210890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ("0 0 1", d11.GetMouseMotionCountsAndReset());
21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w11->Show();
21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0 0 1", d1.GetMouseMotionCountsAndReset());
21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("1 1 0", d11.GetMouseMotionCountsAndReset());
21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transform: move d11 by 100 100.
21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Transform transform;
21172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  transform.Translate(100, 100);
21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w11->SetTransform(transform);
21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("1 1 0", d1.GetMouseMotionCountsAndReset());
21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0 0 1", d11.GetMouseMotionCountsAndReset());
21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w11->SetTransform(gfx::Transform());
21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0 0 1", d1.GetMouseMotionCountsAndReset());
21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("1 1 0", d11.GetMouseMotionCountsAndReset());
21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Closing a window.
21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w11.reset();
21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("1 1 0", d1.GetMouseMotionCountsAndReset());
21322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Make sure we don't synthesize events if the mouse
21342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // is outside of the root window.
21352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator.MoveMouseTo(-10, -10);
21362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("0 0 1", d1.GetMouseMotionCountsAndReset());
21372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Adding new windows.
21392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  w11.reset(CreateTestWindowWithDelegate(
21402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &d11, 1, gfx::Rect(0, 0, 100, 100), w1.get()));
21412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunAllPendingInMessageLoop();
21422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("0 0 0", d1.GetMouseMotionCountsAndReset());
214390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ("0 0 1", d11.GetMouseMotionCountsAndReset());
21442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Closing windows
21462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  w11.reset();
21472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunAllPendingInMessageLoop();
21482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("0 0 0", d1.GetMouseMotionCountsAndReset());
21492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("0 0 0", d11.GetMouseMotionCountsAndReset());
21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RootWindowAttachmentObserver : public WindowObserver {
21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RootWindowAttachmentObserver() : added_count_(0), removed_count_(0) {}
21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~RootWindowAttachmentObserver() {}
21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int added_count() const { return added_count_; }
21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int removed_count() const { return removed_count_; }
21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Clear() {
21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    added_count_ = 0;
21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    removed_count_ = 0;
21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from WindowObserver:
21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWindowAddedToRootWindow(Window* window) OVERRIDE {
21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++added_count_;
21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2169effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual void OnWindowRemovingFromRootWindow(Window* window,
2170effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                              Window* new_root) OVERRIDE {
21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++removed_count_;
21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int added_count_;
21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int removed_count_;
21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(RootWindowAttachmentObserver);
21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, RootWindowAttachment) {
21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RootWindowAttachmentObserver observer;
21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test a direct add/remove from the RootWindow.
21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w1(new Window(NULL));
21865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w1->Init(aura::WINDOW_LAYER_NOT_DRAWN);
21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->AddObserver(&observer);
21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ParentWindow(w1.get());
21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, observer.added_count());
21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, observer.removed_count());
21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1.reset();
21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, observer.added_count());
21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, observer.removed_count());
21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer.Clear();
21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test an indirect add/remove from the RootWindow.
22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1.reset(new Window(NULL));
22015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w1->Init(aura::WINDOW_LAYER_NOT_DRAWN);
22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Window* w11 = new Window(NULL);
22035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w11->Init(aura::WINDOW_LAYER_NOT_DRAWN);
22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w11->AddObserver(&observer);
22052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  w1->AddChild(w11);
22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, observer.added_count());
22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, observer.removed_count());
22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ParentWindow(w1.get());
22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, observer.added_count());
22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, observer.removed_count());
22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1.reset();  // Deletes w11.
22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w11 = NULL;
22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, observer.added_count());
22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, observer.removed_count());
22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer.Clear();
22195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test an indirect add/remove with nested observers.
22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1.reset(new Window(NULL));
22225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w1->Init(aura::WINDOW_LAYER_NOT_DRAWN);
22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w11 = new Window(NULL);
22245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w11->Init(aura::WINDOW_LAYER_NOT_DRAWN);
22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w11->AddObserver(&observer);
22262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  w1->AddChild(w11);
22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Window* w111 = new Window(NULL);
22285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w111->Init(aura::WINDOW_LAYER_NOT_DRAWN);
22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w111->AddObserver(&observer);
22302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  w11->AddChild(w111);
22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, observer.added_count());
22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, observer.removed_count());
22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ParentWindow(w1.get());
22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, observer.added_count());
22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, observer.removed_count());
22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1.reset();  // Deletes w11 and w111.
22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w11 = NULL;
22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w111 = NULL;
22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, observer.added_count());
22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, observer.removed_count());
22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass BoundsChangedWindowObserver : public WindowObserver {
22470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public:
22480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  BoundsChangedWindowObserver() : root_set_(false) {}
22490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
22500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  virtual void OnWindowBoundsChanged(Window* window,
22510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                     const gfx::Rect& old_bounds,
22520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                     const gfx::Rect& new_bounds) OVERRIDE {
22530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    root_set_ = window->GetRootWindow() != NULL;
22540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
22550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
22560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  bool root_set() const { return root_set_; }
22570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
22580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private:
22590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  bool root_set_;
22600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
22610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DISALLOW_COPY_AND_ASSIGN(BoundsChangedWindowObserver);
22620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch};
22630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
22640529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_F(WindowTest, RootWindowSetWhenReparenting) {
22650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  Window parent1(NULL);
22660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  parent1.Init(aura::WINDOW_LAYER_NOT_DRAWN);
22670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  Window parent2(NULL);
22680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  parent2.Init(aura::WINDOW_LAYER_NOT_DRAWN);
22690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ParentWindow(&parent1);
22700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ParentWindow(&parent2);
22710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  parent1.SetBounds(gfx::Rect(10, 10, 300, 300));
22720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  parent2.SetBounds(gfx::Rect(20, 20, 300, 300));
22730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
227446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  BoundsChangedWindowObserver observer;
22750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  Window child(NULL);
22760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  child.Init(aura::WINDOW_LAYER_NOT_DRAWN);
22770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  child.SetBounds(gfx::Rect(5, 5, 100, 100));
22780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  parent1.AddChild(&child);
22790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
22800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // We need animations to start in order to observe the bounds changes.
22815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::ScopedAnimationDurationScaleMode test_duration_mode(
22825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
22830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ui::ScopedLayerAnimationSettings settings1(child.layer()->GetAnimator());
22840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  settings1.SetTransitionDuration(base::TimeDelta::FromMilliseconds(100));
22855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  gfx::Rect new_bounds(gfx::Rect(35, 35, 50, 50));
22865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  child.SetBounds(new_bounds);
22870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
22880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  child.AddObserver(&observer);
22890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
22900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Reparenting the |child| will cause it to get moved. During this move
22910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // the window should still have root window set.
22920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  parent2.AddChild(&child);
22930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(observer.root_set());
22940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
22955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Animations should stop and the bounds should be as set before the |child|
22965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // got reparented.
22975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(new_bounds.ToString(), child.GetTargetBounds().ToString());
22985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(new_bounds.ToString(), child.bounds().ToString());
22995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ("55,55 50x50", child.GetBoundsInRootWindow().ToString());
23000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
23010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, OwnedByParentFalse) {
23035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // By default, a window is owned by its parent. If this is set to false, the
23045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // window will not be destroyed when its parent is.
23055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w1(new Window(NULL));
23075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w1->Init(aura::WINDOW_LAYER_NOT_DRAWN);
23085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> w2(new Window(NULL));
23095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w2->set_owned_by_parent(false);
23105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w2->Init(aura::WINDOW_LAYER_NOT_DRAWN);
23112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  w1->AddChild(w2.get());
23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1.reset();
23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should be able to deref w2 still, but its parent should now be NULL.
23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, w2->parent());
23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Used By DeleteWindowFromOnWindowDestroyed. Destroys a Window from
23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OnWindowDestroyed().
23235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OwningWindowDelegate : public TestWindowDelegate {
23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
23255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwningWindowDelegate() {}
23265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetOwnedWindow(Window* window) {
23285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    owned_window_.reset(window);
23295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
23305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void OnWindowDestroyed(Window* window) OVERRIDE {
23325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    owned_window_.reset(NULL);
23335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
23345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
23365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> owned_window_;
23375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OwningWindowDelegate);
23395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
23405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
23425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates a window with two child windows. When the first child window is
23445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destroyed (WindowDelegate::OnWindowDestroyed) it deletes the second child.
23455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This synthesizes BrowserView and the status bubble. Both are children of the
23465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// same parent and destroying BrowserView triggers it destroying the status
23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bubble.
23485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, DeleteWindowFromOnWindowDestroyed) {
23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> parent(new Window(NULL));
23505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  parent->Init(aura::WINDOW_LAYER_NOT_DRAWN);
23515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OwningWindowDelegate delegate;
23525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Window* c1 = new Window(&delegate);
23535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  c1->Init(aura::WINDOW_LAYER_NOT_DRAWN);
23542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parent->AddChild(c1);
23555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Window* c2 = new Window(NULL);
23565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  c2->Init(aura::WINDOW_LAYER_NOT_DRAWN);
23572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parent->AddChild(c2);
23585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate.SetOwnedWindow(c2);
23595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent.reset();
23605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
23615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
23635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Used by DelegateNotifiedAsBoundsChange to verify OnBoundsChanged() is
23655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// invoked.
23665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BoundsChangeDelegate : public TestWindowDelegate {
23675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
23685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BoundsChangeDelegate() : bounds_changed_(false) {}
23695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void clear_bounds_changed() { bounds_changed_ = false; }
23715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool bounds_changed() const {
23725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return bounds_changed_;
23735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
23745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Window
23765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnBoundsChanged(const gfx::Rect& old_bounds,
23775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const gfx::Rect& new_bounds) OVERRIDE {
23785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bounds_changed_ = true;
23795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
23805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
23825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Was OnBoundsChanged() invoked?
23835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool bounds_changed_;
23845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BoundsChangeDelegate);
23865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
23875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
23895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies the delegate is notified when the actual bounds of the layer
23915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// change.
23925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, DelegateNotifiedAsBoundsChange) {
23935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BoundsChangeDelegate delegate;
23945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We cannot short-circuit animations in this test.
23965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::ScopedAnimationDurationScaleMode test_duration_mode(
23975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
23985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> window(
24005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestWindowWithDelegate(&delegate, 1,
24012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   gfx::Rect(0, 0, 100, 100), root_window()));
24025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window->layer()->GetAnimator()->set_disable_timer_for_test(true);
24035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate.clear_bounds_changed();
24055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Animate to a different position.
24075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
24085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator());
24095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window->SetBounds(gfx::Rect(100, 100, 100, 100));
24105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
24115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Bounds shouldn't immediately have changed.
24135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,0 100x100", window->bounds().ToString());
24145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(delegate.bounds_changed());
24155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Animate to the end, which should notify of the change.
24175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeTicks start_time =
24185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      window->layer()->GetAnimator()->last_step_time();
241946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ui::LayerAnimator* animator = window->layer()->GetAnimator();
242046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  animator->Step(start_time + base::TimeDelta::FromMilliseconds(1000));
24215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(delegate.bounds_changed());
24225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE("0,0 100x100", window->bounds().ToString());
24235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies the delegate is notified when the actual bounds of the layer
24265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// change even when the window is not the layer's delegate
24275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, DelegateNotifiedAsBoundsChangeInHiddenLayer) {
24285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BoundsChangeDelegate delegate;
24295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We cannot short-circuit animations in this test.
24315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::ScopedAnimationDurationScaleMode test_duration_mode(
24325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
24335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Window> window(
24355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateTestWindowWithDelegate(&delegate, 1,
24362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   gfx::Rect(0, 0, 100, 100), root_window()));
24375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window->layer()->GetAnimator()->set_disable_timer_for_test(true);
24385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate.clear_bounds_changed();
24405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Suppress paint on the window since it is hidden (should reset the layer's
24425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // delegate to NULL)
24435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window->SuppressPaint();
24445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, window->layer()->delegate());
24455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Animate to a different position.
24475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
24485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator());
24495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window->SetBounds(gfx::Rect(100, 100, 110, 100));
24505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
24515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Layer delegate is NULL but we should still get bounds changed notification.
24535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("100,100 110x100", window->GetTargetBounds().ToString());
24545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(delegate.bounds_changed());
24555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate.clear_bounds_changed();
24575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Animate to the end: will *not* notify of the change since we are hidden.
24595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeTicks start_time =
24605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      window->layer()->GetAnimator()->last_step_time();
246146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ui::LayerAnimator* animator = window->layer()->GetAnimator();
246246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  animator->Step(start_time + base::TimeDelta::FromMilliseconds(1000));
24635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No bounds changed notification at the end of animation since layer
24655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // delegate is NULL.
24665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(delegate.bounds_changed());
2467a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_NE("0,0 100x100", window->layer()->bounds().ToString());
24685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
24715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Used by AddChildNotifications to track notification counts.
24735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AddChildNotificationsObserver : public WindowObserver {
24745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddChildNotificationsObserver() : added_count_(0), removed_count_(0) {}
24765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string CountStringAndReset() {
24785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string result = base::IntToString(added_count_) + " " +
24795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::IntToString(removed_count_);
24805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    added_count_ = removed_count_ = 0;
24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result;
24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
24835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // WindowObserver overrides:
24855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWindowAddedToRootWindow(Window* window) OVERRIDE {
24865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    added_count_++;
24875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2488effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual void OnWindowRemovingFromRootWindow(Window* window,
2489effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                              Window* new_root) OVERRIDE {
24905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    removed_count_++;
24915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
24925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
24945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int added_count_;
24955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int removed_count_;
24965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AddChildNotificationsObserver);
24985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
24995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
25015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Assertions around when root window notifications are sent.
25035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WindowTest, AddChildNotifications) {
25045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddChildNotificationsObserver observer;
25052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
25062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Window> w2(CreateTestWindowWithId(1, root_window()));
25075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w2->AddObserver(&observer);
25085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w2->Focus();
25095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(w2->HasFocus());
25105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move |w2| to be a child of |w1|.
25125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  w1->AddChild(w2.get());
25135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sine we moved in the same root, observer shouldn't be notified.
25145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0 0", observer.CountStringAndReset());
25155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |w2| should still have focus after moving.
25165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(w2->HasFocus());
25175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests that a delegate that destroys itself when the window is destroyed does
25202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// not break.
25212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WindowTest, DelegateDestroysSelfOnWindowDestroy) {
25222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Window> w1(CreateTestWindowWithDelegate(
25232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new DestroyWindowDelegate(),
25242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0,
25252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(10, 20, 30, 40),
25262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      root_window()));
25272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
25282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class HierarchyObserver : public WindowObserver {
25302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
25312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HierarchyObserver(Window* target) : target_(target) {
25322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    target_->AddObserver(this);
25332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
25342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~HierarchyObserver() {
25352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    target_->RemoveObserver(this);
25362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
25372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ValidateState(
25392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int index,
25402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const WindowObserver::HierarchyChangeParams& params) const {
25412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ParamsMatch(params_[index], params);
25422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
25432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Reset() {
25452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params_.clear();
25462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
25472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
25492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from WindowObserver:
25502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWindowHierarchyChanging(
25512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const HierarchyChangeParams& params) OVERRIDE {
25522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params_.push_back(params);
25532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
25542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWindowHierarchyChanged(
25552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const HierarchyChangeParams& params) OVERRIDE {
25562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params_.push_back(params);
25572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
25582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ParamsMatch(const WindowObserver::HierarchyChangeParams& p1,
25602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   const WindowObserver::HierarchyChangeParams& p2) const {
25612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(p1.phase, p2.phase);
25622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(p1.target, p2.target);
25632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(p1.new_parent, p2.new_parent);
25642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(p1.old_parent, p2.old_parent);
25652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(p1.receiver, p2.receiver);
25662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
25672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Window* target_;
25692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<WindowObserver::HierarchyChangeParams> params_;
25702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(HierarchyObserver);
25722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
25732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests hierarchy change notifications.
25752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WindowTest, OnWindowHierarchyChange) {
25762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
25772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Simple add & remove.
25782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    HierarchyObserver oroot(root_window());
25792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<Window> w1(CreateTestWindowWithId(1, NULL));
25812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    HierarchyObserver o1(w1.get());
25822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Add.
25842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_window()->AddChild(w1.get());
25852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WindowObserver::HierarchyChangeParams params;
25872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
25882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.target = w1.get();
25892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.old_parent = NULL;
25902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.new_parent = root_window();
25912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.receiver = w1.get();
25922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    o1.ValidateState(0, params);
25932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
25952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.receiver = w1.get();
25962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    o1.ValidateState(1, params);
25972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.receiver = root_window();
25992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    oroot.ValidateState(0, params);
26002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Remove.
26022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    o1.Reset();
26032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    oroot.Reset();
26042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_window()->RemoveChild(w1.get());
26062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
26082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.old_parent = root_window();
26092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.new_parent = NULL;
26102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.receiver = w1.get();
26112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    o1.ValidateState(0, params);
26132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.receiver = root_window();
26152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    oroot.ValidateState(0, params);
26162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
26182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.receiver = w1.get();
26192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    o1.ValidateState(1, params);
26202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
26212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
26232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Add & remove of hierarchy. Tests notification order per documentation in
26242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // WindowObserver.
26252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    HierarchyObserver o(root_window());
26262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<Window> w1(CreateTestWindowWithId(1, NULL));
26272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Window* w11 = CreateTestWindowWithId(11, w1.get());
26282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    w1->AddObserver(&o);
26292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    w11->AddObserver(&o);
26302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Add.
26322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_window()->AddChild(w1.get());
26332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Dispatched to target first.
26352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int index = 0;
26362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WindowObserver::HierarchyChangeParams params;
26372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
26382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.target = w1.get();
26392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.old_parent = NULL;
26402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.new_parent = root_window();
26412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.receiver = w1.get();
26422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    o.ValidateState(index++, params);
26432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Dispatched to target's children.
26452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.receiver = w11;
26462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    o.ValidateState(index++, params);
26472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
26492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Now process the "changed" phase.
26512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.receiver = w1.get();
26522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    o.ValidateState(index++, params);
26532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.receiver = w11;
26542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    o.ValidateState(index++, params);
26552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.receiver = root_window();
26562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    o.ValidateState(index++, params);
26572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Remove.
26592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_window()->RemoveChild(w1.get());
26602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
26612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.old_parent = root_window();
26622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.new_parent = NULL;
26632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.receiver = w1.get();
26642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    o.ValidateState(index++, params);
26652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.receiver = w11;
26662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    o.ValidateState(index++, params);
26672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.receiver = root_window();
26682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    o.ValidateState(index++, params);
26692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
26702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.receiver = w1.get();
26712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    o.ValidateState(index++, params);
26722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.receiver = w11;
26732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    o.ValidateState(index++, params);
26742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    w1.reset();
26762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
26772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
26792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Reparent. Tests notification order per documentation in WindowObserver.
26802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
26812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Window* w11 = CreateTestWindowWithId(11, w1.get());
26822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Window* w111 = CreateTestWindowWithId(111, w11);
26832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<Window> w2(CreateTestWindowWithId(2, root_window()));
26842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    HierarchyObserver o(root_window());
26862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    w1->AddObserver(&o);
26872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    w11->AddObserver(&o);
26882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    w111->AddObserver(&o);
26892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    w2->AddObserver(&o);
26902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    w2->AddChild(w11);
26922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Dispatched to target first.
26942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int index = 0;
26952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WindowObserver::HierarchyChangeParams params;
26962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGING;
26972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.target = w11;
26982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.old_parent = w1.get();
26992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.new_parent = w2.get();
27002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.receiver = w11;
27012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    o.ValidateState(index++, params);
27022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Then to target's children.
27042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.receiver = w111;
27052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    o.ValidateState(index++, params);
27062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Then to target's old parent chain.
27082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.receiver = w1.get();
27092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    o.ValidateState(index++, params);
27102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.receiver = root_window();
27112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    o.ValidateState(index++, params);
27122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // "Changed" phase.
27142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.phase = WindowObserver::HierarchyChangeParams::HIERARCHY_CHANGED;
27152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.receiver = w11;
27162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    o.ValidateState(index++, params);
27172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.receiver = w111;
27182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    o.ValidateState(index++, params);
27192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.receiver = w2.get();
27202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    o.ValidateState(index++, params);
27212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.receiver = root_window();
27222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    o.ValidateState(index++, params);
27232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    w1.reset();
27252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    w2.reset();
27262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
27272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
27292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2730a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Verifies SchedulePaint() on a layerless window results in damaging the right
2731a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// thing.
2732a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(WindowTest, LayerlessWindowSchedulePaint) {
2733a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Window root(NULL);
27345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  root.Init(aura::WINDOW_LAYER_NOT_DRAWN);
2735a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  root.SetBounds(gfx::Rect(0, 0, 100, 100));
2736a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2737a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Window* layerless_window = new Window(NULL);  // Owned by |root|.
27385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  layerless_window->Init(WINDOW_LAYER_NONE);
2739a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  layerless_window->SetBounds(gfx::Rect(10, 11, 12, 13));
2740a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  root.AddChild(layerless_window);
2741a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2742a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  root.layer()->SendDamagedRects();
2743a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  layerless_window->SchedulePaintInRect(gfx::Rect(1, 2, 100, 4));
2744a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Note the the region is clipped by the parent hence 100 going to 11.
2745a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("11,13 11x4",
2746a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            gfx::SkIRectToRect(root.layer()->damaged_region().getBounds()).
2747a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            ToString());
2748a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2749a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Window* layerless_window2 = new Window(NULL);  // Owned by |layerless_window|.
27505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  layerless_window2->Init(WINDOW_LAYER_NONE);
2751a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  layerless_window2->SetBounds(gfx::Rect(1, 2, 3, 4));
2752a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  layerless_window->AddChild(layerless_window2);
2753a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2754a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  root.layer()->SendDamagedRects();
2755a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  layerless_window2->SchedulePaintInRect(gfx::Rect(1, 2, 100, 4));
2756a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Note the the region is clipped by the |layerless_window| hence 100 going to
2757a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // 2.
2758a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("12,15 2x2",
2759a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            gfx::SkIRectToRect(root.layer()->damaged_region().getBounds()).
2760a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            ToString());
2761a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
2762a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2763a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Verifies bounds of layerless windows are correctly updated when adding
2764a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// removing.
2765a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(WindowTest, NestedLayerlessWindowsBoundsOnAddRemove) {
2766a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Creates the following structure (all children owned by root):
2767a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // root
2768a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  //   w1ll      1,2
2769a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  //     w11ll   3,4
2770a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  //       w111  5,6
2771a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  //     w12     7,8
2772a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  //       w121  9,10
2773a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  //
2774a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // ll: layer less, eg no layer
2775a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Window root(NULL);
27765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  root.Init(WINDOW_LAYER_NOT_DRAWN);
2777a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  root.SetBounds(gfx::Rect(0, 0, 100, 100));
2778a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2779a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Window* w1ll = new Window(NULL);
27805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w1ll->Init(WINDOW_LAYER_NONE);
2781a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w1ll->SetBounds(gfx::Rect(1, 2, 100, 100));
2782a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2783a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Window* w11ll = new Window(NULL);
27845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w11ll->Init(WINDOW_LAYER_NONE);
2785a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w11ll->SetBounds(gfx::Rect(3, 4, 100, 100));
2786a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w1ll->AddChild(w11ll);
2787a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2788a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Window* w111 = new Window(NULL);
27895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w111->Init(WINDOW_LAYER_NOT_DRAWN);
2790a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w111->SetBounds(gfx::Rect(5, 6, 100, 100));
2791a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w11ll->AddChild(w111);
2792a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2793a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Window* w12 = new Window(NULL);
27945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w12->Init(WINDOW_LAYER_NOT_DRAWN);
2795a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w12->SetBounds(gfx::Rect(7, 8, 100, 100));
2796a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w1ll->AddChild(w12);
2797a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2798a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Window* w121 = new Window(NULL);
27995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w121->Init(WINDOW_LAYER_NOT_DRAWN);
2800a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w121->SetBounds(gfx::Rect(9, 10, 100, 100));
2801a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w12->AddChild(w121);
2802a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2803a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  root.AddChild(w1ll);
2804a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2805a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // All layers should be parented to the root.
2806a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(root.layer(), w111->layer()->parent());
2807a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(root.layer(), w12->layer()->parent());
2808a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(w12->layer(), w121->layer()->parent());
2809a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2810a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Ensure bounds are what we expect.
2811a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("1,2 100x100", w1ll->bounds().ToString());
2812a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("3,4 100x100", w11ll->bounds().ToString());
2813a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("5,6 100x100", w111->bounds().ToString());
2814a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("7,8 100x100", w12->bounds().ToString());
2815a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("9,10 100x100", w121->bounds().ToString());
2816a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2817a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Bounds of layers are relative to the nearest ancestor with a layer.
2818a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("8,10 100x100", w12->layer()->bounds().ToString());
2819a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("9,12 100x100", w111->layer()->bounds().ToString());
2820a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("9,10 100x100", w121->layer()->bounds().ToString());
2821a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2822a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Remove and repeat.
2823a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  root.RemoveChild(w1ll);
2824a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2825a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(w111->layer()->parent() == NULL);
2826a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(w12->layer()->parent() == NULL);
2827a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2828a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Verify bounds haven't changed again.
2829a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("1,2 100x100", w1ll->bounds().ToString());
2830a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("3,4 100x100", w11ll->bounds().ToString());
2831a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("5,6 100x100", w111->bounds().ToString());
2832a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("7,8 100x100", w12->bounds().ToString());
2833a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("9,10 100x100", w121->bounds().ToString());
2834a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2835a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Bounds of layers should now match that of windows.
2836a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("7,8 100x100", w12->layer()->bounds().ToString());
2837a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("5,6 100x100", w111->layer()->bounds().ToString());
2838a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("9,10 100x100", w121->layer()->bounds().ToString());
2839a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2840a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  delete w1ll;
2841a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
2842a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2843a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Verifies bounds of layerless windows are correctly updated when bounds
2844a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// of ancestor changes.
2845a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(WindowTest, NestedLayerlessWindowsBoundsOnSetBounds) {
2846a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Creates the following structure (all children owned by root):
2847a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // root
2848a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  //   w1ll      1,2
2849a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  //     w11ll   3,4
2850a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  //       w111  5,6
2851a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  //     w12     7,8
2852a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  //       w121  9,10
2853a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  //
2854a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // ll: layer less, eg no layer
2855a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Window root(NULL);
28565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  root.Init(WINDOW_LAYER_NOT_DRAWN);
2857a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  root.SetBounds(gfx::Rect(0, 0, 100, 100));
2858a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2859a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Window* w1ll = new Window(NULL);
28605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w1ll->Init(WINDOW_LAYER_NONE);
2861a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w1ll->SetBounds(gfx::Rect(1, 2, 100, 100));
2862a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2863a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Window* w11ll = new Window(NULL);
28645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w11ll->Init(WINDOW_LAYER_NONE);
2865a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w11ll->SetBounds(gfx::Rect(3, 4, 100, 100));
2866a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w1ll->AddChild(w11ll);
2867a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2868a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Window* w111 = new Window(NULL);
28695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w111->Init(WINDOW_LAYER_NOT_DRAWN);
2870a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w111->SetBounds(gfx::Rect(5, 6, 100, 100));
2871a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w11ll->AddChild(w111);
2872a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2873a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Window* w12 = new Window(NULL);
28745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w12->Init(WINDOW_LAYER_NOT_DRAWN);
2875a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w12->SetBounds(gfx::Rect(7, 8, 100, 100));
2876a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w1ll->AddChild(w12);
2877a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2878a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Window* w121 = new Window(NULL);
28795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w121->Init(WINDOW_LAYER_NOT_DRAWN);
2880a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w121->SetBounds(gfx::Rect(9, 10, 100, 100));
2881a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w12->AddChild(w121);
2882a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2883a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  root.AddChild(w1ll);
2884a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2885a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w111->SetBounds(gfx::Rect(7, 8, 11, 12));
2886a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("7,8 11x12", w111->bounds().ToString());
2887a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("7,8 11x12", w111->GetTargetBounds().ToString());
2888a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("11,14 11x12", w111->layer()->bounds().ToString());
2889a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2890a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Set back.
2891a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w111->SetBounds(gfx::Rect(5, 6, 100, 100));
2892a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("5,6 100x100", w111->bounds().ToString());
2893a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("5,6 100x100", w111->GetTargetBounds().ToString());
2894a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("9,12 100x100", w111->layer()->bounds().ToString());
2895a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2896a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Setting the bounds of a layerless window needs to adjust the bounds of
2897a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // layered children.
2898a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w11ll->SetBounds(gfx::Rect(5, 6, 100, 100));
2899a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("5,6 100x100", w11ll->bounds().ToString());
2900a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("5,6 100x100", w11ll->GetTargetBounds().ToString());
2901a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("5,6 100x100", w111->bounds().ToString());
2902a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("5,6 100x100", w111->GetTargetBounds().ToString());
2903a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("11,14 100x100", w111->layer()->bounds().ToString());
2904a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2905a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  root.RemoveChild(w1ll);
2906a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2907a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w111->SetBounds(gfx::Rect(7, 8, 11, 12));
2908a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("7,8 11x12", w111->bounds().ToString());
2909a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("7,8 11x12", w111->GetTargetBounds().ToString());
2910a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("7,8 11x12", w111->layer()->bounds().ToString());
2911a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2912a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  delete w1ll;
2913a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
2914a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2915a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace {
2916a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2917a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Tracks the number of times paint is invoked along with what the clip and
2918a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// translate was.
2919a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class PaintWindowDelegate : public TestWindowDelegate {
2920a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public:
2921a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  PaintWindowDelegate() : paint_count_(0) {}
2922a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual ~PaintWindowDelegate() {}
2923a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2924a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const gfx::Rect& most_recent_paint_clip_bounds() const {
2925a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return most_recent_paint_clip_bounds_;
2926a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
2927a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2928a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const gfx::Vector2d& most_recent_paint_matrix_offset() const {
2929a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return most_recent_paint_matrix_offset_;
2930a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
2931a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2932a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void clear_paint_count() { paint_count_ = 0; }
2933a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int paint_count() const { return paint_count_; }
2934a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2935a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // TestWindowDelegate::
2936a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
2937a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    paint_count_++;
2938a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    canvas->GetClipBounds(&most_recent_paint_clip_bounds_);
2939a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const SkMatrix& matrix = canvas->sk_canvas()->getTotalMatrix();
2940a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    most_recent_paint_matrix_offset_ = gfx::Vector2d(
2941a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        SkScalarFloorToInt(matrix.getTranslateX()),
2942a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        SkScalarFloorToInt(matrix.getTranslateY()));
2943a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
2944a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2945a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private:
2946a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int paint_count_;
2947a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gfx::Rect most_recent_paint_clip_bounds_;
2948a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gfx::Vector2d most_recent_paint_matrix_offset_;
2949a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2950a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PaintWindowDelegate);
2951a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
2952a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2953a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace
2954a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2955a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Assertions around layerless children being painted when non-layerless window
2956a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// is painted.
2957a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(WindowTest, PaintLayerless) {
2958a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Creates the following structure (all children owned by root):
2959a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // root
2960a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  //   w1ll      1,2 40x50
2961a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  //     w11ll   3,4 11x12
2962a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  //       w111  5,6
2963a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  //
2964a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // ll: layer less, eg no layer
2965a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  PaintWindowDelegate w1ll_delegate;
2966a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  PaintWindowDelegate w11ll_delegate;
2967a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  PaintWindowDelegate w111_delegate;
2968a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2969a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Window root(NULL);
29705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  root.Init(WINDOW_LAYER_NOT_DRAWN);
2971a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  root.SetBounds(gfx::Rect(0, 0, 100, 100));
2972a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2973a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Window* w1ll = new Window(&w1ll_delegate);
29745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w1ll->Init(WINDOW_LAYER_NONE);
2975a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w1ll->SetBounds(gfx::Rect(1, 2, 40, 50));
2976a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w1ll->Show();
2977a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  root.AddChild(w1ll);
2978a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2979a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Window* w11ll = new Window(&w11ll_delegate);
29805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w11ll->Init(WINDOW_LAYER_NONE);
2981a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w11ll->SetBounds(gfx::Rect(3, 4, 11, 12));
2982a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w11ll->Show();
2983a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w1ll->AddChild(w11ll);
2984a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2985a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Window* w111 = new Window(&w111_delegate);
29865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w111->Init(WINDOW_LAYER_NOT_DRAWN);
2987a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w111->SetBounds(gfx::Rect(5, 6, 100, 100));
2988a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w111->Show();
2989a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w11ll->AddChild(w111);
2990a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2991a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(0, w1ll_delegate.paint_count());
2992a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(0, w11ll_delegate.paint_count());
2993a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(0, w111_delegate.paint_count());
2994a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2995a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Paint the root, this should trigger painting of the two layerless
2996a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // descendants but not the layered descendant.
2997a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gfx::Canvas canvas(gfx::Size(200, 200), 1.0f, true);
2998a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static_cast<ui::LayerDelegate&>(root).OnPaintLayer(&canvas);
2999a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3000a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // NOTE: SkCanvas::getClipBounds() extends the clip 1 pixel to the left and up
3001a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // and 2 pixels down and to the right.
3002a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(1, w1ll_delegate.paint_count());
3003a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("-1,-1 42x52",
3004a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            w1ll_delegate.most_recent_paint_clip_bounds().ToString());
3005a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("[1 2]",
3006a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            w1ll_delegate.most_recent_paint_matrix_offset().ToString());
3007a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(1, w11ll_delegate.paint_count());
3008a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("-1,-1 13x14",
3009a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            w11ll_delegate.most_recent_paint_clip_bounds().ToString());
3010a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("[4 6]",
3011a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            w11ll_delegate.most_recent_paint_matrix_offset().ToString());
3012a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(0, w111_delegate.paint_count());
3013a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
3014a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3015a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace {
3016a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3017a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)std::string ConvertPointToTargetString(const Window* source,
3018a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                       const Window* target) {
3019a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gfx::Point location;
3020a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Window::ConvertPointToTarget(source, target, &location);
3021a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return location.ToString();
3022a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
3023a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3024a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace
3025a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3026a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Assertions around Window::ConvertPointToTarget() with layerless windows.
3027a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(WindowTest, ConvertPointToTargetLayerless) {
3028a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Creates the following structure (all children owned by root):
3029a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // root
3030a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  //   w1ll      1,2
3031a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  //     w11ll   3,4
3032a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  //       w111  5,6
3033a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  //     w12     7,8
3034a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  //       w121  9,10
3035a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  //
3036a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // ll: layer less, eg no layer
3037a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Window root(NULL);
30385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  root.Init(WINDOW_LAYER_NOT_DRAWN);
3039a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  root.SetBounds(gfx::Rect(0, 0, 100, 100));
3040a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3041a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Window* w1ll = new Window(NULL);
30425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w1ll->Init(WINDOW_LAYER_NONE);
3043a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w1ll->SetBounds(gfx::Rect(1, 2, 100, 100));
3044a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3045a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Window* w11ll = new Window(NULL);
30465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w11ll->Init(WINDOW_LAYER_NONE);
3047a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w11ll->SetBounds(gfx::Rect(3, 4, 100, 100));
3048a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w1ll->AddChild(w11ll);
3049a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3050a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Window* w111 = new Window(NULL);
30515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w111->Init(WINDOW_LAYER_NOT_DRAWN);
3052a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w111->SetBounds(gfx::Rect(5, 6, 100, 100));
3053a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w11ll->AddChild(w111);
3054a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3055a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Window* w12 = new Window(NULL);
30565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w12->Init(WINDOW_LAYER_NOT_DRAWN);
3057a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w12->SetBounds(gfx::Rect(7, 8, 100, 100));
3058a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w1ll->AddChild(w12);
3059a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3060a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Window* w121 = new Window(NULL);
30615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w121->Init(WINDOW_LAYER_NOT_DRAWN);
3062a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w121->SetBounds(gfx::Rect(9, 10, 100, 100));
3063a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  w12->AddChild(w121);
3064a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3065a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  root.AddChild(w1ll);
3066a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3067a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // w111->w11ll
3068a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("5,6", ConvertPointToTargetString(w111, w11ll));
3069a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3070a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // w111->w1ll
3071a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("8,10", ConvertPointToTargetString(w111, w1ll));
3072a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3073a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // w111->root
3074a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("9,12", ConvertPointToTargetString(w111, &root));
3075a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3076a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // w111->w12
3077a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("1,2", ConvertPointToTargetString(w111, w12));
3078a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3079a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // w111->w121
3080a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("-8,-8", ConvertPointToTargetString(w111, w121));
3081a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3082a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // w11ll->w111
3083a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("-5,-6", ConvertPointToTargetString(w11ll, w111));
3084a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3085a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // w11ll->w11ll
3086a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("3,4", ConvertPointToTargetString(w11ll, w1ll));
3087a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3088a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // w11ll->root
3089a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("4,6", ConvertPointToTargetString(w11ll, &root));
3090a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3091a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // w11ll->w12
3092a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("-4,-4", ConvertPointToTargetString(w11ll, w12));
3093a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
3094a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
30955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if !defined(NDEBUG)
30965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Verifies PrintWindowHierarchy() doesn't crash with a layerless window.
30975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(WindowTest, PrintWindowHierarchyNotCrashLayerless) {
30985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Window root(NULL);
30995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  root.Init(WINDOW_LAYER_NONE);
31005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  root.SetBounds(gfx::Rect(0, 0, 100, 100));
31015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  root.PrintWindowHierarchy(0);
31025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
31035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
31045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
31055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
31065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
31075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// See AddWindowsFromString() for details.
31085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)aura::Window* CreateWindowFromDescription(const std::string& description,
31095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                          WindowDelegate* delegate) {
31105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WindowLayerType window_type = WINDOW_LAYER_NOT_DRAWN;
31115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<std::string> tokens;
31125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Tokenize(description, ":", &tokens);
31135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!tokens.empty());
31145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string name(tokens[0]);
31155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  tokens.erase(tokens.begin());
31165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!tokens.empty()) {
31175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (tokens[0] == "ll") {
31185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      window_type = WINDOW_LAYER_NONE;
31195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      tokens.erase(tokens.begin());
31205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
31215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(tokens.empty()) << "unknown tokens for creating window "
31225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           << description;
31235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
31245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Window* window = new Window(delegate);
31255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->Init(window_type);
31265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->SetName(name);
31275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Window name is only propagated to layer in debug builds.
31285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (window->layer())
31295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    window->layer()->set_name(name);
31305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return window;
31315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
31325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
31335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Creates and adds a tree of windows to |parent|. |description| consists
31345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// of the following pieces:
31355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//   X: Identifies a new window. Consists of a name and optionally ":ll" to
31365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//      specify  WINDOW_LAYER_NONE, eg "w1:ll".
31375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//   []: optionally used to specify the children of the window. Contains any
31385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//       number of window identifiers and their corresponding children.
31395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// For example: "[ a [ a1 a2:ll ] b c [ c1 ] ]" creates the tree:
31405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//   a
31415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//     a1
31425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//     a2 -> WINDOW_LAYER_NONE.
31435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//   b
31445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//   c
31455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//     c1
31465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// NOTE: you must have a space after every token.
31475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string::size_type AddWindowsFromString(aura::Window* parent,
31485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                            const std::string& description,
31495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                            std::string::size_type start_pos,
31505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                            WindowDelegate* delegate) {
31515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(parent);
31525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string::size_type end_pos = description.find(' ', start_pos);
31535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  while (end_pos != std::string::npos) {
31545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string::size_type part_length = end_pos - start_pos;
31555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string window_description =
31565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        description.substr(start_pos, part_length);
31575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (window_description == "[") {
31585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      start_pos = AddWindowsFromString(parent->children().back(),
31595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       description,
31605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       end_pos + 1,
31615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       delegate);
31625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      end_pos = description.find(' ', start_pos);
31635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (end_pos == std::string::npos && start_pos != end_pos)
31645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        end_pos = description.length();
31655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else if (window_description == "]") {
31665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ++end_pos;
31675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
31685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
31695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      Window* window =
31705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          CreateWindowFromDescription(window_description, delegate);
31715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      parent->AddChild(window);
31725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      start_pos = ++end_pos;
31735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      end_pos = description.find(' ', start_pos);
31745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
31755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
31765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return end_pos;
31775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
31785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
31795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Used by BuildRootWindowTreeDescription().
31805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string BuildWindowTreeDescription(const aura::Window& window) {
31815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string result;
31825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  result += window.name();
31835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (window.children().empty())
31845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return result;
31855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
31865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  result += " [ ";
31875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (size_t i = 0; i < window.children().size(); ++i) {
31885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (i != 0)
31895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      result += " ";
31905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    result += BuildWindowTreeDescription(*(window.children()[i]));
31915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
31925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  result += " ]";
31935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return result;
31945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
31955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
31965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Creates a string from |window|. See AddWindowsFromString() for details of the
31975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// returned string. This does *not* include the layer type in the description,
31985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// on the name.
31995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string BuildRootWindowTreeDescription(const aura::Window& window) {
32005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string result;
32015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (size_t i = 0; i < window.children().size(); ++i) {
32025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (i != 0)
32035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      result += " ";
32045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    result += BuildWindowTreeDescription(*(window.children()[i]));
32055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
32065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return result;
32075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
32085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
32095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Used by BuildRootWindowTreeDescription().
32105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string BuildLayerTreeDescription(const ui::Layer& layer) {
32115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string result;
32125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  result += layer.name();
32135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (layer.children().empty())
32145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return result;
32155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
32165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  result += " [ ";
32175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (size_t i = 0; i < layer.children().size(); ++i) {
32185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (i != 0)
32195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      result += " ";
32205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    result += BuildLayerTreeDescription(*(layer.children()[i]));
32215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
32225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  result += " ]";
32235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return result;
32245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
32255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
32265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Builds a string for all the children of |layer|. The returned string is in
32275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// the same format as AddWindowsFromString() but only includes the name of the
32285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// layers.
32295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string BuildRootLayerTreeDescription(const ui::Layer& layer) {
32305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string result;
32315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (size_t i = 0; i < layer.children().size(); ++i) {
32325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (i != 0)
32335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      result += " ";
32345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    result += BuildLayerTreeDescription(*(layer.children()[i]));
32355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
32365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return result;
32375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
32385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
32395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Returns the first window whose name matches |name| in |parent|.
32405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)aura::Window* FindWindowByName(aura::Window* parent,
32415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               const std::string& name) {
32425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (parent->name() == name)
32435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return parent;
32445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (size_t i = 0; i < parent->children().size(); ++i) {
32455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    aura::Window* child = FindWindowByName(parent->children()[i], name);
32465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (child)
32475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return child;
32485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
32495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return NULL;
32505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
32515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
32525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
32535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
32545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Direction to stack.
32555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)enum StackType {
32565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  STACK_ABOVE,
32575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  STACK_BELOW,
32585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  STACK_AT_BOTTOM,
32595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  STACK_AT_TOP,
32605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
32615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
32625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Permutations of StackChildAt with various data.
32635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(WindowTest, StackChildAtLayerless) {
32645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct TestData {
32655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Describes the window tree to create. See AddWindowsFromString() for
32665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // details.
32675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string initial_description;
32685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
32695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Identifies the window to move.
32705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string source_window;
32715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
32725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Window to move |source_window| relative to. Not used for STACK_AT_BOTTOM
32735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // or STACK_AT_TOP.
32745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string target_window;
32755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
32765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    StackType stack_type;
32775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
32785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Expected window and layer results.
32795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string expected_description;
32805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string expected_layer_description;
32815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } data[] = {
32825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // 1 at top.
32835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    {
32845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "1:ll [ 11 12 ] 2:ll [ 21 ]",
32855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "1",
32865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "",
32875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      STACK_AT_TOP,
32885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "2 [ 21 ] 1 [ 11 12 ]",
32895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "21 11 12",
32905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    },
32915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
32925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // 1 at bottom.
32935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    {
32945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "1:ll [ 11 12 ] 2:ll [ 21 ]",
32955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "1",
32965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "",
32975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      STACK_AT_BOTTOM,
32985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "1 [ 11 12 ] 2 [ 21 ]",
32995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "11 12 21",
33005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    },
33015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
33025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // 2 at bottom.
33035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    {
33045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "1:ll [ 11 12 ] 2:ll [ 21 ]",
33055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "2",
33065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "",
33075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      STACK_AT_BOTTOM,
33085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "2 [ 21 ] 1 [ 11 12 ]",
33095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "21 11 12",
33105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    },
33115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
33125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // 3 below 2.
33135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    {
33145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "1:ll [ 11 12 ] 2:ll [ 21 ] 3:ll",
33155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "3",
33165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "2",
33175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      STACK_BELOW,
33185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "1 [ 11 12 ] 3 2 [ 21 ]",
33195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "11 12 21",
33205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    },
33215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
33225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // 2 below 1.
33235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    {
33245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "1:ll [ 11 12 ] 2:ll [ 21 ]",
33255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "2",
33265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "1",
33275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      STACK_BELOW,
33285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "2 [ 21 ] 1 [ 11 12 ]",
33295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "21 11 12",
33305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    },
33315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
33325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // 1 above 3.
33335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    {
33345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "1:ll [ 11 12 ] 2:ll [ 21 ] 3:ll",
33355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "1",
33365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "3",
33375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      STACK_ABOVE,
33385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "2 [ 21 ] 3 1 [ 11 12 ]",
33395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "21 11 12",
33405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    },
33415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
33425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // 1 above 2.
33435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    {
33445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "1:ll [ 11 12 ] 2:ll [ 21 ]",
33455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "1",
33465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "2",
33475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      STACK_ABOVE,
33485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "2 [ 21 ] 1 [ 11 12 ]",
33495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "21 11 12",
33505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    },
33515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
33525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
33535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    test::TestWindowDelegate delegate;
33545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Window root(NULL);
33555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    root.Init(WINDOW_LAYER_NOT_DRAWN);
33565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    root.SetBounds(gfx::Rect(0, 0, 100, 100));
33575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    AddWindowsFromString(
33585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        &root,
33595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        data[i].initial_description,
33605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        static_cast<std::string::size_type>(0), &delegate);
33615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    aura::Window* source = FindWindowByName(&root, data[i].source_window);
33625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_TRUE(source != NULL) << "unable to find source window "
33635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                << data[i].source_window << " at " << i;
33645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    aura::Window* target = FindWindowByName(&root, data[i].target_window);
33655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    switch (data[i].stack_type) {
33665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case STACK_ABOVE:
33675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        ASSERT_TRUE(target != NULL) << "unable to find target window "
33685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                    << data[i].target_window << " at " << i;
33695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        source->parent()->StackChildAbove(source, target);
33705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
33715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case STACK_BELOW:
33725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        ASSERT_TRUE(target != NULL) << "unable to find target window "
33735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                    << data[i].target_window << " at " << i;
33745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        source->parent()->StackChildBelow(source, target);
33755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
33765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case STACK_AT_BOTTOM:
33775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        source->parent()->StackChildAtBottom(source);
33785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
33795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case STACK_AT_TOP:
33805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        source->parent()->StackChildAtTop(source);
33815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
33825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
33835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(data[i].expected_layer_description,
33845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              BuildRootLayerTreeDescription(*root.layer()))
33855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        << "layer tree doesn't match at " << i;
33865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(data[i].expected_description,
33875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              BuildRootWindowTreeDescription(root))
33885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        << "window tree doesn't match at " << i;
33895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
33905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
33915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
339246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace {
339346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
339446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class TestLayerAnimationObserver : public ui::LayerAnimationObserver {
339546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public:
339646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  TestLayerAnimationObserver()
339746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      : animation_completed_(false),
339846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        animation_aborted_(false) {}
339946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual ~TestLayerAnimationObserver() {}
340046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
340146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool animation_completed() const { return animation_completed_; }
340246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool animation_aborted() const { return animation_aborted_; }
340346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
340446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void Reset() {
340546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    animation_completed_ = false;
340646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    animation_aborted_ = false;
340746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
340846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
340946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private:
341046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // ui::LayerAnimationObserver:
341146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void OnLayerAnimationEnded(
341246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      ui::LayerAnimationSequence* sequence) OVERRIDE {
341346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    animation_completed_ = true;
341446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
341546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
341646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void OnLayerAnimationAborted(
341746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      ui::LayerAnimationSequence* sequence) OVERRIDE {
341846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    animation_aborted_ = true;
341946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
342046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
342146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void OnLayerAnimationScheduled(
342246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      ui::LayerAnimationSequence* sequence) OVERRIDE {
342346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
342446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
342546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool animation_completed_;
342646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool animation_aborted_;
342746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
342846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestLayerAnimationObserver);
342946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)};
343046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
343146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
343246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
343346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(WindowTest, WindowDestroyCompletesAnimations) {
34345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::ScopedAnimationDurationScaleMode test_duration_mode(
34355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
343646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_refptr<ui::LayerAnimator> animator =
343746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      ui::LayerAnimator::CreateImplicitAnimator();
343846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  TestLayerAnimationObserver observer;
343946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  animator->AddObserver(&observer);
344046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Make sure destroying a Window completes the animation.
344146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  {
344246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scoped_ptr<Window> window(CreateTestWindowWithId(1, root_window()));
34431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    window->layer()->SetAnimator(animator.get());
344446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
344546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    gfx::Transform transform;
344646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    transform.Scale(0.5f, 0.5f);
344746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    window->SetTransform(transform);
344846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
344946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    EXPECT_TRUE(animator->is_animating());
345046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    EXPECT_FALSE(observer.animation_completed());
345146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
34521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(animator.get());
345346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_FALSE(animator->is_animating());
345446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(observer.animation_completed());
345546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_FALSE(observer.animation_aborted());
345646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  animator->RemoveObserver(&observer);
345746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  observer.Reset();
345846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
345946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  animator = ui::LayerAnimator::CreateImplicitAnimator();
346046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  animator->AddObserver(&observer);
346146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ui::Layer layer;
34621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  layer.SetAnimator(animator.get());
346346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  {
346446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scoped_ptr<Window> window(CreateTestWindowWithId(1, root_window()));
346546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    window->layer()->Add(&layer);
346646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
346746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    gfx::Transform transform;
346846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    transform.Scale(0.5f, 0.5f);
346946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    layer.SetTransform(transform);
347046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
347146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    EXPECT_TRUE(animator->is_animating());
347246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    EXPECT_FALSE(observer.animation_completed());
347346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
347446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
34751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(animator.get());
347646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_FALSE(animator->is_animating());
347746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(observer.animation_completed());
347846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_FALSE(observer.animation_aborted());
347946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  animator->RemoveObserver(&observer);
348046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
348146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
34825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace test
34835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace aura
3484