summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSadrul Habib Chowdhury <sadrul@chromium.org>2015-07-13 16:08:10 -0400
committerSadrul Habib Chowdhury <sadrul@chromium.org>2015-07-13 20:09:31 +0000
commit6ffa49b37d0af3eeb442349777e12f9eca8d0e89 (patch)
treefc4b59751b375f180c8edc16557a36c7ea78ecd2
parent407d3a40db600b17aaec9e10f49b016a42afe438 (diff)
downloadchromium_src-6ffa49b37d0af3eeb442349777e12f9eca8d0e89.zip
chromium_src-6ffa49b37d0af3eeb442349777e12f9eca8d0e89.tar.gz
chromium_src-6ffa49b37d0af3eeb442349777e12f9eca8d0e89.tar.bz2
x11: Make sure a Widget is not attempted to be destroyed more than once.
A DesktopWindowTreeHostX11 destroys its children on destruction. So it is necessary to make sure the Window hasn't already been destroyed with its parent before attempting to destroy it during app tear-down. BUG=504692 Review URL: https://codereview.chromium.org/1213103003 TBR=sadrul@ (myself) Cr-Commit-Position: refs/heads/master@{#336567} (cherry picked from commit 2a2cfc8f230219e533323b688678187edef7b2ab) Review URL: https://codereview.chromium.org/1235773007 . Cr-Commit-Position: refs/branch-heads/2403@{#502} Cr-Branched-From: f54b8097a9c45ed4ad308133d49f05325d6c5070-refs/heads/master@{#330231}
-rw-r--r--ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc12
-rw-r--r--ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h5
-rw-r--r--ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc27
-rw-r--r--ui/views/widget/native_widget_aura.cc5
4 files changed, 42 insertions, 7 deletions
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
index 69c5b2f..ceffac0 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
@@ -237,7 +237,17 @@ void DesktopWindowTreeHostX11::SwapNonClientEventHandler(
x11_non_client_event_filter_ = handler.Pass();
}
-void DesktopWindowTreeHostX11::CleanUpWindowList() {
+void DesktopWindowTreeHostX11::CleanUpWindowList(
+ void (*func)(aura::Window* window)) {
+ if (!open_windows_)
+ return;
+ while (!open_windows_->empty()) {
+ XID xid = open_windows_->front();
+ func(GetContentWindowForXID(xid));
+ if (!open_windows_->empty() && open_windows_->front() == xid)
+ open_windows_->erase(open_windows_->begin());
+ }
+
delete open_windows_;
open_windows_ = NULL;
}
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
index 94d4b1b..59591bd 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
@@ -83,8 +83,9 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11
// Swaps the current handler for events in the non client view with |handler|.
void SwapNonClientEventHandler(scoped_ptr<ui::EventHandler> handler);
- // Deallocates the internal list of open windows.
- static void CleanUpWindowList();
+ // Runs the |func| callback for each content-window, and deallocates the
+ // internal list of open windows.
+ static void CleanUpWindowList(void (*func)(aura::Window* window));
protected:
// Overridden from DesktopWindowTreeHost:
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc
index 17eb63a8..64cb2b7 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc
@@ -456,6 +456,33 @@ TEST_F(DesktopWindowTreeHostX11Test, ToggleMinimizePropogateToContentWindow) {
EXPECT_TRUE(widget.GetNativeWindow()->IsVisible());
}
+TEST_F(DesktopWindowTreeHostX11Test, ChildWindowDestructionDuringTearDown) {
+ Widget parent_widget;
+ Widget::InitParams parent_params =
+ CreateParams(Widget::InitParams::TYPE_WINDOW);
+ parent_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ parent_params.native_widget = new DesktopNativeWidgetAura(&parent_widget);
+ parent_widget.Init(parent_params);
+ parent_widget.Show();
+ ui::X11EventSource::GetInstance()->DispatchXEvents();
+
+ Widget child_widget;
+ Widget::InitParams child_params =
+ CreateParams(Widget::InitParams::TYPE_WINDOW);
+ child_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ child_params.native_widget = new DesktopNativeWidgetAura(&child_widget);
+ child_params.parent = parent_widget.GetNativeWindow();
+ child_widget.Init(child_params);
+ child_widget.Show();
+ ui::X11EventSource::GetInstance()->DispatchXEvents();
+
+ // Sanity check that the two widgets each have their own XID.
+ ASSERT_NE(parent_widget.GetNativeWindow()->GetHost()->GetAcceleratedWidget(),
+ child_widget.GetNativeWindow()->GetHost()->GetAcceleratedWidget());
+ Widget::CloseAllSecondaryWidgets();
+ EXPECT_TRUE(DesktopWindowTreeHostX11::GetAllOpenWindows().empty());
+}
+
class MouseEventRecorder : public ui::EventHandler {
public:
MouseEventRecorder() {}
diff --git a/ui/views/widget/native_widget_aura.cc b/ui/views/widget/native_widget_aura.cc
index bf113e6..d5bb6df 100644
--- a/ui/views/widget/native_widget_aura.cc
+++ b/ui/views/widget/native_widget_aura.cc
@@ -1060,10 +1060,7 @@ void Widget::CloseAllSecondaryWidgets() {
#endif
#if defined(USE_X11) && !defined(OS_CHROMEOS)
- std::vector<aura::Window*> open_windows =
- DesktopWindowTreeHostX11::GetAllOpenWindows();
- std::for_each(open_windows.begin(), open_windows.end(), CloseWindow);
- DesktopWindowTreeHostX11::CleanUpWindowList();
+ DesktopWindowTreeHostX11::CleanUpWindowList(CloseWindow);
#endif
}