Photoshop command state change after uxpShowModal

Hey, in the simple example script below, if I check the state of a menu command before and after opening/closing a simple modal, the values are different (true before and false after).

The command in question is the ‘Undo’ command and it is ‘enabled’ before the modal execution according the menu command info provided by menuBarInfo

I’ve included the console dump attached below too… Any ideas?

I forgot to me mention, this only happens for some commands, and the command state is true when checked from the debug console after the palette is closed…

Thanks in advance for your help!

const { core } = require("photoshop");
const { entrypoints } = require("uxp");

console.log("loading plugin");

entrypoints.setup({
  commands: {
    launchPalette: () => launchPalette(),
  },
});

async function launchPalette() {
  console.log("launching palette");

  // check command state before modal
  const before = await core.getMenuCommandState({ commandID: 101 });
  console.log("command state (before modal):", before);

  // open modal
  const result = await openProgrammaticDialog();
  console.log("modal result:", result);

  // check command state after modal
  const after = await core.getMenuCommandState({ commandID: 101 });
  console.log("command state (after modal):", after);
}

// programmatic dialog
const openProgrammaticDialog = async () => {
  const theDialog = document.createElement("dialog");
  const doButton = document.createElement("sp-button");
  const doNotButton = document.createElement("sp-button");

  doButton.textContent = "Do!";
  doButton.setAttribute("variant", "cta");
  doNotButton.textContent = "Do Not.";
  doNotButton.setAttribute("variant", "secondary");

  doButton.onclick = () => {
    theDialog.close("ok");
  };
  doNotButton.onclick = () => {
    theDialog.close("reasonCanceled");
  };

  theDialog.appendChild(doNotButton);
  theDialog.appendChild(doButton);

  document.body.appendChild(theDialog);

  const r = await theDialog.uxpShowModal({ title: "Programmatic Dialog" });
  theDialog.remove();
  return r;
};

Console Log Dump:

main.js:13 launching palette
main.js:17 command state (before modal): [true]
main.js:21 modal result: ok
main.js:25 command state (after modal): [false]

Does the same happen if you use theDialog.close() (instead of remove())?
I believe UXP handles .close() differently

Edit: Oh, I see you’re closing it with buttons and removing from DOM. Nevermind

What happens if uxpShowModal is executed inside executeAsModal?

Photoshop seems to be made up of a very modal set of movements, so if you don’t indicate that a modal operation is modal and blocking, there may be inconsistencies in the movements. Not sure though.

1 Like

If you open dialog it blocks menu items. So you can’t click “undo” in menu. So you get false

@Jarda, in the code I posted, the dialog is opened and the. has been closed when I check the command state (the last time). Photoshop is no longer in a modal state after the dialog is closed. Also, if I run the check from the debug console, it returns true, and I can also click the actual menu item in the ui.

@sttk3, thanks for the idea! I’ll give it a try and report back.

1 Like

Hey @sttk3, it seems you were correct. By awaiting executeAsModal which awaits the actual modal, the state is correctly reported as true both before and after the modal. Thanks again for your insight! I’m not sure I would have ever even tried this approach. Cheers!

const result = await core.executeAsModal(await openProgrammaticDialog);
2 Likes

Happy to have that figured out.