Bug 1938101 [Linux] Track waiting D&D operations and don't start more than one r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D246411
This commit is contained in:
stransky
2025-04-29 07:15:44 +00:00
parent f018711324
commit 3cc2bbee90
2 changed files with 23 additions and 18 deletions

View File

@@ -1434,23 +1434,25 @@ RefPtr<DragData> nsDragSession::GetDragData(GdkAtom aRequestedFlavor) {
} }
} }
mWaitingForDragDataRequests++; if (mWaitingForDragDataContext == mTargetDragContext) {
LOGDRAGSERVICE(" %s failed to get as we're already waiting to data",
GUniquePtr<gchar>(gdk_atom_name(aRequestedFlavor)).get());
return nullptr;
}
mWaitingForDragDataContext = mTargetDragContext;
// We'll get the data by nsDragSession::TargetDataReceived() // We'll get the data by nsDragSession::TargetDataReceived()
gtk_drag_get_data(mTargetWidget, mTargetDragContext, aRequestedFlavor, gtk_drag_get_data(mTargetWidget, mTargetDragContext, aRequestedFlavor,
mTargetTime); mTargetTime);
LOGDRAGSERVICE( LOGDRAGSERVICE(" about to start inner iteration");
" about to start inner iteration, mWaitingForDragDataRequests %d",
mWaitingForDragDataRequests);
gtk_main_iteration(); gtk_main_iteration();
PRTime entryTime = PR_Now(); PRTime entryTime = PR_Now();
int32_t timeout = StaticPrefs::widget_gtk_clipboard_timeout_ms() * 1000; int32_t timeout = StaticPrefs::widget_gtk_clipboard_timeout_ms() * 1000;
while (mWaitingForDragDataRequests && mDoingDrag) { while (mWaitingForDragDataContext && mDoingDrag) {
// check the number of iterations // check the number of iterations
LOGDRAGSERVICE(" doing iteration, mWaitingForDragDataRequests %d ...", LOGDRAGSERVICE(" doing iteration");
mWaitingForDragDataRequests);
if (PR_Now() - entryTime > timeout) { if (PR_Now() - entryTime > timeout) {
LOGDRAGSERVICE(" failed to get D&D data in time!\n"); LOGDRAGSERVICE(" failed to get D&D data in time!\n");
break; break;
@@ -1459,9 +1461,8 @@ RefPtr<DragData> nsDragSession::GetDragData(GdkAtom aRequestedFlavor) {
} }
// We failed to get all data in time // We failed to get all data in time
if (mWaitingForDragDataRequests) { if (mWaitingForDragDataContext) {
LOGDRAGSERVICE(" failed to get all data, mWaitingForDragDataRequests %d", LOGDRAGSERVICE(" failed to get all data");
mWaitingForDragDataRequests);
} }
RefPtr<DragData> data = RefPtr<DragData> data =
@@ -1482,15 +1483,18 @@ void nsDragSession::TargetDataReceived(GtkWidget* aWidget,
gint aY, gint aY,
GtkSelectionData* aSelectionData, GtkSelectionData* aSelectionData,
guint aInfo, guint32 aTime) { guint aInfo, guint32 aTime) {
MOZ_ASSERT(mWaitingForDragDataRequests); MOZ_ASSERT(mWaitingForDragDataContext);
mWaitingForDragDataRequests--;
GdkAtom target = gtk_selection_data_get_target(aSelectionData); GdkAtom target = gtk_selection_data_get_target(aSelectionData);
LOGDRAGSERVICE( LOGDRAGSERVICE("nsDragSession::TargetDataReceived(%p) MIME %s ", aContext,
"nsDragSession::TargetDataReceived(%p) MIME %s " GUniquePtr<gchar>(gdk_atom_name(target)).get());
"mWaitingForDragDataRequests %d",
aContext, GUniquePtr<gchar>(gdk_atom_name(target)).get(), if (mWaitingForDragDataContext != aContext) {
mWaitingForDragDataRequests); LOGDRAGSERVICE(" quit - wrong drag context!");
return;
}
mWaitingForDragDataContext = nullptr;
RefPtr<DragData> dragData; RefPtr<DragData> dragData;

View File

@@ -347,7 +347,8 @@ class nsDragSession : public nsBaseDragSession, public nsIObserver {
mozilla::LayoutDeviceIntPoint mTargetWindowPoint; mozilla::LayoutDeviceIntPoint mTargetWindowPoint;
int mWaitingForDragDataRequests = 0; // Track gtk_drag_get_data() requests here.
RefPtr<GdkDragContext> mWaitingForDragDataContext;
bool IsDragFlavorAvailable(GdkAtom aRequestedFlavor); bool IsDragFlavorAvailable(GdkAtom aRequestedFlavor);