Close / hide the panel in uxp

Command ID… I don’t think I’ve heard of that and googling didn’t help much… What’s command ID and how do I get it and then how do I use it :sweat_smile:?
Maybe I can get it on the start of the panel, store it, and use it to toggle the UXP panel…

Check this post - it should point you to the right direction

1 Like

This rabbit hole is deep and you would not like the crazy world inside if you have to work with negative IDs.

You would rather take a “blue pill” and settle with the conclusion that it can’t be done :smiley:

1 Like

Not sure if this would help in your case, but I like to try and think of workarounds.

What if you made the “panel” an invisible panel that opened up a dialog with your panel stuff? Then you would have control of your sudo panel dialog.

getting the command ID on the 1st launch of the panel and then using it to toggle the panel seems to work! at least for now… :slight_smile: thanks!

kritskiy I’ve tried them all but it doesn’t work because it always gives me a negative id value, it only works at that moment, then when you open photoshop again it doesn’t work anymore or it opens another panel.

I’m also getting a negative number (from looking inside the menuBarInfo object), that then I use in the await core.performMenuCommand({commandID: ID}) to close the panel. You need to make sure the ID is set every time you start the panel for the first time

precisely, every time you restart photoshop you have to enter the panel id again, I use many panels and I can’t reset all the ids at every reboot. I’m amazed how this problem hasn’t been addressed yet.

I tried this snippet

const psCore = require('photoshop').core;
psCore.performMenuCommand({ "commandID": -20013});
1 Like

I’ve tried writing the code following your advice, and it works until I scroll through a menu. After that, I need to click the button twice to make it work again, as if the interface state doesn’t update. Do you have any solutions?

const core = require('photoshop').core;
const { executeAsModal } = require("photoshop").core;
async function toggleRetouchPanel(shouldBeVisible) {
    const batchCommands = {
        _obj: "get",
        _target: [
            {
                _property: "menuBarInfo"
            },
            {
                _ref: "application",
                _enum: "ordinal",
                _value: "targetEnum"
            }
        ],
    };

    let applicationState = await require('photoshop').action.batchPlay([batchCommands], {});
    let pluginsMenu = applicationState[0].menuBarInfo.submenu.find(menu => menu.name === core.translateUIString("$$$/Menu/Plugins"));
    let retouchMenu = pluginsMenu.submenu.find(menu => menu.title === "retouch");

    if (retouchMenu) {
        let retouchMenuItem = retouchMenu.submenu.find(item => item.title === "Retouch");
        if (retouchMenuItem && retouchMenuItem.checked !== shouldBeVisible) {
            let retouchCommandId = retouchMenuItem.command;
            console.log(`Executing Command ID: ${retouchCommandId}`);
            await core.performMenuCommand({ commandID: retouchCommandId });
        }
    } else {
        console.log("Retouch menu not found.");
    }
}

document.getElementById("showRetouchPanel").addEventListener('click', async () => {
    
     await executeAsModal(() => toggleRetouchPanel(true), { "commandName": "Show Retouch Panel" });
});


@svumme

I tried your script, unfortunately it doesn’t work
I put the name of my panel instead of retouch but it doesn’t work,
I use Mac,
If I get something wrong let me know


const core = require('photoshop').core;
const { executeAsModal } = require("photoshop").core;
async function toggleRetouchPanel(shouldBeVisible) {
    const batchCommands = {
        _obj: "get",
        _target: [
            {
                _property: "menuBarInfo"
            },
            {
                _ref: "application",
                _enum: "ordinal",
                _value: "targetEnum"
            }
        ],
    };

    let applicationState = await require('photoshop').action.batchPlay([batchCommands], {});
    let pluginsMenu = applicationState[0].menuBarInfo.submenu.find(menu => menu.name === core.translateUIString("$$$/Menu/Plugins"));
    let retouchMenu = pluginsMenu.submenu.find(menu => menu.title === "Name my panel");

    if (retouchMenu) {
        let retouchMenuItem = retouchMenu.submenu.find(item => item.title === "Name my panel");
        if (retouchMenuItem && retouchMenuItem.checked !== shouldBeVisible) {
            let retouchCommandId = retouchMenuItem.command;
            console.log(`Executing Command ID: ${retouchCommandId}`);
            await core.performMenuCommand({ commandID: retouchCommandId });
        }
    } else {
        console.log("Retouch menu not found.");
    }
}

document.getElementById("showName my panelPanel").addEventListener('click', async () => {
    
     await executeAsModal(() => toggleRetouchPanel(true), { "commandName": "Show Name my panel Panel" });
});

Check this answer. If I understand correctly what you’re asking, it might solve the issue:

1 Like

Thank you for the advice, the script works perfectly this way!


const core = require('photoshop').core;
const { executeAsModal } = require("photoshop").core;


async function getCommandState(commandId) {
    const descriptor = {
        _obj: 'uiInfo',
        _target: {
            _ref: 'application',
            _enum: 'ordinal',
            _value: 'targetEnum',
        },
        command: 'getCommandEnabled',
        commandID: commandId,
    };

    const result = await require('photoshop').action.batchPlay([descriptor], {});
    return result[0].result;
}


async function toggleRetouchPanel() {
    const batchCommands = {
        _obj: "get",
        _target: [
            {
                _property: "menuBarInfo"
            },
            {
                _ref: "application",
                _enum: "ordinal",
                _value: "targetEnum"
            }
        ],
    };

    let applicationState = await require('photoshop').action.batchPlay([batchCommands], {});
    let pluginsMenu = applicationState[0].menuBarInfo.submenu.find(menu => menu.name === core.translateUIString("$$$/Menu/Plugins"));
    let retouchMenu = pluginsMenu.submenu.find(menu => menu.title === "retouch");

    if (retouchMenu) {
        let retouchMenuItem = retouchMenu.submenu.find(item => item.title === "Retouch");
        if (retouchMenuItem) {
            
                await getCommandState(retouchMenuItem.command);
                console.log(`Executing Command ID: ${retouchMenuItem.command}`);
                await core.performMenuCommand({ commandID: retouchMenuItem.command });
        }
    } else {
        console.log("Retouch menu not found.");
    }
}


document.getElementById("showRetouchPanel").addEventListener('click', async () => {
    await executeAsModal(() => toggleRetouchPanel(), { "commandName": "Show Retouch Panel" });
});


2 Likes

I tried this script and managed to get it working on my mac
but now I have a problem,
if I put Photoshop in English it works if I put my language
it does not work.
the translation string is present in the script

core.translateUIString("$$$/Menu/Plugins")

Does anyone have an idea how to get around this problem

A strange thing happens to me

if I put these 2 strings it doesn’t open the side menu
the one when I click on the 3 tabs at the top right
if I remove them the menu works and the panel doesn’t work

Does anyone have an idea how to fix it

const core = require('photoshop').core;
const { executeAsModal } = require("photoshop").core;

Is it still the case that there’s no direct way to close a UXP panel via scripting aside from BatchPlay?

There really should be an API for this for UXP outside of PS.

Try using single quotes instead of double quotes, sometimes this silly thing can fix everything,