diff options
author | tdresser@chromium.org <tdresser@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-03 21:35:06 +0000 |
---|---|---|
committer | tdresser@chromium.org <tdresser@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-03 21:35:06 +0000 |
commit | d1d067abf68561a23f8bdff954d90fbab73b420a (patch) | |
tree | e6bfec8daf95b7dc097cb68a5be1ab32ed530ea6 /ui/aura | |
parent | 5b597e18292ed8551ad694258cbd3542bdb134cd (diff) | |
download | chromium_src-d1d067abf68561a23f8bdff954d90fbab73b420a.zip chromium_src-d1d067abf68561a23f8bdff954d90fbab73b420a.tar.gz chromium_src-d1d067abf68561a23f8bdff954d90fbab73b420a.tar.bz2 |
CHECK that ui::Windows being destroyed have been hidden if necessary
There have been a bunch of crashes due to the GestureRecognizer targeting
touches to windows that have been destroyed. When a window is hidden
(in WindowEventDispatcher::OnWindowHidden), all references to that window
are removed from the GestureRecognizer.
It looks like some windows with touches targeted to them are being
destroyed without being hidden first. This change CHECKs that this
never occurs.
BUG=342040
Review URL: https://codereview.chromium.org/224063002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@261531 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/aura')
-rw-r--r-- | ui/aura/window.cc | 22 | ||||
-rw-r--r-- | ui/aura/window.h | 3 | ||||
-rw-r--r-- | ui/aura/window_event_dispatcher.cc | 13 | ||||
-rw-r--r-- | ui/aura/window_event_dispatcher.h | 4 |
4 files changed, 26 insertions, 16 deletions
diff --git a/ui/aura/window.cc b/ui/aura/window.cc index 86c9046..2c9aab8 100644 --- a/ui/aura/window.cc +++ b/ui/aura/window.cc @@ -235,6 +235,15 @@ Window::~Window() { if (host) host->dispatcher()->OnPostNotifiedWindowDestroying(this); + // The window should have already had its state cleaned up in + // WindowEventDispatcher::OnWindowHidden(), but there have been some crashes + // involving windows being destroyed without being hidden first. See + // crbug.com/342040. This should help us debug the issue. TODO(tdresser): + // remove this once we determine why we have windows that are destroyed + // without being hidden. + bool window_incorrectly_cleaned_up = CleanupGestureState(); + CHECK(!window_incorrectly_cleaned_up); + // Then destroy the children. RemoveOrDestroyChildren(); @@ -1324,6 +1333,19 @@ void Window::OnWindowBoundsChanged(const gfx::Rect& old_bounds) { OnWindowBoundsChanged(this, old_bounds, bounds())); } +bool Window::CleanupGestureState() { + bool state_modified = false; + state_modified |= ui::GestureRecognizer::Get()->CancelActiveTouches(this); + state_modified |= + ui::GestureRecognizer::Get()->CleanupStateForConsumer(this); + for (Window::Windows::iterator iter = children_.begin(); + iter != children_.end(); + ++iter) { + state_modified |= (*iter)->CleanupGestureState(); + } + return state_modified; +} + void Window::OnPaintLayer(gfx::Canvas* canvas) { Paint(canvas); } diff --git a/ui/aura/window.h b/ui/aura/window.h index 2324533..6fbea36 100644 --- a/ui/aura/window.h +++ b/ui/aura/window.h @@ -326,6 +326,9 @@ class AURA_EXPORT Window : public ui::LayerDelegate, void PrintWindowHierarchy(int depth) const; #endif + // Returns true if there was state needing to be cleaned up. + bool CleanupGestureState(); + protected: // Deletes (or removes if not owned by parent) all child windows. Intended for // use from the destructor. diff --git a/ui/aura/window_event_dispatcher.cc b/ui/aura/window_event_dispatcher.cc index 5489596..36d8e6c 100644 --- a/ui/aura/window_event_dispatcher.cc +++ b/ui/aura/window_event_dispatcher.cc @@ -307,7 +307,7 @@ void WindowEventDispatcher::OnWindowHidden(Window* invisible, if (invisible->Contains(old_dispatch_target_)) old_dispatch_target_ = NULL; - CleanupGestureState(invisible); + invisible->CleanupGestureState(); // Do not clear the capture, and the |event_dispatch_target_| if the // window is moving across hosts, because the target itself is actually still @@ -333,17 +333,6 @@ void WindowEventDispatcher::OnWindowHidden(Window* invisible, } } -void WindowEventDispatcher::CleanupGestureState(Window* window) { - ui::GestureRecognizer::Get()->CancelActiveTouches(window); - ui::GestureRecognizer::Get()->CleanupStateForConsumer(window); - const Window::Windows& windows = window->children(); - for (Window::Windows::const_iterator iter = windows.begin(); - iter != windows.end(); - ++iter) { - CleanupGestureState(*iter); - } -} - Window* WindowEventDispatcher::GetGestureTarget(ui::GestureEvent* event) { Window* target = NULL; if (!event->IsEndingEvent()) { diff --git a/ui/aura/window_event_dispatcher.h b/ui/aura/window_event_dispatcher.h index f0cb67f..6b476b7 100644 --- a/ui/aura/window_event_dispatcher.h +++ b/ui/aura/window_event_dispatcher.h @@ -162,10 +162,6 @@ class AURA_EXPORT WindowEventDispatcher : public ui::EventProcessor, // on capture (like DragDropTracker). void OnWindowHidden(Window* invisible, WindowHiddenReason reason); - // Cleans up the state of gestures for all windows in |window| (including - // |window| itself). This includes cancelling active touch points. - void CleanupGestureState(Window* window); - // Returns a target window for the given gesture event. Window* GetGestureTarget(ui::GestureEvent* event); |