diff options
author | asanka@chromium.org <asanka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-08 18:22:48 +0000 |
---|---|---|
committer | asanka@chromium.org <asanka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-08 18:22:48 +0000 |
commit | dea021504bc43df9ec7c3e3dcca7fdbe255dc5f9 (patch) | |
tree | 78f9b939e4492f7fadafe18ee1a630e2ff73e265 | |
parent | e77473e905d9a4daf4b58d62b516b38e4decac01 (diff) | |
download | chromium_src-dea021504bc43df9ec7c3e3dcca7fdbe255dc5f9.zip chromium_src-dea021504bc43df9ec7c3e3dcca7fdbe255dc5f9.tar.gz chromium_src-dea021504bc43df9ec7c3e3dcca7fdbe255dc5f9.tar.bz2 |
Merge 80096 - Notify child widgets before and after a reparenting.Attaching a native view to a NativeViewHostWin may cause thatview to be disassociated from a view hierarchy with a differentFocusManager. Notifying the widgets that they are about to beremoved from their current parent gives them the opportunity todisassociate themselves from their current FocusManager.BUG=77447TEST=noneReview URL: http://codereview.chromium.org/6776025
TBR=asanka@chromium.org
Review URL: http://codereview.chromium.org/6813049
git-svn-id: svn://svn.chromium.org/chrome/branches/696/src@80960 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/ui/views/tab_contents/tab_contents_view_win.cc | 2 | ||||
-rw-r--r-- | views/controls/native/native_view_host_win.cc | 24 | ||||
-rw-r--r-- | views/widget/native_widget.h | 5 | ||||
-rw-r--r-- | views/widget/widget_win.cc | 32 |
4 files changed, 41 insertions, 22 deletions
diff --git a/chrome/browser/ui/views/tab_contents/tab_contents_view_win.cc b/chrome/browser/ui/views/tab_contents/tab_contents_view_win.cc index 9f4427b..1682223 100644 --- a/chrome/browser/ui/views/tab_contents/tab_contents_view_win.cc +++ b/chrome/browser/ui/views/tab_contents/tab_contents_view_win.cc @@ -89,7 +89,7 @@ void TabContentsViewWin::Unparent() { focus_manager_ = views::WidgetWin::GetFocusManager(); // Note that we do not DCHECK on focus_manager_ as it may be NULL when used // with an external tab container. - ::SetParent(GetNativeView(), GetHiddenTabHostWindow()); + NativeWidget::ReparentNativeView(GetNativeView(), GetHiddenTabHostWindow()); } void TabContentsViewWin::CreateView(const gfx::Size& initial_size) { diff --git a/views/controls/native/native_view_host_win.cc b/views/controls/native/native_view_host_win.cc index f8bda8e..f25e722 100644 --- a/views/controls/native/native_view_host_win.cc +++ b/views/controls/native/native_view_host_win.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -35,33 +35,15 @@ void NativeViewHostWin::NativeViewAttached() { // borders), when we change the parent below. ShowWindow(host_->native_view(), SW_HIDE); - // Need to set the HWND's parent before changing its size to avoid flashing. - SetParent(host_->native_view(), host_->GetWidget()->GetNativeView()); + NativeWidget::ReparentNativeView(host_->native_view(), + host_->GetWidget()->GetNativeView()); host_->Layout(); - // Notify children that parent changed, so they can adjust focus. - NativeWidget::NativeWidgets widgets; - NativeWidget::GetAllNativeWidgets(host_->native_view(), &widgets); - for (NativeWidget::NativeWidgets::iterator it = widgets.begin(); - it != widgets.end(); ++it) { - (*it)->GetWidget()->NotifyNativeViewHierarchyChanged( - true, - host_->GetWidget()->GetNativeView()); - } } void NativeViewHostWin::NativeViewDetaching(bool destroyed) { if (!destroyed && installed_clip_) UninstallClip(); installed_clip_ = false; - // Notify children that parent is removed. - NativeWidget::NativeWidgets widgets; - NativeWidget::GetAllNativeWidgets(host_->native_view(), &widgets); - for (NativeWidget::NativeWidgets::iterator it = widgets.begin(); - it != widgets.end(); ++it) { - (*it)->GetWidget()->NotifyNativeViewHierarchyChanged( - false, - host_->GetWidget()->GetNativeView()); - } } void NativeViewHostWin::AddedToWidget() { diff --git a/views/widget/native_widget.h b/views/widget/native_widget.h index fadad34..ad203ea 100644 --- a/views/widget/native_widget.h +++ b/views/widget/native_widget.h @@ -46,6 +46,11 @@ class NativeWidget { static void GetAllNativeWidgets(gfx::NativeView native_view, NativeWidgets* children); + // Reparent a NativeView and notify all NativeWidgets in + // |native_view|'s hierarchy of the change. + static void ReparentNativeView(gfx::NativeView native_view, + gfx::NativeView new_parent); + // Returns the Widget associated with this NativeWidget. This function is // guaranteed to return non-NULL for the lifetime of the NativeWidget. virtual Widget* GetWidget() = 0; diff --git a/views/widget/widget_win.cc b/views/widget/widget_win.cc index baf5627..99077b5 100644 --- a/views/widget/widget_win.cc +++ b/views/widget/widget_win.cc @@ -1196,4 +1196,36 @@ void NativeWidget::GetAllNativeWidgets(gfx::NativeView native_view, reinterpret_cast<LPARAM>(children)); } +void NativeWidget::ReparentNativeView(gfx::NativeView native_view, + gfx::NativeView new_parent) { + if (!native_view) + return; + + HWND previous_parent = ::GetParent(native_view); + if (previous_parent == new_parent) + return; + + NativeWidgets widgets; + GetAllNativeWidgets(native_view, &widgets); + + // First notify all the widgets that they are being disassociated + // from their previous parent. + for (NativeWidgets::iterator it = widgets.begin(); + it != widgets.end(); ++it) { + // TODO(beng): Rename this notification to NotifyNativeViewChanging() + // and eliminate the bool parameter. + (*it)->GetWidget()->NotifyNativeViewHierarchyChanged(false, + previous_parent); + } + + ::SetParent(native_view, new_parent); + + // And now, notify them that they have a brand new parent. + for (NativeWidgets::iterator it = widgets.begin(); + it != widgets.end(); ++it) { + (*it)->GetWidget()->NotifyNativeViewHierarchyChanged(true, + new_parent); + } +} + } // namespace views |