Commit 006f475c authored by shrikant@chromium.org's avatar shrikant@chromium.org

Revert 233297 "Fix windowed NPAPI plugins covering up dialogs on..."

Error Log:
[ RUN      ] PrintPreviewTest.WindowedNPAPIPluginHidden
[3852:2708:1106/120416:ERROR:dxva_video_decode_accelerator.cc(421)] Direct3DCreate9Ex failed, HRESULT: 0x8876086a
[3852:2708:1106/120416:ERROR:dxva_video_decode_accelerator.cc(398)] Failed to initialize D3D device and manager
[2672:2864:1106/120416:2596964:ERROR:chrome_views_delegate.cc(172)] NOT IMPLEMENTED
[2672:2864:1106/120416:2596964:ERROR:desktop_root_window_host_win.cc(688)] NOT IMPLEMENTED
[2672:3764:1106/120417:2597915:ERROR:gpu_message_filter.cc(189)] Renderer 3 tried to access a surface for renderer 0
[2672:3764:1106/120417:2597931:ERROR:gpu_message_filter.cc(189)] Renderer 3 tried to access a surface for renderer 0
[2672:3764:1106/120417:2597931:ERROR:gpu_message_filter.cc(189)] Renderer 3 tried to access a surface for renderer 0
[2672:3764:1106/120417:2597931:ERROR:gpu_message_filter.cc(189)] Renderer 3 tried to access a surface for renderer 0
[2904:3556:1106/120418:VERBOSE2:ipc_channel_win.cc(85)] sending message @0B515550 on channel @0B550EA8 with type 262228 (0 in queue)
[2904:3556:1106/120418:VERBOSE2:ipc_channel_win.cc(409)] sent message @0B515550 on channel @0B550EA8 with type 262228
[2672:2864:1106/120418:2598820:ERROR:chrome_views_delegate.cc(172)] NOT IMPLEMENTED
[2672:3764:1106/120418:2599273:ERROR:gpu_message_filter.cc(189)] Renderer 6 tried to access a surface for renderer 0
[2672:3764:1106/120419:2599351:ERROR:gpu_message_filter.cc(189)] Renderer 6 tried to access a surface for renderer 0
[2672:3764:1106/120419:2599366:ERROR:gpu_message_filter.cc(189)] Renderer 6 tried to access a surface for renderer 0
[2672:3764:1106/120419:2599366:ERROR:gpu_message_filter.cc(189)] Renderer 6 tried to access a surface for renderer 0
browser\ui\webui\print_preview\print_preview_ui_browsertest.cc(124): error: Value of: 2
Expected: result
Which is: 1
[  FAILED  ] PrintPreviewTest.WindowedNPAPIPluginHidden, where TypeParam =  and GetParam() =  (4804 ms)
[632/632] PrintPreviewTest.WindowedNPAPIPluginHidden (5614 ms)

> Fix windowed NPAPI plugins covering up dialogs on Win Aura.
> 
> The original fix stopped working with the new style of dialogs, since they're not parented to the WebContents anymore but instead to its parent. It also turns out we don't need to watch out for transient windows, as they're now top level ones with their own HWND so clipping works through the OS and we don't need to do anything special.
> 
> BUG=299224
> R=ben@chromium.org
> 
> Review URL: https://codereview.chromium.org/53153003

TBR=jam@chromium.org

Review URL: https://codereview.chromium.org/63013002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@233333 0039d316-1c4b-4281-b951-d872f2087c98
parent b61a0740
...@@ -3,29 +3,17 @@ ...@@ -3,29 +3,17 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "base/command_line.h" #include "base/command_line.h"
#include "base/prefs/pref_service.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h" #include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/content_settings/host_content_settings_map.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h" #include "chrome/common/url_constants.h"
#include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_observer.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_navigation_observer.h" #include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h" #include "content/public/test/test_utils.h"
#if defined(OS_WIN) && defined(USE_AURA)
#include "content/public/browser/web_contents_view.h"
#include "ui/aura/root_window.h"
#endif
namespace { namespace {
class PrintPreviewTest : public InProcessBrowserTest { class PrintPreviewTest : public InProcessBrowserTest {
...@@ -77,58 +65,4 @@ IN_PROC_BROWSER_TEST_F(PrintPreviewTest, PrintCommands) { ...@@ -77,58 +65,4 @@ IN_PROC_BROWSER_TEST_F(PrintPreviewTest, PrintCommands) {
ASSERT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ADVANCED_PRINT)); ASSERT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ADVANCED_PRINT));
} }
#if defined(OS_WIN) && defined(USE_AURA)
BOOL CALLBACK EnumerateChildren(HWND hwnd, LPARAM l_param) {
HWND* child = reinterpret_cast<HWND*>(l_param);
*child = hwnd;
// The first child window is the plugin, then its children. So stop
// enumerating after the first callback.
return FALSE;
}
// This test verifies that constrained windows aren't covered by windowed NPAPI
// plugins. The code which fixes this is in WebContentsViewAura::WindowObserver.
IN_PROC_BROWSER_TEST_F(PrintPreviewTest, WindowedNPAPIPluginHidden) {
browser()->profile()->GetPrefs()->SetBoolean(prefs::kPluginsAlwaysAuthorize,
true);
// First load the page and wait for the NPAPI plugin's window to display.
string16 expected_title(ASCIIToUTF16("ready"));
content::WebContents* tab =
browser()->tab_strip_model()->GetActiveWebContents();
content::TitleWatcher title_watcher(tab, expected_title);
GURL url = ui_test_utils::GetTestUrl(
base::FilePath().AppendASCII("printing"),
base::FilePath().AppendASCII("npapi_plugin.html"));
ui_test_utils::NavigateToURL(browser(), url);
EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
// Now get the region of the plugin before and after the print preview is
// shown. They should be different.
HWND hwnd =
tab->GetView()->GetNativeView()->GetDispatcher()->GetAcceleratedWidget();
HWND child = NULL;
EnumChildWindows(hwnd, EnumerateChildren,reinterpret_cast<LPARAM>(&child));
RECT region_before, region_after;
int result = GetWindowRgnBox(child, &region_before);
ASSERT_EQ(result, SIMPLEREGION);
// Now print preview.
Print();
result = GetWindowRgnBox(child, &region_after);
ASSERT_EQ(result, SIMPLEREGION);
bool rects_equal =
region_before.left == region_after.left &&
region_before.top == region_after.top &&
region_before.right == region_after.right &&
region_before.bottom == region_after.bottom;
ASSERT_FALSE(rects_equal);
}
#endif
} // namespace } // namespace
<hmtl>
<body>
<embed type="application/vnd.npapi-test"
height="300"
width="300"
name="set_title_in_paint"
id="1"
mode="np_embed"/>
</body>
<script>
function SetTitle() {
window.document.title = "ready";
return;
}
</script>
</hmtl>
\ No newline at end of file
...@@ -442,6 +442,113 @@ class RenderWidgetHostViewAura::WindowObserver : public aura::WindowObserver { ...@@ -442,6 +442,113 @@ class RenderWidgetHostViewAura::WindowObserver : public aura::WindowObserver {
DISALLOW_COPY_AND_ASSIGN(WindowObserver); DISALLOW_COPY_AND_ASSIGN(WindowObserver);
}; };
#if defined(OS_WIN)
// On Windows, we need to watch the top level window for changes to transient
// windows because they can cover the view and we need to ensure that they're
// rendered on top of windowed NPAPI plugins.
class RenderWidgetHostViewAura::TransientWindowObserver
: public aura::WindowObserver {
public:
explicit TransientWindowObserver(RenderWidgetHostViewAura* view)
: view_(view), top_level_(NULL) {
view_->window_->AddObserver(this);
}
virtual ~TransientWindowObserver() {
view_->window_->RemoveObserver(this);
StopObserving();
}
// Overridden from aura::WindowObserver:
virtual void OnWindowHierarchyChanged(
const aura::WindowObserver::HierarchyChangeParams& params) OVERRIDE {
aura::Window* top_level = GetToplevelWindow();
if (top_level == top_level_)
return;
StopObserving();
top_level_ = top_level;
if (top_level_ && top_level_ != view_->window_)
top_level_->AddObserver(this);
}
virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
if (window == top_level_)
StopObserving();
}
virtual void OnWindowBoundsChanged(aura::Window* window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) OVERRIDE {
if (window->transient_parent())
SendPluginCutoutRects();
}
virtual void OnWindowVisibilityChanged(aura::Window* window,
bool visible) OVERRIDE {
if (window->transient_parent())
SendPluginCutoutRects();
}
virtual void OnAddTransientChild(aura::Window* window,
aura::Window* transient) OVERRIDE {
transient->AddObserver(this);
// Just wait for the OnWindowBoundsChanged of the transient, since the size
// is not known now.
}
virtual void OnRemoveTransientChild(aura::Window* window,
aura::Window* transient) OVERRIDE {
transient->RemoveObserver(this);
SendPluginCutoutRects();
}
aura::Window* GetToplevelWindow() {
aura::Window* root = view_->window_->GetRootWindow();
if (!root)
return NULL;
aura::client::ActivationClient* activation_client =
aura::client::GetActivationClient(root);
if (!activation_client)
return NULL;
return activation_client->GetToplevelWindow(view_->window_);
}
void StopObserving() {
if (!top_level_)
return;
const aura::Window::Windows& transients = top_level_->transient_children();
for (size_t i = 0; i < transients.size(); ++i)
transients[i]->RemoveObserver(this);
if (top_level_ != view_->window_)
top_level_->RemoveObserver(this);
top_level_ = NULL;
}
void SendPluginCutoutRects() {
std::vector<gfx::Rect> cutouts;
if (top_level_) {
const aura::Window::Windows& transients =
top_level_->transient_children();
for (size_t i = 0; i < transients.size(); ++i) {
if (transients[i]->IsVisible())
cutouts.push_back(transients[i]->GetBoundsInRootWindow());
}
}
view_->UpdateTransientRects(cutouts);
}
private:
RenderWidgetHostViewAura* view_;
aura::Window* top_level_;
DISALLOW_COPY_AND_ASSIGN(TransientWindowObserver);
};
#endif
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// RenderWidgetHostViewAura, public: // RenderWidgetHostViewAura, public:
...@@ -477,6 +584,9 @@ RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost* host) ...@@ -477,6 +584,9 @@ RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost* host)
aura::client::SetActivationChangeObserver(window_, this); aura::client::SetActivationChangeObserver(window_, this);
aura::client::SetFocusChangeObserver(window_, this); aura::client::SetFocusChangeObserver(window_, this);
gfx::Screen::GetScreenFor(window_)->AddObserver(this); gfx::Screen::GetScreenFor(window_)->AddObserver(this);
#if defined(OS_WIN)
transient_observer_.reset(new TransientWindowObserver(this));
#endif
software_frame_manager_.reset(new SoftwareFrameManager( software_frame_manager_.reset(new SoftwareFrameManager(
weak_ptr_factory_.GetWeakPtr())); weak_ptr_factory_.GetWeakPtr()));
} }
...@@ -574,6 +684,7 @@ void RenderWidgetHostViewAura::WasShown() { ...@@ -574,6 +684,7 @@ void RenderWidgetHostViewAura::WasShown() {
#if defined(OS_WIN) #if defined(OS_WIN)
LPARAM lparam = reinterpret_cast<LPARAM>(this); LPARAM lparam = reinterpret_cast<LPARAM>(this);
EnumChildWindows(ui::GetHiddenWindow(), ShowWindowsCallback, lparam); EnumChildWindows(ui::GetHiddenWindow(), ShowWindowsCallback, lparam);
transient_observer_->SendPluginCutoutRects();
#endif #endif
} }
...@@ -586,7 +697,6 @@ void RenderWidgetHostViewAura::WasHidden() { ...@@ -586,7 +697,6 @@ void RenderWidgetHostViewAura::WasHidden() {
released_front_lock_ = NULL; released_front_lock_ = NULL;
#if defined(OS_WIN) #if defined(OS_WIN)
constrained_rects_.clear();
aura::WindowEventDispatcher* dispatcher = window_->GetDispatcher(); aura::WindowEventDispatcher* dispatcher = window_->GetDispatcher();
if (dispatcher) { if (dispatcher) {
HWND parent = dispatcher->GetAcceleratedWidget(); HWND parent = dispatcher->GetAcceleratedWidget();
...@@ -781,10 +891,14 @@ void RenderWidgetHostViewAura::MovePluginWindows( ...@@ -781,10 +891,14 @@ void RenderWidgetHostViewAura::MovePluginWindows(
plugin_window_moves_[moves[i].window] = moves[i]; plugin_window_moves_[moves[i].window] = moves[i];
// constrained_rects_ are relative to the root window. We want to convert // transient_rects_ and constrained_rects_ are relative to the root window.
// them to be relative to the plugin window. // We want to convert them to be relative to the plugin window.
for (size_t j = 0; j < constrained_rects_.size(); ++j) { std::vector<gfx::Rect> cutout_rects;
gfx::Rect offset_cutout = constrained_rects_[j]; cutout_rects.assign(transient_rects_.begin(), transient_rects_.end());
cutout_rects.insert(cutout_rects.end(), constrained_rects_.begin(),
constrained_rects_.end());
for (size_t j = 0; j < cutout_rects.size(); ++j) {
gfx::Rect offset_cutout = cutout_rects[j];
offset_cutout -= moves[i].window_rect.OffsetFromOrigin(); offset_cutout -= moves[i].window_rect.OffsetFromOrigin();
moves[i].cutout_rects.push_back(offset_cutout); moves[i].cutout_rects.push_back(offset_cutout);
} }
...@@ -1248,6 +1362,12 @@ void RenderWidgetHostViewAura::DidReceiveFrameFromRenderer() { ...@@ -1248,6 +1362,12 @@ void RenderWidgetHostViewAura::DidReceiveFrameFromRenderer() {
} }
#if defined(OS_WIN) #if defined(OS_WIN)
void RenderWidgetHostViewAura::UpdateTransientRects(
const std::vector<gfx::Rect>& rects) {
transient_rects_ = rects;
UpdateCutoutRects();
}
void RenderWidgetHostViewAura::UpdateConstrainedWindowRects( void RenderWidgetHostViewAura::UpdateConstrainedWindowRects(
const std::vector<gfx::Rect>& rects) { const std::vector<gfx::Rect>& rects) {
constrained_rects_ = rects; constrained_rects_ = rects;
...@@ -1260,7 +1380,10 @@ void RenderWidgetHostViewAura::UpdateCutoutRects() { ...@@ -1260,7 +1380,10 @@ void RenderWidgetHostViewAura::UpdateCutoutRects() {
HWND parent = window_->GetDispatcher()->GetAcceleratedWidget(); HWND parent = window_->GetDispatcher()->GetAcceleratedWidget();
CutoutRectsParams params; CutoutRectsParams params;
params.widget = this; params.widget = this;
params.cutout_rects = constrained_rects_; params.cutout_rects.assign(transient_rects_.begin(), transient_rects_.end());
params.cutout_rects.insert(params.cutout_rects.end(),
constrained_rects_.begin(),
constrained_rects_.end());
params.geometry = &plugin_window_moves_; params.geometry = &plugin_window_moves_;
LPARAM lparam = reinterpret_cast<LPARAM>(&params); LPARAM lparam = reinterpret_cast<LPARAM>(&params);
EnumChildWindows(parent, SetCutoutRectsCallback, lparam); EnumChildWindows(parent, SetCutoutRectsCallback, lparam);
...@@ -3086,6 +3209,9 @@ RenderWidgetHostViewAura::~RenderWidgetHostViewAura() { ...@@ -3086,6 +3209,9 @@ RenderWidgetHostViewAura::~RenderWidgetHostViewAura() {
factory->RemoveObserver(this); factory->RemoveObserver(this);
} }
window_observer_.reset(); window_observer_.reset();
#if defined(OS_WIN)
transient_observer_.reset();
#endif
if (window_->GetDispatcher()) if (window_->GetDispatcher())
window_->GetDispatcher()->RemoveRootWindowObserver(this); window_->GetDispatcher()->RemoveRootWindowObserver(this);
UnlockMouse(); UnlockMouse();
......
...@@ -395,6 +395,10 @@ class CONTENT_EXPORT RenderWidgetHostViewAura ...@@ -395,6 +395,10 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
class WindowObserver; class WindowObserver;
friend class WindowObserver; friend class WindowObserver;
#if defined(OS_WIN)
class TransientWindowObserver;
friend class TransientWindowObserver;
#endif
// Overridden from ImageTransportFactoryObserver: // Overridden from ImageTransportFactoryObserver:
virtual void OnLostResources() OVERRIDE; virtual void OnLostResources() OVERRIDE;
...@@ -552,6 +556,11 @@ class CONTENT_EXPORT RenderWidgetHostViewAura ...@@ -552,6 +556,11 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
BrowserAccessibilityManager* GetOrCreateBrowserAccessibilityManager(); BrowserAccessibilityManager* GetOrCreateBrowserAccessibilityManager();
#if defined(OS_WIN) #if defined(OS_WIN)
// Sets the cutout rects from transient windows. These are rectangles that
// windowed NPAPI plugins shouldn't paint in. Overwrites any previous cutout
// rects.
void UpdateTransientRects(const std::vector<gfx::Rect>& rects);
// Updates the total list of cutout rects, which is the union of transient // Updates the total list of cutout rects, which is the union of transient
// windows and constrained windows. // windows and constrained windows.
void UpdateCutoutRects(); void UpdateCutoutRects();
...@@ -722,8 +731,11 @@ class CONTENT_EXPORT RenderWidgetHostViewAura ...@@ -722,8 +731,11 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
PaintObserver* paint_observer_; PaintObserver* paint_observer_;
#if defined(OS_WIN) #if defined(OS_WIN)
// The list of rectangles from constrained windows over this view. Windowed scoped_ptr<TransientWindowObserver> transient_observer_;
// NPAPI plugins shouldn't draw over them.
// The list of rectangles from transient and constrained windows over this
// view. Windowed NPAPI plugins shouldn't draw over them.
std::vector<gfx::Rect> transient_rects_;
std::vector<gfx::Rect> constrained_rects_; std::vector<gfx::Rect> constrained_rects_;
typedef std::map<HWND, WebPluginGeometry> PluginWindowMoves; typedef std::map<HWND, WebPluginGeometry> PluginWindowMoves;
......
...@@ -663,66 +663,15 @@ class WebContentsViewAura::WindowObserver ...@@ -663,66 +663,15 @@ class WebContentsViewAura::WindowObserver
view_->window_->GetDispatcher()->RemoveRootWindowObserver(this); view_->window_->GetDispatcher()->RemoveRootWindowObserver(this);
if (parent_) if (parent_)
parent_->RemoveObserver(this); parent_->RemoveObserver(this);
#if defined(OS_WIN)
if (parent_) {
const aura::Window::Windows& children = parent_->children();
for (size_t i = 0; i < children.size(); ++i)
children[i]->RemoveObserver(this);
}
#endif
} }
// Overridden from aura::WindowObserver: // Overridden from aura::WindowObserver:
#if defined(OS_WIN)
// Constrained windows are added as children of the parent's parent's view
// which may overlap with windowed NPAPI plugins. In that case, tell the RWHV
// so that it can update the plugins' cutout rects accordingly.
// Note: this is hard coding how Chrome layer adds its dialogs. Since NPAPI is
// going to be deprecated in a year, this is ok for now. The test for this is
// PrintPreviewTest.WindowedNPAPIPluginHidden.
virtual void OnWindowAdded(aura::Window* new_window) OVERRIDE {
if (new_window->parent() != parent_)
return;
new_window->AddObserver(this);
UpdateConstrainedWindows(NULL);
}
virtual void OnWillRemoveWindow(aura::Window* window) OVERRIDE {
if (window->parent() == parent_ && window != view_->window_) {
window->RemoveObserver(this);
UpdateConstrainedWindows(window);
}
}
virtual void OnWindowVisibilityChanged(aura::Window* window,
bool visible) OVERRIDE {
if (window->parent() == parent_ && window != view_->window_)
UpdateConstrainedWindows(NULL);
}
#endif
virtual void OnWindowParentChanged(aura::Window* window, virtual void OnWindowParentChanged(aura::Window* window,
aura::Window* parent) OVERRIDE { aura::Window* parent) OVERRIDE {
if (window != view_->window_) if (window == parent_)
return; return;
if (parent_) if (parent_)
parent_->RemoveObserver(this); parent_->RemoveObserver(this);
#if defined(OS_WIN)
if (parent_) {
const aura::Window::Windows& children = 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>());
}
#endif
parent_ = parent; parent_ = parent;
if (parent) if (parent)
parent->AddObserver(this); parent->AddObserver(this);
...@@ -731,24 +680,18 @@ class WebContentsViewAura::WindowObserver ...@@ -731,24 +680,18 @@ class WebContentsViewAura::WindowObserver
virtual void OnWindowBoundsChanged(aura::Window* window, virtual void OnWindowBoundsChanged(aura::Window* window,
const gfx::Rect& old_bounds, const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) OVERRIDE { const gfx::Rect& new_bounds) OVERRIDE {
if (window == parent_ || window == view_->window_) { SendScreenRects();
SendScreenRects(); if (view_->touch_editable_)
if (view_->touch_editable_) view_->touch_editable_->UpdateEditingController();
view_->touch_editable_->UpdateEditingController();
#if defined(OS_WIN)
} else {
UpdateConstrainedWindows(NULL);
#endif
}
} }
virtual void OnWindowAddedToRootWindow(aura::Window* window) OVERRIDE { virtual void OnWindowAddedToRootWindow(aura::Window* window) OVERRIDE {
if (window == view_->window_) if (window != parent_)
window->GetDispatcher()->AddRootWindowObserver(this); window->GetDispatcher()->AddRootWindowObserver(this);
} }
virtual void OnWindowRemovingFromRootWindow(aura::Window* window) OVERRIDE { virtual void OnWindowRemovingFromRootWindow(aura::Window* window) OVERRIDE {
if (window == view_->window_) if (window != parent_)
window->GetDispatcher()->RemoveRootWindowObserver(this); window->GetDispatcher()->RemoveRootWindowObserver(this);
} }
...@@ -769,35 +712,104 @@ class WebContentsViewAura::WindowObserver ...@@ -769,35 +712,104 @@ class WebContentsViewAura::WindowObserver
SendScreenRects(); SendScreenRects();
} }
WebContentsViewAura* view_;
// We cache the old parent so that we can unregister when it's not the parent
// anymore.
aura::Window* parent_;
DISALLOW_COPY_AND_ASSIGN(WindowObserver);
};
#if defined(OS_WIN) #if defined(OS_WIN)
// Constrained windows are added as children of the WebContent's view which may
// overlap with windowed NPAPI plugins. In that case, tell the RWHV so that it
// can update the plugins' cutout rects accordingly.
class WebContentsViewAura::ChildWindowObserver : public aura::WindowObserver,
public WebContentsObserver {
public:
explicit ChildWindowObserver(WebContentsViewAura* view)
: WebContentsObserver(view->web_contents_),
view_(view),
web_contents_destroyed_(false) {
view_->window_->AddObserver(this);
}
virtual ~ChildWindowObserver() {
view_->window_->RemoveObserver(this);
const aura::Window::Windows& children = view_->window_->children();
for (size_t i = 0; i < children.size(); ++i)
children[i]->RemoveObserver(this);
}
// Overridden from aura::WindowObserver:
virtual void OnWindowAdded(aura::Window* new_window) OVERRIDE {
// If new child windows are added to the WebContent's view, tell the RWHV.
// We also start watching them to know when their size is updated. Of
// course, ignore the shadow window that contains the RWHV and child windows
// of the child windows that we are watching.
RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura(
view_->web_contents_->GetRenderWidgetHostView());
aura::Window* content_window = view ? view->GetNativeView() : NULL;
if (new_window->parent() == view_->window_ &&
new_window != content_window) {
new_window->AddObserver(this);
UpdateConstrainedWindows(NULL);
}
}
virtual void OnWillRemoveWindow(aura::Window* window) OVERRIDE {
RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura(
view_->web_contents_->GetRenderWidgetHostView());
aura::Window* content_window = view ? view->GetNativeView() : NULL;
if (window->parent() == view_->window_ &&
window != content_window) {
window->RemoveObserver(this);
UpdateConstrainedWindows(window);
}
}
virtual void OnWindowBoundsChanged(aura::Window* window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) OVERRIDE {
if (window->parent() == view_->window_ &&
window != view_->GetContentNativeView()) {
UpdateConstrainedWindows(NULL);
}
}
// Overridden from WebContentsObserver:
virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE {
web_contents_destroyed_ = true;
}
private:
void UpdateConstrainedWindows(aura::Window* exclude) { void UpdateConstrainedWindows(aura::Window* exclude) {
if (web_contents_destroyed_)
return;
RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura( RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura(
view_->web_contents_->GetRenderWidgetHostView()); view_->web_contents_->GetRenderWidgetHostView());
if (!view) if (!view)
return; return;
std::vector<gfx::Rect> constrained_windows; std::vector<gfx::Rect> constrained_windows;
const aura::Window::Windows& children = parent_->children(); const aura::Window::Windows& children = view_->window_->children();
aura::Window* content = view_->GetContentNativeView();
for (size_t i = 0; i < children.size(); ++i) { for (size_t i = 0; i < children.size(); ++i) {
if (children[i] != view_->window_ && if (children[i] != content && children[i] != exclude)
children[i] != exclude &&
children[i]->IsVisible()) {
constrained_windows.push_back(children[i]->GetBoundsInRootWindow()); constrained_windows.push_back(children[i]->GetBoundsInRootWindow());
}
} }
view->UpdateConstrainedWindowRects(constrained_windows); view->UpdateConstrainedWindowRects(constrained_windows);
} }
#endif
WebContentsViewAura* view_; WebContentsViewAura* view_;
bool web_contents_destroyed_;
// We cache the old parent so that we can unregister when it's not the parent DISALLOW_COPY_AND_ASSIGN(ChildWindowObserver);
// anymore.
aura::Window* parent_;
DISALLOW_COPY_AND_ASSIGN(WindowObserver);
}; };
#endif
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// WebContentsViewAura, public: // WebContentsViewAura, public:
...@@ -824,7 +836,9 @@ WebContentsViewAura::~WebContentsViewAura() { ...@@ -824,7 +836,9 @@ WebContentsViewAura::~WebContentsViewAura() {
return; return;
window_observer_.reset(); window_observer_.reset();
#if defined(OS_WIN)
child_window_observer_.reset();
#endif
// Window needs a valid delegate during its destructor, so we explicitly // Window needs a valid delegate during its destructor, so we explicitly
// delete it here. // delete it here.
window_.reset(); window_.reset();
...@@ -1155,6 +1169,9 @@ void WebContentsViewAura::CreateView( ...@@ -1155,6 +1169,9 @@ void WebContentsViewAura::CreateView(
window_->SetName("WebContentsViewAura"); window_->SetName("WebContentsViewAura");
window_observer_.reset(new WindowObserver(this)); window_observer_.reset(new WindowObserver(this));
#if defined(OS_WIN)
child_window_observer_.reset(new ChildWindowObserver(this));
#endif
// delegate_->GetDragDestDelegate() creates a new delegate on every call. // delegate_->GetDragDestDelegate() creates a new delegate on every call.
// Hence, we save a reference to it locally. Similar model is used on other // Hence, we save a reference to it locally. Similar model is used on other
......
...@@ -50,6 +50,9 @@ class CONTENT_EXPORT WebContentsViewAura ...@@ -50,6 +50,9 @@ class CONTENT_EXPORT WebContentsViewAura
private: private:
class WindowObserver; class WindowObserver;
#if defined(OS_WIN)
class ChildWindowObserver;
#endif
virtual ~WebContentsViewAura(); virtual ~WebContentsViewAura();
...@@ -190,6 +193,9 @@ class CONTENT_EXPORT WebContentsViewAura ...@@ -190,6 +193,9 @@ class CONTENT_EXPORT WebContentsViewAura
scoped_ptr<aura::Window> overscroll_window_; scoped_ptr<aura::Window> overscroll_window_;
scoped_ptr<WindowObserver> window_observer_; scoped_ptr<WindowObserver> window_observer_;
#if defined(OS_WIN)
scoped_ptr<ChildWindowObserver> child_window_observer_;
#endif
// The WebContentsImpl whose contents we display. // The WebContentsImpl whose contents we display.
WebContentsImpl* web_contents_; WebContentsImpl* web_contents_;
......
...@@ -97,8 +97,7 @@ PluginTest* CreatePluginTest(const std::string& test_name, ...@@ -97,8 +97,7 @@ PluginTest* CreatePluginTest(const std::string& test_name,
} else if (test_name == "hidden_plugin" || } else if (test_name == "hidden_plugin" ||
test_name == "create_instance_in_paint" || test_name == "create_instance_in_paint" ||
test_name == "alert_in_window_message" || test_name == "alert_in_window_message" ||
test_name == "ensure_scripting_works_in_destroy" || test_name == "ensure_scripting_works_in_destroy") {
test_name == "set_title_in_paint") {
new_test = new WindowedPluginTest(instance, host_functions); new_test = new WindowedPluginTest(instance, host_functions);
#endif #endif
} else if (test_name == "setup") { } else if (test_name == "setup") {
......
...@@ -38,8 +38,7 @@ NPError WindowedPluginTest::SetWindow(NPWindow* pNPWindow) { ...@@ -38,8 +38,7 @@ NPError WindowedPluginTest::SetWindow(NPWindow* pNPWindow) {
} }
if ((test_name() == "create_instance_in_paint" && test_id() == "1") || if ((test_name() == "create_instance_in_paint" && test_id() == "1") ||
test_name() == "alert_in_window_message" || test_name() == "alert_in_window_message") {
test_name() == "set_title_in_paint") {
static ATOM window_class = 0; static ATOM window_class = 0;
if (!window_class) { if (!window_class) {
WNDCLASSEX wcex; WNDCLASSEX wcex;
...@@ -134,10 +133,6 @@ LRESULT CALLBACK WindowedPluginTest::WindowProc( ...@@ -134,10 +133,6 @@ LRESULT CALLBACK WindowedPluginTest::WindowProc(
// and verify that we don't hang the browser. // and verify that we don't hang the browser.
CallJSFunction(this_ptr, "CallAlert"); CallJSFunction(this_ptr, "CallAlert");
CallJSFunction(this_ptr, "CallAlert"); CallJSFunction(this_ptr, "CallAlert");
} else if (this_ptr->test_name() == "set_title_in_paint" &&
message == WM_PAINT) {
this_ptr->done_ = true;
CallJSFunction(this_ptr, "SetTitle");
} }
if (this_ptr->done_) { if (this_ptr->done_) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment