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 |