Commit cc4be1cb authored by James Cook's avatar James Cook Committed by Commit Bot

cros: Cleanup ShelfWidget::DelegateView shutdown

Make it use DeleteDelegate() to be more consistent with
StatusAreaWidgetDelegate. Defer closing the widget until all the
top-level windows are closed.

Bug: 628655
Test: ash_unittests
Change-Id: I066b45dab9c848b8f990f7fb51f0170e5e66a861
Reviewed-on: https://chromium-review.googlesource.com/907390
Commit-Queue: James Cook <jamescook@chromium.org>
Reviewed-by: default avatarMichael Wasserman <msw@chromium.org>
Cr-Commit-Position: refs/heads/master@{#540550}
parent dbc48ca4
...@@ -471,6 +471,8 @@ void RootWindowController::Shutdown() { ...@@ -471,6 +471,8 @@ void RootWindowController::Shutdown() {
void RootWindowController::CloseChildWindows() { void RootWindowController::CloseChildWindows() {
// NOTE: this may be called multiple times. // NOTE: this may be called multiple times.
// TODO: Only call this once. The multiple calls cause complexity in the
// dependent Shelf and ShelfWidget code.
// Deactivate keyboard container before closing child windows and shutting // Deactivate keyboard container before closing child windows and shutting
// down associated layout managers. // down associated layout managers.
...@@ -505,6 +507,7 @@ void RootWindowController::CloseChildWindows() { ...@@ -505,6 +507,7 @@ void RootWindowController::CloseChildWindows() {
while (!toplevel_windows.windows().empty()) while (!toplevel_windows.windows().empty())
delete toplevel_windows.Pop(); delete toplevel_windows.Pop();
} }
// And then remove the containers. // And then remove the containers.
while (!root->children().empty()) { while (!root->children().empty()) {
aura::Window* child = root->children()[0]; aura::Window* child = root->children()[0];
...@@ -514,6 +517,8 @@ void RootWindowController::CloseChildWindows() { ...@@ -514,6 +517,8 @@ void RootWindowController::CloseChildWindows() {
root->RemoveChild(child); root->RemoveChild(child);
} }
// Removing the containers destroys ShelfLayoutManager. ShelfWidget outlives
// ShelfLayoutManager because ShelfLayoutManager holds a pointer to it.
shelf_->DestroyShelfWidget(); shelf_->DestroyShelfWidget();
aura::client::SetDragDropClient(GetRootWindow(), nullptr); aura::client::SetDragDropClient(GetRootWindow(), nullptr);
......
...@@ -90,6 +90,7 @@ void Shelf::CreateShelfWidget(aura::Window* root) { ...@@ -90,6 +90,7 @@ void Shelf::CreateShelfWidget(aura::Window* root) {
} }
void Shelf::ShutdownShelfWidget() { void Shelf::ShutdownShelfWidget() {
// May be called multiple times during shutdown.
if (shelf_widget_) if (shelf_widget_)
shelf_widget_->Shutdown(); shelf_widget_->Shutdown();
} }
......
...@@ -73,7 +73,8 @@ class ShelfWidget::DelegateView : public views::WidgetDelegate, ...@@ -73,7 +73,8 @@ class ShelfWidget::DelegateView : public views::WidgetDelegate,
default_last_focusable_child_ = default_last_focusable_child; default_last_focusable_child_ = default_last_focusable_child;
} }
// views::WidgetDelegateView: // views::WidgetDelegate:
void DeleteDelegate() override { delete this; }
views::Widget* GetWidget() override { return View::GetWidget(); } views::Widget* GetWidget() override { return View::GetWidget(); }
const views::Widget* GetWidget() const override { return View::GetWidget(); } const views::Widget* GetWidget() const override { return View::GetWidget(); }
...@@ -106,6 +107,8 @@ ShelfWidget::DelegateView::DelegateView(ShelfWidget* shelf_widget) ...@@ -106,6 +107,8 @@ ShelfWidget::DelegateView::DelegateView(ShelfWidget* shelf_widget)
focus_cycler_(nullptr), focus_cycler_(nullptr),
opaque_background_(ui::LAYER_SOLID_COLOR) { opaque_background_(ui::LAYER_SOLID_COLOR) {
DCHECK(shelf_widget_); DCHECK(shelf_widget_);
set_owned_by_client(); // Deleted by DeleteDelegate().
SetLayoutManager(std::make_unique<views::FillLayout>()); SetLayoutManager(std::make_unique<views::FillLayout>());
set_allow_deactivate_on_esc(true); set_allow_deactivate_on_esc(true);
opaque_background_.SetBounds(GetLocalBounds()); opaque_background_.SetBounds(GetLocalBounds());
...@@ -216,12 +219,36 @@ ShelfWidget::ShelfWidget(aura::Window* shelf_container, Shelf* shelf) ...@@ -216,12 +219,36 @@ ShelfWidget::ShelfWidget(aura::Window* shelf_container, Shelf* shelf)
ShelfWidget::~ShelfWidget() { ShelfWidget::~ShelfWidget() {
// Must call Shutdown() before destruction. // Must call Shutdown() before destruction.
DCHECK(!status_area_widget_); DCHECK(did_shutdown_);
}
void ShelfWidget::Shutdown() {
if (did_shutdown_)
return;
// Shutting down the status area widget may cause some widgets (e.g. bubbles)
// to close, so uninstall the ShelfLayoutManager event filters first. Don't
// reset the pointer until later because other widgets (e.g. app list) may
// access it later in shutdown.
if (shelf_layout_manager_)
shelf_layout_manager_->PrepareForShutdown();
if (status_area_widget_) {
background_animator_.RemoveObserver(status_area_widget_.get());
Shell::Get()->focus_cycler()->RemoveWidget(status_area_widget_.get());
status_area_widget_.reset();
}
// Don't need to update the shelf background during shutdown.
background_animator_.RemoveObserver(delegate_view_); background_animator_.RemoveObserver(delegate_view_);
background_animator_.RemoveObserver(this); background_animator_.RemoveObserver(this);
// Don't need to observe focus/activation during shutdown.
Shell::Get()->focus_cycler()->RemoveWidget(this); Shell::Get()->focus_cycler()->RemoveWidget(this);
SetFocusCycler(nullptr); SetFocusCycler(nullptr);
RemoveObserver(this); RemoveObserver(this);
did_shutdown_ = true;
} }
void ShelfWidget::CreateStatusAreaWidget(aura::Window* status_container) { void ShelfWidget::CreateStatusAreaWidget(aura::Window* status_container) {
...@@ -290,23 +317,6 @@ FocusCycler* ShelfWidget::GetFocusCycler() { ...@@ -290,23 +317,6 @@ FocusCycler* ShelfWidget::GetFocusCycler() {
return delegate_view_->focus_cycler(); return delegate_view_->focus_cycler();
} }
void ShelfWidget::Shutdown() {
// Shutting down the status area widget may cause some widgets (e.g. bubbles)
// to close, so uninstall the ShelfLayoutManager event filters first. Don't
// reset the pointer until later because other widgets (e.g. app list) may
// access it later in shutdown.
if (shelf_layout_manager_)
shelf_layout_manager_->PrepareForShutdown();
if (status_area_widget_) {
background_animator_.RemoveObserver(status_area_widget_.get());
Shell::Get()->focus_cycler()->RemoveWidget(status_area_widget_.get());
status_area_widget_.reset();
}
CloseNow();
}
void ShelfWidget::UpdateIconPositionForPanel(aura::Window* panel) { void ShelfWidget::UpdateIconPositionForPanel(aura::Window* panel) {
ShelfID id = ShelfID::Deserialize(panel->GetProperty(kShelfIDKey)); ShelfID id = ShelfID::Deserialize(panel->GetProperty(kShelfIDKey));
if (id.IsNull()) if (id.IsNull())
......
...@@ -143,6 +143,8 @@ class ASH_EXPORT ShelfWidget : public views::Widget, ...@@ -143,6 +143,8 @@ class ASH_EXPORT ShelfWidget : public views::Widget,
ScopedSessionObserver scoped_session_observer_; ScopedSessionObserver scoped_session_observer_;
bool did_shutdown_ = false;
DISALLOW_COPY_AND_ASSIGN(ShelfWidget); DISALLOW_COPY_AND_ASSIGN(ShelfWidget);
}; };
......
...@@ -721,8 +721,6 @@ Shell::~Shell() { ...@@ -721,8 +721,6 @@ Shell::~Shell() {
toast_manager_.reset(); toast_manager_.reset();
for (aura::Window* root : GetAllRootWindows())
Shelf::ForWindow(root)->ShutdownShelfWidget();
tray_bluetooth_helper_.reset(); tray_bluetooth_helper_.reset();
// Accesses root window containers. // Accesses root window containers.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment