react-dnd manager start handler#3119
Conversation
|
I'm going to start testing this thoroughly, and you can feel free to do the same. |
|
It does still seem to be possible to get into a state where the button highlights, but drag-and-drop is not activated. I think it's harder, but I can still do it semi-reliably. |
|
Interesting. That suggests that the timeout is finishing before react-dnd has a chance to stop propagation and prevent Let's keep working on this. Thanks. |
|
This uses my other fixes (#3113) so that
I'll take a look at |
Got it, thanks.
We could create minute timing offset, though that seems a bit hacky.
Yeah, there is some subtle timing thing here that's difficult to identify. Thanks for taking another look! |
Right, maybe I'll try that to make sure that it solves the issue, and then we can discuss whether we like it. |
|
Disabling Reducing the Next I'll see if I can find out any more information about why drag-and-drop takes so long to begin. |
|
TLDR: Here is a healthy drag:
Next, here is a long press that is cancelled by movement:
And finally, here is the bug:
So because |
Oops, that's not good either.
Sounds promising. I think the exact timing will be affected by performance unfortunately. If the app slows down, it might create more false positives. We could also just delay the appearance of the highlight, without touching the long press timing if that's the only thing affected. Though maybe there is an alert or something else tied to the timeout.
Is this a bug in Would it be possible to lean on Thanks and let me know what you recommend. |
I'd say so. I'm not sure what the rationale is for cancelling
I don't think so. The only options that I can think of are:
The third option would be to tweak the timing as we've discussed above, however, now that I've realized that this is not quite a race condition, I've also realized that it's still possible to break it with any timing offset. Reducing the timeout so that drag-and-drop initializes sooner will fix the initial repro steps, but it's still possible to wiggle your finger juuuuuust right and break it. Video.18.mov |
I'm open to this. I've already had to patch |
OK, should I follow these instructions and put the patch in |
|
Yes, thanks! Once you edit the dependency file, it should generate a patch for you. It might even put it directly in |
|
I think it worked! I also needed to add this bit of code because |
There was a problem hiding this comment.
Thank you! This seems promising, but I'm getting some weird behavior with this change. Half the time I try this, the long press gets canceled and gestures stop working.
Steps to Reproduce
- Refresh the page
- Draw and cancel a gesture
- Long press and drag a thought with the timing of the original issue.
- Attempt to input a gesture in the gesture zone.
Current Behavior
The long press gets canceled for some reason, then gestures stop working.
In this video, after the long press I'm swiping on the gesture zone.
trim.D3DD6052-2788-4C53-9722-F75C0649CE05.MOV
|
Hmm, I was able to find a bug with drag-and-drop after drawing a gesture, but it doesn't look quite the same as yours. I discovered that I'll keep looking to try to reproduce your bug, but please do let me know if this fixed it for you. |
|
Thanks. It's still occurring for me, although it doesn't happen very often I'm afraid. Maybe 1 in 10 times. Either gestures are completely disabled and the Gesture Zone starts allowing scrolling, or sometimes both drag-and-drop and gestures are incorrectly active at the same time. |
|
As for the flickering bullet shown in the video, I still haven't been able to reproduce it, but I can see how it could be the inverse of the bug above (i.e. drag-and-drop and gesture are active at the same time). Instead of the timeout in This would cause the bullet to highlight because
It seems like there are 3 issues to consider:
|
|
After mulling a bit, I see three possible solutions:
|
|
Thanks so much for the in-depth analysis. I'll try to offer my thoughts, although I have to maintain a bit of distance to avoid spending too much time myself. Thanks for your understanding.
That seems fine. Since we use the same
I'm not sure. I will have to rely on your experience so that I don't get too deep on the implementation details. I do know that we want to avoid modifying
Yes, that seems like a plausible cause. Something must be leading to It seems like the long press should always be set to inactive on
It's a bit hard for me to wrap my had around, but I'm open to it if it's not a ton of code.
Seems low impact enough.
This feels too high risk to me. One thing you could try is setting touchSlop to |
That's what I did here without actually using the In any case, that fixed most of the buggy behavior. What's left is due to situations where one timeout (e.g.
So I'm going to try to do option number 2 above:
and see if it's possible to guard against out-of-order event handlers to ensure that either
|
… should have fired already
Got it, thanks. Yes, we should use a single constant for that, and probably rename it to
You think it's really the exact millisecond? That seems so difficult to hit in practice, and I reproduced the issue a few times.
I'm worried about how complex this is, but see what you can do. It seems like there should be a more robust way to defer to Anything you can do to manage complexity here is going to help this be maintainable over time. |
That seemed to be what was happening for the bug that I was able to reproduce, but maybe you're seeing something different.
A custom event sounds like a good idea, and may allow me to get rid of the |
| (value === LongPressState.DragInProgress && state.longPress === LongPressState.DragHold) || | ||
| // Drag should only begin after long press has begun, but the occasional race condition | ||
| // may allow react-dnd to initiate a drag before useLongPress sets this to DragHold. | ||
| // Drag should not re-start after DragCanceled. |
There was a problem hiding this comment.
This is hopefully not true anymore, but the async nature of useLongPress and beginDrag makes me nervous that removing it might re-introduce some rare bug.
raineorshine
left a comment
There was a problem hiding this comment.
Great work! Thanks for your persistence. This looks like a solid approach now. Coordinating with TouchBackend resolves any weird timing issues between long press and drag-and-drop, or racing timeouts. I tried repeatedly to reproduce the original issue on an iPhone and was not able to.




Fixes #3072 and #3073
There was a brief gap between the start of a touch and the firing of
react-dnd'sstartevent, so there was a window where long press had begun (bullet highlighted) but drag-and-drop had not been initialized.Now
TouchBackendImpl.tshas been patched to emit adragStartevent when drag-and-drop initializes.useLongPresslistens for that event on mobile devices in order to synchronize long press timing with drag-and-drop.