d3 / d3-drag

Drag and drop SVG, HTML or Canvas using mouse or touch input.
https://d3js.org/d3-drag
ISC License
335 stars 61 forks source link

The default filter should return false if event.ctrlKey. #62

Closed JHStoops closed 5 years ago

JHStoops commented 5 years ago

Our page uses some fairly complex D3, but we've noticed an issue that can be consistently reproduced even in simple examples.

Steps to reproduce:

  1. (On a Mac) control + click on any draggable item or background, which opens a context menu;
  2. Click outside of the context menu to close it
  3. You're now in a dragging state, even though you released the click.
  4. click again to escape the drag state.

This doesn't happen when you replace the first step with a regular right-click; so we expect it might have something to do with the meta-key control being involved in the process that lets the key-down event trigger, but doesn't register the key-up event and thus thinks it's in drag state until a new click event is dispatched.

We made this codepen as an example. In its current form it uses microlibraries, but it gave the same results when importing the latest version of the full d3 library (v5) https://codepen.io/anon/pen/rEdmRZ

And any example from https://github.com/d3/d3/wiki/Gallery that includes dragging, such as: http://bl.ocks.org/robschmuecker/7880033 https://observablehq.com/@d3/versor-dragging http://bl.ocks.org/shunpochang/66620bad0e6b201f261c

mbostock commented 5 years ago

Currently our assumption is that the context menu is summoned via right-click, not control-click. The default filter is:

function filter() {
  return !d3.event.button;
}

We could change it to

function filter() {
  return !d3.event.ctrlKey && !d3.event.button;
}

but I don’t think we’d want to do this unless we knew that Control-Click brings up the context menu, since some users might want to use control key when dragging. I’m not sure how we’d be able to know the correct behavior since it is platform specific.

JHStoops commented 5 years ago

I think it's fair to assume that only a minority of users use control + click to open a context menu on Macs.

Thanks for looking into this. Keep up the amazing work!

mbostock commented 5 years ago

I think changing the default filter to ignore the gesture if d3.event.ctrlKey is true is a good idea, since it is the default on macOS, and people can always override this default if they want to allow dragging with Control.

JHStoops commented 5 years ago

I just noticed you reopened the issue and implemented a fix. I tested it in our app, and it works like a charm. Thanks, good sir!

curran commented 1 year ago

I'm curious, if you remove the default filter and try to ctrl+drag on a Mac, does it work? I would guess that it does, because only ctrl+click (and not drag) would cause the context menu to appear.

I ask because I'm developing something with Ctrl+drag as a "thing" to trigger a certain behavior, and I'm not sure it would work on a Mac (I don't have access to a Mac). Fingers crossed it would work!