C++ to UXP Communication
For developers with the intent to utilize the C++ based plugin SDK in conjunction with a UXP based plugin, the C++ SDK now includes a method to communicate with its UXP counterpart. On C++ side, we use the component's plugin name property in the plugin resource to identify plugins, and on UXP side, we use the id
field from the manifest.json
file.
PIUXPSuite
The PIUXPSuite communicates with UXP plugins using PIActionDescriptors. Use the ActionDescriptor suite as defined in the SDK's PIAction.h
whenever using this suite. To start with, grab PIUXPSuite.h and add it to your C++ project.
The signatures in PIUXPSuite.h
are as follows:
Copied to your clipboard1typedef void (*PIUXPMessageNotifier)(PIActionDescriptor descriptor);2typedef struct PsUXPSuite13{4 SPAPI SPErr (*SendUXPMessage) (SPPluginRef selfRef, const char* uxpPluginId, PIActionDescriptor descriptor);5 SPAPI SPErr (*AddUXPMessageListener) (SPPluginRef selfRef, PIUXPMessageNotifier notifier);6 SPAPI SPErr (*RemoveUXPMessageListener) (SPPluginRef selfRef);78} PsUXPSuite1;
CSDK to UXP messaging
PsUXPSuite1.SendUXPMessage
can be used to send messages to a UXP plugin given the plugin ID (from manifest.json
) and an action descriptor containing the message.
Includes and globals
First, make sure to include the right files and declare the globals to store the important pointers.
Copied to your clipboard1// Include these2#include "PIActions.h" // For PIActionDescriptor3#include "PIUXPSuite.h" // For messaging45// Your globals6SPBasicSuite * sSPBasic = NULL; // This is passed to your main function7SPPluginRef gPlugInRef = NULL; // This is passed to your main function8PsUXPSuite1* sUxpProcs = NULL; // You acquire this using sSPBasic9PSActionDescriptorProcs* sDescriptorProcs = NULL; // You acquire this using sSPBasic
Based on Plugin Type...
Automation Plugins: AutoPluginMain
For Automation plugins, the entry method is called AutoPluginMain
use the code below to extract the plugin reference and the basic suite.
Copied to your clipboard1DLLExport SPAPI SPErr AutoPluginMain(const char* caller, const char* selector, void* message) {23 SPMessageData* basicMessage = (SPMessageData*) message;4 sSPBasic = basicMessage->basic;5 gPlugInRef = basicMessage->self;6 ...
Filter plugins: PluginMain
Filter plugins use an entry method called PluginMain
, in which you can grab the basic suite and the plugin reference directly.
Copied to your clipboard1DLLExport MACPASCAL void PluginMain(const int16 selector,2 FilterRecordPtr filterRecord,3 intptr_t * data,4 int16 * result) {5 sSPBasic = filterRecord->sSPBasic;6 gPlugInRef = filterRecord->plugInRef;7 ...
Acquiring the suites
Next up is acquiring the correct suites to create your messages with ActionDescriptors and sending them to the UXP plugin of your choice.
Copied to your clipboard1// in your main method2 sSPBasic->AcquireSuite(kPSUXPSuite,3 kPSUXPSuiteVersion1,4 (const void**)&sUxpProcs);56 sSPBasic->AcquireSuite(kPSActionDescriptorSuite,7 kPSActionDescriptorSuiteVersion,8 (const void**)&sDescriptorProcs);910 PIActionDescriptor desc;11 sDescriptorProcs->Make(&desc);12 sDescriptorProcs->PutString(desc, 'helo', "Hello World!");13 sDescriptorProcs->PutFloat(desc, 'fltp', 0.952);1415 const char* UXP_MANIFEST_ID = "com.your.pluginId";16 sUxpProcs->SendUXPMessage(gPlugInRef, UXP_MANIFEST_ID, desc);17}
On your UXP plugin
Add a messaging listener using the messaging
API group. Any descriptors sent from a CSDK plugin to the ID of this plugin will arrive on this callback.
Copied to your clipboard1let callback = (o) => {2 console.log("Message from " + o.pluginId + ":" + o.message);3}45require('photoshop').messaging.addSDKMessagingListener(callback);67...8// You can remove your listener using this API9require('photoshop').messaging.removeSDKMessagingListener(callback);
UXP to CSDK messaging
For communication from a UXP plugin to a C plugin, define a listener within your CPlugin, and utilize both AddUXPMessageListener
and RemoveUXPMessageListener
at the appropriate time.
Listener Callback
All messages sent to this plugin will be handled in this method
Copied to your clipboard1void UXPMessageHandler(PIActionDescriptor descriptor) {2 // do something3}
Adding listener
Use the code below where you'd like to start listening to messages.
Copied to your clipboardsUxpProcs->AddUXPMessageListener(gPlugInRef, UXPMessageHandler);
Removing listener
Use the code below to stop listening to messages from UXP plugins.
Copied to your clipboardsUxpProcs->RemoveUXPMessageListener(gPlugInRef);
NOTE: Only one notifier per plugin may be registered.
Sending the message from UXP
To send messages to the C Plugin, take note of the Component Id as defined in its resouce PiPL
. This is the second parameter of the PIComponentProperty
.
With this Id, use the messaging group of the photoshop package to send your message across.
Copied to your clipboard1let messageContent = {2 status: "ok",3 filter: 4164};5window.require('photoshop').messaging.sendSDKPluginMessage(<YourPluginComponentId>, messageContent);