| Index: content/browser/web_contents/aura/native_view_screen_bounds_observer.cc
|
| diff --git a/content/browser/web_contents/aura/native_view_screen_bounds_observer.cc b/content/browser/web_contents/aura/native_view_screen_bounds_observer.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..5334232c3643e01f29dd4b09af4ab3bd32286a07
|
| --- /dev/null
|
| +++ b/content/browser/web_contents/aura/native_view_screen_bounds_observer.cc
|
| @@ -0,0 +1,134 @@
|
| +// Copyright (c) 2013 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "content/browser/web_contents/aura/native_view_screen_bounds_observer.h"
|
| +
|
| +#include <algorithm>
|
| +
|
| +#include "base/debug/trace_event.h"
|
| +#include "content/browser/web_contents/web_contents_view_aura.h"
|
| +#include "ui/aura/test/aura_test_base.h"
|
| +#include "ui/aura/window.h"
|
| +
|
| +namespace content {
|
| +
|
| +NativeViewScreenBoundsObserver::NativeViewScreenBoundsObserver(
|
| + NativeViewScreenBoundsObserverDelegate* delegate,
|
| + aura::Window* window)
|
| + : delegate_(delegate),
|
| + window_(window) {
|
| + DCHECK(delegate);
|
| + DCHECK(window);
|
| + delegate_ = delegate;
|
| + window_ = window;
|
| + std::set<aura::Window*> windows_to_root = CollectAllWindowsToRoot(window_);
|
| + AddToObserved(windows_to_root);
|
| +}
|
| +
|
| +NativeViewScreenBoundsObserver::~NativeViewScreenBoundsObserver() {
|
| + RemoveFromObserved(observed_);
|
| + if (window_->GetDispatcher())
|
| + window_->GetDispatcher()->RemoveRootWindowObserver(this);
|
| +}
|
| +
|
| +void NativeViewScreenBoundsObserver::OnWindowParentChanged(
|
| + aura::Window* window,
|
| + aura::Window* parent) {
|
| + std::set<aura::Window*> windows_to_root = CollectAllWindowsToRoot(window_);
|
| + std::set<aura::Window*> difference;
|
| + std::set_difference(
|
| + observed_.begin(),
|
| + observed_.end(),
|
| + windows_to_root.begin(),
|
| + windows_to_root.end(),
|
| + std::inserter(difference, difference.end()));
|
| + RemoveFromObserved(difference);
|
| +
|
| + difference.clear();
|
| + std::set_difference(
|
| + windows_to_root.begin(),
|
| + windows_to_root.end(),
|
| + observed_.begin(),
|
| + observed_.end(),
|
| + std::inserter(difference, difference.end()));
|
| + AddToObserved(difference);
|
| +}
|
| +
|
| +void NativeViewScreenBoundsObserver::OnWindowBoundsChanged(
|
| + aura::Window* window,
|
| + const gfx::Rect& old_bounds,
|
| + const gfx::Rect& new_bounds) {
|
| + if (old_bounds.size() == new_bounds.size()) {
|
| + delegate_->OnScreenPositionChanged();
|
| + } else {
|
| + delegate_->OnScreenBoundsChanged();
|
| + }
|
| +}
|
| +
|
| +void NativeViewScreenBoundsObserver::OnWindowAddedToRootWindow(
|
| + aura::Window* window) {
|
| + if (window == window_ && window_->GetDispatcher())
|
| + window_->GetDispatcher()->AddRootWindowObserver(this);
|
| +}
|
| +
|
| +void NativeViewScreenBoundsObserver::OnWindowRemovingFromRootWindow(
|
| + aura::Window* window) {
|
| + if (window == window_ && window_->GetDispatcher())
|
| + window_->GetDispatcher()->RemoveRootWindowObserver(this);
|
| +}
|
| +
|
| +void NativeViewScreenBoundsObserver::OnRootWindowHostMoved(
|
| + const aura::RootWindow* root,
|
| + const gfx::Point& new_origin) {
|
| + TRACE_EVENT1("ui",
|
| + "WebContentsViewAura::WindowObserver::OnWindowTreeHostMoved",
|
| + "new_origin", new_origin.ToString());
|
| +
|
| + // This is for the desktop case (i.e. Aura desktop).
|
| + delegate_->OnScreenPositionChanged();
|
| +}
|
| +
|
| +std::set<aura::Window*> NativeViewScreenBoundsObserver::CollectAllWindowsToRoot(
|
| + aura::Window* window) {
|
| + std::set<aura::Window*> ret_val;
|
| + if (window)
|
| + ret_val.insert(window);
|
| + while (window && window->parent()) {
|
| + ret_val.insert(window->parent());
|
| + window = window->parent();
|
| + }
|
| + return ret_val;
|
| +}
|
| +
|
| +void NativeViewScreenBoundsObserver::AddToObserved(
|
| + const std::set<aura::Window*>& windows) {
|
| + for (std::set<aura::Window*>::iterator iter = windows.begin();
|
| + iter != windows.end();
|
| + ++iter) {
|
| + if (observed_.end() == observed_.find(*iter)) {
|
| + (*iter)->AddObserver(this);
|
| + observed_.insert(*iter);
|
| + }
|
| + }
|
| +}
|
| +
|
| +void NativeViewScreenBoundsObserver::RemoveFromObserved(
|
| + const std::set<aura::Window*>& windows) {
|
| + // Since windows can possibly be |observer_| we cannot blindly iterate and
|
| + // delete, since const & means that |windows| is a reference to
|
| + // |observer_|. Thus if we erase an entry from |observed_| it may be erased
|
| + // from |windows| which we are iterating.
|
| + for (std::set<aura::Window*>::iterator iter = windows.begin();
|
| + iter != windows.end();) {
|
| + std::set<aura::Window*>::iterator next = iter;
|
| + next++;
|
| + if (observed_.end() != observed_.find(*iter)) {
|
| + (*iter)->RemoveObserver(this);
|
| + observed_.erase(*iter);
|
| + }
|
| + iter = next;
|
| + }
|
| +}
|
| +
|
| +} // namespace content
|
|
|