Chromium Code Reviews| Index: ui/views/window/dialog_client_view.cc |
| diff --git a/ui/views/window/dialog_client_view.cc b/ui/views/window/dialog_client_view.cc |
| index 5d543a7572efe2b85b8772f293c766cbdb19430f..844e7b99d9fadd671ad8457c62f82ad3a378170f 100644 |
| --- a/ui/views/window/dialog_client_view.cc |
| +++ b/ui/views/window/dialog_client_view.cc |
| @@ -17,6 +17,7 @@ |
| #include "ui/views/controls/button/md_text_button.h" |
| #include "ui/views/layout/grid_layout.h" |
| #include "ui/views/style/platform_style.h" |
| +#include "ui/views/view_observer.h" |
| #include "ui/views/views_delegate.h" |
| #include "ui/views/widget/widget.h" |
| #include "ui/views/window/dialog_delegate.h" |
| @@ -49,6 +50,36 @@ gfx::Size GetBoundingSizeForVerticalStack(const gfx::Size& size1, |
| size1.height() + size2.height()); |
| } |
| +// ViewDeletionObserver implements an observer to track the deletion of the |
| +// view in focus. |
| +class ViewDeletionObserver : public ViewObserver { |
| + public: |
| + explicit ViewDeletionObserver(View* observed_view) |
| + : observed_view_(observed_view) { |
| + if (observed_view_) |
| + observed_view_->AddObserver(this); |
| + } |
| + |
| + ~ViewDeletionObserver() override { |
| + if (observed_view_) |
| + observed_view_->RemoveObserver(this); |
| + } |
| + |
| + // ViewObserver: |
| + void OnViewIsDeleting(View* observed_view) override { |
| + DCHECK_EQ(observed_view, observed_view_); |
| + observed_view_ = nullptr; |
| + observed_view_->RemoveObserver(this); |
| + } |
| + |
| + View* focused_view() { return observed_view_; } |
|
sky
2017/05/18 16:05:29
Style guide says accessors like this should match
Ackerman
2017/05/18 18:24:17
Done.
|
| + |
| + private: |
| + View* observed_view_ = nullptr; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(ViewDeletionObserver); |
| +}; |
| + |
| } // namespace |
| // Simple container to bubble child view changes up the view hierarchy. |
| @@ -319,6 +350,8 @@ void DialogClientView::SetupLayout() { |
| base::AutoReset<bool> auto_reset(&adding_or_removing_views_, true); |
| GridLayout* layout = new GridLayout(button_row_container_); |
| layout->set_minimum_size(minimum_size_); |
| + FocusManager* focus_manager = GetFocusManager(); |
| + ViewDeletionObserver deletion_observer(focus_manager->GetFocusedView()); |
| // Clobber any existing LayoutManager since it has weak references to child |
| // Views which may be removed by SetupViews(). |
| @@ -399,6 +432,13 @@ void DialogClientView::SetupLayout() { |
| column_set->LinkColumnSizes(link[0], link[1], link[2], -1); |
| } |
| layout->AddPaddingRow(kFixed, insets.bottom()); |
| + |
| + // The default focus is lost when child views are added back into the dialog. |
| + // This restores focus if the button is still available. |
| + View* previously_focused_view = deletion_observer.focused_view(); |
| + if (previously_focused_view && !focus_manager->GetFocusedView() && |
| + Contains(previously_focused_view)) |
|
sky
2017/05/18 16:05:29
As the conditional spans multiple lines use {}
Ackerman
2017/05/18 18:24:17
Done.
|
| + previously_focused_view->RequestFocus(); |
| } |
| void DialogClientView::SetupViews() { |