JDK-6388028 : Drop cursor flashes to NO_DROP temporarily when changing drop action
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 6
  • Priority: P3
  • Status: Open
  • Resolution: Unresolved
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2006-02-20
  • Updated: 2011-01-19
Related Reports
Relates :  
Relates :  
Description
When the user changes their mouse drag gesture with modifiers, the drag and drop mouse cursor temporarily flashes to NO_DROP before going to the right one. Test case:

(This is on Windows XP - don't know about other platforms)

- Launch SwingSet2
- On the Options menu, select "Enable Drag Support"
- In the internal frames demo, select text "Frame" in the text field labelled "Frame title"
- Initiate a drag and drag to the right of the text.
- The MOVE DnD cursor is shown
- Press down Control to select a COPY action
- Before the COPY cursor is shown, it quickly flashes to NO_DROP cursor
- Release Control. It quickly flashes to NO_DROP again before returning to MOVE.
- This happens when dragging from Java into native apps too and is very repeatable (only occasionally does the flash not happen).

A little debugging code in DragSourceContext suggests that updateCurrentCursor is being called once with 0 dropOp and 0 targetAct. This is wrong.

Comments
EVALUATION DELETED - comment was added to wrong bug report.
27-07-2006

EVALUATION My previous comment that this is fixed by 6385534 is only partially true. The visible aspect of the problem is now masked by that fix, but the problem is still there. Users inspecting the event in dropActionChanged() will still get the wrong actions. The problem with this bug is that when dropActionChanged is called, we're still receiving the old user action. And the reason on Windows seems obvious if you look at the native code in AWT_DnDDS.cpp: There are two methods: AwtDragSource::QueryContinueDrag AwtDragSource::GiveFeedback QueryContinueDrag is called by the native system to ask if DnD should continue. Then GiveFeedback is called to update the visual representation. The problem seems to stem from the fact that we call to update the actions from QueryContinueDrag. I think this should be moved to GiveFeedback. Also there is some mouse cursor code in QueryContinueDrag that is duplicated in GiveFeedback. I don't think it belongs in QueryContinueDrag. I've prototyped and attached a webrev for fixing this on Windows and it works to solve the problem.
12-04-2006

EVALUATION I see the problem in the way we set the targetAction field. Let's examine a simple scenario. 1.A user drags something on Linux from one component to another. 2.We are receiving notifications about that. 3.After each of ���mouse move��� notification (in fact ClientMessage) we update targetAction. After that we know which action could be accepted by target component. 4.If the user type some of modifier key (for instance CTRL), we handle key event. In this case we do not update targetAction and it is the same as it was set in the previous ���mouse event��� notification. 5.There is the rub. As we set targetAction for mouse move, we must update it if a modifier key was pressed because modifier key had changed drop operation. The best way to resolve the problem is to get all actions supported by target together. To get them as soon as pointer begins to slide over target component. For example: we receive from target bit mask 11 ��� COPY and PASTE so after it there is no need to ask again if we try to COPY 01 or MOVE 10 we have gotten this information. But it seems that it is difficult to do that on Windows platform. In case of Windows application we use system of notifications which is synchronous. So a developer can ask target about supported actions every time he wants and looks like there is no way to get all supported actions at once. I am looking at that and looking for solution. Another way is to ask somehow target about supported action if we handle modifier key pressing. Here we should synchronize waiting of the answer in our code. This way is not easy and not the fastest.
01-03-2006

EVALUATION The previous evaluation led me to looking into this further, thanks! I now believe this to be a duplicate of 6385534. Fixing 6385534 as I've suggested resolves this bug also.
27-02-2006

EVALUATION We update cursor twice. First time in DragSourceContext.dragOver(). Second time in DragSourceContext.dropActionChanged(). May be that is unnecessary, In DragSourceContext.dropActionChanged() drop action is COPY and target action is MOVE so set cursor in drop is not possible state. It is not correct. In case of DragSourceContext.dragOver() drop action is equal to target action (COPY). That is correct because we are pressing CTRL. I commented DragSourceContext.dropActionChanged() invocation and all works fine. I looking for the root of the problem with target action contained in DragSourceDragEvent which we recieve in DragSourceContext.dropActionChanged().
26-02-2006

EVALUATION The same situation is on Linux platform. Looks like we recieve DragSourceDragEvent containing incorrect dropAction value.
21-02-2006