Community
Participate
Working Groups
Build ID: M20070212-1330 Steps To Reproduce: 1. Open an Eclipse application which has a Button object. 2. Left mouse click on the button to display a dropdown shell under the button. 3. Left mouse click on the button one more time to try to close the dropdown shell. Result: On Linux platform (RHEL4 and SLED10), the dropdown shell closes and re-opens right away. On Windows, the dropdown shell closes. Expected result: as on Windows, user would expect the second click on the button to close the dropdown shell. More information: 1. This problem happens on linux platform. In my testing, I see it on RHEL4 and SLED10. 2. The dropdown shell has SWT.Deactivate event handler to close the shell. Usually when user clicks on anywhere outside the dropdown shell, the handler will be called to close the dropdown shell. So naturally user would expect the second click on the button will close the dropdown shell too. 3. I found that on Linux, on the second click on the button, not only the dropdown shell's SWT.Deactivate event handler is called, the button's mouseDown event handler is called too. But on Windows, only the dropdown shell's SWT.Deactivate event handler is called. Button does not catch any mouse event. 4. In SWT Button, only when the mouseUp event handler sees that there is a mouseDown event before it, then it will call listener's SWT.Selection event handler. Therefore, on Linux, on the second click on the button, since mouseDown event happens, mouseUp event will call the listener's selection handler which will open the dropdown shell again. But on Windows, on the second click on the button, there is not a mouseDown event before the mouseUp event, so the selection listener is not called to open the dropdown shell. I will attach a snippet to show the event fired on the console.
Created attachment 65531 [details] Sinppet to demo the dropdown shell re-opened on the second click on the button on Linux Here are the println statements on the event fired on two clicks on the button: On Windows: First mouse down on the Open button: Open button entering mouseDown event handler First mouse up on the Open button to display the dropdown shell: Open button entering mouseUp event handler Open button entering widgetSelected event handler and will show the dropdown shell Then second mouse down on the Open button: dropDownShell entering Deactivate event handler and will hide the dropdown shell dropDownShell entering Deactivate event handler and will hide the dropdown shell Second mouse up the Open button Open button entering mouseUp event handler As a result, the dropdown shell is closed. ============================================================================== On Linux: First mouse down on the Open button: Open button entering mouseDown event handler First mouse up on the Open button to display the dropdown shell: Open button entering mouseUp event handler Open button entering widgetSelected event handler and will show the dropdown shell (Up till here, both Windows and Linux are the same behavior) Second mouse down on the Open button: dropDownShell entering Deactivate event handler and will hide the dropdown shell Open button entering mouseDown event handler Second mouse up the Open button: Open button entering mouseUp event handler Open button entering widgetSelected event handler and will show the dropdown shell As a result, the dropdown shell is still opened.
Bogdan, can you conifrm this bug?
3.3M7 It turns out that there is a bug here but the bug is actually on Windows - Linux is actually doing the right thing here. Running your snippet on Windows, clicking on the Open button when the on_top shell is visible causes the on_top shell to close but something eats the mouse down event. So the 'extra' mouseDown event you initially reported as seeing on Linux is actually correct and you should be getting one on Windows as well. Also, a few notes about your snippet: 1) You can work around this bug by running the hide code in an asyncExec 2) DROP_DOWN is not a valid style hint for a shell - it has no effect on it 3) You should not use Device.DEBUG=true in your snippets (or code) as it forces the X server to run synchronously We're currently trying to find out what's happened to the mouseDown event on Windows.
Thanks for all this information! We think that the problem is on Linux because we want the behavior on Windows, which means clicking on the button when the dropdown window is visible should close the dropdown window. 1. We can try the asyncExec. 2. We use the DROP_DOWN style bit to get a shadow around the dropdown shell. 3. I got the suggestion in another bugzilla report to use Device.DEBUG=true in order to get more debug info. And I don't see the difference between using it and not using it. Thanks for telling me the difference.
Mei Thom, have you found a path through this that works for you?
Chih-Hung, can you take a look at this and provide a response?
To clarify.. we are happy with the way it works on Windows. We want Linux to behave the same way as Windows. Are you saying that is not the right approach and Linux is working as expected?
We solve this issue by changing our design. The SWT.Deactivate event will not hide the Shell if it is caused by that Button and the SWT.Selection event will hide/show the Shell depend on the state.
Glad to hear you have a workaround. I understand that this is a consistency problem between platforms. The real solution here is to find out why Win32 is eating the SelectionEvent on the second mouse down. Moving over to Steve.
This code works around the problem (the behavior is the same on Windows and Linux): import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Device; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; public class PR_184974 { static Display display = null; static Shell shell = null; static Button button = null; static Shell dropDownShell = null; public static void main(String[] args) { Device.DEBUG = true; display = new Display(); shell = new Shell(display); shell.setLayout(new RowLayout()); // create the drop down shell dropDownShell = new Shell(shell, SWT.ON_TOP | SWT.DROP_DOWN); dropDownShell.setLayout(new RowLayout()); dropDownShell.setVisible(false); dropDownShell.addListener(SWT.Deactivate, new Listener() { public void handleEvent(Event event) { System.out.println("dropDownShell entering Deactivate event handler and will hide the dropdown shell"); display.asyncExec(new Runnable () { public void run () { hideDropDown(); } }); } }); dropDownShell.addListener(SWT.Close, new Listener() { public void handleEvent(Event event) { hideDropDown(); } }); // create the button button = new Button(shell, SWT.PUSH); button.setText("Open"); button.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { if (!dropDownShell.isVisible()) { System.out.println("Open button entering widgetSelected event handler and will show the dropdown shell"); if (dropDownShell != null && !dropDownShell.isDisposed()) { showDropDown(); } } } }); button.addMouseListener(new MouseAdapter() { public void mouseDown(MouseEvent e) { System.out.println("Open button entering mouseDown event handler"); super.mouseDown(e); } public void mouseUp(MouseEvent e) { System.out .println("Open button entering mouseUp event handler"); super.mouseUp(e); } }); shell.setSize(300, 300); shell.addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { if (dropDownShell != null && !dropDownShell.isDisposed()) { dropDownShell.dispose(); dropDownShell = null; } } }); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); } private static void showDropDown() { if (dropDownShell != null && !dropDownShell.isDisposed()) { dropDownShell.setText("This is a drop down shell"); dropDownShell.setSize(100, 200); Rectangle buttonRect = button.getBounds(); Point p = button.getParent().toDisplay(new Point(buttonRect.x, buttonRect.y + buttonRect.height)); dropDownShell.setLocation(p.x, p.y); dropDownShell.setVisible(true); dropDownShell.setFocus(); } } private static void hideDropDown() { dropDownShell.setVisible(false); } }
To be clear, the selection event is delivered and the shell pops back up (which is unwanted behavior for the code snippet, but correct).
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. As such, we're closing this bug. If you have further information on the current state of the bug, please add it and reopen this bug. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant. -- The automated Eclipse Genie.