summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorasanka@chromium.org <asanka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-08 18:22:48 +0000
committerasanka@chromium.org <asanka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-08 18:22:48 +0000
commitdea021504bc43df9ec7c3e3dcca7fdbe255dc5f9 (patch)
tree78f9b939e4492f7fadafe18ee1a630e2ff73e265
parente77473e905d9a4daf4b58d62b516b38e4decac01 (diff)
downloadchromium_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.cc2
-rw-r--r--views/controls/native/native_view_host_win.cc24
-rw-r--r--views/widget/native_widget.h5
-rw-r--r--views/widget/widget_win.cc32
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