-
Notifications
You must be signed in to change notification settings - Fork 433
Description
Describe the bug
I've spend a few days to get to the bottom of this issue. My code implements a dragListener that didn't behave correctly but jumped back and forth. I long thought it was a problem in my own code, but in the end I discovered it is due to Component. pointerDragged(final Component lead, final int x, final int y, final Object currentPointerPress) duplicating events, which then arrive out of order, probably due to the order in which callSerially executes the submitted Runnables.
It seems the error is linked to the additional calls here
private void pointerDragged(final Component lead, final int x, final int y, final Object currentPointerPress)
...
if (dragCallbacks < 2) {
dragCallbacks++;
Display.getInstance().callSerially(new Runnable() {
public void run() {
if (dragActivated) {
lead.pointerDragged(x, y, currentPointerPress);
}
dragCallbacks--;
}
});
}
To Reproduce
Run the below example code. Drag "DRAG ME" consistently upwards and you can see that many events arrive with a wrong y value, indicating (wrongly) that the drag direction has changed and that the received drag position has suddenly moved back to an earlier position like if the user's finger was jittering up and down.
int lastY = -1;
int dragDirection = 0; //0: init; -1=up; 1=down
int lastDragDirection = 0;
Form hi = new Form("Welcome", BoxLayout.y());
Label dragMe = new Label("DRAG ME");
dragMe.setDraggable(true);
dragMe.addDragOverListener((evt) -> {
int y = evt.getY();
lastDragDirection = dragDirection;
if (lastY == -1 || y == lastY) { //ignore same y value
} else if (y < lastY) {
dragDirection = -1;
} else if (y > lastY) {
dragDirection = 1;
}
if (lastDragDirection != dragDirection) {
Label dropTarget = evt.getDropTarget() instanceof Label ? (Label) evt.getDropTarget() : null;
Log.p("Dragging " + (dragDirection == -1 ? "UP " : dragDirection == 1 ? "DOWN" : "INIT") + " y= " + y + " d= " + (lastY - y)
+ (dropTarget != null ? " over " + dropTarget.getText() : ""));
}
lastY = y;
});
for (int i = 0; i < 20; i++) {
if (i == 10) {
hi.add(dragMe);
}
Label l = new Label("DropTarget " + i);
l.setDropTarget(true);
hi.add(l);
}
hi.show();
Expected behavior
The drag events should not duplicated, or if there is an important reason for doing it, it should be ensured they don't arrive out of order.
Desktop (please complete the following information):
- OS: MacOS, Simulator