Is it possible to add a custom action in dock contextual menu for an AppleScript application?

I have this AppleScript that handles the lifecycle of an executable

global pid
    
    on run
        set pid to (do shell script "'{{EXE_PATH}}' configure &>/dev/null & echo $!" with administrator privileges)
    end run
    
    on idle
        try
          do shell script "ps -p " & pid
        on error
          quit
        end try
    
        return 1
    end idle
    
    on quit
        try
            do shell script "kill " & pid with administrator privileges
        on error errMsg
            #already killed ignore the error
        end try
        continue quit
    end quit

I would like to add a custom action in the dock contextual menu.

Online i found this code for the custom action that i want

on run
  ...
  tell current application's NSApp to set its delegate to me
end run

on applicationDockMenu:sender -- return a menu to be added to the Dock menu
    tell (current application's NSMenu's alloc's initWithTitle:"")
        its addItem:(current application's NSMenuItem's alloc's initWithTitle:"Custom action" action:"customAction:" keyEquivalent:"")
        return it
    end tell
end applicationDockMenu

on customAction:sender -- a regular action handler
    ...
end customAction:

image

The action works, but unfortunately, by setting the delegate i’m no longer able to close the application with the Quit button in the contextual menu. The application seems to be frozen and the only way to close it seems to be Force quit

How can i handle the quit logic? After changing the delegate the on quit is no longer invoked

1 Like

did you try to implement applicationShouldTerminate: (or Will)? I’m not sure it’s a solution, just a shot in the dark.

1 Like

Nice, as I see, you are creating a launcher for a background application that needs administrator privileges, and you need to add the possibility to send some contextual commands when the application is running.

I am not an expert of applescript, but I don’t feel the solution is to replace on quit with applicationWillTerminate, the on quit looks correct to me.

I think this tell current application's NSApp to set its delegate to me is overriding the default delegate and breaks the on quit.

But lets wait for some more experts in this forum, I am sure someone knows how to handle it properly.

1 Like

I tried it but it does not seem to work

Take a look at this topic, particularly the reply from @Piyomaru.

There are multiple AppleScript application runtimes (the application executable) that provide varying features. With the basic AppleScript application, by (re)setting the app delegate, you essentially disconnected the built-in menu item target/action settings for quit. Since you have access to the main menu, the settings there can be changed to the new app delegate, however, the applicationDockMenu delegate method just adds your items to those provided by the system, which will still use the applet runtime’s default target/action.

You would need to create an application using the Cocoa-AppleScript applet or Xcode project runtimes in order to keep the quit/terminate functionality, since they use a separate appDelegate script. When using the Cocoa-AppleScript applet (the version that works), for smaller applications the main.scpt can even be ignored, with everything done in the CocoaAppletAppDelegate script (located in the Resources folder of the template). Note that you would also need to use NSTimer instead of the idle handler, as these runtimes don’t implement it (it is just a wrapper around NSTimer anyway).

1 Like