netbeans icon indicating copy to clipboard operation
netbeans copied to clipboard

Mac OS "Open With" does not open the files

Open mbastian opened this issue 3 years ago • 5 comments

Description

On Mac OS, Netbeans does not support opening files by double clicking or right clicking (Open With). Also, terminal commands like open foo.java -a /Applications/NetBeans/Apache\ NetBeans\ 13.app/ would open Netbeans but the file itself once started.

As there has been work recently on a native Swift launcher I wonder if that would make it easier to implement this one.

Thank you!

Use case/motivation

Opening files from Finder would make Netbeans more convenient to use.

Related issues

I know this was discussed previously but I couldn't locate a recent GH issue about it.

Are you willing to submit a PR?

  • [ ] Yes I am willing to submit a PR!

Code of Conduct

mbastian avatar Apr 19 '22 20:04 mbastian

@mbastian I looked into this and I do not believe it is possible with the current implementation. I think we would need to change the macOS Native launcher to use libjvm.dylib rather than just executing the unix shell script launcher. This is what the Windows launcher does. Such a change would probably require a discussion on the dev mailing list.

cc @neilcsmith-net @mcdonnell-john

oyarzun avatar Jul 23 '22 15:07 oyarzun

@oyarzun do you know where info on handling Open As events in Swift is? I wonder if the launcher can handle the event and pass to the shell script? Directly running the Swift launcher inside the App bundle with the file as an argument works as expected.

neilcsmith-net avatar Jul 27 '22 11:07 neilcsmith-net

@neilcsmith-net it is handled by the AppDelegate in a NSApplication, but console applications do not have an app delegate.

https://developer.apple.com/documentation/appkit/nsapplicationdelegate https://developer.apple.com/documentation/appkit/nsapplicationdelegate/2887193-application

This allows "open with" to work, but add an extra icon in the dock.

diff --git a/nb/ide.launcher/macosx/Sources/NetBeansLauncher/main.swift b/nb/ide.launcher/macosx/Sources/NetBeansLauncher/main.swift
index 923952ae1a..3c8b23cce7 100644
--- a/nb/ide.launcher/macosx/Sources/NetBeansLauncher/main.swift
+++ b/nb/ide.launcher/macosx/Sources/NetBeansLauncher/main.swift
@@ -18,21 +18,66 @@
 */

 import Foundation
+import AppKit

-let netbeansURL = Bundle.main.url(forResource: "netbeans", withExtension: "", subdirectory: "NetBeans/netbeans/bin")
+var openArgs = [String]()
+
+func launchNB() {
+    let launchNetbeans = Process()
+    launchNetbeans.arguments = args
+    launchNetbeans.executableURL = netbeansURL
+    do {
+        try launchNetbeans.run()
+    }
+    catch {
+        NSLog("NetBeans failed to start")
+    }
+
+    // needed to keep Dock name based on CFBundleName from Info.plist
+    // does not work if called from command line.
+    launchNetbeans.waitUntilExit()
+}
+
+class AppDelegate: NSObject, NSApplicationDelegate {
+    func application(_ application: NSApplication, open urls: [URL]) {
+        for url in urls {
+            args.append(url.path)
+            NSLog("urls %@", url.path)
+        }
+    }
+
+    func application(_ sender: NSApplication, openFile filename: String) -> Bool {
+        args.append(filename)
+        NSLog("openFile %@", filename)
+        return true
+    }
+
+    func application(_ sender: NSApplication, openFiles filenames: [String]) {
+        for filename in filenames {
+            args.append(filename)
+            NSLog("openFiles %@", filename)
+        }
+    }
+
+    func applicationDidFinishLaunching(_ notification: Notification) {
+        launchNB()
+    }
+}

 var args = [String]()
+let app = NSApplication.shared
+let delegate = AppDelegate()
+app.delegate = delegate
+
+
+let netbeansURL = Bundle.main.url(forResource: "netbeans", withExtension: "", subdirectory: "NetBeans/netbeans/bin")
+

 // add user's command line arguments
 for argument in Array(CommandLine.arguments.dropFirst()) {
     args.append(argument)
 }

-let launchNetbeans = Process()
-launchNetbeans.arguments = args
-launchNetbeans.executableURL = netbeansURL
-try launchNetbeans.run()

-// needed to keep Dock name based on CFBundleName from Info.plist
-// does not work if called from command line.
-launchNetbeans.waitUntilExit()
+app.run()
+

oyarzun avatar Jul 31 '22 15:07 oyarzun

it is handled by the AppDelegate in a NSApplication, but console applications do not have an app delegate.

Thanks. That was what I was looking for. I realise the difference with console applications, although is the Swift launcher calling the shell script also the reason the open files listener in applemenu is not working?

Is blocking the run loop with waitUntilExit a good idea?

neilcsmith-net avatar Aug 01 '22 11:08 neilcsmith-net

Is blocking the run loop with waitUntilExit a good idea?

It was the only way I could figure out to get the dock icon to not be called "java". But it does not work In the above diff.

Thanks. That was what I was looking for. I realise the difference with console applications, although is the Swift launcher calling the shell script also the reason the open files listener in applemenu is not working?

Maybe... Although, I just replaced the Swift launcher with a symlink to the bash script in the app bundle (the way it used to be), and the "Open with" does not work either. I'll do some debugging to see if there might be a solution via the applemenu.

oyarzun avatar Aug 01 '22 13:08 oyarzun