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

Bug 313208

Summary: Shell focus problems after closing sub-dialog
Product: [Eclipse Project] Platform Reporter: Markus Keller <markus.kell.r>
Component: SWTAssignee: Scott Kovatch <skovatch>
Status: RESOLVED FIXED QA Contact: Silenio Quarti <Silenio_Quarti>
Severity: normal    
Priority: P3 CC: daniel_megert, derkanzler, h1055071, shylu_hv, skovatch
Version: 3.6   
Target Milestone: 3.7 M1   
Hardware: PC   
OS: Mac OS X   
Whiteboard:
Attachments:
Description Flags
Possible fix
none
Bigger fix
none
Fix for Tree, List, & Table
none
Fix for Tree, List, & Table none

Description Markus Keller CLA 2010-05-17 13:55:21 EDT
I20100516-0800 Cocoa (works fine on WinXP)

Steps in the SDK:
- in a new project, open Properties dialog and go to the Builders page
- click New
- click OK
- click OK
- double-click the newly created Ant builder
- click Cancel

=> now, the Properties dialog is broken:
- Tab or Ctrl+Tab don't move the focus
- when you Command+Tab to another application, the Properties dialog still looks active (colored trim buttons), but it isn't. When you try to Command+Tab back to the dialog, it doesn't take focus.
- when you try to click OK or Cancel, the first click does not press the button. But the second click works as expected.

I didn't find a good pattern to tell where or why this happens, but it happens consistently for some dialogs. Another case in the SDK is when you add a resource filter and then double-click to edit a filter.
Comment 1 Scott Kovatch CLA 2010-06-02 19:42:03 EDT
Just a guess, but my hunch is that this is triggered by a modal dialog-atop-another modal dialog situation. This could also be related to focus restoration, which isn't correct right now.
Comment 2 Scott Kovatch CLA 2010-06-03 17:20:03 EDT
Same problem as bug 279958. When the dialog is opened we are still inside the NSTableView's tracking loop, which needs an exception or mouse up to stop tracking.

There are two possible problems here: Normally the double-click action doesn't fire until the second mouse up is received within the double click duration. SWT fires the MouseDoubleClick on the second mouse down, not the second mouse up. The other possibility is that we aren't in NSEventTrackingRunLoopMode when the Display is in sleep(), so the mouseUp is lost.

Here's the stack trace when we're in this state:

"main" prio=6 tid=0000000013001000 nid=0xa059d4e0 runnable [00000000bfffb000]
   java.lang.Thread.State: RUNNABLE
	at org.eclipse.swt.internal.cocoa.OS.objc_msgSend_bool(Native Method)
	at org.eclipse.swt.internal.cocoa.NSRunLoop.runMode(NSRunLoop.java:42)
	at org.eclipse.swt.widgets.Display.sleep(Display.java:4193)
	at org.eclipse.jface.window.Window.runEventLoop(Window.java:826)
	at org.eclipse.jface.window.Window.open(Window.java:801)
	at org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationsDialog.open(LaunchConfigurationsDialog.java:1133)
	at org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationPropertiesDialog.open(LaunchConfigurationPropertiesDialog.java:203)
	at org.eclipse.debug.ui.DebugUITools.openLaunchConfigurationPropertiesDialog(DebugUITools.java:448)
	at org.eclipse.debug.ui.DebugUITools.openLaunchConfigurationPropertiesDialog(DebugUITools.java:425)
	at org.eclipse.ui.externaltools.internal.ui.BuilderPropertyPage.editConfiguration(BuilderPropertyPage.java:632)
	at org.eclipse.ui.externaltools.internal.ui.BuilderPropertyPage.handleEditButtonPressed(BuilderPropertyPage.java:710)
	at org.eclipse.ui.externaltools.internal.ui.BuilderPropertyPage.access$4(BuilderPropertyPage.java:683)
	at org.eclipse.ui.externaltools.internal.ui.BuilderPropertyPage$5.handleEvent(BuilderPropertyPage.java:334)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
	at org.eclipse.swt.widgets.Display.sendEvent(Display.java:3776)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1367)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1390)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1375)
	at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:1187)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3622)
	at org.eclipse.swt.widgets.Display.applicationNextEventMatchingMask(Display.java:4479)
	at org.eclipse.swt.widgets.Display.applicationProc(Display.java:4739)
	at org.eclipse.swt.internal.cocoa.OS.objc_msgSendSuper(Native Method)
	at org.eclipse.swt.widgets.Widget.callSuper(Widget.java:220)
	at org.eclipse.swt.widgets.Widget.mouseDownSuper(Widget.java:1025)
	at org.eclipse.swt.widgets.Table.mouseDownSuper(Table.java:1930)
	at org.eclipse.swt.widgets.Widget.mouseDown(Widget.java:1021)
	at org.eclipse.swt.widgets.Control.mouseDown(Control.java:2240)
	at org.eclipse.swt.widgets.Table.mouseDown(Table.java:1912)
	at org.eclipse.swt.widgets.Display.windowProc(Display.java:4976)
	at org.eclipse.swt.internal.cocoa.OS.objc_msgSendSuper(Native Method)
	at org.eclipse.swt.widgets.Widget.callSuper(Widget.java:220)
	at org.eclipse.swt.widgets.Widget.windowSendEvent(Widget.java:1943)
	at org.eclipse.swt.widgets.Shell.windowSendEvent(Shell.java:2008)
	at org.eclipse.swt.widgets.Display.windowProc(Display.java:5040)
	at org.eclipse.swt.internal.cocoa.OS.objc_msgSendSuper(Native Method)
	at org.eclipse.swt.widgets.Display.applicationSendEvent(Display.java:4582)
	at org.eclipse.swt.widgets.Display.applicationProc(Display.java:4659)
	at org.eclipse.swt.internal.cocoa.OS.objc_msgSend(Native Method)
	at org.eclipse.swt.internal.cocoa.NSApplication.sendEvent(NSApplication.java:115)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3274)
	at org.eclipse.jface.window.Window.runEventLoop(Window.java:825)
	at org.eclipse.jface.window.Window.open(Window.java:801)
	at org.eclipse.ui.dialogs.PropertyDialogAction.run(PropertyDialogAction.java:157)
	at org.eclipse.jface.action.Action.runWithEvent(Action.java:498)
	at org.eclipse.jface.commands.ActionHandler.execute(ActionHandler.java:119)
	at org.eclipse.core.commands.Command.executeWithChecks(Command.java:476)
	at org.eclipse.core.commands.ParameterizedCommand.executeWithChecks(ParameterizedCommand.java:508)
	at org.eclipse.ui.internal.handlers.HandlerService.executeCommand(HandlerService.java:169)
	at org.eclipse.ui.internal.keys.WorkbenchKeyboard.executeCommand(WorkbenchKeyboard.java:468)
	at org.eclipse.ui.internal.keys.WorkbenchKeyboard.press(WorkbenchKeyboard.java:786)
	at org.eclipse.ui.internal.keys.WorkbenchKeyboard.processKeyEvent(WorkbenchKeyboard.java:885)
	at org.eclipse.ui.internal.keys.WorkbenchKeyboard.filterKeySequenceBindings(WorkbenchKeyboard.java:567)
	at org.eclipse.ui.internal.keys.WorkbenchKeyboard.access$3(WorkbenchKeyboard.java:508)
	at org.eclipse.ui.internal.keys.WorkbenchKeyboard$KeyDownFilter.handleEvent(WorkbenchKeyboard.java:123)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
	at org.eclipse.swt.widgets.Display.filterEvent(Display.java:1031)
	at org.eclipse.swt.widgets.Display.sendEvent(Display.java:3775)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1367)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1390)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1375)
	at org.eclipse.swt.widgets.Widget.sendKeyEvent(Widget.java:1404)
	at org.eclipse.swt.widgets.Widget.sendKeyEvent(Widget.java:1400)
	at org.eclipse.swt.widgets.Tree.sendKeyEvent(Tree.java:2431)
	at org.eclipse.swt.widgets.Control.keyDown(Control.java:2095)
	at org.eclipse.swt.widgets.Composite.keyDown(Composite.java:600)
	at org.eclipse.swt.widgets.Display.windowProc(Display.java:4978)
	at org.eclipse.swt.internal.cocoa.OS.objc_msgSendSuper(Native Method)
	at org.eclipse.swt.widgets.Widget.callSuper(Widget.java:220)
	at org.eclipse.swt.widgets.Widget.windowSendEvent(Widget.java:1943)
	at org.eclipse.swt.widgets.Shell.windowSendEvent(Shell.java:2008)
	at org.eclipse.swt.widgets.Display.windowProc(Display.java:5040)
	at org.eclipse.swt.internal.cocoa.OS.objc_msgSendSuper(Native Method)
	at org.eclipse.swt.widgets.Display.applicationSendEvent(Display.java:4582)
	at org.eclipse.swt.widgets.Display.applicationProc(Display.java:4659)
	at org.eclipse.swt.internal.cocoa.OS.objc_msgSend(Native Method)
	at org.eclipse.swt.internal.cocoa.NSApplication.sendEvent(NSApplication.java:115)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3274)
	at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2629)
	at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2593)
	at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2427)
	at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:670)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:663)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:115)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:369)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:619)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:574)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1407)
Comment 3 Scott Kovatch CLA 2010-06-03 18:29:25 EDT
Created attachment 171042 [details]
Possible fix

Deferred events should only be processed in the default runloop mode. This patch fixes this problem and bug 279958. It should also fix bug 300918, but I haven't been able to install an SWT with this fix locally yet.
Comment 4 Scott Kovatch CLA 2010-06-04 14:30:34 EDT
Interestingly enough, this is the real fix for bug 308844.

Unfortunately it prevents MouseDown and MouseUp from being fired until the mouse is released. The bug only happens with NSTableView and subclasses (i.e., Table and Tree) so I should be able to refine it a bit.
Comment 5 Scott Kovatch CLA 2010-06-28 18:29:40 EDT
Created attachment 172977 [details]
Bigger fix

This is a more targeted fix but has more code. If a Tree, Table or List is being tracked and its containing window loses key status, the next time the window regains key status it will create an NSLeftMouseUp event for Display.applicationNextEventMatchingMask to return when the next request for an event in NSEventTrackingRunLoopMode happens.
Comment 6 Scott Kovatch CLA 2010-06-28 18:30:50 EDT
Silenio, I think we should go with this. It's the least invasive fix I can think of right now -- it won't disrupt the generation of SWT events for the control.
Comment 7 Scott Kovatch CLA 2010-06-28 18:32:41 EDT
Never mind. I managed to break it already.
Comment 8 Scott Kovatch CLA 2010-06-29 13:46:05 EDT
Created attachment 173026 [details]
Fix for Tree, List, & Table

This is the way to go. Defer sending of the MouseDoubleClick event until after the last mouse up for Tree, Table, and List, which are all NSOutlineView-based. This has the nice benefit that there's no visual difference in behavior to the user, as nothing happens until the second mouse-up anyway.

For non-NSTableView-based controls there's no change in behavior, but if needed we can add it pretty easily.
Comment 9 Scott Kovatch CLA 2010-06-29 13:46:53 EDT
Silenio, please review. With the Java changes we can get rid of the NSException hack in callback.c as well.
Comment 10 Scott Kovatch CLA 2010-06-29 13:56:42 EDT
Created attachment 173029 [details]
Fix for Tree, List, & Table

Took out changes from an unrelated accessibility fix.
Comment 11 Scott Kovatch CLA 2010-07-15 18:28:22 EDT
Fixed in HEAD > 20100715. It fixes this plus all of the related bugs that I've encountered so far, so I want it to get some wider testing.

If we decide it's holding up well we'll put it into 3.6.1.
Comment 12 Scott Kovatch CLA 2010-07-15 18:28:42 EDT
.
Comment 13 Scott Kovatch CLA 2010-07-15 18:29:02 EDT
*** Bug 280052 has been marked as a duplicate of this bug. ***
Comment 14 Silenio Quarti CLA 2010-07-16 09:45:51 EDT
In Display.applicationSendTrackingEvent(), SWT.MouseDoubleClick should be sent before SWT.MouseDown to keep the same event order of the other platforms.

I agree, let us see how this holds before back porting to 3.6.1.
Comment 15 Markus Keller CLA 2010-07-29 10:37:27 EDT
*** Bug 319260 has been marked as a duplicate of this bug. ***
Comment 16 Scott Kovatch CLA 2010-08-17 16:34:15 EDT
*** Bug 279958 has been marked as a duplicate of this bug. ***
Comment 17 Scott Kovatch CLA 2010-10-18 23:28:33 EDT
This bug is still fixed, but there's a better fix that should go into 3.6.2.