Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/views/controls/native/native_view_host_aura.h" | 5 #include "ui/views/controls/native/native_view_host_aura.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "ui/aura/client/aura_constants.h" | 9 #include "ui/aura/client/aura_constants.h" |
| 10 #include "ui/aura/window.h" | 10 #include "ui/aura/window.h" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 48 | 48 |
| 49 struct EventDetails { | 49 struct EventDetails { |
| 50 EventType type; | 50 EventType type; |
| 51 aura::Window* window; | 51 aura::Window* window; |
| 52 gfx::Rect bounds; | 52 gfx::Rect bounds; |
| 53 bool operator!=(const EventDetails& rhs) { | 53 bool operator!=(const EventDetails& rhs) { |
| 54 return type != rhs.type || window != rhs.window || bounds != rhs.bounds; | 54 return type != rhs.type || window != rhs.window || bounds != rhs.bounds; |
| 55 } | 55 } |
| 56 }; | 56 }; |
| 57 | 57 |
| 58 NativeViewHostWindowObserver() {} | 58 NativeViewHostWindowObserver() |
| 59 : visibility_state_after_reparenting_(false) {} | |
| 60 | |
| 59 virtual ~NativeViewHostWindowObserver() {} | 61 virtual ~NativeViewHostWindowObserver() {} |
| 60 | 62 |
| 61 const std::vector<EventDetails>& events() const { return events_; } | 63 const std::vector<EventDetails>& events() const { return events_; } |
| 62 | 64 |
| 63 // aura::WindowObserver overrides | 65 // aura::WindowObserver overrides |
| 64 virtual void OnWindowVisibilityChanged(aura::Window* window, | 66 virtual void OnWindowVisibilityChanged(aura::Window* window, |
| 65 bool visible) OVERRIDE { | 67 bool visible) OVERRIDE { |
| 66 EventDetails event; | 68 EventDetails event; |
| 67 event.type = visible ? EVENT_SHOWN : EVENT_HIDDEN; | 69 event.type = visible ? EVENT_SHOWN : EVENT_HIDDEN; |
| 68 event.window = window; | 70 event.window = window; |
| 69 event.bounds = window->GetBoundsInRootWindow(); | 71 event.bounds = window->GetBoundsInRootWindow(); |
| 70 | 72 |
| 71 // Dedupe events as a single Hide() call can result in several | 73 // Dedupe events as a single Hide() call can result in several |
| 72 // notifications. | 74 // notifications. |
| 73 if (events_.size() == 0u || events_.back() != event) | 75 if (events_.size() == 0u || events_.back() != event) |
| 74 events_.push_back(event); | 76 events_.push_back(event); |
| 75 } | 77 } |
| 76 | 78 |
| 77 virtual void OnWindowBoundsChanged(aura::Window* window, | 79 virtual void OnWindowBoundsChanged(aura::Window* window, |
| 78 const gfx::Rect& old_bounds, | 80 const gfx::Rect& old_bounds, |
| 79 const gfx::Rect& new_bounds) OVERRIDE { | 81 const gfx::Rect& new_bounds) OVERRIDE { |
| 80 EventDetails event; | 82 EventDetails event; |
| 81 event.type = EVENT_BOUNDS_CHANGED; | 83 event.type = EVENT_BOUNDS_CHANGED; |
| 82 event.window = window; | 84 event.window = window; |
| 83 event.bounds = window->GetBoundsInRootWindow(); | 85 event.bounds = window->GetBoundsInRootWindow(); |
| 84 events_.push_back(event); | 86 events_.push_back(event); |
| 85 } | 87 } |
| 86 | 88 |
| 89 virtual void OnWindowParentChanged(aura::Window* window, | |
|
sky
2014/09/11 14:55:05
Can't you at events_, since presumably OnWindowVis
ananta
2014/09/11 15:01:56
OnWindowVisibilityChanged is only called in Chrome
sky
2014/09/11 15:29:20
OnWindowVisibilityChanged is from aura::WindowObse
| |
| 90 aura::Window* parent) OVERRIDE { | |
| 91 if (parent && !visibility_state_after_reparenting_) | |
| 92 visibility_state_after_reparenting_ = window->IsVisible(); | |
| 93 } | |
| 94 | |
| 95 int visibility_state_after_reparenting() const { | |
| 96 return visibility_state_after_reparenting_; | |
| 97 } | |
| 98 | |
| 87 private: | 99 private: |
| 88 std::vector<EventDetails> events_; | 100 std::vector<EventDetails> events_; |
| 89 gfx::Rect bounds_at_visibility_changed_; | 101 gfx::Rect bounds_at_visibility_changed_; |
| 90 | 102 |
| 103 // Tracks the visibility state of the window after it was reparented. | |
| 104 // changed. | |
| 105 int visibility_state_after_reparenting_; | |
| 106 | |
| 91 DISALLOW_COPY_AND_ASSIGN(NativeViewHostWindowObserver); | 107 DISALLOW_COPY_AND_ASSIGN(NativeViewHostWindowObserver); |
| 92 }; | 108 }; |
| 93 | 109 |
| 94 class NativeViewHostAuraTest : public ViewsTestBase { | 110 class NativeViewHostAuraTest : public ViewsTestBase { |
| 95 public: | 111 public: |
| 96 NativeViewHostAuraTest() { | 112 NativeViewHostAuraTest() { |
| 97 } | 113 } |
| 98 | 114 |
| 99 NativeViewHostAura* native_host() { | 115 NativeViewHostAura* native_host() { |
| 100 return static_cast<NativeViewHostAura*>(host_->native_wrapper_.get()); | 116 return static_cast<NativeViewHostAura*>(host_->native_wrapper_.get()); |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 317 | 333 |
| 318 NativeViewHostWindowObserver test_observer; | 334 NativeViewHostWindowObserver test_observer; |
| 319 clipping_window()->AddObserver(&test_observer); | 335 clipping_window()->AddObserver(&test_observer); |
| 320 child()->GetNativeView()->AddObserver(&test_observer); | 336 child()->GetNativeView()->AddObserver(&test_observer); |
| 321 | 337 |
| 322 host()->Detach(); | 338 host()->Detach(); |
| 323 | 339 |
| 324 ASSERT_EQ(3u, test_observer.events().size()); | 340 ASSERT_EQ(3u, test_observer.events().size()); |
| 325 EXPECT_EQ(NativeViewHostWindowObserver::EVENT_HIDDEN, | 341 EXPECT_EQ(NativeViewHostWindowObserver::EVENT_HIDDEN, |
| 326 test_observer.events()[0].type); | 342 test_observer.events()[0].type); |
| 327 EXPECT_EQ(clipping_window(), test_observer.events()[0].window); | 343 EXPECT_EQ(child()->GetNativeView(), test_observer.events()[0].window); |
| 344 EXPECT_EQ(NativeViewHostWindowObserver::EVENT_HIDDEN, | |
| 345 test_observer.events()[1].type); | |
| 346 EXPECT_EQ(clipping_window(), test_observer.events()[1].window); | |
| 328 EXPECT_EQ(NativeViewHostWindowObserver::EVENT_BOUNDS_CHANGED, | 347 EXPECT_EQ(NativeViewHostWindowObserver::EVENT_BOUNDS_CHANGED, |
| 329 test_observer.events()[1].type); | |
| 330 EXPECT_EQ(child()->GetNativeView(), test_observer.events()[1].window); | |
| 331 EXPECT_EQ(NativeViewHostWindowObserver::EVENT_HIDDEN, | |
| 332 test_observer.events()[2].type); | 348 test_observer.events()[2].type); |
| 333 EXPECT_EQ(child()->GetNativeView(), test_observer.events()[2].window); | 349 EXPECT_EQ(child()->GetNativeView(), test_observer.events()[2].window); |
| 334 | 350 |
| 335 clipping_window()->RemoveObserver(&test_observer); | 351 clipping_window()->RemoveObserver(&test_observer); |
| 336 child()->GetNativeView()->RemoveObserver(&test_observer); | 352 child()->GetNativeView()->RemoveObserver(&test_observer); |
| 337 | 353 |
| 338 DestroyHost(); | 354 DestroyHost(); |
| 339 } | 355 } |
| 340 | 356 |
| 341 // Ensure the native view receives the correct bounds notification when it is | 357 // Ensure the native view receives the correct bounds notification when it is |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 387 EXPECT_TRUE(child()->IsVisible()); | 403 EXPECT_TRUE(child()->IsVisible()); |
| 388 | 404 |
| 389 host()->SetVisible(false); | 405 host()->SetVisible(false); |
| 390 EXPECT_FALSE(clipping_window()->IsVisible()); | 406 EXPECT_FALSE(clipping_window()->IsVisible()); |
| 391 EXPECT_FALSE(child()->IsVisible()); | 407 EXPECT_FALSE(child()->IsVisible()); |
| 392 | 408 |
| 393 DestroyHost(); | 409 DestroyHost(); |
| 394 DestroyTopLevel(); | 410 DestroyTopLevel(); |
| 395 } | 411 } |
| 396 | 412 |
| 413 // This test validates that detaching the host after it has become visible with | |
| 414 // valid bounds, hides the host native view before it is reparented. | |
| 415 TEST_F(NativeViewHostAuraTest, DetachHidesNativeViewBeforeReparenting) { | |
| 416 CreateHost(); | |
| 417 | |
| 418 toplevel()->SetBounds(gfx::Rect(20, 20, 100, 100)); | |
| 419 toplevel()->Show(); | |
| 420 | |
| 421 host()->SetBounds(10, 10, 80, 80); | |
| 422 EXPECT_TRUE(clipping_window()->IsVisible()); | |
| 423 EXPECT_TRUE(child()->IsVisible()); | |
| 424 | |
| 425 NativeViewHostWindowObserver test_observer; | |
| 426 host()->native_view()->AddObserver(&test_observer); | |
| 427 | |
| 428 // Save away the native view in a local as it is null'ed out in the Detach | |
| 429 // call. | |
| 430 aura::Window* native_view = host()->native_view(); | |
| 431 host()->Detach(); | |
| 432 | |
| 433 EXPECT_FALSE(clipping_window()->IsVisible()); | |
| 434 EXPECT_FALSE(child()->IsVisible()); | |
| 435 | |
| 436 EXPECT_FALSE(test_observer.visibility_state_after_reparenting()); | |
| 437 native_view->RemoveObserver(&test_observer); | |
| 438 DestroyHost(); | |
| 439 DestroyTopLevel(); | |
| 440 } | |
| 441 | |
| 397 } // namespace views | 442 } // namespace views |
| OLD | NEW |