Bug 256469 - Popup Outline Ctrl+O has non-deterministic behavior (chars are lost)
Summary: Popup Outline Ctrl+O has non-deterministic behavior (chars are lost)
Status: VERIFIED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.4.1   Edit
Hardware: PC Windows XP
: P3 major (vote)
Target Milestone: 3.5 M6   Edit
Assignee: Silenio Quarti CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-11-25 12:34 EST by Randy Hudson CLA
Modified: 2009-11-18 09:32 EST (History)
5 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Randy Hudson CLA 2008-11-25 12:34:13 EST
This is lost (degraded) functionality, starting in 3.4.1, the following keystrokes have non-deterministic behavior:

In the CU Editor:
CTRL+O,g,e,t,F,o,o

Sometimes, the popup outline appears and the prefix "getFoo" is recognized, but often, especially the first time invoking, such as when browsing around classes, any number of characters will be lost, which causes the search to fail (search for "tFoo", for example).
Comment 1 Dani Megert CLA 2008-11-26 02:44:27 EST
Yes, I've seen that too but also with other dialogs. Can you confirm that?
Comment 2 Dani Megert CLA 2008-11-28 10:35:46 EST
Tracked the issue down: if - for whatever reason - an asyncExec happens while the dialog is opened and the key is pressed, then that keyDown event is lost.

Looks somewhat similar to bug 222281.
Comment 3 Dani Megert CLA 2008-11-28 11:10:10 EST
Test Case:
1. start the snippet
2. in the shell quickly type two numbers, e.g. 9 9
   ==> dialog opens but first item instead of item starting with 9 is selected
   ==> second 9 is lost

Now, set BUG to 'false' and repeat above steps ==> event not lost, correct item selected.

/*******************************************************************************
 * Copyright (c) 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.snippets;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;


public class TreeEventsScrewedBug {

	private static final boolean BUG= true;

	public static void main(String[] args) {
		final Display display= new Display();
		display.addFilter(SWT.KeyDown, new Listener() {
			public void handleEvent(Event event) {
				System.out.println(event);
			}

		});

		final Shell shell= new Shell(display);
		shell.setSize(100, 100);

		Text b= new Text(shell, SWT.SINGLE);
		b.setSize(90, 90);
		b.addKeyListener(new KeyListener() {
			public void keyPressed(KeyEvent e) {
				Shell shell2= new Shell(shell, SWT.TOOL);
				Tree tree= new Tree(shell2, SWT.SINGLE);
				for (int i= 0; i < 2000; i++) {
					TreeItem item= new TreeItem(tree, 0);
					item.setText("" + i + " aItem " + i);
				}
				tree.setSize(100, 100);
				shell2.setSize(200, 200);
				shell2.setVisible(true);
				shell2.setFocus();
				
				// FIXME: this screws the event notification
				if (BUG)
					display.asyncExec(new Runnable() {
						public void run() {
						}
					});
			}

			public void keyReleased(KeyEvent e) {
				// TODO Auto-generated method stub

			}
		});

		shell.open();
		
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
		
		display.dispose();
	}

}

   
Comment 4 Silenio Quarti CLA 2008-12-01 13:52:45 EST
The problem happens because we post a message to the OS queue in asyncExec() in order to wake up the UI thread.

I tried implementing wake() by signaling an event (CreateEvent()) and changing sleep() to call MsgWaitForMultipleObjectsEx() instead of WaitMessage() (adding that event as an wait object). Key events are not ignored with this implementation, but it only works for the SWT event loop. Any modal loop in the OS (i.e MessageBox, etc) would not wake properly since they do not wait on our event.
Comment 5 Steve Northover CLA 2008-12-01 14:25:06 EST
This means sync/asycnExec() would be broken when ever Window runs a modal operating system loop (message box, window resize/drag, drag detect etc.)  We can't implement this solution until we have a fix for these cases.
Comment 6 Dani Megert CLA 2008-12-02 02:55:27 EST
Stopping the UI thread is not the issues for me as long as the stopped events are fired afterwards.
Comment 7 Randy Hudson CLA 2008-12-03 09:59:10 EST
Silenio, is this asyncExec behavior new? We use asyncExecs in a rich text editor to queue layouts, and keystrokes don't get lost there.

Daniel, has JDT always used asyncExec, or is this new in 3.4.1?  Just wondering what changed between 3.4.0 and 3.4.1. What does the async do here?
Comment 8 Dani Megert CLA 2008-12-03 10:08:51 EST
>Daniel, has JDT always used asyncExec, or is this new in 3.4.1?
It's not just JDT and it's not new. Same issue is in older builds too.
Comment 9 Randy Hudson CLA 2008-12-03 10:59:07 EST
The following hack to the snippet flushes the events caused by constructing the Shell and assigning focus:

	...
	shell2.setVisible(true);
	shell2.setFocus();
+	while (display.readAndDispatch());
	...
Comment 10 Randy Hudson CLA 2008-12-03 11:07:47 EST
(In reply to comment #8)
> >Daniel, has JDT always used asyncExec, or is this new in 3.4.1?
> It's not just JDT and it's not new. Same issue is in older builds too.
> 

I just tried to reproduce this problem in 3.4.0 and couldn't, even when invoking CTRL+O on OS.java, keystrokes don't get lost.
Comment 11 Dani Megert CLA 2008-12-03 11:13:47 EST
>I just tried to reproduce this problem in 3.4.0 and couldn't, even when
>invoking CTRL+O on OS.java, keystrokes don't get lost.
It does here. Might depend on how fast you and your machine really are ;-)
Comment 12 Steve Northover CLA 2008-12-03 11:57:49 EST
RE: comment #19.  I assume this "fixes" the problem too by running the key events before the asyncExec() is added?  I had tried touching the event queue way down deep in the operating system to see if this helped and it didn't.

Of course, running an event loop like this is a bad idea.
Comment 13 Dani Megert CLA 2009-02-03 09:36:10 EST
Any update on this one?
Comment 14 Steve Northover CLA 2009-02-03 13:51:28 EST
The fix that Silenio describes in comment #4 is not complete (won't work for operating system modal loops) and very dangerous.  I'll discuss it with him but I think we are out of options.
Comment 15 Randy Hudson CLA 2009-02-03 18:20:16 EST
Since the problem happens when wakeThread() is called (my interpretation of comment 4), what if you simply stop calling wakeThread()? My guess is that works unless the OS is running the event loop?
Comment 16 Steve Northover CLA 2009-02-03 18:52:06 EST
It's not that simple.  Even if you are in the UI thread, you might be running from a deferred event.  We are zeroing in on a fix ... stand by.
Comment 17 Silenio Quarti CLA 2009-02-04 09:47:13 EST
Fixed > 20090204. Please try the latest.
Comment 18 Dani Megert CLA 2009-02-06 02:14:41 EST
Verified in N20090205-2000. Thanks!
Comment 19 Mike Wilson CLA 2009-11-18 09:32:41 EST
(In reply to comment #16)
> It's not that simple.  Even if you are in the UI thread, you might be running
> from a deferred event.  We are zeroing in on a fix ... stand by.

You know, reading this bug reminds me that I've seen this pattern a lot in SWT: Problem is identified, discussed, then magically a "FIXED >xxx" comment gets added, but no details about the nature of the fix. This makes it hard for someone looking at the bug later (particularly, when it is discovered that the fix causes other issues ;-) ) to understand what was done.

If you added a sentence that pointed us in the right direction, it would make it easier for us to know where to look when trying to understand the other interactions.