Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(558)

Unified Diff: content/browser/web_contents/aura/native_view_screen_bounds_observer.cc

Issue 54623007: Make code path for bounds changes getting to renderer less brittle (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Experimenting with single observer design Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698