diff options
author | flackr@chromium.org <flackr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-30 16:30:52 +0000 |
---|---|---|
committer | flackr@chromium.org <flackr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-30 16:30:52 +0000 |
commit | d97d38b20772b07e97facc02a700b360dff8d5ab (patch) | |
tree | 9f1951bc3459ac431c8116d0774ffd9f4dc83918 /ui/aura | |
parent | 751459731324e2db0b5a04f205c2407ee1fb687d (diff) | |
download | chromium_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.cc | 21 | ||||
-rw-r--r-- | ui/aura/window.cc | 8 | ||||
-rw-r--r-- | ui/aura/window.h | 3 | ||||
-rw-r--r-- | ui/aura/window_unittest.cc | 22 |
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, |