summaryrefslogtreecommitdiffstats
path: root/ui/aura
diff options
context:
space:
mode:
authortdresser@chromium.org <tdresser@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-03 21:35:06 +0000
committertdresser@chromium.org <tdresser@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-03 21:35:06 +0000
commitd1d067abf68561a23f8bdff954d90fbab73b420a (patch)
treee6bfec8daf95b7dc097cb68a5be1ab32ed530ea6 /ui/aura
parent5b597e18292ed8551ad694258cbd3542bdb134cd (diff)
downloadchromium_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.cc22
-rw-r--r--ui/aura/window.h3
-rw-r--r--ui/aura/window_event_dispatcher.cc13
-rw-r--r--ui/aura/window_event_dispatcher.h4
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);