Closed Bug 1581285 Opened 5 years ago Closed 5 years ago

Drag ends stop firing - STILL - in Firefox nightly 71.0a1 2019-09-13

Categories

(Core :: DOM: Copy & Paste and Drag & Drop, defect)

71 Branch
defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla71
Tracking Status
firefox71 --- fixed

People

(Reporter: jschachter, Assigned: enndeakin)

References

Details

Attachments

(1 file)

User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0

Steps to reproduce:

This has already been discussed in 1476195 which was assumed to be a duplicate of 1580721 and 1545366 (and others). The jsfiddle originally shown in 1545366 shows that we still have the problem.

To reproduce, visit https://jsfiddle.net/oun3hwyk/ then drag and drop the "draggable" element as fast as you can. Watch the console log for the 'dragstart' and 'dragend' messages.

Actual results:

Within 60 seconds of rapid fire dragging, you should see that Firefox stops firing the dragend event. Whatever was done in 1476195 did not fix the problem.

The missing dragend is wreaking havoc on my complex javascript application that relies heavily on drag & drop. As discussed in 1545366, the problem appeared in 69.0, and is still present in the latest 71.0a1 nightly (2019-09-13) despite the fix for 1476195.

Expected results:

Rapid fire drag/drop should not cause firefox to stop dropping dragend events. The same fiddle on Chrome works just fine - you can drag/drop as fast as you want all day and dragend always fires.

I did not file this from the browser that shows the problem, so the user agent in the original comment is not correct. It should be:

"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0"

To clarify, the now fixed bug 1476195 and its duplicates are Mac specific.

Bug 1545366 is probably a similar issue that might be Windows specific.

Yes. My bug has been closed as well. But it is not solved in 71.0a1 (2019-09-15).
https://bugzilla.mozilla.org/show_bug.cgi?id=1580688

The issue i described there is not dependend on the operating system! I tested it on various machines. This bug is critical!!!
I might have to remove Firefox from the supported browser list of our application until this is fixed, which is quite sad.

Given that this is horribly broken in the current public version of Firefox (69), may I request that the Mozilla team roll the public version back to 68.0.2, wherein drag/drop works? Or at least restore the drag/drop functionality from 68.0.2 to 69? My company and my paying customers cannot wait until 71 becomes public, assuming the bug is fixed by then.

YMMV, but the following desperation measures appear (for us) to reduce the frequency of this bug (but they do not eliminate it):

  1. Erect a permanent full-screen transparent div FOO at zIndex 10000 or whatever will make it stay on top.
  2. Don't do anything at all in a drop event. Move all processing and DOM manipulation to dragEnd. If you need the coordinates of the drop, record them for dragEnd and return.
  3. In the dragEnd event,
  • FOO.style.pointerEvents = "none"; // block all mouse event handlers
  • setTimer 30ms, function = { // required for the block to take effect
    <whatever your drop or dragEnd handler used to do>
    setTimer 500ms, function = {
    FOO.style.pointerEvents = 'auto'; // allow mouse events again after a half-second hiatus
    }
    }

Notes:

  • Erecting this "deflector shield" in the drop event as opposed to dragEnd does not seem to be helpful.
  • The "deflector shield" is required in order to see a bug frequency difference. Just putting all processing on timer events (decoupling all work from drag-associated events) is not helpful by itself.
  • No issues on Chrome. Firefox bug only.

We now have reliable user feedback on our desperation "deflector shield" measure. As we expected from our own testing, it does reduce bug frequency substantially, but it does not eliminate the bug.

Unlike in bug 1580688, in our complex application, refreshing the page does reset the event pipeline and dragend-s reappear.

I hope this doesn't mean that what we're seeing in our application is a completely different bug. The jsfiddle attached to this bug

https://jsfiddle.net/oun3hwyk/

behaves like bug 1580688, wherein a page refresh does not reset the event pipeline. We're working on concise steps to reproduce our bug (wherein a page refresh does reset the event pipeline) just in case it is different.

Status: UNCONFIRMED → NEW
Component: Untriaged → Drag and Drop
Ever confirmed: true
Product: Firefox → Core

This is killing our business.

When this bug occurs, drags are dead. Scrollbars are dead. We get nothing but dragStarts, no other drag events. There's got to be something obvious going on, some internal state that's messed up. If the root cause is elusive, maybe we could paper this over by detecting this confused state (two/three/four/<pick a number> dragStarts in a row without a dragEnd?) and resetting whatever is confused.

What's happening here is:

At https://searchfox.org/mozilla-central/rev/f43ae7e1c43a4a940b658381157a6ea6c5a185c1/widget/nsDragServiceProxy.cpp#77 we are starting a drag session in the child process.

At https://searchfox.org/mozilla-central/rev/f43ae7e1c43a4a940b658381157a6ea6c5a185c1/dom/ipc/BrowserParent.cpp#3716 the parent process ESM is told to start tracking a drag. However, it doesn't actually start the native drag in the parent process until the next mousemove event arrives.

In the meantime, the user has let go of the mouse, so the parent process ESM stops tracking the drag session. Note that an actual native drag never started so the OS never thinks a drag happened. However, the child process is never informed of this and still has an active drag session. This causes the next drag attempt to fail (at https://searchfox.org/mozilla-central/rev/f43ae7e1c43a4a940b658381157a6ea6c5a185c1/dom/events/EventStateManager.cpp#2002 )

I'm thinking that we could fix this by:

a) when the parent receives the mouseup event, a drag never actually started, yet there is a process in nsBaseDragService::mChildProcesses, send a separate notification to that child to cancel dragging.
b) or could this be done via the mouseup event? Or, given OOP iframes, might the mouseup get sent to a different child process if it occurs in a different iframe?

smaug, does a) sound reasonable to you?

Flags: needinfo?(bugs)

Note that I am easily able to reproduce this by dragging in the same location repeatedly. This issue occurs on all platforms.

It can be fixed by dragging some part of the browser UI around (urlbar, bookmarks, etc.) as this starts a real drag, resetting the state in the child process. Though I seem to recall a comment in one of these bugs that that didn't fix the issue, but I can't find that comment right now.

@Neil: The comment you may be referring to (RE resetting the state) is that in the simple repros of this bug, refreshing the browser page does not clear up the problem (as was reported in 1580688); however, oddly, it does clear up the problem in our application, confirmed by multiple users across multiple platforms. This worries us, because it may mean we are seeing a different issue. But, despite significant effort, we have not been able to strip down our app to create a small repro of the problem that is cleared up by a refresh. Instead, every stripped-down repro we've created behaves just like the other repros. So we are at a loss to explain why a page refresh clears up the issue in our (complex) app.

FWIW I am able to reset the problem by dragging a browser tab, but not by dragging the urlbar or other parts of the UI that are not draggable.

Multiple users of our app now confirm that dragging a browser tab un-wedges drag/drop from its stuck condition.

In case this helps anyone else in our situation, we are inserting pop-up instructions to users on how to un-wedge our application. We trigger the instructions pop-up by detecting the occurrence of at least three consecutive dragStart events without intervening dragOver, drop, or dragEnd events. This is embarrassing, of course, but far better than failing silently. We picked "three" because we have seen consecutive dragStart events occur from time to time during normal operation, and we do not want to trigger the pop-up unless it is truly necessary. Most users will re-try a failed drag-drop a number of times before giving up, so "three" is likely reasonable.

Another workaround for now is to just call alert() in your page. This opens a modal dialog and releases the drag session.

@Neil: Confirmed. That is a much better work-around, thank you.

Flags: needinfo?(bugs)
Pushed by neil@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/2b2ad2a24d1d
cancel drags in child processes when the drag gesture is stopped in the parent, r=smaug
Status: NEW → RESOLVED
Closed: 5 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla71
Assignee: nobody → enndeakin
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: