diff --git a/ui/base/x/x11_drag_drop_client.cc b/ui/base/x/x11_drag_drop_client.cc index f1c43001fec27..0209900d3b77d 100644 --- a/ui/base/x/x11_drag_drop_client.cc +++ b/ui/base/x/x11_drag_drop_client.cc @@ -234,8 +234,14 @@ std::vector XDragDropClient::GetOfferedDragOperations() const { void XDragDropClient::CompleteXdndPosition(x11::Window source_window, const gfx::Point& screen_point) { + // delegate_->UpdateDrag() may spin a nested RunLoop that destroys |this| + // (via CloseNow -> ~X11Window -> ~XDragDropClient). + auto alive = weak_factory_.GetWeakPtr(); DragOperation drag_operation = PreferredDragOperation(delegate_->UpdateDrag(screen_point)); + if (!alive) { + return; + } // Sends an XdndStatus message back to the source_window. l[2,3] // theoretically represent an area in the window where the current action is @@ -428,7 +434,13 @@ void XDragDropClient::OnXdndStatus(const x11::ClientMessageEvent& event) { void XDragDropClient::OnXdndLeave(const x11::ClientMessageEvent& event) { DVLOG(1) << "OnXdndLeave"; + // delegate_->OnBeforeDragLeave() may spin a nested RunLoop that destroys + // |this| (via CloseNow -> ~X11Window -> ~XDragDropClient). + auto alive = weak_factory_.GetWeakPtr(); delegate_->OnBeforeDragLeave(); + if (!alive) { + return; + } ResetDragContext(); } @@ -437,7 +449,13 @@ void XDragDropClient::OnXdndDrop(const x11::ClientMessageEvent& event) { auto source_window = static_cast(event.data.data32[0]); + // delegate_->PerformDrop() may spin a nested RunLoop that destroys |this| + // (via CloseNow -> ~X11Window -> ~XDragDropClient). + auto alive = weak_factory_.GetWeakPtr(); DragOperation drag_operation = delegate_->PerformDrop(); + if (!alive) { + return; + } auto xev = PrepareXdndClientMessage(kXdndFinished, source_window); xev.data.data32[1] = (drag_operation != DragOperation::kNone) ? 1 : 0; diff --git a/ui/base/x/x11_drag_drop_client.h b/ui/base/x/x11_drag_drop_client.h index 88360078bbcdb..f5f7717c64111 100644 --- a/ui/base/x/x11_drag_drop_client.h +++ b/ui/base/x/x11_drag_drop_client.h @@ -9,6 +9,7 @@ #include "base/component_export.h" #include "base/memory/raw_ptr.h" +#include "base/memory/weak_ptr.h" #include "base/timer/timer.h" #include "ui/base/dragdrop/mojom/drag_drop_types.mojom-shared.h" #include "ui/base/x/selection_utils.h" @@ -251,6 +252,8 @@ class COMPONENT_EXPORT(UI_BASE_X) XDragDropClient { // only if we have previously received a status message from // |source_current_window_|. bool status_received_since_enter_ = false; + + base::WeakPtrFactory weak_factory_{this}; }; } // namespace ui