| Index: content/browser/web_contents/aura/constrained_windows_observer.cc
|
| diff --git a/content/browser/web_contents/aura/constrained_windows_observer.cc b/content/browser/web_contents/aura/constrained_windows_observer.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..4de9c7859a1eb5d93a033a6a4a10f742c659d2dd
|
| --- /dev/null
|
| +++ b/content/browser/web_contents/aura/constrained_windows_observer.cc
|
| @@ -0,0 +1,197 @@
|
| +// 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/constrained_windows_observer.h"
|
| +
|
| +#include "content/browser/renderer_host/render_view_host_factory.h"
|
| +#include "content/browser/renderer_host/render_widget_host_view_aura.h"
|
| +#include "content/browser/renderer_host/render_widget_host_view_aura.h"
|
| +#include "content/browser/web_contents/web_contents_impl.h"
|
| +#include "content/browser/web_contents/web_contents_view_aura.h"
|
| +#include "content/public/browser/render_widget_host.h"
|
| +#include "ui/aura/window.h"
|
| +
|
| +namespace content {
|
| +namespace {
|
| +
|
| +RenderWidgetHostViewAura* ToRenderWidgetHostViewAura(
|
| + RenderWidgetHostView* view) {
|
| + if (!view || RenderViewHostFactory::has_factory())
|
| + return NULL; // Can't cast to RenderWidgetHostViewAura in unit tests.
|
| + RenderProcessHostImpl* process = static_cast<RenderProcessHostImpl*>(
|
| + view->GetRenderWidgetHost()->GetProcess());
|
| + if (process->IsGuest())
|
| + return NULL;
|
| + return static_cast<RenderWidgetHostViewAura*>(view);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +ConstrainedWindowsObserver::ConstrainedWindowsObserver(
|
| + WebContentsViewAura* view)
|
| + : view_(view),
|
| + constrained_parent_(NULL) {
|
| + view_->window_->AddObserver(this);
|
| + if (view_->window_->GetRootWindow())
|
| + view_->window_->GetRootWindow()->AddObserver(this);
|
| +}
|
| +
|
| +ConstrainedWindowsObserver::~ConstrainedWindowsObserver() {
|
| + view_->window_->RemoveObserver(this);
|
| +
|
| + if (constrained_parent_) {
|
| + constrained_parent_->RemoveObserver(this);
|
| + const aura::Window::Windows& children = constrained_parent_->children();
|
| + for (size_t i = 0; i < children.size(); ++i)
|
| + children[i]->RemoveObserver(this);
|
| + }
|
| +
|
| + aura::Window* root_window = view_->window_->GetRootWindow();
|
| + if (root_window) {
|
| + root_window->RemoveObserver(this);
|
| + const aura::Window::Windows& root_children = root_window->children();
|
| + for (size_t i = 0; i < root_children.size(); ++i)
|
| + root_children[i]->RemoveObserver(this);
|
| + }
|
| +}
|
| +
|
| +// There are two sets of windows that are of interest, those that are a child
|
| +// of a root window associated with |view_| and those that are a sibling of the
|
| +// window for |view_|. Since NPAPI is going to be deprecated in a year, this is
|
| +// ok for now. The test for this is PrintPreviewTest.WindowedNPAPIPluginHidden.
|
| +void ConstrainedWindowsObserver::OnWindowAdded(aura::Window* new_window) {
|
| + if (new_window == view_->window_)
|
| + return;
|
| +
|
| + if (new_window == constrained_parent_)
|
| + return; // This happens if the parent moves to the root window.
|
| +
|
| + // Observe sibling windows of the WebContents, or children of the root
|
| + // window.
|
| + if (new_window->parent() == constrained_parent_ ||
|
| + new_window->parent() == view_->window_->GetRootWindow()) {
|
| + new_window->AddObserver(this);
|
| + UpdateConstrainedWindows(NULL);
|
| + }
|
| +}
|
| +
|
| +void ConstrainedWindowsObserver::OnWillRemoveWindow(aura::Window* window) {
|
| + if (window == view_->window_)
|
| + return;
|
| +
|
| + window->RemoveObserver(this);
|
| + UpdateConstrainedWindows(window);
|
| +}
|
| +
|
| +void ConstrainedWindowsObserver::OnWindowVisibilityChanged(
|
| + aura::Window* window,
|
| + bool visible) {
|
| + if (window == view_->window_)
|
| + return;
|
| +
|
| + if (window->parent() == constrained_parent_ ||
|
| + window->parent() == view_->window_->GetRootWindow()) {
|
| + UpdateConstrainedWindows(NULL);
|
| + }
|
| +}
|
| +
|
| +void ConstrainedWindowsObserver::OnWindowParentChanged(aura::Window* window,
|
| + aura::Window* parent) {
|
| + if (window != view_->window_)
|
| + return;
|
| + if (constrained_parent_)
|
| + constrained_parent_->RemoveObserver(this);
|
| +
|
| + if (constrained_parent_) {
|
| + const aura::Window::Windows& children = constrained_parent_->children();
|
| + for (size_t i = 0; i < children.size(); ++i)
|
| + children[i]->RemoveObserver(this);
|
| +
|
| + RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura(
|
| + view_->web_contents_->GetRenderWidgetHostView());
|
| + if (view)
|
| + view->UpdateConstrainedWindowRects(std::vector<gfx::Rect>());
|
| + }
|
| +
|
| + // When we get parented to the root window, the code below will watch the
|
| + // parent, aka root window. Since we already watch the root window on
|
| + // Windows, unregister first so that the debug check doesn't fire.
|
| + if (parent && parent == window->GetRootWindow())
|
| + parent->RemoveObserver(this);
|
| +
|
| + // We need to undo the above if we were parented to the root window and then
|
| + // got parented to another window. At that point, the code before the ifdef
|
| + // would have stopped watching the root window.
|
| + if (window->GetRootWindow() &&
|
| + parent != window->GetRootWindow() &&
|
| + !window->GetRootWindow()->HasObserver(this)) {
|
| + window->GetRootWindow()->AddObserver(this);
|
| + }
|
| +
|
| + constrained_parent_ = parent;
|
| +
|
| + if (constrained_parent_) {
|
| + constrained_parent_->AddObserver(this);
|
| + if (constrained_parent_ != window->GetRootWindow()) {
|
| + const aura::Window::Windows& children = constrained_parent_->children();
|
| + for (size_t i = 0; i < children.size(); ++i) {
|
| + if (children[i] != view_->window_)
|
| + children[i]->AddObserver(this);
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +void ConstrainedWindowsObserver::OnWindowBoundsChanged(
|
| + aura::Window* window,
|
| + const gfx::Rect& old_bounds,
|
| + const gfx::Rect& new_bounds) {
|
| + if (window != constrained_parent_ && window != view_->window_)
|
| + UpdateConstrainedWindows(NULL);
|
| +}
|
| +
|
| +void ConstrainedWindowsObserver::OnWindowAddedToRootWindow(
|
| + aura::Window* window) {
|
| + if (window == view_->window_) {
|
| + if (!window->GetRootWindow()->HasObserver(this))
|
| + window->GetRootWindow()->AddObserver(this);
|
| + }
|
| +}
|
| +
|
| +void ConstrainedWindowsObserver::OnWindowRemovingFromRootWindow(
|
| + aura::Window* window) {
|
| + if (window == view_->window_) {
|
| + window->GetRootWindow()->RemoveObserver(this);
|
| +
|
| + const aura::Window::Windows& root_children =
|
| + window->GetRootWindow()->children();
|
| + for (size_t i = 0; i < root_children.size(); ++i) {
|
| + if (root_children[i] != view_->window_ &&
|
| + root_children[i] != constrained_parent_)
|
| + root_children[i]->RemoveObserver(this);
|
| + }
|
| + }
|
| +}
|
| +
|
| +void ConstrainedWindowsObserver::UpdateConstrainedWindows(
|
| + aura::Window* exclude) {
|
| + RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura(
|
| + view_->web_contents_->GetRenderWidgetHostView());
|
| + if (!view)
|
| + return;
|
| +
|
| + std::vector<gfx::Rect> constrained_windows;
|
| + const aura::Window::Windows& children = constrained_parent_->children();
|
| + for (size_t i = 0; i < children.size(); ++i) {
|
| + if (children[i] != view_->window_ &&
|
| + children[i] != exclude &&
|
| + children[i]->IsVisible()) {
|
| + constrained_windows.push_back(children[i]->GetBoundsInRootWindow());
|
| + }
|
| + }
|
| +
|
| + view->UpdateConstrainedWindowRects(constrained_windows);
|
| +}
|
| +
|
| +} // namespace content
|
|
|