summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura.cc75
-rw-r--r--content/browser/renderer_host/render_widget_host_view_base.cc15
-rw-r--r--content/browser/renderer_host/render_widget_host_view_base.h6
3 files changed, 88 insertions, 8 deletions
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index a0c54fa..28162bc 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -50,6 +50,10 @@
#include "ui/gfx/screen.h"
#include "ui/gfx/skia_util.h"
+#if defined(OS_WIN)
+#include "ui/base/win/hidden_window.h"
+#endif
+
using WebKit::WebScreenInfo;
using WebKit::WebTouchEvent;
@@ -71,6 +75,41 @@ const int kMouseLockBorderPercentage = 15;
// resized frame from a renderer.
const int kResizeLockTimeoutMs = 67;
+#if defined(OS_WIN)
+// Used to associate a plugin HWND with its RenderWidgetHostViewAura instance.
+const wchar_t kWidgetOwnerProperty[] = L"RenderWidgetHostViewAuraOwner";
+
+BOOL CALLBACK WindowDestroyingCallback(HWND window, LPARAM param) {
+ RenderWidgetHostViewAura* widget =
+ reinterpret_cast<RenderWidgetHostViewAura*>(param);
+ if (GetProp(window, kWidgetOwnerProperty) == widget) {
+ // Properties set on HWNDs must be removed to avoid leaks.
+ RemoveProp(window, kWidgetOwnerProperty);
+ RenderWidgetHostViewBase::DetachPluginWindowsCallback(window);
+ }
+ return TRUE;
+}
+
+BOOL CALLBACK HideWindowsCallback(HWND window, LPARAM param) {
+ RenderWidgetHostViewAura* widget =
+ reinterpret_cast<RenderWidgetHostViewAura*>(param);
+ if (GetProp(window, kWidgetOwnerProperty) == widget)
+ SetParent(window, ui::GetHiddenWindow());
+ return TRUE;
+}
+
+BOOL CALLBACK ShowWindowsCallback(HWND window, LPARAM param) {
+ RenderWidgetHostViewAura* widget =
+ reinterpret_cast<RenderWidgetHostViewAura*>(param);
+
+ HWND parent =
+ widget->GetNativeView()->GetRootWindow()->GetAcceleratedWidget();
+ if (GetProp(window, kWidgetOwnerProperty) == widget)
+ SetParent(window, parent);
+ return TRUE;
+}
+#endif
+
ui::TouchStatus DecideTouchStatus(const WebKit::WebTouchEvent& event,
WebKit::WebTouchPoint* point) {
if (event.type == WebKit::WebInputEvent::TouchEnd &&
@@ -310,6 +349,11 @@ void RenderWidgetHostViewAura::WasShown() {
}
AdjustSurfaceProtection();
+
+#if defined(OS_WIN)
+ LPARAM lparam = reinterpret_cast<LPARAM>(this);
+ EnumChildWindows(ui::GetHiddenWindow(), ShowWindowsCallback, lparam);
+#endif
}
void RenderWidgetHostViewAura::WasHidden() {
@@ -326,6 +370,13 @@ void RenderWidgetHostViewAura::WasHidden() {
}
AdjustSurfaceProtection();
+
+#if defined(OS_WIN)
+ HWND parent = window_->GetRootWindow()->GetAcceleratedWidget();
+ LPARAM lparam = reinterpret_cast<LPARAM>(this);
+
+ EnumChildWindows(parent, HideWindowsCallback, lparam);
+#endif
}
void RenderWidgetHostViewAura::SetSize(const gfx::Size& size) {
@@ -392,6 +443,18 @@ void RenderWidgetHostViewAura::MovePluginWindows(
moves[i].window_rect.Offset(view_bounds.origin());
}
MovePluginWindowsHelper(parent, moves);
+
+ // Make sure each plugin window (or its wrapper if it exists) has a pointer to
+ // |this|.
+ for (size_t i = 0; i < moves.size(); ++i) {
+ HWND window = moves[i].window;
+ if (GetParent(window) != parent) {
+ window = GetParent(window);
+ DCHECK(GetParent(window) == parent);
+ }
+ if (!GetProp(window, kWidgetOwnerProperty))
+ CHECK(SetProp(window, kWidgetOwnerProperty, this));
+ }
#endif // defined(OS_WIN)
}
@@ -1297,10 +1360,16 @@ void RenderWidgetHostViewAura::OnDeviceScaleFactorChanged(
void RenderWidgetHostViewAura::OnWindowDestroying() {
#if defined(OS_WIN)
- if (window_->GetRootWindow()) {
- HWND parent = window_->GetRootWindow()->GetAcceleratedWidget();
- DetachPluginsHelper(parent);
+ HWND parent = NULL;
+ // If the tab was hidden and it's closed, host_->is_hidden would have been
+ // reset to false in RenderWidgetHostImpl::RendererExited.
+ if (!window_->GetRootWindow() || host_->is_hidden()) {
+ parent = ui::GetHiddenWindow();
+ } else {
+ parent = window_->GetRootWindow()->GetAcceleratedWidget();
}
+ LPARAM lparam = reinterpret_cast<LPARAM>(this);
+ EnumChildWindows(parent, WindowDestroyingCallback, lparam);
#endif
}
diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc
index 935fc11..4053413 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.cc
+++ b/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -186,17 +186,22 @@ BOOL CALLBACK PainEnumChildProc(HWND hwnd, LPARAM lparam) {
}
// Windows callback for OnDestroy to detach the plugin windows.
-BOOL CALLBACK DetachPluginWindowsCallback(HWND window, LPARAM param) {
+BOOL CALLBACK DetachPluginWindowsCallbackInternal(HWND window, LPARAM param) {
+ RenderWidgetHostViewBase::DetachPluginWindowsCallback(window);
+ return TRUE;
+}
+
+} // namespace
+
+// static
+void RenderWidgetHostViewBase::DetachPluginWindowsCallback(HWND window) {
if (webkit::npapi::WebPluginDelegateImpl::IsPluginDelegateWindow(window) &&
!IsHungAppWindow(window)) {
::ShowWindow(window, SW_HIDE);
SetParent(window, NULL);
}
- return TRUE;
}
-} // namespace
-
// static
void RenderWidgetHostViewBase::MovePluginWindowsHelper(
HWND parent,
@@ -331,7 +336,7 @@ void RenderWidgetHostViewBase::DetachPluginsHelper(HWND parent) {
// away. This will prevent the plugin windows from getting destroyed
// automatically. The detached plugin windows will get cleaned up in proper
// sequence as part of the usual cleanup when the plugin instance goes away.
- EnumChildWindows(parent, DetachPluginWindowsCallback, NULL);
+ EnumChildWindows(parent, DetachPluginWindowsCallbackInternal, NULL);
}
#endif // OS_WIN
diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h
index 2c9c828..c1eb02d 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.h
+++ b/content/browser/renderer_host/render_widget_host_view_base.h
@@ -66,6 +66,12 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
// Notification that a resize or move session ended on the native widget.
void UpdateScreenInfo();
+#if defined(OS_WIN)
+ // The callback that DetachPluginsHelper calls for each child window. Call
+ // this directly if you want to do custom filtering on plugin windows first.
+ static void DetachPluginWindowsCallback(HWND window);
+#endif
+
protected:
// Interface class only, do not construct.
RenderWidgetHostViewBase();