Index: content/browser/renderer_host/render_widget_host_view_aura.cc |
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 bad6fbc9ba255eb49a636f19e829412978381da8..6a9a42080067950e1e3922c3ca1b6b2b9ae9ef28 100644 |
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc |
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc |
@@ -448,6 +448,7 @@ RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost* host, |
cursor_visibility_state_in_renderer_(UNKNOWN), |
#if defined(OS_WIN) |
legacy_render_widget_host_HWND_(NULL), |
+ legacy_window_destroyed_(false), |
#endif |
has_snapped_to_boundary_(false), |
touch_editing_client_(NULL), |
@@ -601,6 +602,16 @@ void RenderWidgetHostViewAura::WasShown() { |
delegated_frame_host_->WasShown(browser_latency_info); |
#if defined(OS_WIN) |
+ if (legacy_render_widget_host_HWND_) { |
+ // Reparent the legacy Chrome_RenderWidgetHostHWND window to the parent |
+ // window before reparenting any plugins. This ensures that the plugin |
+ // windows stay on top of the child Zorder in the parent and receive |
+ // mouse events, etc. |
+ legacy_render_widget_host_HWND_->UpdateParent( |
+ GetNativeView()->GetHost()->GetAcceleratedWidget()); |
+ legacy_render_widget_host_HWND_->SetBounds( |
+ window_->GetBoundsInRootWindow()); |
+ } |
LPARAM lparam = reinterpret_cast<LPARAM>(this); |
EnumChildWindows(ui::GetHiddenWindow(), ShowWindowsCallback, lparam); |
#endif |
@@ -619,6 +630,10 @@ void RenderWidgetHostViewAura::WasHidden() { |
HWND parent = host->GetAcceleratedWidget(); |
LPARAM lparam = reinterpret_cast<LPARAM>(this); |
EnumChildWindows(parent, HideWindowsCallback, lparam); |
+ // We reparent the legacy Chrome_RenderWidgetHostHWND window to the global |
+ // hidden window on the same lines as Windowed plugin windows. |
+ if (legacy_render_widget_host_HWND_) |
+ legacy_render_widget_host_HWND_->UpdateParent(ui::GetHiddenWindow()); |
} |
#endif |
} |
@@ -782,11 +797,19 @@ bool RenderWidgetHostViewAura::IsSurfaceAvailableForCopy() const { |
void RenderWidgetHostViewAura::Show() { |
window_->Show(); |
WasShown(); |
+#if defined(OS_WIN) |
+ if (legacy_render_widget_host_HWND_) |
+ legacy_render_widget_host_HWND_->Show(); |
+#endif |
} |
void RenderWidgetHostViewAura::Hide() { |
window_->Hide(); |
WasHidden(); |
+#if defined(OS_WIN) |
+ if (legacy_render_widget_host_HWND_) |
+ legacy_render_widget_host_HWND_->Hide(); |
+#endif |
} |
bool RenderWidgetHostViewAura::IsShowing() { |
@@ -1038,7 +1061,12 @@ void RenderWidgetHostViewAura::UpdateMouseLockRegion() { |
::ClipCursor(&window_rect); |
} |
} |
-#endif // defined(OS_WIN) |
+ |
+void RenderWidgetHostViewAura::OnLegacyWindowDestroyed() { |
+ legacy_render_widget_host_HWND_ = NULL; |
+ legacy_window_destroyed_ = true; |
+} |
+#endif |
void RenderWidgetHostViewAura::OnSwapCompositorFrame( |
uint32 output_surface_id, |
@@ -1070,11 +1098,6 @@ void RenderWidgetHostViewAura::DidStopFlinging() { |
} |
#if defined(OS_WIN) |
-void RenderWidgetHostViewAura::SetLegacyRenderWidgetHostHWND( |
- LegacyRenderWidgetHostHWND* legacy_hwnd) { |
- legacy_render_widget_host_HWND_ = legacy_hwnd; |
-} |
- |
void RenderWidgetHostViewAura::SetParentNativeViewAccessible( |
gfx::NativeViewAccessible accessible_parent) { |
} |
@@ -1082,9 +1105,8 @@ void RenderWidgetHostViewAura::SetParentNativeViewAccessible( |
gfx::NativeViewId RenderWidgetHostViewAura::GetParentForWindowlessPlugin() |
const { |
if (legacy_render_widget_host_HWND_) { |
- HWND hwnd = legacy_render_widget_host_HWND_->hwnd(); |
- if (::IsWindow(hwnd)) |
- return reinterpret_cast<gfx::NativeViewId>(hwnd); |
+ return reinterpret_cast<gfx::NativeViewId>( |
+ legacy_render_widget_host_HWND_->hwnd()); |
} |
return NULL; |
} |
@@ -1227,11 +1249,8 @@ RenderWidgetHostViewAura::CreateBrowserAccessibilityManager( |
gfx::AcceleratedWidget |
RenderWidgetHostViewAura::AccessibilityGetAcceleratedWidget() { |
#if defined(OS_WIN) |
- if (legacy_render_widget_host_HWND_) { |
- HWND hwnd = legacy_render_widget_host_HWND_->hwnd(); |
- if (::IsWindow(hwnd)) |
- return hwnd; |
- } |
+ if (legacy_render_widget_host_HWND_) |
+ return legacy_render_widget_host_HWND_->hwnd(); |
#endif |
return gfx::kNullAcceleratedWidget; |
} |
@@ -1763,7 +1782,20 @@ void RenderWidgetHostViewAura::OnWindowDestroying(aura::Window* window) { |
} |
LPARAM lparam = reinterpret_cast<LPARAM>(this); |
EnumChildWindows(parent, WindowDestroyingCallback, lparam); |
- legacy_render_widget_host_HWND_ = NULL; |
+ |
+ // The LegacyRenderWidgetHostHWND instance is destroyed when its window is |
+ // destroyed. Normally we control when that happens via the Destroy call |
+ // in the dtor. However there may be cases where the window is destroyed |
+ // by Windows, i.e. the parent window is destroyed before the |
+ // RenderWidgetHostViewAura instance goes away etc. To avoid that we |
+ // destroy the LegacyRenderWidgetHostHWND instance here. |
+ if (legacy_render_widget_host_HWND_) { |
+ legacy_render_widget_host_HWND_->set_host(NULL); |
+ legacy_render_widget_host_HWND_->Destroy(); |
+ // The Destroy call above will delete the LegacyRenderWidgetHostHWND |
+ // instance. |
+ legacy_render_widget_host_HWND_ = NULL; |
+ } |
#endif |
// Make sure that the input method no longer references to this object before |
@@ -2264,6 +2296,13 @@ RenderWidgetHostViewAura::~RenderWidgetHostViewAura() { |
// Aura root window and we don't have a way to get an input method object |
// associated with the window, but just in case. |
DetachFromInputMethod(); |
+ |
+#if defined(OS_WIN) |
+ // The LegacyRenderWidgetHostHWND window should have been destroyed in |
+ // RenderWidgetHostViewAura::OnWindowDestroying and the pointer should |
+ // be set to NULL. |
+ DCHECK(!legacy_render_widget_host_HWND_); |
+#endif |
} |
void RenderWidgetHostViewAura::UpdateCursorIfOverSelf() { |
@@ -2420,6 +2459,34 @@ void RenderWidgetHostViewAura::InternalSetBounds(const gfx::Rect& rect) { |
selection_focus_); |
} |
#if defined(OS_WIN) |
+ // Create the legacy dummy window which corresponds to the bounds of the |
+ // webcontents. This will be passed as the container window for windowless |
+ // plugins. |
+ // Plugins like Flash assume the container window which is returned via the |
+ // NPNVnetscapeWindow property corresponds to the bounds of the webpage. |
+ // This is not true in Aura where we have only HWND which is the main Aura |
+ // window. If we return this window to plugins like Flash then it causes the |
+ // coordinate translations done by these plugins to break. |
+ // Additonally the legacy dummy window is needed for accessibility and for |
+ // scrolling to work in legacy drivers for trackpoints/trackpads, etc. |
+ if (!legacy_window_destroyed_ && GetNativeViewId()) { |
+ if (!legacy_render_widget_host_HWND_) { |
+ legacy_render_widget_host_HWND_ = LegacyRenderWidgetHostHWND::Create( |
+ reinterpret_cast<HWND>(GetNativeViewId())); |
+ } |
+ if (legacy_render_widget_host_HWND_) { |
+ legacy_render_widget_host_HWND_->set_host(this); |
+ legacy_render_widget_host_HWND_->SetBounds( |
+ window_->GetBoundsInRootWindow()); |
+ // There are cases where the parent window is created, made visible and |
+ // the associated RenderWidget is also visible before the |
+ // LegacyRenderWidgetHostHWND instace is created. Ensure that it is shown |
+ // here. |
+ if (!host_->is_hidden()) |
+ legacy_render_widget_host_HWND_->Show(); |
+ } |
+ } |
+ |
if (mouse_locked_) |
UpdateMouseLockRegion(); |
#endif |
@@ -2465,6 +2532,14 @@ void RenderWidgetHostViewAura::AddedToRootWindow() { |
input_method->SetFocusedTextInputClient(this); |
} |
+#if defined(OS_WIN) |
+ // The parent may have changed here. Ensure that the legacy window is |
+ // reparented accordingly. |
+ if (legacy_render_widget_host_HWND_) |
+ legacy_render_widget_host_HWND_->UpdateParent( |
+ reinterpret_cast<HWND>(GetNativeViewId())); |
+#endif |
+ |
delegated_frame_host_->AddedToWindow(); |
} |
@@ -2478,6 +2553,13 @@ void RenderWidgetHostViewAura::RemovingFromRootWindow() { |
window_->GetHost()->RemoveObserver(this); |
delegated_frame_host_->RemovingFromWindow(); |
+ |
+#if defined(OS_WIN) |
+ // Update the legacy window's parent temporarily to the desktop window. It |
+ // will eventually get reparented to the right root. |
+ if (legacy_render_widget_host_HWND_) |
+ legacy_render_widget_host_HWND_->UpdateParent(::GetDesktopWindow()); |
+#endif |
} |
void RenderWidgetHostViewAura::DetachFromInputMethod() { |