diff --git a/ui/ozone/platform/wayland/host/wayland_event_source.cc b/ui/ozone/platform/wayland/host/wayland_event_source.cc index 0f96ec1ebd420..765c6ae10b3d1 100644 --- a/ui/ozone/platform/wayland/host/wayland_event_source.cc +++ b/ui/ozone/platform/wayland/host/wayland_event_source.cc @@ -957,12 +957,19 @@ void WaylandEventSource::ReleasePressedPointerButtons( return; } + // OnPointerButtonEvent with kImmediate may spin a nested message loop that + // destroys |window|. Re-check liveness on every iteration so we never pass a + // freed pointer into SetPointerFocusedWindow. + base::WeakPtr window_weak = + window ? window->AsWeakPtr() : nullptr; + for (const auto& [button, name] : kMouseButtonToStringMap) { if (button & pointer_flags_) { VLOG(1) << "Synthesizing pointer release for: " << name; TRACE_EVENT_INSTANT("wayland.debug", "SynthesizePointerRelease", "button", name); - OnPointerButtonEvent(EventType::kMouseReleased, button, timestamp, window, + OnPointerButtonEvent(EventType::kMouseReleased, button, timestamp, + window_weak.get(), wl::EventDispatchPolicy::kImmediate, /*allow_release_of_unpressed_button=*/false, /*is_synthesized=*/true);