Loading widget/gtk/nsDragService.cpp +14 −9 Original line number Diff line number Diff line Loading @@ -114,7 +114,8 @@ static void invisibleSourceDragDataGet(GtkWidget* aWidget, nsDragService::nsDragService() : mScheduledTask(eDragTaskNone), mTaskSource(0), mScheduledTaskIsRunning(false) mScheduledTaskIsRunning(false), mCachedDragContext() #ifdef MOZ_WAYLAND , mPendingWaylandDataOffer(nullptr), Loading Loading @@ -485,6 +486,7 @@ nsDragService::EndDragSession(bool aDoneDrag, uint32_t aKeyModifiers) { #endif mTargetWindow = nullptr; mPendingWindow = nullptr; mCachedDragContext = 0; return nsBaseDragService::EndDragSession(aDoneDrag, aKeyModifiers); } Loading Loading @@ -1038,6 +1040,14 @@ void nsDragService::ReplyToDragMotion(RefPtr<DataOffer> aDragContext) { } #endif void nsDragService::EnsureCachedDataValidForContext( GdkDragContext* aDragContext) { if (mCachedDragContext != (uintptr_t)aDragContext) { mCachedData.Clear(); mCachedDragContext = (uintptr_t)aDragContext; } } void nsDragService::TargetDataReceived(GtkWidget* aWidget, GdkDragContext* aContext, gint aX, gint aY, Loading @@ -1046,6 +1056,8 @@ void nsDragService::TargetDataReceived(GtkWidget* aWidget, LOGDRAGSERVICE(("nsDragService::TargetDataReceived")); TargetResetData(); EnsureCachedDataValidForContext(aContext); mTargetDragDataReceived = true; gint len = gtk_selection_data_get_length(aSelectionData); const guchar* data = gtk_selection_data_get_data(aSelectionData); Loading Loading @@ -1146,6 +1158,7 @@ void nsDragService::GetTargetDragData(GdkAtom aFlavor, // as mTargetDragContext. // Especially with multiple items the same data is requested // very often. EnsureCachedDataValidForContext(mTargetDragContext); if (auto cached = mCachedData.Lookup(flavor)) { mTargetDragDataLen = cached->Length(); LOGDRAGSERVICE(("Using cached data for %s, length is %d", flavor.get(), Loading Loading @@ -2017,8 +2030,6 @@ gboolean nsDragService::RunScheduledTask() { #endif mTargetTime = mPendingTime; mCachedData.Clear(); // http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#drag-and-drop-processing-model // (as at 27 December 2010) indicates that a "drop" event should only be // fired (at the current target element) if the current drag operation is Loading Loading @@ -2079,10 +2090,6 @@ gboolean nsDragService::RunScheduledTask() { gtk_drag_finish(mTargetDragContext, success, /* del = */ FALSE, mTargetTime); } // This drag is over, so clear out our reference to the previous // window. mTargetWindow = nullptr; // Make sure to end the drag session. If this drag started in a // different app, we won't get a drag_end signal to end it from. EndDragSession(true, GetCurrentModifiers()); Loading @@ -2096,8 +2103,6 @@ gboolean nsDragService::RunScheduledTask() { mTargetWaylandDataOffer = nullptr; #endif mCachedData.Clear(); // If we got another drag signal while running the sheduled task, that // must have happened while running a nested event loop. Leave the task // source on the event loop. Loading widget/gtk/nsDragService.h +8 −0 Original line number Diff line number Diff line Loading @@ -138,6 +138,11 @@ class nsDragService final : public nsBaseDragService, public nsIObserver { // We cache all data for the current drag context, // because waiting for the data in GetTargetDragData can be very slow. nsTHashMap<nsCStringHashKey, nsTArray<uint8_t>> mCachedData; // mCachedData are tied to mCachedDragContext. mCachedDragContext is not // ref counted and may be already deleted on Gtk side. // We used it for mCachedData invalidation only and can't be used for // any D&D operation. uintptr_t mCachedDragContext; #ifdef MOZ_WAYLAND RefPtr<DataOffer> mPendingWaylandDataOffer; Loading Loading @@ -186,6 +191,9 @@ class nsDragService final : public nsBaseDragService, public nsIObserver { void GetTargetDragData(GdkAtom aFlavor, nsTArray<nsCString>& aDropFlavors); // this will reset all of the target vars void TargetResetData(void); // Ensure our data cache belongs to aDragContext and clear the cache if // aDragContext is different than mCachedDragContext. void EnsureCachedDataValidForContext(GdkDragContext* aDragContext); // source side vars Loading Loading
widget/gtk/nsDragService.cpp +14 −9 Original line number Diff line number Diff line Loading @@ -114,7 +114,8 @@ static void invisibleSourceDragDataGet(GtkWidget* aWidget, nsDragService::nsDragService() : mScheduledTask(eDragTaskNone), mTaskSource(0), mScheduledTaskIsRunning(false) mScheduledTaskIsRunning(false), mCachedDragContext() #ifdef MOZ_WAYLAND , mPendingWaylandDataOffer(nullptr), Loading Loading @@ -485,6 +486,7 @@ nsDragService::EndDragSession(bool aDoneDrag, uint32_t aKeyModifiers) { #endif mTargetWindow = nullptr; mPendingWindow = nullptr; mCachedDragContext = 0; return nsBaseDragService::EndDragSession(aDoneDrag, aKeyModifiers); } Loading Loading @@ -1038,6 +1040,14 @@ void nsDragService::ReplyToDragMotion(RefPtr<DataOffer> aDragContext) { } #endif void nsDragService::EnsureCachedDataValidForContext( GdkDragContext* aDragContext) { if (mCachedDragContext != (uintptr_t)aDragContext) { mCachedData.Clear(); mCachedDragContext = (uintptr_t)aDragContext; } } void nsDragService::TargetDataReceived(GtkWidget* aWidget, GdkDragContext* aContext, gint aX, gint aY, Loading @@ -1046,6 +1056,8 @@ void nsDragService::TargetDataReceived(GtkWidget* aWidget, LOGDRAGSERVICE(("nsDragService::TargetDataReceived")); TargetResetData(); EnsureCachedDataValidForContext(aContext); mTargetDragDataReceived = true; gint len = gtk_selection_data_get_length(aSelectionData); const guchar* data = gtk_selection_data_get_data(aSelectionData); Loading Loading @@ -1146,6 +1158,7 @@ void nsDragService::GetTargetDragData(GdkAtom aFlavor, // as mTargetDragContext. // Especially with multiple items the same data is requested // very often. EnsureCachedDataValidForContext(mTargetDragContext); if (auto cached = mCachedData.Lookup(flavor)) { mTargetDragDataLen = cached->Length(); LOGDRAGSERVICE(("Using cached data for %s, length is %d", flavor.get(), Loading Loading @@ -2017,8 +2030,6 @@ gboolean nsDragService::RunScheduledTask() { #endif mTargetTime = mPendingTime; mCachedData.Clear(); // http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#drag-and-drop-processing-model // (as at 27 December 2010) indicates that a "drop" event should only be // fired (at the current target element) if the current drag operation is Loading Loading @@ -2079,10 +2090,6 @@ gboolean nsDragService::RunScheduledTask() { gtk_drag_finish(mTargetDragContext, success, /* del = */ FALSE, mTargetTime); } // This drag is over, so clear out our reference to the previous // window. mTargetWindow = nullptr; // Make sure to end the drag session. If this drag started in a // different app, we won't get a drag_end signal to end it from. EndDragSession(true, GetCurrentModifiers()); Loading @@ -2096,8 +2103,6 @@ gboolean nsDragService::RunScheduledTask() { mTargetWaylandDataOffer = nullptr; #endif mCachedData.Clear(); // If we got another drag signal while running the sheduled task, that // must have happened while running a nested event loop. Leave the task // source on the event loop. Loading
widget/gtk/nsDragService.h +8 −0 Original line number Diff line number Diff line Loading @@ -138,6 +138,11 @@ class nsDragService final : public nsBaseDragService, public nsIObserver { // We cache all data for the current drag context, // because waiting for the data in GetTargetDragData can be very slow. nsTHashMap<nsCStringHashKey, nsTArray<uint8_t>> mCachedData; // mCachedData are tied to mCachedDragContext. mCachedDragContext is not // ref counted and may be already deleted on Gtk side. // We used it for mCachedData invalidation only and can't be used for // any D&D operation. uintptr_t mCachedDragContext; #ifdef MOZ_WAYLAND RefPtr<DataOffer> mPendingWaylandDataOffer; Loading Loading @@ -186,6 +191,9 @@ class nsDragService final : public nsBaseDragService, public nsIObserver { void GetTargetDragData(GdkAtom aFlavor, nsTArray<nsCString>& aDropFlavors); // this will reset all of the target vars void TargetResetData(void); // Ensure our data cache belongs to aDragContext and clear the cache if // aDragContext is different than mCachedDragContext. void EnsureCachedDataValidForContext(GdkDragContext* aDragContext); // source side vars Loading