Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 186038

Summary: [DND] On Linux-gtk, the SWT.Activate event is not fired to the popup shell during a dragging operation
Product: [Eclipse Project] Platform Reporter: Mei Thom <mei_thom>
Component: SWTAssignee: Platform-SWT-Inbox <platform-swt-inbox>
Status: CLOSED WORKSFORME QA Contact:
Severity: normal    
Priority: P3 CC: cbeth, cchiang, cocoakevin, duongn, ericwill, snorthov
Version: 3.2.2Keywords: triaged
Target Milestone: ---   
Hardware: PC   
OS: Linux-GTK   
Whiteboard:
Attachments:
Description Flags
Sinppet to demo the missing of SWT.Activate event fired to the dropdown shell during a draggin operation on Linux none

Description Mei Thom CLA 2007-05-08 16:59:45 EDT
Build ID: N20070212-1330

Steps To Reproduce:
1. Create an application shell with only two buttons - one is a drag source and another one is a drop target.
2. When drag from the drag source button to hover on the drop target button, the drop target button displays a dropdown shell under it. 
3. Then release the mouse anywhere as a drop.
4. With the dropdown shell still opened, click on anywhere outside the dropdown shell.

Expected result: the dropdown shell is dismissed.

Actual result: On Windows, the dropdown shell is dismissed as expected. But on Linux like SLED10 and RHEL4, the dropdown shell stays opened.


More information:
1. This problem happens on Linux gtk platform like SLED10 and RHEL4.
2. I am attaching a snippet to demo the problem. Please compare the println statements on the SWT.Activate and SWT.Deactivate events fired to the dropdown shell. 
When dragging from the drag source button to hover on to the drop target button, the dragOver() codes call to display the dropdown shell, and call dropdownShell.setfocus(). This time, on Windows, we see an SWT.Activate event fired to the dropdown shell. Later when clicking on somewhere outside the dropdown shell, an SWT.Deactivate event is fired to the dropdown shell and its SWT.Deactivate event handler closes the shell. 
On the contrary, On Linux-gtk, when dragging from the drag source button to hover on the drop target button, we see the dropdown shell is displayed, but there is no SWT.Activate event fired on the dropdown shell. Later when clicking anywhere outside the dropdown shell, there is no SWT.Deactivate event triggered to the dropdown shell. So its SWT.Deactivate event handler does not execute to close the shell, and hence the shell stays opened. The only way to close the dropdown shell is to click inside the dropdown shell to fire an SWT.Activate event to the dropdown shell, then click outside the dropdown shell to trigger the SWT.Deactivate event to the dropdown shell and its handler closes the shell.

Note: when running the snippet on my SLED10 system, I got this error:
(SWT: <a number>): Gdk-CRITICAL **: gdk_event_copy: assertion 'event != NULL' failed
There was no problem at all running the snippet on Windows. I have tried a lot to fix this, but could not. However, this SWT.Activate event missing on Linux problem is not due to this error, because in our developing product, we have the similar drag and drop behavior and no problem on Linux. The only problem on Linux is that the dropdown shell did not go away after the D&D operation. That's why I am opening this bugzilla report. 

Here is the real use case:
User drags a row of document from a table widget and drags hover over a button. During this time, the dragOver() codes call to display a dropdown menu under the button. Then the user can further drag the row of document down to the menu and drop inside the menu. After the drop, on Windows, the user can click on anywhere outside the menu to close the dropdown menu. But on Linux, user clicks outside the menu but cannot close the menu. The only workaround is to click inside the menu to activate it, and then click outside the menu to close it.
Comment 1 Mei Thom CLA 2007-05-08 17:07:34 EDT
Created attachment 66364 [details]
Sinppet to demo the missing of SWT.Activate event fired to the dropdown shell during a draggin operation on Linux

Here are the println statements from running the snippet on Windows:

(When drag over on to the "Drop target" button:)
dropDownShell gets Activate event!

(When release mouse as a drop on the "Drop target" button:)
Drag source

(When mouse click outside the dropdown shell:)
dropDownShell entering Deactivate event handler and will hide the dropdown shell
dropDownShell entering Deactivate event handler and will hide the dropdown shell


Here are the println statements from running the snippet on Linux (SLED10):

(When drag over on to the "Drop target" button, only see the dropdown shell displayed and no output)

(When release mouse as a drop on the "Drop target" button:)
Drag source

(When mouse click outside the dropdown shell, no output and the dropdown shell stays opened.)
Comment 2 Steve Northover CLA 2007-05-11 08:07:41 EDT
Duong, please investigate and determine whether the missing activate event is happening when drag and drop is removed.  If so, give this report to Bogdan and CC Kevin.
Comment 3 Steve Northover CLA 2007-05-11 08:08:21 EDT
Duong, see comment in this bug report.
Comment 4 Duong Nguyen CLA 2007-05-11 12:03:39 EDT
I don't think this has anything to do with drag-and-drop. I removed all the dnd code (removed DragSource and DropTarget completely) and re-ran the example. 

Press the first button ("Drop target") and the drop down shell appears. Click anywhere outside of the drop down shell and it's still visible.
Comment 5 Duong Nguyen CLA 2007-05-11 12:05:39 EDT
Reassigning to Bogdan.
Comment 6 Kevin Barnes CLA 2007-05-11 12:10:53 EDT
The ON_TOP shell never went away for Duong because of bug 186557. With the very latest from HEAD, the shell sends the deactivate event properly.
Comment 7 Mei Thom CLA 2007-05-11 12:25:41 EDT
I just commented out all the drag and drop codes and ran it again: 
1. Click on the "Drop target" button. The dropdown shell pops up and see this
on the console:
"dropDwonShell gets Activate event!"
2. Click outside the dropdown shell (not the "Drop target" button though) and
the dropdonw shell is closed. On the console, I see this:
"dropDownShell entering Deactivate event handler and will hide the dropdown
shell"

If you click on the "Drop target" button to try to close the dropdown shell,
the dropdown shell will be closed and pops up again. Please see:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=184974
[SWT] Extra mouseDown event on second press on Button object
Comment 8 Duong Nguyen CLA 2007-05-11 16:07:01 EDT
I got the latest code from Kevin and the problem only happens during DND.

During the drag-and-drop, the drop-down-shell does not receive any focus events to activate it. The main shell always has focus. Currently, I don't have a fix for this problem.

I have some work arounds for you that may work:
1) Remove the SW.ON_TOP style from the drop-down-shell.  
OR
2) Hide the drop-down-shell when you leave the drop target
eg.
	public void dragLeave(DropTargetEvent event) { 
		if (dropDownShell.isVisible()) {
			hideDropDown(dropDownShell);
		}
	} 
OR	
3) Activate the drop-down-shell when the drag-and-drop is complated
eg.
	public void dragFinished(DragSourceEvent event) { 
		Display.getCurrent().asyncExec(new Runnable() {
			public void run() {
				dropDownShell.setActive();
			}
		});
	} 

Hopefully one of these work arounds can be used to solve your problem.

Comment 9 Mei Thom CLA 2007-05-11 21:49:19 EDT
Thank you for finding workarounds. However, 1) and 2) won't work for us and maybe 3) stands a chance:

1) We need the SWT.ON_TOP style bit for the dropdown menu because on RHEL4, when navigate down some submenu levels, the application crashes due to X Window error. Please see the error message on the Comment #4 of https://bugs.eclipse.org/bugs/show_bug.cgi?id=173335.

2) After the drop, we need to update the UI on the dropdown menu to reflect the change, so need to keep the menu opened.

3) The drag source is from other contribution components, so we cannot call dropDownShell.setActive() from dragFinished(). I did try adding to call dropDownShell.setActive() or dropDownShell.forceFocus() at the end of drop(), but still did not work. However, I did not use display.asyncExec() and don't know if this will make a difference. I'll try this way and let you know if this helps.
Comment 10 Mei Thom CLA 2007-05-14 20:55:35 EDT
The workaround #3 works. I put the codes in the workaround #3 to the end of drop() and the dropDownShell could get the Activate event. Hence the dropDownShell could get the Deactivate event later when we click on outside the dropDownShell. 
However, if I just call dropDownShell.setActive() directly instead of using  Display.getCurrent().asyncExec(), the dropDownShell still did not get the Activate event. Can you tell me why only asyncExec() worked?

Thanks!
Comment 11 Duong Nguyen CLA 2007-05-15 10:34:42 EDT
During the drag, any activate events are consumed somewhere and are ignored. The drop event is still within the scope of a drag-and-drop. When you wrapper the activate call inside the asyncExec(), the call will be deferred until after the dnd has completed.
Comment 12 Eric Williams CLA 2017-07-28 09:33:07 EDT
I can no longer reproduce this issue, closing. Please re-open with details if the issue persists.