Better way to see if a mask is active

I’m trying to see if a layer mask is active or not - that is to say, whether the currently active thing we’re editing is a layer mask or not (rather than whether a mask is enabled or present).

So far I’ve got this, which looks at app.activeDocument.activeChannels, which returns an error if a mask is active, but that seems hackish, and I’m hoping to get on the app store, so I’m wondering if there’s a better way that I’ve missed!

async function isMaskActive() {
    try {
        const app = require("photoshop").app;
        // This will throw an error if a mask is active
        app.activeDocument.activeChannels;
        return false;
    } catch (error) {
        // If we get the "Unknown or unsupported active channels" error,
        // it means we're in a mask
        if (error.message.includes("Unknown or unsupported active channels")) {
            return true;
        }
        // For any other error, we should probably rethrow it
        throw error;
    }
}

In Alchemist, there is a “targetChannels” property that appears to change depending on whether or not the layer mask is the active canvas. You might have to write a getter to access it, though. I’m not sure if it’s present in the DOM or not.

3 Likes

Thanks. Yes I see it in Alchemist but it doesn’t seem to be in the DOM.

This is a bit beyond my experience so I’ve had AI assist. With that caveat the following seems to work…

 //Checks if a layer mask or quick mask is currently active
async function isMaskActive() {
    const targetChannels = await getTargetChannels();
    // If targetChannels is a single channel with _index: 4, mask is active
    return (
        Array.isArray(targetChannels) &&
        targetChannels.length === 1 &&
        targetChannels[0]._index === 4
    );
}

async function getTargetChannels() {
    const app = require("photoshop").app;
    const doc = app.activeDocument;
    const layer = doc.activeLayers && doc.activeLayers.length > 0 ? doc.activeLayers[0] : null;
    if (!layer) {
        console.log("No active layer.");
        return null;
    }

    const result = await batchPlay(
        [{
            _obj: "get",
            _target: [
                { _ref: "layer", _id: layer.id }
            ],
            _options: { dialogOptions: "dontDisplay" }
        }],
        {}
    );
    // The targetChannels property should be in result[0]
    return result[0].targetChannels || null;
}