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

Bug 480318

Summary: SWT Menu does not fire Selection Event when touch display is enabled
Product: [Eclipse Project] Platform Reporter: Andreas Muelder <Andreas.Muelder>
Component: SWTAssignee: Conrad Groth <info>
Status: RESOLVED FIXED QA Contact: Andreas Muelder <Andreas.Muelder>
Severity: blocker    
Priority: P3 CC: info, niraj.modi, p.beauvoir
Version: 4.6   
Target Milestone: 4.6 M5   
Hardware: PC   
OS: Windows 10   
See Also: https://git.eclipse.org/r/63376
https://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?id=f88d45cfaff9ef6d91ef0a233e070546bdf5acdc
Whiteboard:
Bug Depends on:    
Bug Blocks: 493795    

Description Andreas Muelder CLA 2015-10-21 11:39:38 EDT
swt.Menu does not work under windows under Windows 10 with Touch Display, no selection event is raised. The attached snipped prints nothing.

When I open the Windows device manager/human Interface Devices and disable HID-compliant Touch Screen, "Menu Item" is printed as one would expect.

package org.eclipse.swt.snippets;

import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;

public class Snippet131 {
public static void main (String [] args) {
	final Display display = new Display ();
	final Shell shell = new Shell (display);
	shell.addListener (SWT.MenuDetect, new Listener () {
		@Override
		public void handleEvent (Event event) {
			Menu menu = new Menu (shell, SWT.POP_UP);
			MenuItem item = new MenuItem (menu, SWT.PUSH);
			item.setText ("Menu Item");
			
			item.addListener (SWT.Selection, new Listener () {
				@Override
				public void handleEvent (Event e) {
					System.out.println ("Item Selected");
				}
			});
			menu.setLocation (event.x, event.y);
			menu.setVisible (true);
			while (!menu.isDisposed () && menu.isVisible ()) {
				if (!display.readAndDispatch ()) display.sleep ();
			}
			menu.dispose ();
		}
	});
	shell.pack ();
	shell.open ();
	while (!shell.isDisposed ()) {
		if (!display.readAndDispatch ()) display.sleep ();
	}
	display.dispose ();
}
}
Comment 1 Phil Beauvoir CLA 2015-11-30 09:13:13 EST
Seeing this in Eclipse 4.4
Comment 2 Conrad Groth CLA 2015-12-29 10:21:29 EST
I can also reproduce it. Surprisingly it works, if the popup item is larger than the shell and the item is clicked or touched outside the bounds of the shell.
I will further analyze that.
Comment 3 Conrad Groth CLA 2015-12-30 07:19:49 EST
I analyzed the problem and finally found one issue (in the snippet, not SWT). The readAndDispath loop will run, until the menu gets hidden. Right after that the menu is disposed, which means, no listeners will be informed anymore.
The corresponding message for the clicked/touched item from the OS will be received by the Display, but it is not dispatched to already disposed widgets. The difference between clicking the item inside or outside the bounds of the shell is, that inside the bounds some more messages are sent by the OS, so that the SELECTED message isn't dispatched anymore. Ouside the bounds of the shell, the SELECTED message comes "faster" and can be dispatched.

The solution is, to dispatch all unread messages, before the menu is disposed: 
> 			while (!menu.isDisposed () && menu.isVisible ()) {
> 				if (!display.readAndDispatch ()) display.sleep ();
> 			}
while (display.readAndDispatch ());
> 			menu.dispose ();

> When I open the Windows device manager/human Interface Devices and disable
> HID-compliant Touch Screen, "Menu Item" is printed as one would expect.
I tried to reproduce the problem with and without the above mentioned solution with my Microsoft Surface Pro 3. I see no difference between touching and clicking the menu item. Can you try to reproduce the issue WITH the solution?
Comment 4 Eclipse Genie CLA 2015-12-30 07:27:08 EST
New Gerrit change created: https://git.eclipse.org/r/63376
Comment 5 Andreas Muelder CLA 2016-01-12 04:50:15 EST
Conrad, thanks for analyzing, the snippet works as expected with your provided workaround. 

I added the missing while (display.readAndDispatch ()); to the GMF PopupMenu were the problem originates.

https://bugs.eclipse.org/bugs/show_bug.cgi?id=485619
Comment 6 Niraj Modi CLA 2016-01-25 05:21:35 EST
(In reply to Andreas Muelder from comment #5)
> Conrad, thanks for analyzing, the snippet works as expected with your
> provided workaround. 
> 
> I added the missing while (display.readAndDispatch ()); to the GMF PopupMenu
> were the problem originates.
> 
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=485619

Don't have access to a Windows 10 machine with Touch Display to test.
So, going by Andreas confirmation for the proposed gerrit patch and will merge the changes to master shortly.
Comment 8 Niraj Modi CLA 2016-01-25 05:44:08 EST
(In reply to Eclipse Genie from comment #7)
> Gerrit change https://git.eclipse.org/r/63376 was merged to [master].
> Commit:
> http://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/
> ?id=f88d45cfaff9ef6d91ef0a233e070546bdf5acdc

Thanks Conrad/Andreas for your contributions. Resolving now.