Is it possible to read if Layers Panel is enabled?

I use this function to hide or undhide the Layers Panel for my plugin workflow:

//If Layers Panel is hidden it shows it, and viceversa.
async function toggleLayersPanel() {
  await runCommandID(1098);
}

async function runCommandID(id) {
  await core.performMenuCommand({ 
    commandID: id, 
    kcanDispatchWhileModal: true, 
    _isCommand: false 
  });
}

However, for a better experience as a developer and bring a better UX to users, I would like to read if the Layers Panel is hidden or not. Is it possible?

Using F7 or the function above toggles the Layers Panel, but I would know if the user has the Layers Panel visible or not.

Thanks!

Get panelList from the app. Find panel by panelId (you’ll need to check what’s the ID you need). Panel has visible and obscured properties

bp([
    {
        "_obj": "get",
        "_target": [
            {"_property": 'panelList'},
            {"_ref": "application", "_enum": "ordinal", "_value": "targetEnum"},
        ],
        "_options": {"dialogOptions": "dontDisplay"}
    }
])[0]['panelList']?.find(p => p.ID === panelId)
1 Like

Thanks Karmalakas, how is this supposed to work? Does the bp function returns anything? I tried to console.log() the result but it returns a pending promise.

const res = await batchPlay([
      {
        "_obj": "get",
        "_target": [
          { "_property": 'panelList' },
          { "_ref": "application", "_enum": "ordinal", "_value": "targetEnum" },
        ],
        "_options": { "dialogOptions": "dontDisplay" }
      }
    ])[0]['panelList']?.find(p => p.ID === panelId)

This gives me an error that ‘panelList’ is unfedined.

If I try to console.log() the next code:

const res = await batchPlay([
      {
        "_obj": "get",
        "_target": [
          { "_property": 'panelList' },
          { "_ref": "application", "_enum": "ordinal", "_value": "targetEnum" },
        ],
        "_options": { "dialogOptions": "dontDisplay" }
      }
    ]

It returns a pending promise. I’m kind of new with promises now in UXP so I don’t get it 100% how it works or how I could get the data from that batchPlay command.

Can you elaborate a little more? I would appreciate it! Seems I don’t get it right enough.

Oops… My bad
Forgot to add BP options

        {
            synchronousExecution: true,
            modalBehavior: "execute"
        }

So it would be:

bp(
  [
    {
      "_obj": "get",
      "_target": [
        {"_property": 'panelList'},
        {"_ref": "application", "_enum": "ordinal", "_value": "targetEnum"},
      ],
      "_options": {"dialogOptions": "dontDisplay"}
    }
  ],
  {
    synchronousExecution: true,
    modalBehavior: "execute"
  }
)[0]['panelList']?.find(p => p.ID === panelId)

synchronousExecution: true here is the key to get result

It’s a bit strange that with await batchPlay() you get a promise, because await should give you a normal result and then you could get panel like this:

res[0]['panelList']?.find(p => p.ID === panelId)
2 Likes

This works now perfect Karmalakas, thank you very much!!

Is there a way that I can make visible or not a specifiic panel with some command like this one? Instead the one I have with the runCommandID() function ?

I don’t know of any. I also use command ID, which IMO must be solved by Adobe. This makes no sense to me

1 Like

There have been some but those are no longer available for 3rd parties. I am not a fan of these restrictions.

You could try this one: https://developer.adobe.com/photoshop/uxp/2022/uxp/reference-js/Modules/uxp/Plugin%20Manager/Plugin/#showpanelpanelid But I don’t know if that support panels that you don’t own.

1 Like

From the description I understand this might actually work if you have in manifest v5 this:

"permissions": {        
    "ipc": {
        "enablePluginCommunication": true   
    }
}

Just not clear if this showPanel() is only for plugins panels or for all :thinking:

1 Like

I tested and can confirm that pluginManager is available only with permission.

2 Likes

@photonic Where did you find correct number for runCommandID?

I would like to hide some other panels

With this function you can get the list of all the panels and see their ID:

async function getPanelsList() {
    return await batchPlay([
        {
            "_obj": "get",
            "_target": [
                { "_property": 'panelList' },
                { "_ref": "application", 
                  "_enum": "ordinal", 
                  "_value": "targetEnum" },
            ],
            "_options": { "dialogOptions": "dontDisplay" }
        }
    ], {
        synchronousExecution: true,
        modalBehavior: "execute"
    })[0].panelList;
}

const panelsList = await getPanelsList();
  
console.log(panelsList);

And with this other function you can check if a panel is visible using its ID:

async function isPanelVisible(panelID) {
    const res = await batchPlay([
        {
            "_obj": "get",
            "_target": [
                { "_property": 'panelList' },
                { "_ref": "application",
                  "_enum": "ordinal", 
                  "_value": "targetEnum" },
            ],
            "_options": { "dialogOptions": "dontDisplay" }
        }
    ], {
        synchronousExecution: true,
        modalBehavior: "execute"
    })[0].panelList?.find(p => p.ID === panelID).visible;
    return res;
}

Then what you can do is use the Alchemist to listen when you hide or show the panel from the Window menu and it will log something like this, you should get the ID which will toggle the panel:

Then, use the ID with this function to toggle the panel, by toggle means that if it is open the function will close it, if it is closed the function will open it:

async function runCommandID(id) {
  await core.performMenuCommand({ commandID: id, 
  kcanDispatchWhileModal: true, _isCommand: false });
}

// This toggles the Layers panel
await runCommandID(1098);

So use the isPanelVisible("panelid.static.layers") function to see if the panel is visible and toggle it or viceversa, depends on what you want to show or hide, the runCommandID() remember it “toggles” the panel, not opens it estrictly, it opens if it i s closed or closes if it is opened.

Hope this is helpful!

2 Likes

The problem with publishing this is that Adobe might want to make this feature 1st party only in the next PS release. Same as UXP 3rd party can’t quit PS or toggle all panels even if ExtendScript DOM had API for that.

But I don’t understand how they decide what should be a first party or third party and what category this falls into.

If they do that they would be cutting our creative freedom. Hiding panels like layers, histogram, history, etc and so others ( which show pixel update data) can improve drastically UXP execution, so why doing it if the goal is going forward with better performance?? Shoud I delete the comment then?