summaryrefslogtreecommitdiffstats
path: root/ui/aura
diff options
context:
space:
mode:
authorflackr@chromium.org <flackr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-30 16:30:52 +0000
committerflackr@chromium.org <flackr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-30 16:30:52 +0000
commitd97d38b20772b07e97facc02a700b360dff8d5ab (patch)
tree9f1951bc3459ac431c8116d0774ffd9f4dc83918 /ui/aura
parent751459731324e2db0b5a04f205c2407ee1fb687d (diff)
downloadchromium_src-d97d38b20772b07e97facc02a700b360dff8d5ab.zip
chromium_src-d97d38b20772b07e97facc02a700b360dff8d5ab.tar.gz
chromium_src-d97d38b20772b07e97facc02a700b360dff8d5ab.tar.bz2
Release aura::Desktop event handler windows on detaching an ancestor window.
BUG=105443 TEST=None Review URL: http://codereview.chromium.org/8700013 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@112236 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/aura')
-rw-r--r--ui/aura/desktop.cc21
-rw-r--r--ui/aura/window.cc8
-rw-r--r--ui/aura/window.h3
-rw-r--r--ui/aura/window_unittest.cc22
4 files changed, 45 insertions, 9 deletions
diff --git a/ui/aura/desktop.cc b/ui/aura/desktop.cc
index 59cd962..f5bd54d 100644
--- a/ui/aura/desktop.cc
+++ b/ui/aura/desktop.cc
@@ -538,19 +538,22 @@ void Desktop::WindowDetachedFromDesktop(Window* detached) {
// If the ancestor of the capture window is detached,
// release the capture.
- aura::Window* window = capture_window_;
- while (window && window != detached)
- window = window->parent();
- if (window && window != this)
+ if (detached->Contains(capture_window_) && detached != this)
ReleaseCapture(capture_window_);
- // If the ancestor of the capture window is detached,
+ // If the ancestor of the focused window is detached,
// release the focus.
- window = focused_window_;
- while (window && window != detached)
- window = window->parent();
- if (window)
+ if (detached->Contains(focused_window_))
SetFocusedWindow(NULL);
+
+ // If the ancestor of any event handler windows are detached, release the
+ // pointer to those windows.
+ if (detached->Contains(mouse_pressed_handler_))
+ mouse_pressed_handler_ = NULL;
+ if (detached->Contains(mouse_moved_handler_))
+ mouse_moved_handler_ = NULL;
+ if (detached->Contains(touch_event_handler_))
+ touch_event_handler_ = NULL;
}
void Desktop::OnLayerAnimationEnded(
diff --git a/ui/aura/window.cc b/ui/aura/window.cc
index 6b4c5d2..d394d10 100644
--- a/ui/aura/window.cc
+++ b/ui/aura/window.cc
@@ -277,6 +277,14 @@ void Window::RemoveChild(Window* child) {
child->OnParentChanged();
}
+bool Window::Contains(const Window* other) const {
+ for (const Window* parent = other; parent; parent = parent->parent_) {
+ if (parent == this)
+ return true;
+ }
+ return false;
+}
+
Window* Window::GetChildById(int id) {
return const_cast<Window*>(const_cast<const Window*>(this)->GetChildById(id));
}
diff --git a/ui/aura/window.h b/ui/aura/window.h
index 9e1f05f..8aa38fd 100644
--- a/ui/aura/window.h
+++ b/ui/aura/window.h
@@ -146,6 +146,9 @@ class AURA_EXPORT Window : public ui::LayerDelegate {
const Windows& children() const { return children_; }
+ // Returns true if this Window contains |other| somewhere in its children.
+ bool Contains(const Window* other) const;
+
// Adds or removes |child| as a transient child of this window. Transient
// children get the following behavior:
// . The transient parent destroys any transient children when it is
diff --git a/ui/aura/window_unittest.cc b/ui/aura/window_unittest.cc
index 9d5f368..ea112f05 100644
--- a/ui/aura/window_unittest.cc
+++ b/ui/aura/window_unittest.cc
@@ -137,6 +137,28 @@ TEST_F(WindowTest, GetChildById) {
EXPECT_EQ(w111.get(), w1->GetChildById(111));
}
+// Make sure that Window::Contains correctly handles children, grandchildren,
+// and not containing NULL or parents.
+TEST_F(WindowTest, Contains) {
+ Window parent(NULL);
+ parent.Init(ui::Layer::LAYER_HAS_NO_TEXTURE);
+ Window child1(NULL);
+ child1.Init(ui::Layer::LAYER_HAS_NO_TEXTURE);
+ Window child2(NULL);
+ child2.Init(ui::Layer::LAYER_HAS_NO_TEXTURE);
+
+ child1.SetParent(&parent);
+ child2.SetParent(&child1);
+
+ EXPECT_TRUE(parent.Contains(&parent));
+ EXPECT_TRUE(parent.Contains(&child1));
+ EXPECT_TRUE(parent.Contains(&child2));
+
+ EXPECT_FALSE(parent.Contains(NULL));
+ EXPECT_FALSE(child1.Contains(&parent));
+ EXPECT_FALSE(child2.Contains(&child1));
+}
+
TEST_F(WindowTest, ConvertPointToWindow) {
// Window::ConvertPointToWindow is mostly identical to
// Layer::ConvertPointToLayer, except NULL values for |source| are permitted,