diff --git a/shell/browser/ui/autofill_popup.cc b/shell/browser/ui/autofill_popup.cc index 2c266f8427..2640425fdf 100644 --- a/shell/browser/ui/autofill_popup.cc +++ b/shell/browser/ui/autofill_popup.cc @@ -172,20 +172,30 @@ void AutofillPopup::CreateView(content::RenderFrameHost* frame_host, bool offscreen, views::View* parent, const gfx::RectF& r) { + DCHECK(parent); + Hide(); + // A Widget can outlive its NativeWidget during teardown. + // Do not create a child popup once the parent native view is gone. + views::Widget* parent_widget = parent->GetWidget(); + if (!parent_widget || parent_widget->IsClosed() || + !parent_widget->GetNativeView()) { + return; + } + frame_host_ = frame_host; element_bounds_ = gfx::ToEnclosedRect(r); - gfx::Vector2d height_offset(0, element_bounds_.height()); - gfx::Point menu_position(element_bounds_.origin() + height_offset); + gfx::Vector2d height_offset{0, element_bounds_.height()}; + gfx::Point menu_position{element_bounds_.origin() + height_offset}; views::View::ConvertPointToScreen(parent, &menu_position); - popup_bounds_ = gfx::Rect(menu_position, element_bounds_.size()); + popup_bounds_ = gfx::Rect{menu_position, element_bounds_.size()}; parent_ = parent; parent_->AddObserver(this); - view_ = new AutofillPopupView(this, parent->GetWidget()); + view_ = new AutofillPopupView{this, parent_widget}; if (offscreen) { auto* rwhv = embedder_frame_host ? embedder_frame_host->GetView() @@ -212,13 +222,19 @@ void AutofillPopup::Hide() { void AutofillPopup::SetItems(const std::vector& values, const std::vector& labels) { - DCHECK(view_); values_ = values; labels_ = labels; + + if (!view_) + return; + UpdatePopupBounds(); view_->OnSuggestionsChanged(); - if (view_) // could be hidden after the change - view_->DoUpdateBoundsAndRedrawPopup(); + + if (!view_) + return; + + view_->DoUpdateBoundsAndRedrawPopup(); } void AutofillPopup::AcceptSuggestion(int index) { diff --git a/shell/browser/ui/views/autofill_popup_view.cc b/shell/browser/ui/views/autofill_popup_view.cc index 630c22dbcb..f61f873730 100644 --- a/shell/browser/ui/views/autofill_popup_view.cc +++ b/shell/browser/ui/views/autofill_popup_view.cc @@ -69,9 +69,16 @@ AutofillPopupView::~AutofillPopupView() { void AutofillPopupView::Show() { if (!popup_) return; - bool visible = parent_widget_->IsVisible(); - visible = visible || view_proxy_; - if (!visible || parent_widget_->IsClosed()) + + DCHECK(parent_widget_); + + // The parent Widget can outlive its NativeWidget during teardown. + // Don't initialize the popup after the native parent view is gone. + if (parent_widget_->IsClosed() || !parent_widget_->GetNativeView()) + return; + + const bool visible = view_proxy_ || parent_widget_->IsVisible(); + if (!visible) return; const bool initialize_widget = !GetWidget(); @@ -234,10 +241,14 @@ void AutofillPopupView::DoUpdateBoundsAndRedrawPopup() { if (!popup_) return; + views::Widget* const widget = GetWidget(); + if (!widget) + return; + // Clamp popup_bounds_ to ensure it's never zero-width. popup_->popup_bounds_.Union( gfx::Rect(popup_->popup_bounds_.origin(), gfx::Size(1, 1))); - GetWidget()->SetBounds(popup_->popup_bounds_); + widget->SetBounds(popup_->popup_bounds_); if (view_proxy_.get()) { view_proxy_->SetBounds(popup_->popup_bounds_in_view()); }