Open Bug 1561879 Opened 1 year ago Updated 1 year ago

Sometimes drag operation started in a sidebar contents provided by an addon is immediately canceled on macOS

Categories

(Core :: DOM: Drag & Drop, defect, P3)

defect

Tracking

()

Tracking Status
firefox69 --- affected

People

(Reporter: yuki, Unassigned)

Details

This is similar to the bug 1561522. On macOS drag event started in a sidebar panel provided by an addon is sometimes canceled immediately, then dragend event is dispatched and its screenX and screenY are zero.

Steps to reproduce

  1. Prepare a macOS machine. I've tested on MacBook Pro with Retina display.
  2. Start Nightly with a clean profile.
  3. Go to about:debugging.
  4. Load a testcase https://bugzilla.mozilla.org/attachment.cgi?id=9074116 (a development build of Tree Style Tab) as a temporary addon. Then the sidebar appears and TST's sidebar panel is loaded.
  5. Open a debugger tab for the loaded temporary addon TST.
  6. Choose the console tab in the debugger.
  7. Click the pull down menu in the sidebar header, and choose "Move Sidebar to RIght".
  8. Put the browser window at bottom-right edge of the screen (to maximize the erratic coordinates.)
  9. Drag an item in the sidebar and drop it on the dragged item itself (of course inside the sidebar area) again and again.

Actual result

Sometimes the drag operation is canceled immediately and you get console output like below

expected range of screenX:  Object { from: 1355.199951171875, to: 1581.199951171875 }
screenX on dragstart:       1440
screenX on dragend:         0 <= invalid!
expected range of screenY:  Object { from: 483.20001220703125, to: 929.2000122070312 }
screenY on dragstart:       771
screenY on dragend:         0 <= invalid!

And then the dragged tab is detached to a window, because TST detected that the tab was dropped at (0,0) - too far from the sidebar area.

Expected result:

You get no console output or output like below

expected range of screenX:  Object { from: 1355.199951171875, to: 1581.199951171875 }
screenX on dragstart:       1440
screenX on dragend:         1450 <= between the expected range
expected range of screenY:  Object { from: 483.20001220703125, to: 929.2000122070312 }
screenY on dragstart:       771
screenY on dragend:         760 <= between the expected range

Environment

  • macOS 10.14.5 Mojave
  • Nightly 69.0a1 build id: 20190626215508
Priority: -- → P3
Component: DOM: Events → Drag and Drop
Priority: P3 → --

I couldn't reproduce this problem with another mac, MacBook Air without Retina display.

This looks an IPC issue.

As I commented at https://bugzilla.mozilla.org/show_bug.cgi?id=1561522#c2 coordinates of the dragend event is initialized with nsBaseDragService::SetDragEndPoint().
https://searchfox.org/mozilla-central/rev/06bd14ced96f25ff1dbd5352cb985fc0fa12a64e/widget/nsBaseDragService.h#61
On macOS the method is called on three locations below:
https://searchfox.org/mozilla-central/rev/867cbb1a2b232398616e1aa42f913f37c6cb38e4/dom/ipc/ContentChild.cpp#3319
https://searchfox.org/mozilla-central/rev/867cbb1a2b232398616e1aa42f913f37c6cb38e4/widget/cocoa/nsChildView.mm#5385
https://searchfox.org/mozilla-central/rev/867cbb1a2b232398616e1aa42f913f37c6cb38e4/widget/cocoa/nsChildView.mm#5389
So I tried to investigate when the invalid point [0, 0] is given, with inserting MOZ_LOG before those lines. And after logging I've realized that both callers in nsChildView.mm set correct point but only ContentChild::RecvEndDragSession() sets the invalid point [0, 0]. I'm not well about IPC but due to some reasons coordinates information looks lost while IPC.

As the next step how should I research? Any advice?

After more research I've realized that nsBaseDragService::EndDragSession() is called only one time at success cases but it is called twice on failure cases.
First time it is called from here, this is common on both success and failure cases.
Second time is called from nsBaseDragService::InvokeDragSession() as EndDragSession(true, 0). This is the reason why the invalid point [0, 0] is delivered to dragend listeners.

Then, why the "cleanup" code is called only on failure cases?

nsBaseDragService::InvokeDragSession() is called from EventStateManager::GenerateDragGesture(), it is the only one caller. But EventStateManager::GenerateDragGesture() is called too frequently with mouse moves, so I couldn't find out why it is called twice on the failure case.

The priority flag is not set for this bug.
:enndeakin, could you have a look please?

For more information, please visit auto_nag documentation.

Flags: needinfo?(enndeakin)
Flags: needinfo?(enndeakin)
Priority: -- → P3
You need to log in before you can comment on or make changes to this bug.