Community
Participate
Working Groups
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.
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.
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)
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.
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.
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.
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.
Never mind. I managed to break it already.
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.
Silenio, please review. With the Java changes we can get rid of the NSException hack in callback.c as well.
Created attachment 173029 [details] Fix for Tree, List, & Table Took out changes from an unrelated accessibility fix.
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.
.
*** Bug 280052 has been marked as a duplicate of this bug. ***
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.
*** Bug 319260 has been marked as a duplicate of this bug. ***
*** Bug 279958 has been marked as a duplicate of this bug. ***
This bug is still fixed, but there's a better fix that should go into 3.6.2.