diff --git a/ui/views/focus/focus_manager.cc b/ui/views/focus/focus_manager.cc index 8c154ec47cef9..4ff0116416acc 100644 --- a/ui/views/focus/focus_manager.cc +++ b/ui/views/focus/focus_manager.cc @@ -390,10 +390,11 @@ void FocusManager::SetFocusedView(View* view) { void FocusManager::ClearFocus() { // SetFocusedView(nullptr) is going to clear out the stored view to. We need // to persist it in this case. - views::View* focused_view = GetStoredFocusView(); + // SetFocusedView() may synchronously destroy the view via Blur(); track it. + ViewTracker focused_view(GetStoredFocusView()); SetFocusedView(nullptr); ClearNativeFocus(); - SetStoredFocusView(focused_view); + SetStoredFocusView(focused_view.view()); } void FocusManager::AdvanceFocusIfNecessary() { @@ -414,14 +415,16 @@ void FocusManager::AdvanceFocusIfNecessary() { } void FocusManager::StoreFocusedView(bool clear_native_focus) { - View* focused_view = focused_view_; // Don't do anything if no focused view. Storing the view (which is nullptr), // in this case, would clobber the view that was previously saved. if (!focused_view_) { return; } - View* v = focused_view_; + // SetFocusedView(nullptr) / ClearFocus() invoke Blur() on the focused view, + // and Blur() callbacks are allowed to synchronously destroy the view. Track + // it instead of holding a raw pointer. + ViewTracker focused_view(focused_view_); if (clear_native_focus) { // Temporarily disable notification. ClearFocus() will set the focus to the @@ -433,11 +436,11 @@ void FocusManager::StoreFocusedView(bool clear_native_focus) { ClearFocus(); } else { SetFocusedView(nullptr); - SetStoredFocusView(focused_view); + SetStoredFocusView(focused_view.view()); } - if (v) { - v->SchedulePaint(); // Remove focus border. + if (focused_view.view()) { + focused_view.view()->SchedulePaint(); // Remove focus border. } }