Bug 201154 - Add support in SWT for event-based document opening
Summary: Add support in SWT for event-based document opening
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.3   Edit
Hardware: PC All
: P3 enhancement with 6 votes (vote)
Target Milestone: 3.6 M5   Edit
Assignee: Kevin Barnes CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 273612 (view as bug list)
Depends on:
Blocks: 4922 178927 252646
  Show dependency tree
 
Reported: 2007-08-24 19:07 EDT by Mike Schrag CLA
Modified: 2010-06-18 16:52 EDT (History)
22 users (show)

See Also:


Attachments
OS X equinox launcher patch (4.42 KB, patch)
2007-08-25 20:21 EDT, Mike Schrag CLA
no flags Details | Diff
OS X SWT patch (9.68 KB, patch)
2007-08-25 20:21 EDT, Mike Schrag CLA
no flags Details | Diff
OS X equinox launcher patch (turns into commandline args) (8.27 KB, patch)
2007-08-29 10:03 EDT, Mike Schrag CLA
no flags Details | Diff
Updated (combined) patch against latest SWT (12.93 KB, patch)
2007-11-21 01:52 EST, Mike Schrag CLA
no flags Details | Diff
SWT v3555a Cococa patch for document reopen event (8.68 KB, application/octet-stream)
2009-10-21 08:15 EDT, Mike Schrag CLA
no flags Details
R351 Equinox Carbon/Cocoa patch (10.60 KB, patch)
2009-10-21 08:16 EDT, Mike Schrag CLA
no flags Details | Diff
R351 Equinox 32/64bit fat binaries (126.33 KB, application/zip)
2009-10-21 08:16 EDT, Mike Schrag CLA
no flags Details
10.5 fat binary build of the equinox launcher (126.78 KB, application/zip)
2009-10-21 12:26 EDT, Mike Schrag CLA
no flags Details
10.5/10.6 fat binary build of the equinox launcher (124.69 KB, application/octet-stream)
2009-11-04 15:12 EST, Mike Schrag CLA
no flags Details
R351 Equinox Carbon/Cocoa patch (Leopard/Snow Leopard compat) (12.87 KB, patch)
2009-11-04 15:15 EST, Mike Schrag CLA
no flags Details | Diff
SWT patch (119.12 KB, patch)
2009-11-30 16:30 EST, Kevin Barnes CLA
no flags Details | Diff
SWT patch (cleaned up) (112.47 KB, patch)
2010-01-13 12:23 EST, Kevin Barnes CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Mike Schrag CLA 2007-08-24 19:07:31 EDT
Build ID: All

Steps To Reproduce:
I assume there are equivalent API's on other OS's, but on Mac OS X, there are specific Apple Events (kAEOpenDocuments) that you must handle to have an SWT(/RCP) app open documents from the file manager.  Currently SWT does not provide an API for accessing these events, so it's impossible to create a document-based SWT app that properly integrates with the OS.

More information:
I have patches for supporting:
1) Listening for the kAEOpenDocuments event when the app is already running, and firing a new event SWT ExternalOpen containing the list of specified files.

2) The nastier part (that I also have a patch for) is the case where you double-click documents from Finder BEFORE the app is running.  This will launch the app, but currently the Equinox launcher consumes apple events before SWT is running.  On OS X, I patched the equinox executable to support Apple Events, and I can capture the list of documents that were opened from Finder.

3) The final step is where I am a bit stuck.  Equinox launcher now has the list of the documents that were opened, but the VM has already been launched, so I can't "trick" things into looking like command-line params to the VM.  This list of documents has to somehow get from equinox over to SWT so that SWT can fire the new ExternalOpen event  in response to the app launch, but I don't see any precedent for passing data like this.  A couple options seem possible -- first might be to delay launching the VM just long enough to get the openDocuments or openApplication call, and then append the document list to the VM parameters, which would make the list of documents accessible to an application (still sort of wonky for SWT to access, though).  The other might be to stuff the list of opened paths into System properties with a known key that SWT can look at also.  I'm open to suggestions here?

4) This would obviously need to be written on the other OS's.  I THINK that on Linux and Win, double-clicked documents end up on the commandline for the app.  I don't know how Linux/Win respond when you double-click documents and the app is already open, but I presume there is some OS notification event that fires that is similar to how OS X works.  If it IS true that Lin/Win both pass the opening documents on commandline, then the variation of #3 where we delay launching just slightly to get the kAEOpenDocuments/OpenApp event might make the most sense, because it will make the OS X environment behave consistently with the other platforms.
Comment 1 Matthew Hall CLA 2007-08-24 21:55:13 EDT
please attach your patches so we can see what the proposed API looks like
Comment 2 Mike Schrag CLA 2007-08-25 20:21:19 EDT
Created attachment 76977 [details]
OS X equinox launcher patch
Comment 3 Mike Schrag CLA 2007-08-25 20:21:49 EDT
Created attachment 76978 [details]
OS X SWT patch
Comment 4 Mike Schrag CLA 2007-08-25 20:26:10 EDT
There's actually very little additional public API added at the moment.  Currently it's only a new event type (ExternalOpen, id = 43).  Obviously the decisions on exactly how information should be passed from the launcher into SWT to be able to fire the event about files to open at startup may require additional API to exist.

These two patches add a couple things:
1) OS X equinox launcher now has support for listening for Apple Events, and it specifically catches openApplication and openDocuments events (though does nothing with them at the moment other than parse out the list of file paths that were selected).  This catches the events that are fired when the app is launched.  If the app is launched by double-clicking the application icon, openApplication is fired.  If the application is launched by double-clicking files of the types associated with the app (and the app is not already running), openDocuments is fired.

2) OS X SWT implementation now also listens for the openDocuments apple event.  If the app is already running, openDocuments is fired if you double-click on another file of a type that is associated with the application.
Comment 5 Mike Schrag CLA 2007-08-29 10:03:21 EDT
Created attachment 77255 [details]
OS X equinox launcher patch (turns into commandline args)

I checked on Windows, and it is definitely the case that opening a file with an RCP app passes the selected file(s) on the commandline.  I have modified the OS X launcher process to block VM startup until the openDocuments event is received (which is a very very short time), and then shoves them into the front of the program arguments.  This should bring the Eclipse/RCP startup process on OS X into parity with Windows and Linux.  This means that on OS X, you can now call:

      String[] args = EclipseEnvironmentInfo.getDefault().getNonFrameworkArgs();

and the first entries will be opened documents.  This equinox patch is really a separate beast from the SWT patch (which provides runtime support for OS-opened-documents notifying an already-running RCP/Eclipse app), and I'm wondering if this should be split into two separate bugs?
Comment 6 Chris Aniszczyk CLA 2007-08-31 12:25:28 EDT
Cool stuff, you may want to comment on bug 178927 which is kind of tracking this whole issue of passing things into a running eclipse instance.
Comment 7 Steve Northover CLA 2007-09-10 23:50:14 EDT
I've been on vacation and am finally getting back to work.  I am interested, but incredibly swamped.

Windows has the concept of finding a running instance rather than starting another process but not (that I am aware of), the idea of passing arguments to that instance.  As far as I know, GTK doesn't have either concept.  I'm wondering whether it is ok to offer the API but fail on other platforms.
Comment 8 Chris Aniszczyk CLA 2007-09-26 13:28:19 EDT
Andrew :D
Comment 9 Mike Schrag CLA 2007-11-21 01:52:14 EST
Created attachment 83404 [details]
Updated (combined) patch against latest SWT

Here's the latest version of this patch updated against HEAD ...
Comment 10 Steve Northover CLA 2008-02-27 08:01:03 EST
This is really interesting but fell off a cliff for 3.4.  I'm wondering if it is too Mac specific for a general API?
Comment 11 Mike Schrag CLA 2008-02-27 09:17:49 EST
I have to believe that other OS's have equivalent events to OS X ...  On Windows, If I have Word already open and I double-click another word document, Wndows somehow opens that in the existing Word instance, right?

From the SWT perspective, the API is pretty generalized -- You basically just get an array of paths to open if your OS is capable of firing such an event.  The nice part is that even if your OS doesn't support this mechanism, it doesn't actually cause problems, as it's really a "nice-to-have" behavior.  If you don't support it, the even will just never fire, and you would never be the wiser.

Linux, I have NO idea on.  I have to believe GTK has some notification for this as well, but I've really just never looked.

By the way, I have the updated patch for this, but I BELIEVE the only thing that changed is the count of procs in the native proc array.
Comment 12 Mike Schrag CLA 2009-10-20 13:16:18 EDT
I have a Cocoa port of this and the corresponding equinox launcher code for double-clicking from finder if there's any interesting
Comment 13 Jordi Boehme Lopez CLA 2009-10-21 07:38:59 EDT
Hey Mike,

I'm interested on your patch (or even better an already compiled launcher) for the case where you
double-click documents from Finder BEFORE the app is running.
I think a SWT API is not necessarily needed. Commandline args or a systempropery should do the trick.

Do you have this at hand?
Comment 14 Mike Schrag CLA 2009-10-21 08:15:27 EDT
Created attachment 150098 [details]
SWT v3555a Cococa patch for document reopen event
Comment 15 Mike Schrag CLA 2009-10-21 08:16:02 EDT
Created attachment 150099 [details]
R351 Equinox Carbon/Cocoa patch
Comment 16 Mike Schrag CLA 2009-10-21 08:16:21 EDT
Created attachment 150100 [details]
R351 Equinox 32/64bit fat binaries
Comment 17 Mike Schrag CLA 2009-10-21 08:21:21 EDT
(In reply to comment #13)
> Hey Mike,
> 
> I'm interested on your patch (or even better an already compiled launcher) for
> the case where you
> double-click documents from Finder BEFORE the app is running.
> I think a SWT API is not necessarily needed. Commandline args or a
> systempropery should do the trick.
> 
> Do you have this at hand?

The equinox implementation does, in fact, push onto the commandline args. I access them in my RCP apps' WorkbenchAdvisor.postStartup method, where you can call:

String[] args = EclipseEnvironmentInfo.getDefault().getNonFrameworkArgs();

You can loop over them, skipping Eclipse args, and the ones on the end will be the ones sent at startup. 

However, SWT API is required to support document reopening, where your user double-clicks on a file when your app is already running. I added support for listening for the necessary apple events, and I added a new SWT event "ExternalOpen" that has an event.data containing the array of filenames.

The nice part is that in Cocoa 3.5.1, I could implement the enhancements entirely in Java, vs the Carbon version required a bunch of C junk. I didn't bother doing the Carbon SWT part of this bug because I only use Cocoa now.
Comment 18 Jordi Boehme Lopez CLA 2009-10-21 10:07:09 EDT
Thanks a lot for your work.

But I get an error:

dyld: Symbol not found: _OBJC_CLASS_$_NSURL
  Referenced from: /Users/jordi/Desktop/RCP App/RCP App.app/Contents/MacOS/eclipse
  Expected in: /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
Trace/BPT trap

Any Idea how to fix that?
Comment 19 Mike Schrag CLA 2009-10-21 10:33:48 EDT
Are you on a 3.5.1-based RCP app? That's what this is all built against. Did you put replace the launcher plugins as well?  Did you rename the executable I provided to match whatever name your app expects (i.e. that it matches the ini file). In your app.ini file, the launcher.library should also match the version that was provided here. I honestly don't know why that is failing. I've run this on two different machines in 32 and 64bit without any problems.  It's complaining about NSURL, too, which doesn't really make any sense.

Can you "otool -L eclipse" on your system and see if it says anything weird?

Also, are you on Snow Leopard or Leopard?
Comment 20 Jordi Boehme Lopez CLA 2009-10-21 11:07:58 EDT
It is a 3.5.1 based app. I renamed and replaced the executable (I changed it for the bugzilla comment), I replaced the launcher plugins as well (as the version did not change) and there was no need to change the "launcher.library" property as the version did not change.

I'm on Leopard (10.5), using Cocoa on my iMac here at the Office (I'll check it with Snow Leo at home this evening).

"otool -L launcher" returns the following:
Macintosh:MacOS jordi$ otool -L launcher
launcher:
	/System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 15.0.0)
	/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 103.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 124.1.1)
	/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 227.0.0)
	/System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices (compatibility version 1.0.0, current version 44.0.0)
	/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 550.0.0)
	/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices (compatibility version 1.0.0, current version 38.0.0)
	/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 751.0.0)
	/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 1038.11.0)

Any ideas?
Comment 21 Mike Schrag CLA 2009-10-21 11:24:31 EDT
yeah i just checked on leopard and got the same thing.  i must have linked against 10.6 api's or something. let me check my build.
Comment 22 Mike Schrag CLA 2009-10-21 12:26:53 EDT
Created attachment 150134 [details]
10.5 fat binary build of the equinox launcher

Yeah, the equinox launcher build script doesn't specify the 10.5 SDK, so it was building with the SL SDK.  See the patch on Bug 292922
Comment 23 Jordi Boehme Lopez CLA 2009-10-22 06:00:29 EDT
The binaries work now. The application launches, but I still get no information of the file that was opened from finder.
I tried String[] args = EclipseEnvironmentInfo.getDefault().getNonFrameworkArgs();
and other API, like context.getArguments() ... but no luck. There is still no filename.

Am I missing something?
Comment 24 Mike Schrag CLA 2009-10-22 07:48:42 EDT
Does your Info.plist have a CFBundleDocumentTypes section?  This is from Entity Modeler's:

        <key>CFBundleDocumentTypes</key>
                <array>
                        <dict>
                                <key>CFBundleTypeExtensions</key>
                                        <array>
                                                <string>eomodel</string>
                                                <string>eomodeld</string>
                                        </array>

                                <key>CFBundleTypeIconFile</key>
                                        <string>EOModel.icns</string>

                                <key>CFBundleTypeName</key>
                                        <string>Apple EOModel File</string>

                                <key>CFBundleTypeRole</key>
                                        <string>Editor</string>

                                <key>LSIsAppleDefaultForType</key>
                                        <true/>

                                <key>LSTypeIsPackage</key>
                                        <true/>
                        </dict>
                </array>
Comment 25 Jordi Boehme Lopez CLA 2009-10-22 07:58:51 EDT
Yes, my Info.plist hast that kind of information (I am able to doubleclick the .yim file from the finder to make the RCP app start)

	<key>CFBundleDocumentTypes</key>
	<array>
		<dict>
			<key>LSIsAppleDefaultForType</key>
			<true/>
			<key>LSTypeIsPackage</key>
			<false/>
			<key>CFBundleTypeIconFile</key>
			<string>InstallProfile.icns</string>
			<key>CFBundleTypeMIMETypes</key>
			<array>
				<string>application/yim-template</string>
			</array>
			<key>CFBundleTypeExtensions</key>
			<array>
				<string>yim</string>
			</array>
			<key>CFBundleTypeName</key>
			<string>Yoxos Install Profile</string>
			<key>CFBundleTypeRole</key>
			<string>Editor</string>
		</dict>
	</array>
Comment 26 Mike Schrag CLA 2009-10-22 08:11:33 EDT
And you're sure it's launching the .app you expect?  I've been testing before and I've had multiple copies of my RCP app on the machine, and OS X can sometimes get confused about which one is the one to use. Make sure you empty your trashcan of old ones, etc.

You can grab http://webobjects.mdimension.com/wolips/releases/Entity%20Modeler%201.0.17.dmg and just make a new EOModel and save it and then double-click from Finder to see if mine works.  If my app doesn't work, then it's my bug. If it does, then it's your bug :)
Comment 27 Jordi Boehme Lopez CLA 2009-10-22 11:42:05 EDT
Hey Mike,

I tried you Application (really nice!), saved a ".eomodeld" file and closed the App.
Then I doubleclicked the ".eomodeld" file from the Finder.
Your app launched, but the ".eomodeld" file was not loaded!

So I guess, the bug is not on my side.
Comment 28 Mike Schrag CLA 2009-10-22 11:49:09 EDT
Must be another Leopard issue.  I had to change the ordering of the semaphore blocking when I went to Cocoa, and I'm wondering if there are subtle differences between L and SL for the events.  I'll take a look.  If you would, try it on Snow Leopard with your app and see if it works?
Comment 29 Mike Schrag CLA 2009-11-04 15:12:00 EST
Created attachment 151354 [details]
10.5/10.6 fat binary build of the equinox launcher

I've tested this on 32/64 bit snow leopard and 64bit leopard and both launch and pass the opened document through.  There was an issue with apple event handling that changed between 10.5 and 10.6 that was tripping it up before.
Comment 30 Mike Schrag CLA 2009-11-04 15:15:53 EST
Created attachment 151355 [details]
R351 Equinox Carbon/Cocoa patch (Leopard/Snow Leopard compat)

Here's the source for the changes.
Comment 31 Jeff McAffer CLA 2009-11-12 11:40:09 EST
Hey guys, is there any chance of some progress on this?  Strangely this topic seems to come up more and more in various RCP and even other scenarios.  The flows work on all machines other than our poor cousin the Mac :-)  Would it make sense to break the problem into chunks?  Seems like there are the following items:
1. getting the file info to the launcher
2. identifying running systems to pipe launched file info to
3. integration of these events into the workbench etc.

The first feels like a disparity relative to other platforms. Would be great to have that addressed.

#2 is way cool and there has been lots of discussion about how to do that on other platforms but to date it is not there. Would be great to have but would be a shame to hold up #1 for this.

#3 I'm not sure what is needed here and if that is related to #1 or just #2.
Thoughts?
Comment 32 Kevin Barnes CLA 2009-11-12 11:50:07 EST
This is under investigation at the moment. It's a complex problem that will require coordination of equinox (for launcher changes), SWT, and the workbench so it's going to take some time.
Comment 33 Jeff McAffer CLA 2009-11-12 21:13:37 EST
Thanks for the update Kevin.  I am wondering if we can divide and conquer by addressing the simple case (#1) and then going on to the more complex topics. Of course, I know very little about the details here but it seems like #1 should be considerably easier as a more constrained version of general case. From what I've seen, for the basic case, there is a working version on Leopard 64bit (or something) and but there are issues on Snow Leopard.
Comment 34 Kevin Barnes CLA 2009-11-12 22:19:35 EST
The launcher changes and SWT changes have to be made at the same time and I'm am getting close. I already have a working code for win32 and cocoa and I'm working on GTK. 

The workbench changes will be pretty simple. They'll have to listen and react to a new SWT event (probably SWT.OpenFile or something similar). Once I've got working code for all platforms, I'll help the workbench guys take advantage of it.

We haven't made a decision on how the file associations will be made in the OS. On mac, we can do it in the plist file, but on other platforms it's usually done by installers (I think). For the time being, we're considering that problem to be outside of the scope of this PR.
Comment 35 Mike Schrag CLA 2009-11-13 08:08:35 EST
Kevin -- In your impl, did you end up unifying the initially-launched-with-file vs the open-file-after-running so that they both fire an SWT event?  I was never happy with my impl that the developer had to handle them differently. I seem to recall it was tricky because SWT wasn't able to access the API that held the commandline params after launch (or something like that)?  Very interested to see what your approach was.
Comment 36 Kevin Barnes CLA 2009-11-13 10:12:46 EST
On cocoa, it was only necessary to handle the application:openFile: delegate message in your application delegate. The file name is passed in as an argument.

On windows it's a long story involving a mutex, a timer, some shared memory, and a message.
Comment 37 Mike Schrag CLA 2009-11-17 14:05:59 EST
Kevin -- would you be willing to share your patches for the Mac side?  It would be nice to standardize on a single impl and I can give you some feedback on them.
Comment 38 Kevin Barnes CLA 2009-11-17 14:17:13 EST
I will soon. I'm still working on a gtk implementation so I won't be able to make any API decisions until that's done.
Comment 39 Jordi Boehme Lopez CLA 2009-11-17 14:28:49 EST
I volunteer to test the Mac stuff as well! :)
Comment 40 Kevin Barnes CLA 2009-11-30 16:30:04 EST
Created attachment 153400 [details]
SWT patch

Patch includes changes for SWT for carbon, cocoa, win32 and gtk. There may be some printlns and general cleanup to do still.
Only new API is a constant in SWT that defines a new OpenDoc event. You'll have to add your listener to the display early (before calling readAndDispatch) to be sure not to miss any events. Also you'll need to be sure that the -name parameter is set in the eclipse.ini file to patch the name of the app as set when Display.setAppName is called. For Eclipse SDK, that name is "Eclipse".
This patch does not solve the problem of creating file associations in the first place, and it's reliant on equinox releasing the launcher patch attached to bug 178927.
Comment 41 Scott Kovatch CLA 2009-12-03 19:21:00 EST
Is this being targeted for 3.5.x or 3.6? I found out today Flash Catalyst is very motivated to take advantage of this as soon as possible.
Comment 42 Scott Kovatch CLA 2009-12-03 19:28:53 EST
(In reply to comment #41)
> Is this being targeted for 3.5.x or 3.6? I found out today Flash Catalyst is
> very motivated to take advantage of this as soon as possible.

Okay, not THAT motivated, it turns out. Catalyst 1.0 can't move to 3.5.x, but 2.0 will use 3.6, so Adobe doesn't absolutely need this to go into 3.5.
Comment 43 Kevin Barnes CLA 2009-12-03 20:15:39 EST
We won't add this for 3.5.2. We typically don't add new features to maintenance releases.
Targeting 3.6 M5.
Comment 44 Kevin Barnes CLA 2010-01-13 12:23:23 EST
Created attachment 156013 [details]
SWT patch (cleaned up)
Comment 45 Kevin Barnes CLA 2010-01-18 16:54:53 EST
Released patch for tonight's integration build. Launcher changes were made last week.
Comment 46 Markus Keller CLA 2010-01-20 07:08:26 EST
The Javadoc of OpenDoc is missing @see and @since tags, e.g. let it end with:

	 * 
	 * @see org.eclipse.swt.widgets.Display#addListener
	 * @see org.eclipse.swt.widgets.Event
	 * 
	 * @since 3.6
	 */
	public static final int OpenDoc = 46;
Comment 47 Kevin Barnes CLA 2010-01-20 11:02:26 EST
Thanks Markus. I corrected the doc in HEAD.
Comment 48 Kevin Barnes CLA 2010-01-20 16:22:26 EST
patch posts the OpenDoc event. That doesn't work because Display#runDeferredEvents only sends events to widgets (not display) so the event was never delivered. Stupid mistake. Will have a fix in HEAD shortly.
Comment 49 Kevin Barnes CLA 2010-01-22 17:29:37 EST
fixed > 2010-01-20
Comment 50 Scott Kovatch CLA 2010-06-18 16:52:33 EDT
*** Bug 273612 has been marked as a duplicate of this bug. ***