diff options
author | Sadrul Habib Chowdhury <sadrul@chromium.org> | 2015-07-13 16:08:10 -0400 |
---|---|---|
committer | Sadrul Habib Chowdhury <sadrul@chromium.org> | 2015-07-13 20:09:31 +0000 |
commit | 6ffa49b37d0af3eeb442349777e12f9eca8d0e89 (patch) | |
tree | fc4b59751b375f180c8edc16557a36c7ea78ecd2 | |
parent | 407d3a40db600b17aaec9e10f49b016a42afe438 (diff) | |
download | chromium_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}
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 } |