OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "content/browser/web_contents/aura/constrained_windows_observer.h" |
| 6 |
| 7 #include "content/browser/renderer_host/render_view_host_factory.h" |
| 8 #include "content/browser/renderer_host/render_widget_host_view_aura.h" |
| 9 #include "content/browser/renderer_host/render_widget_host_view_aura.h" |
| 10 #include "content/browser/web_contents/web_contents_impl.h" |
| 11 #include "content/browser/web_contents/web_contents_view_aura.h" |
| 12 #include "content/public/browser/render_widget_host.h" |
| 13 #include "ui/aura/window.h" |
| 14 |
| 15 namespace content { |
| 16 namespace { |
| 17 |
| 18 RenderWidgetHostViewAura* ToRenderWidgetHostViewAura( |
| 19 RenderWidgetHostView* view) { |
| 20 if (!view || RenderViewHostFactory::has_factory()) |
| 21 return NULL; // Can't cast to RenderWidgetHostViewAura in unit tests. |
| 22 RenderProcessHostImpl* process = static_cast<RenderProcessHostImpl*>( |
| 23 view->GetRenderWidgetHost()->GetProcess()); |
| 24 if (process->IsGuest()) |
| 25 return NULL; |
| 26 return static_cast<RenderWidgetHostViewAura*>(view); |
| 27 } |
| 28 |
| 29 } // namespace |
| 30 |
| 31 ConstrainedWindowsObserver::ConstrainedWindowsObserver( |
| 32 WebContentsViewAura* view) |
| 33 : view_(view), |
| 34 constrained_parent_(NULL) { |
| 35 view_->window_->AddObserver(this); |
| 36 if (view_->window_->GetRootWindow()) |
| 37 view_->window_->GetRootWindow()->AddObserver(this); |
| 38 } |
| 39 |
| 40 ConstrainedWindowsObserver::~ConstrainedWindowsObserver() { |
| 41 view_->window_->RemoveObserver(this); |
| 42 |
| 43 if (constrained_parent_) { |
| 44 constrained_parent_->RemoveObserver(this); |
| 45 const aura::Window::Windows& children = constrained_parent_->children(); |
| 46 for (size_t i = 0; i < children.size(); ++i) |
| 47 children[i]->RemoveObserver(this); |
| 48 } |
| 49 |
| 50 aura::Window* root_window = view_->window_->GetRootWindow(); |
| 51 if (root_window) { |
| 52 root_window->RemoveObserver(this); |
| 53 const aura::Window::Windows& root_children = root_window->children(); |
| 54 for (size_t i = 0; i < root_children.size(); ++i) |
| 55 root_children[i]->RemoveObserver(this); |
| 56 } |
| 57 } |
| 58 |
| 59 // There are two sets of windows that are of interest, those that are a child |
| 60 // of a root window associated with |view_| and those that are a sibling of the |
| 61 // window for |view_|. Since NPAPI is going to be deprecated in a year, this is |
| 62 // ok for now. The test for this is PrintPreviewTest.WindowedNPAPIPluginHidden. |
| 63 void ConstrainedWindowsObserver::OnWindowAdded(aura::Window* new_window) { |
| 64 if (new_window == view_->window_) |
| 65 return; |
| 66 |
| 67 if (new_window == constrained_parent_) |
| 68 return; // This happens if the parent moves to the root window. |
| 69 |
| 70 // Observe sibling windows of the WebContents, or children of the root |
| 71 // window. |
| 72 if (new_window->parent() == constrained_parent_ || |
| 73 new_window->parent() == view_->window_->GetRootWindow()) { |
| 74 new_window->AddObserver(this); |
| 75 UpdateConstrainedWindows(NULL); |
| 76 } |
| 77 } |
| 78 |
| 79 void ConstrainedWindowsObserver::OnWillRemoveWindow(aura::Window* window) { |
| 80 if (window == view_->window_) |
| 81 return; |
| 82 |
| 83 window->RemoveObserver(this); |
| 84 UpdateConstrainedWindows(window); |
| 85 } |
| 86 |
| 87 void ConstrainedWindowsObserver::OnWindowVisibilityChanged( |
| 88 aura::Window* window, |
| 89 bool visible) { |
| 90 if (window == view_->window_) |
| 91 return; |
| 92 |
| 93 if (window->parent() == constrained_parent_ || |
| 94 window->parent() == view_->window_->GetRootWindow()) { |
| 95 UpdateConstrainedWindows(NULL); |
| 96 } |
| 97 } |
| 98 |
| 99 void ConstrainedWindowsObserver::OnWindowParentChanged(aura::Window* window, |
| 100 aura::Window* parent) { |
| 101 if (window != view_->window_) |
| 102 return; |
| 103 if (constrained_parent_) |
| 104 constrained_parent_->RemoveObserver(this); |
| 105 |
| 106 if (constrained_parent_) { |
| 107 const aura::Window::Windows& children = constrained_parent_->children(); |
| 108 for (size_t i = 0; i < children.size(); ++i) |
| 109 children[i]->RemoveObserver(this); |
| 110 |
| 111 RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura( |
| 112 view_->web_contents_->GetRenderWidgetHostView()); |
| 113 if (view) |
| 114 view->UpdateConstrainedWindowRects(std::vector<gfx::Rect>()); |
| 115 } |
| 116 |
| 117 // When we get parented to the root window, the code below will watch the |
| 118 // parent, aka root window. Since we already watch the root window on |
| 119 // Windows, unregister first so that the debug check doesn't fire. |
| 120 if (parent && parent == window->GetRootWindow()) |
| 121 parent->RemoveObserver(this); |
| 122 |
| 123 // We need to undo the above if we were parented to the root window and then |
| 124 // got parented to another window. At that point, the code before the ifdef |
| 125 // would have stopped watching the root window. |
| 126 if (window->GetRootWindow() && |
| 127 parent != window->GetRootWindow() && |
| 128 !window->GetRootWindow()->HasObserver(this)) { |
| 129 window->GetRootWindow()->AddObserver(this); |
| 130 } |
| 131 |
| 132 constrained_parent_ = parent; |
| 133 |
| 134 if (constrained_parent_) { |
| 135 constrained_parent_->AddObserver(this); |
| 136 if (constrained_parent_ != window->GetRootWindow()) { |
| 137 const aura::Window::Windows& children = constrained_parent_->children(); |
| 138 for (size_t i = 0; i < children.size(); ++i) { |
| 139 if (children[i] != view_->window_) |
| 140 children[i]->AddObserver(this); |
| 141 } |
| 142 } |
| 143 } |
| 144 } |
| 145 |
| 146 void ConstrainedWindowsObserver::OnWindowBoundsChanged( |
| 147 aura::Window* window, |
| 148 const gfx::Rect& old_bounds, |
| 149 const gfx::Rect& new_bounds) { |
| 150 if (window != constrained_parent_ && window != view_->window_) |
| 151 UpdateConstrainedWindows(NULL); |
| 152 } |
| 153 |
| 154 void ConstrainedWindowsObserver::OnWindowAddedToRootWindow( |
| 155 aura::Window* window) { |
| 156 if (window == view_->window_) { |
| 157 if (!window->GetRootWindow()->HasObserver(this)) |
| 158 window->GetRootWindow()->AddObserver(this); |
| 159 } |
| 160 } |
| 161 |
| 162 void ConstrainedWindowsObserver::OnWindowRemovingFromRootWindow( |
| 163 aura::Window* window) { |
| 164 if (window == view_->window_) { |
| 165 window->GetRootWindow()->RemoveObserver(this); |
| 166 |
| 167 const aura::Window::Windows& root_children = |
| 168 window->GetRootWindow()->children(); |
| 169 for (size_t i = 0; i < root_children.size(); ++i) { |
| 170 if (root_children[i] != view_->window_ && |
| 171 root_children[i] != constrained_parent_) |
| 172 root_children[i]->RemoveObserver(this); |
| 173 } |
| 174 } |
| 175 } |
| 176 |
| 177 void ConstrainedWindowsObserver::UpdateConstrainedWindows( |
| 178 aura::Window* exclude) { |
| 179 RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura( |
| 180 view_->web_contents_->GetRenderWidgetHostView()); |
| 181 if (!view) |
| 182 return; |
| 183 |
| 184 std::vector<gfx::Rect> constrained_windows; |
| 185 const aura::Window::Windows& children = constrained_parent_->children(); |
| 186 for (size_t i = 0; i < children.size(); ++i) { |
| 187 if (children[i] != view_->window_ && |
| 188 children[i] != exclude && |
| 189 children[i]->IsVisible()) { |
| 190 constrained_windows.push_back(children[i]->GetBoundsInRootWindow()); |
| 191 } |
| 192 } |
| 193 |
| 194 view->UpdateConstrainedWindowRects(constrained_windows); |
| 195 } |
| 196 |
| 197 } // namespace content |
OLD | NEW |