diff --git a/ui/ozone/platform/wayland/host/wayland_window.cc b/ui/ozone/platform/wayland/host/wayland_window.cc index 7701deda447bd..32a60372fe1df 100644 --- a/ui/ozone/platform/wayland/host/wayland_window.cc +++ b/ui/ozone/platform/wayland/host/wayland_window.cc @@ -1323,7 +1323,14 @@ void WaylandWindow::ProcessPendingConfigureState(uint32_t serial) { } } + // RequestStateFromServer() calls into the delegate's OnStateUpdate(), which + // the views layer documents may synchronously close the widget and destroy + // this platform window. + auto alive = AsWeakPtr(); RequestStateFromServer(state, serial); + if (!alive) { + return; + } // Reset values. pending_configure_state_ = PendingConfigureState(); diff --git a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc index cca168290f53d..372640cdf2828 100644 --- a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc +++ b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc @@ -483,6 +483,19 @@ TEST_P(WaylandWindowTest, DeleteWindowFromOnStateUpdate) { window_->SetBoundsInDIP(gfx::Rect(1024, 768)); } +// Ensures ProcessPendingConfigureState handles the case where the platform +// window is destroyed synchronously inside the delegate's OnStateUpdate +// callout, e.g. when the views layer closes the widget on a state change. +TEST_P(WaylandWindowTest, DeleteWindowFromOnStateUpdateDuringSurfaceConfigure) { + delegate_.set_on_state_update_callback(base::BindLambdaForTesting([&]() { + window_.reset(); + return false; + })); + + window_->HandleSurfaceConfigure(2); + EXPECT_FALSE(window_); +} + TEST_P(WaylandWindowTest, SetTitle) { window_->SetTitle(u"hello"); PostToServerAndWait([id = surface_id_](wl::TestWaylandServerThread* server) {