So I finally got my hands on migration from manifest v4 to v5 (been using API v2 since the beginning, but not new manifest). Seemed fine at first, but ended up spending a whole day just to find, that getters (which don’t even remotely change Ps state) also need to be inside executeAsModal()
Is that true or am I missing something?
This script runs perfectly fine from conslole, but when I put it into a plugin on button click it doesn’t work any more:
const photoshop = require("photoshop")
const layerId = await photoshop.action.batchPlay([{
"_obj": "get",
"_target": [
{ "_property": "targetLayersIDs" },
{ "_ref": "document", "_enum": "ordinal", "_value": "targetEnum" },
],
}], {
synchronousExecution: true,
modalBehavior: "execute",
})[0]["targetLayersIDs"][0]["_id"]
const rs = await photoshop.core.executeAsModal(async (executionContext) => {
let suspensionID
const hostControl = executionContext.hostControl
suspensionID = await hostControl.suspendHistory({
historyStateInfo: {
name: "HISTORY",
target: [{
_ref: "document",
_id: photoshop.app.activeDocument.id,
}],
},
})
await photoshop.action.batchPlay([
{
"_obj": "select",
"_target": [{ "_ref": "layer", "_id": layerId }],
"makeVisible": false,
},
{
"_obj": "select",
"_target": [{ "_ref": "channel", "_enum": "channel", "_value": "mask" }],
},
{
"_obj": "delete",
"_target": [{ "_ref": "channel", "_enum": "ordinal", "_value": "targetEnum" }],
},
{
"_obj": "select",
"_target": [{ "_ref": "layer", "_id": layerId }],
"makeVisible": false,
},
], {
synchronousExecution: true,
modalBehavior: "execute",
})
await photoshop.action.batchPlay([
{
"_obj": "select",
"_target": [{ "_ref": "layer", "_id": layerId }],
"makeVisible": false,
},
{
"_obj": "make",
"new": { "_class": "channel" },
"at": { "_ref": "channel", "_enum": "channel", "_value": "mask" },
"using": { "_enum": "userMaskEnabled", "_value": "hideAll" },
},
{ "_obj": "select", "_target": [{ "_ref": "layer", "_id": layerId }], "makeVisible": false },
], {
synchronousExecution: true,
modalBehavior: "execute",
})
hostControl.resumeHistory(suspensionID)
}, { commandName: "COMMAND NAME" })
In a nutshell:
- It gets selected layer
- Tries to delete a mask if it’s there
- Tries to create a new black mask on that layer
- Reselects the layer
As mentioned, from console it works every time.
If I put it into a plugin, I get these errors on two BatchPlays inside executeAsModal()
:
BpErr1 = { // From the first chunk of descriptors (delete mask)
"message": "My plugin: The command “Select” is not currently available.",
"failedDescriptor": {
"_obj": "select",
"_target": [
{ "_ref": "channel", "_enum": "channel", "_value": "mask" },
],
},
}
BpErr2 = { // From the second chunk of descriptors (create mask)
"message": "My plugin: The command “Make” is not currently available.",
"failedDescriptor": {
"_obj": "make",
"new": { "_class": "channel" },
"at": { "_ref": "channel", "_enum": "channel", "_value": "mask" },
"using": { "_enum": "userMaskEnabled", "_value": "hideAll" },
},
}
What I found after hours and hours of debugging, that if I move this part:
const layerId = await photoshop.action.batchPlay([{
"_obj": "get",
"_target": [
{ "_property": "targetLayersIDs" },
{ "_ref": "document", "_enum": "ordinal", "_value": "targetEnum" },
],
}], {
synchronousExecution: true,
modalBehavior: "execute",
})[0]["targetLayersIDs"][0]["_id"]
inside the same executeAsModal()
a bit lower, it starts working fine…
At some point I tried just setting manifest version back to 4
, but that didn’t help and the only thing I changed, was panels
part in entrypoints.setup()
. Also noticed, that even with getter outside execModal maybe once in 50 times it creates a mask (if there’s a mask already, it deletes every time)
What’s the deal?